Repository: peholmst/vaadin4spring
Branch: master
Commit: 8184d775454c
Files: 32
Total size: 120.0 KB
Directory structure:
gitextract_rbhuxx4x/
├── .gitignore
├── LICENSE.txt
├── README.md
├── eventbus/
│ ├── README.md
│ ├── pom.xml
│ └── src/
│ ├── main/
│ │ └── java/
│ │ └── org/
│ │ └── vaadin/
│ │ └── spring/
│ │ └── events/
│ │ ├── Event.java
│ │ ├── EventBus.java
│ │ ├── EventBusAware.java
│ │ ├── EventBusListener.java
│ │ ├── EventBusListenerMethodFilter.java
│ │ ├── EventScope.java
│ │ ├── ExactTopicFilter.java
│ │ ├── HierachyTopicFilter.java
│ │ ├── NoEventBusListenerMethodFilter.java
│ │ ├── TopicFilter.java
│ │ ├── annotation/
│ │ │ ├── EnableEventBus.java
│ │ │ ├── EventBusListenerMethod.java
│ │ │ ├── EventBusListenerTopic.java
│ │ │ └── EventBusProxy.java
│ │ ├── config/
│ │ │ └── EventBusConfiguration.java
│ │ ├── internal/
│ │ │ ├── AbstractListenerWrapper.java
│ │ │ ├── ClassUtils.java
│ │ │ ├── EventBusListenerWrapper.java
│ │ │ ├── ListenerCollection.java
│ │ │ ├── MethodListenerWrapper.java
│ │ │ └── ScopedEventBus.java
│ │ └── support/
│ │ ├── ApplicationContextEventBroker.java
│ │ └── VaadinEventBusAwareProcessor.java
│ └── test/
│ └── java/
│ └── org/
│ └── vaadin/
│ └── spring/
│ └── events/
│ ├── integration/
│ │ └── ScopedEventBusIntegrationTest.java
│ ├── internal/
│ │ └── ScopedEventBusTest.java
│ └── support/
│ └── ApplicationContextEventBrokerTest.java
└── pom.xml
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
*.orig
# Maven
target/
*.releaseBackup
release.properties
# IntelliJ
*.iml
.idea/
# Eclipse
.settings/
*.project
*.classpath
*.springBeans
# Vaadin
samples/*-sample*/src/main/webapp/VAADIN/themes/*.css
samples/*-sample*/src/main/webapp/VAADIN/themes/**/*.css
samples/*-sample*/src/main/webapp/VAADIN/widgetsets/
samples/*-sample*/src/main/resources/VAADIN/widgetsets/
samples/*-sample*/src/main/resources/VAADIN/themes/**/*.css
# JRebel
rebel.xml
================================================
FILE: LICENSE.txt
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================================================
FILE: README.md
================================================
Vaadin4Spring
=============
This project started as a prototype of an official Vaadin Spring add-on, back in the day when Vaadin 8 was new.
That was many years ago and a lot has happened since that time. Now we have Vaadin 14 and I have deleted almost all
of the extensions and addons since it did not make sense to port them to Vaadin 14.
All that remains is the event bus that is kept by popular demand. **Please note, however, that the event bus has a
design flaw that can lead to potentially serious security problems if used in the wrong way.** Check the
[README](eventbus/README.md) for more information.
================================================
FILE: eventbus/README.md
================================================
The Vaadin4Spring Event Bus
===========================
**Do not use this event bus in new projects.** This version is published to make it easier to port existing
applications that use Vaadin4Spring from Vaadin 8 to Vaadin 14.
## Security Issue with the Application Scoped Event Bus
You can run into serious security problems with the application scoped event bus if you are not careful. Events are
dispatched synchronously to all listeners in the thread that originally fired the event. This means that **all
event listeners will run within the security context of the user that fired the event**.
Because of this I seriously discourage developers from using the application scoped event bus in their projects.
I can't fix this issue either since that would break existing software that relies on the events being dispatched
in this way.
There are discussions of creating a completely new event bus for Vaadin 14+ that would not have this design flaw.
================================================
FILE: eventbus/pom.xml
================================================
<?xml version="1.0"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.vaadin.spring</groupId>
<artifactId>parent-pom</artifactId>
<version>14.0.1-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<groupId>org.vaadin.spring.addons</groupId>
<artifactId>vaadin-spring-addon-eventbus</artifactId>
<packaging>jar</packaging>
<name>Vaadin4Spring Event Bus</name>
<dependencies>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-spring</artifactId>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-spring-boot-starter</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
================================================
FILE: eventbus/src/main/java/org/vaadin/spring/events/Event.java
================================================
/*
* Copyright 2015 The original authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vaadin.spring.events;
import java.io.Serializable;
/**
* A class that represents an event that has been published on an {@link org.vaadin.spring.events.EventBus}.
*
* @author Petter Holmström (petter@vaadin.com)
* @see EventBus#publish(Object, Object)
*/
public class Event<T> implements Serializable {
private static final long serialVersionUID = 4818820872533486223L;
private final EventBus eventBus;
private final Object source;
private final String topic;
private final long timestamp;
private final T payload;
public Event(EventBus eventBus, Object source, T payload) {
this(eventBus, source, payload, "");
}
public Event(EventBus eventBus, Object source, T payload, String topic) {
this.eventBus = eventBus;
this.source = source;
this.payload = payload;
this.topic = topic != null ? topic : "";
this.timestamp = System.currentTimeMillis();
}
/**
* Gets the event bus on which the event was originally published.
*
* @return the event bus, never {@code null}.
*/
public EventBus getEventBus() {
return eventBus;
}
/**
* Gets the scope of the event.
*
* @return the scope, never {@code null}.
*/
public EventScope getScope() {
return eventBus.getScope();
}
/**
* Gets the object that published the event on the event bus.
*
* @return the source of the event, never {@code null}.
*/
public Object getSource() {
return source;
}
/**
* Gets the string which specifies the topic of the event on the event bus.
*
* @return the topic of the event, never {@code null}.
*/
public String getTopic() {
return topic;
}
/**
* Gets the timestamp when the event was published on the event bus.
*
* @return the timestamp.
*/
public long getTimestamp() {
return timestamp;
}
/**
* Gets the payload of the event.
*
* @return the payload, never {@code null}.
*/
public T getPayload() {
return payload;
}
@Override
public String toString() {
return String.format("%s[scope=%s, eventBus=%s, ts=%d, source=[%s], payload=[%s]]",
getClass().getSimpleName(), getScope(), getEventBus(), getTimestamp(), getSource(), getPayload());
}
}
================================================
FILE: eventbus/src/main/java/org/vaadin/spring/events/EventBus.java
================================================
/*
* Copyright 2015 The original authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vaadin.spring.events;
/**
* Interface defining an event bus. This event bus infrastructure complements the
* {@link org.springframework.context.ApplicationEventPublisher} in the following ways:
* <ul>
* <li>Events propagate from parent buses to children</li>
* <li>Events are scoped</li>
* </ul>
* <p>
* There are three event scopes, and therefore three event bus types (each with their own sub interface):
* <ol>
* <li>{@link EventScope#APPLICATION} events are published to the entire application.</li>
* <li>{@link EventScope#SESSION} events are published to the current session.</li>
* <li>{@link EventScope#UI} events are published to the current UI.</li>
* </ol>
* <p>
* The event buses are chained in the following way:
* <ul>
* <li>Application events are propagated to the session event bus.</li>
* <li>Session events are propagated to the UI event bus.</li>
* </ul>
* Furthermore, {@link org.springframework.context.ApplicationEventPublisher} events can be propagated to any event bus
* by using {@link org.vaadin.spring.events.support.ApplicationContextEventBroker}.
* <p>
* You select which {@code EventBus} implementation to inject by using the corresponding interface. For example, to
* inject the UI-scoped event bus, you would use:
* <code>
* @Autowired UIEventBus myUIScopedEventBus;
* </code>
* With this implementation, you can subscribe to and publish events of the application, session and UI scopes (see
* {@link #publish(EventScope, Object, Object)}).
*
* @author Petter Holmström (petter@vaadin.com)
*/
public interface EventBus {
/**
* Publishes the specified payload on the event bus, using the scope of this particular event bus.
*
* @param sender the object that published the event, never {@code null}.
* @param payload the payload of the event to publish, never {@code null}.
* @param <T> the type of the payload.
* @see #getScope()
*/
<T> void publish(Object sender, T payload);
/**
* Publishes the specified payload on the event bus, using the scope of this particular event bus.
* The topic specifies which listeners will be notified.
*
* @param topic the topic of the event to publish, never {@code null}.
* @param sender the object that published the event, never {@code null}.
* @param payload the payload of the event to publish, never {@code null}.
* @param <T> the type of the payload.
* @see #getScope()
*/
<T> void publish(String topic, Object sender, T payload);
/**
* Publishes the specified payload on the event bus, or any of its parent buses, depending on the event scope.
*
* @param scope the scope of the event, never {@code null}.
* @param sender the object that published the event, never {@code null}.
* @param payload the payload of the event to publish, never {@code null}.
* @param <T> the type of the payload;
* @throws UnsupportedOperationException if the payload could not be published with the specified scope.
* @see #publish(Object, Object)
*/
<T> void publish(EventScope scope, Object sender, T payload) throws UnsupportedOperationException;
/**
* Publishes the specified payload on the event bus, or any of its parent buses, depending on the event scope.
* The topic specifies which listeners will be notified.
*
* @param scope the scope of the event, never {@code null}.
* @param topic the topic of the event to publish, never {@code null}.
* @param sender the object that published the event, never {@code null}.
* @param payload the payload of the event to publish, never {@code null}.
* @param <T> the type of the payload;
* @throws UnsupportedOperationException if the payload could not be published with the specified scope.
* @see #publish(Object, Object)
*/
<T> void publish(EventScope scope, String topic, Object sender, T payload) throws UnsupportedOperationException;
/**
* Gets the scope of the events published on this event bus.
*
* @return the event scope, never {@code null}.
* @see org.vaadin.spring.events.Event#getScope()
*/
EventScope getScope();
/**
* Subscribes the specified listener to the event bus, including propagated events from parent event buses.
* The event bus will analyse the payload type of the listener to determine which events it is interested in
* receiving.
* This is the same as calling {@link #subscribe(EventBusListener, boolean) subscribe(listener, true)}.
*
* @param listener the listener to subscribe, never {@code null}.
* @param <T> the type of payload the listener is interested in.
* @see #unsubscribe(EventBusListener)
* @see #subscribeWithWeakReference(EventBusListener)
*/
<T> void subscribe(EventBusListener<T> listener);
/**
* Same as {@link #subscribe(EventBusListener)}, but uses a weak reference to store the listener internally.
*/
<T> void subscribeWithWeakReference(EventBusListener<T> listener);
/**
* Subscribes the topic interested listener to the event bus, including propagated events from parent event buses.
* The event bus will analyse the payload type and topic of the listener to determine which events it is interested
* in receiving.
* @param listener the listener to subscribe, never {@code null}
* @param topic the topic of listener interest
*
* @param <T> the type of payload the listener is interested in
*/
<T> void subscribe(EventBusListener<T> listener, String topic);
/**
* Same as {@link #subscribe(EventBusListener, String)}, but uses a weak reference to store the listener
* internally.
*/
<T> void subscribeWithWeakReference(EventBusListener<T> listener, String topic);
/**
* Subscribes the specified listener to the event bus. The event bus will analyse the
* payload type of the listener to determine which events it is interested in receiving.
*
* @param listener the listener to subscribe, never {@code null}.
* @param includingPropagatingEvents true to notify the listener of events that have propagated from the chain of
* parent event buses, false to only notify the listeners of events that are directly published on this event
* bus.
* @param <T> the type of payload the listener is interested in.
* @see #unsubscribe(EventBusListener)
* @see #subscribeWithWeakReference(EventBusListener, boolean)
*/
<T> void subscribe(EventBusListener<T> listener, boolean includingPropagatingEvents);
/**
* Same as {@link #subscribe(EventBusListener, boolean)}, but uses a weak reference to store the listener
* internally.
*/
<T> void subscribeWithWeakReference(EventBusListener<T> listener, boolean includingPropagatingEvents);
/**
* Subscribes the specified listener to the event bus. The listener need not implement the
* {@link org.vaadin.spring.events.EventBusListener} interface,
* but must contain one or more methods that are annotated with the
* {@link org.vaadin.spring.events.annotation.EventBusListenerMethod} interface and conform to one of these method
* signatures: <code>myMethodName(Event<MyPayloadType>)</code> or <code>myMethodName(MyPayloadType)</code>.
* The event bus will analyse the payload type of the listener methods to determine
* which events the different methods are interested in receiving. This is the same as calling
* {@link #subscribe(Object, boolean) subscribe(listener, true)}.
*
* @param listener the listener to subscribe, never {@code null}.
* @see #subscribeWithWeakReference(Object)
*/
void subscribe(Object listener);
/**
* Same as {@link #subscribe(Object)}, but uses a weak reference to store the listener internally.
*/
void subscribeWithWeakReference(Object listener);
/**
* Subscribes the topic interested listener to the event bus. The listener need not implement the
* {@link org.vaadin.spring.events.EventBusListener} interface,
* but must contain one or more methods that are annotated with the
* {@link org.vaadin.spring.events.annotation.EventBusListenerMethod} interface and conform to one of these method
* signatures: <code>myMethodName(Event<MyPayloadType>)</code> or <code>myMethodName(MyPayloadType)</code>.
* The event bus will analyse the payload type of the listener methods to determine
* which events the different methods are interested in receiving.
* <p>
* Example:
* <code>subscribe(Listener.this, "/news");</code>
* @param listener the listener to subscribe, never {@code null}.
* @param topic the topic of listener interest
* @see #subscribeWithWeakReference(Object, String)
*/
void subscribe(Object listener, String topic);
/**
* Same as {@link #subscribe(Object, String)}, but uses a weak reference to store the listener internally.
*/
void subscribeWithWeakReference(Object listener, String topic);
/**
* Subscribes the specified listener to the event bus. The listener need not implement the
* {@link org.vaadin.spring.events.EventBusListener} interface,
* but must contain one or more methods that are annotated with the
* {@link org.vaadin.spring.events.annotation.EventBusListenerMethod} interface and conform to one of these method
* signatures: <code>myMethodName(Event<MyPayloadType>)</code> or <code>myMethodName(MyPayloadType)</code>.
* The event bus will analyse the payload type of the listener methods to determine
* which events the different methods are interested in receiving.
*
* @param listener the listener to subscribe, never {@code null}.
* @param includingPropagatingEvents true to notify the listener of events that have propagated from the chain of
* parent event buses, false to only notify the listeners of events that are directly published on this event
* bus.
* @see #unsubscribe(Object)
* @see #subscribeWithWeakReference(Object, boolean)
*/
void subscribe(Object listener, boolean includingPropagatingEvents);
/**
* Same as {@link #subscribe(Object, boolean)}, but uses a weak reference to store the listener internally.
*/
void subscribeWithWeakReference(Object listener, boolean includingPropagatingEvents);
/**
* Unsubscribes the specified listener from the event bus. Also works for listeners stored with weak references.
*
* @param listener the listener to unsubscribe, never {@code null}.
* @param <T> the type of the payload.
* @see #subscribe(EventBusListener)
* @see #subscribe(EventBusListener, boolean)
*/
<T> void unsubscribe(EventBusListener<T> listener);
/**
* Unsubscribes the specified listener (and all its listener methods) from the event bus. Also works for listeners
* stored with weak references.
*
* @param listener the listener to unsubscribe, never {@code null}.
* @see #subscribe(Object)
* @see #subscribe(Object, boolean)
*/
void unsubscribe(Object listener);
/**
* Interface implemented by the application scoped event bus.
*
* @see org.vaadin.spring.events.EventScope#APPLICATION
*/
interface ApplicationEventBus extends EventBus {
}
/**
* Interface implemented by the session scoped event bus.
*
* @see org.vaadin.spring.events.EventScope#SESSION
*/
interface SessionEventBus extends EventBus {
}
/**
* Interface implemented by the UI scoped event bus.
*
* @see org.vaadin.spring.events.EventScope#UI
*/
interface UIEventBus extends EventBus {
}
}
================================================
FILE: eventbus/src/main/java/org/vaadin/spring/events/EventBusAware.java
================================================
/*
* Copyright 2015 The original authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vaadin.spring.events;
import org.springframework.beans.factory.Aware;
/**
* Marker super interface for beans that want to get notified of a specific type of event bus.
*
* @author Petter Holmström (petter@vaadin.com)
*/
public interface EventBusAware extends Aware {
/**
* Interface to be implemented by beans that want to get notified of the
* application event bus.
*/
interface ApplicationEventBusAware extends EventBusAware {
/**
* Sets the application scoped event bus.
*/
void setApplicationEventBus(EventBus.ApplicationEventBus applicationEventBus);
}
/**
* Interface to be implemented by beans that want to get notified of the
* session event bus.
*/
interface SessionEventBusAware extends EventBusAware {
/**
* Sets the session scoped event bus.
*/
void setSessionEventBus(EventBus.SessionEventBus sessionEventBus);
}
/**
* Interface to be implemented by beans that want to get notified of the
* UI event bus.
*/
interface UIEventBusAware extends EventBusAware {
/**
* Sets the UI scoped event bus.
*/
void setUIEventBus(EventBus.UIEventBus uiEventBus);
}
}
================================================
FILE: eventbus/src/main/java/org/vaadin/spring/events/EventBusListener.java
================================================
/*
* Copyright 2015 The original authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vaadin.spring.events;
import java.io.Serializable;
/**
* Interface to be implemented by listeners that want to subscribe to an {@link org.vaadin.spring.events.EventBus}.
*
* @param <T> type of event payloads that the listener is interested in receiving.
* @author Petter Holmström (petter@vaadin.com)
*/
public interface EventBusListener<T> extends Serializable {
/**
* Called when an event has been received.
*
* @param event the event, never {@code null}.
*/
void onEvent(Event<T> event);
}
================================================
FILE: eventbus/src/main/java/org/vaadin/spring/events/EventBusListenerMethodFilter.java
================================================
/*
* Copyright 2015 The original authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vaadin.spring.events;
/**
* <p>
* A method annotated with <code>@EventBusListenerMethod</code> will be invoked if it is
* subscribed to the <code>EventBus</code> that published the <code>Event</code>
* (or <code>Object</code> payload). That method will oftentimes employ filtering code
* in the method internals, because of the possibility that multiple annotated methods
* might listen to same the <code>Event</code>.
* </p>
* <p>
* As a convenience, an implementation of this filter may be defined in
* {@link org.vaadin.spring.events.annotation.EventBusListenerMethod#filter()}
* and stand in place of such filtering code.
* </p>
* @author Chris Phillipson (fastnsilver@gmail.com)
*
*/
public interface EventBusListenerMethodFilter {
/**
* Criteria used to influence when an <code>@EventBusListenerMethod</code>
* annotated method with this <code>filter</code> defined will execute
* @param event EventBus event
* @return true if filtering condition met; false otherwise
*/
boolean filter(Event<?> event);
}
================================================
FILE: eventbus/src/main/java/org/vaadin/spring/events/EventScope.java
================================================
/*
* Copyright 2015 The original authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vaadin.spring.events;
/**
* Enumeration of event scopes.
*
* @author Petter Holmström (petter@vaadin.com)
*/
public enum EventScope {
/**
* The event is application wide.
*/
APPLICATION,
/**
* The event is specific to the current (Vaadin) session.
*/
SESSION,
/**
* The event is specific to the current UI.
*/
UI,
/**
* Undefined event scope. An internal event scope used only when no scope has been explicitly defined.
*
* @see org.vaadin.spring.events.annotation.EventBusListenerMethod#scope()
*/
UNDEFINED
}
================================================
FILE: eventbus/src/main/java/org/vaadin/spring/events/ExactTopicFilter.java
================================================
/*
* Copyright 2015 The original authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vaadin.spring.events;
/**
* An implementation of {@link org.vaadin.spring.events.TopicFilter}
* which validates the topics with an exact match (equals).
*
* @author Marco Luthardt (marco.luthardt@iandme.net)
*/
public class ExactTopicFilter implements TopicFilter {
@Override
public boolean validTopic(String eventTopic, String listenerTopic) {
return eventTopic.equals(listenerTopic);
}
}
================================================
FILE: eventbus/src/main/java/org/vaadin/spring/events/HierachyTopicFilter.java
================================================
/*
* Copyright 2015 The original authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vaadin.spring.events;
/**
* An implementation of {@link org.vaadin.spring.events.TopicFilter}
* which validates the topics hierarchical. This means, that the
* listener filter will be checked as prefixed substring against
* the event topic.
*
* <ol>
* <li>match: <code>eventTopic = "foo.bar"</code> and <code>listenerTopic = "foo"</code></li>
* <li>no match: <code>eventTopic = "foo"</code> and <code>listenerTopic = "foo.bar"</code></li>
* <li>no match: <code>eventTopic = "foo.bar"</code> and <code>listenerTopic = "foo.not"</code></li>
* </ol>
*
* @author Marco Luthardt (marco.luthardt@iandme.net)
*/
public class HierachyTopicFilter implements TopicFilter {
@Override
public boolean validTopic(String eventTopic, String listenerTopic) {
return eventTopic.startsWith(listenerTopic);
}
}
================================================
FILE: eventbus/src/main/java/org/vaadin/spring/events/NoEventBusListenerMethodFilter.java
================================================
/*
* Copyright 2015 The original authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vaadin.spring.events;
/**
* A default filter implementation which always returns true.
* @author Chris Phillipson (fastnsilver@gmail.com)
* @see org.vaadin.spring.events.annotation.EventBusListenerMethod#scope()
*/
public class NoEventBusListenerMethodFilter implements EventBusListenerMethodFilter {
@Override
public boolean filter(Event<?> event) {
return true;
}
}
================================================
FILE: eventbus/src/main/java/org/vaadin/spring/events/TopicFilter.java
================================================
/*
* Copyright 2015 The original authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vaadin.spring.events;
/**
* The interface defines a method to validate a given event topic
* an listener topic. The event topic is provided when publishing
* an event and the listener topic by the {@link org.vaadin.spring.events.annotation.EventBusListenerTopic}
* annotation. An implementation of this interface can be used as
* parameter of this annotation.
*
* @author Marco Luthardt (marco.luthardt@iandme.net)
* @see org.vaadin.spring.events.annotation.EventBusListenerTopic
*/
public interface TopicFilter {
/**
* Validates the given event topic against the listener topic.
*
* @param eventTopic the topic provided by while publishing an event, never {@code null}
* @param listenerTopic the topic of the listener method, never {@code null}
*
* @return true true if the event topic matches the listener topic, otherwise false
*/
boolean validTopic(String eventTopic, String listenerTopic);
}
================================================
FILE: eventbus/src/main/java/org/vaadin/spring/events/annotation/EnableEventBus.java
================================================
/*
* Copyright 2015 The original authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vaadin.spring.events.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.context.annotation.Import;
import org.vaadin.spring.events.config.EventBusConfiguration;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(EventBusConfiguration.class)
public @interface EnableEventBus {
}
================================================
FILE: eventbus/src/main/java/org/vaadin/spring/events/annotation/EventBusListenerMethod.java
================================================
/*
* Copyright 2015 The original authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vaadin.spring.events.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.vaadin.spring.events.EventBus;
import org.vaadin.spring.events.EventBusListener;
import org.vaadin.spring.events.EventBusListenerMethodFilter;
import org.vaadin.spring.events.EventScope;
import org.vaadin.spring.events.NoEventBusListenerMethodFilter;
/**
* Annotation to be placed on event bus listener methods. A listener method must always conform to one of the following method signatures:
* <ol>
* <li><code>myMethodName({@link org.vaadin.spring.events.Event Event}<MyPayloadType>)</code></li>
* <li><code>myMethodName(MyPayloadType)</code></li>
* </ol>
* A listener method can have any visibility and any return type.
*
* @author Petter Holmström (petter@vaadin.com)
* @see org.vaadin.spring.events.EventBusListener
* @see EventBus#subscribe(Object)
* @see EventBus#subscribe(Object, boolean)
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface EventBusListenerMethod {
/**
* The default scope of a listener method is <code>EventScope.UNDEFINED</code>
* This means that listener will listen for any {@link EventScope} if {@link EventBus#subscribe(EventBusListener, boolean)} is set to propagate event
*/
EventScope scope() default EventScope.UNDEFINED;
Class<? extends EventBusListenerMethodFilter> filter() default NoEventBusListenerMethodFilter.class;
/**
* Filter by source class
*/
Class<?>[] source() default {};
}
================================================
FILE: eventbus/src/main/java/org/vaadin/spring/events/annotation/EventBusListenerTopic.java
================================================
/*
* Copyright 2015 The original authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vaadin.spring.events.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.vaadin.spring.events.ExactTopicFilter;
import org.vaadin.spring.events.TopicFilter;
/**
* Annotation to be placed on event bus listener methods, additional to
* the {@link org.vaadin.spring.events.annotation.EventBusListenerMethod} annotation.
* A topic is specified as string which will be defined when publishing an event.
* Each method annotated with this annotation and the corresponding topic will be
* called as listener.
*
* Topics can be filtered with implementations of the {@link org.vaadin.spring.events.TopicFilter} interface.
*
* @author Marco Luthardt (marco.luthardt@iandme.net)
* @see org.vaadin.spring.events.annotation.EventBusListenerMethod
* @see org.vaadin.spring.events.TopicFilter
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface EventBusListenerTopic {
/**
* A topic is a string which can be specified while publishing an event. The
* method will only called when the topic matches the given String in the
* published method.
*/
String topic() default "";
/**
* The filter to be used to validate the published and listener topic.
*
* @return an implementation of the {@link org.vaadin.spring.events.TopicFilter} interface.
*/
Class<? extends TopicFilter> filter() default ExactTopicFilter.class;
}
================================================
FILE: eventbus/src/main/java/org/vaadin/spring/events/annotation/EventBusProxy.java
================================================
/*
* Copyright 2015 The original authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vaadin.spring.events.annotation;
import org.springframework.beans.factory.annotation.Qualifier;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Qualifier to be used to indicate that a proxy of an {@link org.vaadin.spring.events.EventBus} should be injected.
*
* @author Petter Holmström (petter@vaadin.com)
*/
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@Qualifier
public @interface EventBusProxy {
}
================================================
FILE: eventbus/src/main/java/org/vaadin/spring/events/config/EventBusConfiguration.java
================================================
/*
* Copyright 2015 The original authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vaadin.spring.events.config;
import com.vaadin.flow.spring.scopes.VaadinSessionScope;
import com.vaadin.flow.spring.scopes.VaadinUIScope;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
import org.vaadin.spring.events.EventBus;
import org.vaadin.spring.events.annotation.EventBusProxy;
import org.vaadin.spring.events.internal.ScopedEventBus;
import org.vaadin.spring.events.support.VaadinEventBusAwareProcessor;
/**
* Configuration class to configure the Spring Vaadin Eventbus
*
* @author Gert-Jan Timmer (gjr.timmer@gmail.com)
*/
@Configuration
public class EventBusConfiguration {
@Bean
VaadinEventBusAwareProcessor vaadinEventBusProcessor() {
return new VaadinEventBusAwareProcessor();
}
@Bean
EventBus.ApplicationEventBus applicationEventBus() {
return new ScopedEventBus.DefaultApplicationEventBus();
}
@Bean
@Scope(value = VaadinSessionScope.VAADIN_SESSION_SCOPE_NAME, proxyMode = ScopedProxyMode.INTERFACES)
@EventBusProxy
EventBus.SessionEventBus proxiedSessionEventBus() {
return sessionEventBus();
}
@Bean
@Scope(value = VaadinSessionScope.VAADIN_SESSION_SCOPE_NAME, proxyMode = ScopedProxyMode.NO)
@Primary
EventBus.SessionEventBus sessionEventBus() {
return new ScopedEventBus.DefaultSessionEventBus(applicationEventBus());
}
@Bean
@Scope(value = VaadinUIScope.VAADIN_UI_SCOPE_NAME, proxyMode = ScopedProxyMode.INTERFACES)
@EventBusProxy
EventBus.UIEventBus proxiedUiEventBus() {
return uiEventBus();
}
@Bean
@Scope(value = VaadinUIScope.VAADIN_UI_SCOPE_NAME, proxyMode = ScopedProxyMode.NO)
@Primary
EventBus.UIEventBus uiEventBus() {
return new ScopedEventBus.DefaultUIEventBus(sessionEventBus());
}
}
================================================
FILE: eventbus/src/main/java/org/vaadin/spring/events/internal/AbstractListenerWrapper.java
================================================
/*
* Copyright 2015 The original authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vaadin.spring.events.internal;
import org.vaadin.spring.events.Event;
import org.vaadin.spring.events.EventBus;
/**
* Base implementation of {@link org.vaadin.spring.events.internal.ListenerCollection.Listener} that implements
* the {@link #supports(org.vaadin.spring.events.Event)} method. An event is supported if:
* <ul>
* <li>The payload type of the listener is either the same type as, or a supertype of, the payload type of the event</li>
* <li>The listener allows propagating events, or the event was originally published on event bus that the listener was subscribed to</li>
* </ul>
*
* @author Petter Holmström (petter@vaadin.com)
*/
abstract class AbstractListenerWrapper implements ListenerCollection.Listener {
private static final long serialVersionUID = 6211420845165980671L;
private final EventBus owningEventBus;
private final Object listenerTarget;
private final boolean includingPropagatingEvents;
private final String topic;
AbstractListenerWrapper(EventBus owningEventBus, Object listenerTarget, String topic, boolean includingPropagatingEvents) {
this.owningEventBus = owningEventBus;
this.topic = topic;
this.listenerTarget = listenerTarget;
this.includingPropagatingEvents = includingPropagatingEvents;
}
/**
* Gets the payload type of the listener.
*/
protected abstract Class<?> getPayloadType();
/**
* Gets the target object that this listener is wrapping.
*/
public Object getListenerTarget() {
return listenerTarget;
}
@Override
public boolean supports(Event<?> event) {
final Class<?> eventPayloadType = event.getPayload().getClass();
return (event.getTopic().equals(topic) || topic == null) &&
getPayloadType().isAssignableFrom(eventPayloadType) &&
(includingPropagatingEvents || event.getEventBus().equals(owningEventBus));
}
}
================================================
FILE: eventbus/src/main/java/org/vaadin/spring/events/internal/ClassUtils.java
================================================
/*
* Copyright 2015 The original authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vaadin.spring.events.internal;
/**
* Utility methods for working with classes and class members.
*
* @author Petter Holmström (petter@vaadin.com)
*/
final class ClassUtils {
private ClassUtils() {
}
/**
* Visitor interface used with {@link ClassUtils#visitClassHierarchy(ClassUtils.ClassVisitor, Class)}.
*/
public interface ClassVisitor {
void visit(Class<?> clazz);
}
/**
* Visits the entire class hierarchy from {@code subClass} to {@code Object}.
*
* @param visitor the visitor to use, must not be {@code null}.
* @param subClass the class whose hierarchy is to be visited, must not be {@code null}.
*/
static void visitClassHierarchy(ClassVisitor visitor, Class<?> subClass) {
Class<?> visitedClass = subClass;
while (visitedClass.getSuperclass() != null) {
visitor.visit(visitedClass);
visitedClass = visitedClass.getSuperclass();
}
}
}
================================================
FILE: eventbus/src/main/java/org/vaadin/spring/events/internal/EventBusListenerWrapper.java
================================================
/*
* Copyright 2015 The original authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vaadin.spring.events.internal;
import org.springframework.core.GenericTypeResolver;
import org.springframework.util.Assert;
import org.vaadin.spring.events.Event;
import org.vaadin.spring.events.EventBus;
import org.vaadin.spring.events.EventBusListener;
/**
* Implementation of {@link org.vaadin.spring.events.internal.AbstractListenerWrapper} that wraps a single
* {@link org.vaadin.spring.events.EventBusListener} instance.
*
* @author Petter Holmström (petter@vaadin.com)
*/
class EventBusListenerWrapper extends AbstractListenerWrapper {
private static final long serialVersionUID = 8964309195124823892L;
private final Class<?> payloadType;
EventBusListenerWrapper(EventBus owningEventBus, EventBusListener<?> listenerTarget, String topic, boolean includingPropagatingEvents) {
super(owningEventBus, listenerTarget, topic, includingPropagatingEvents);
payloadType = GenericTypeResolver.resolveTypeArgument(listenerTarget.getClass(), EventBusListener.class);
Assert.notNull(payloadType, "Could not resolve payload type");
}
@Override
@SuppressWarnings("rawtypes")
public EventBusListener getListenerTarget() {
return (EventBusListener) super.getListenerTarget();
}
@Override
protected Class<?> getPayloadType() {
return payloadType;
}
@Override
@SuppressWarnings("unchecked")
public void publish(Event<?> event) {
getListenerTarget().onEvent(event);
}
}
================================================
FILE: eventbus/src/main/java/org/vaadin/spring/events/internal/ListenerCollection.java
================================================
/*
* Copyright 2015 The original authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vaadin.spring.events.internal;
import java.io.Serializable;
import java.util.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.vaadin.spring.events.Event;
/**
* A collection of listeners. Intended only for internal use by the framework.
*
* @author Petter Holmström (petter@vaadin.com)
*/
class ListenerCollection implements Serializable {
private static final long serialVersionUID = -6237902400879667320L;
private final Logger logger = LoggerFactory.getLogger(getClass());
private final Set<Listener> listeners = new HashSet<Listener>();
private final Set<Listener> weakListeners = Collections.newSetFromMap(new WeakHashMap<Listener, Boolean>());
/**
* Interface defining a listener.
*/
public interface Listener extends Serializable {
/**
* Checks if this listener supports the specified event.
*
* @param event the event to check, never {@code null}.
* @return true if the event is supported, false otherwise.
*/
boolean supports(Event<?> event);
/**
* Publishes the event to the listener.
*
* @param event the event to publish, never {@code null}.
*/
void publish(Event<?> event);
}
/**
* Interface defining a listener filter.
*/
public interface ListenerFilter {
/**
* Checks if the specified listener passes the filter.
*
* @param listener the listener to check, never {@code null}.
* @return true if the listener passes the filter, false otherwise.
*/
boolean passes(Listener listener);
}
/**
* Adds the specified {@link org.vaadin.spring.events.internal.ListenerCollection.Listener} to the listener
* collection.
*
* @param listener the listener to add, never {@code null}.
* @see #remove(org.vaadin.spring.events.internal.ListenerCollection.Listener)
*/
void add(Listener listener) {
logger.trace("Adding listener [{}]", listener);
synchronized (listeners) {
listeners.add(listener);
}
}
/**
* Adds the specified {@link org.vaadin.spring.events.internal.ListenerCollection.Listener} to the listener
* collection,
* using a weak reference. This means the listener does not need to be removed to be eligible for garbage
* collection.
*
* @param listener the listener to add, never {@code null}.
*/
void addWithWeakReference(Listener listener) {
logger.trace("Adding listener [{}] using a weak reference", listener);
synchronized (weakListeners) {
weakListeners.add(listener);
}
}
/**
* Removes a {@link org.vaadin.spring.events.internal.ListenerCollection.Listener} previously added by
* {@link #add(org.vaadin.spring.events.internal.ListenerCollection.Listener)}.
* If no listener definition is found in the collection, nothing happens.
*
* @param listener the listener to remove, never {@code null}.
* @see #add(org.vaadin.spring.events.internal.ListenerCollection.Listener)
*/
void remove(Listener listener) {
logger.trace("Removing listener [{}]", listener);
synchronized (listeners) {
listeners.remove(listener);
}
synchronized (weakListeners) {
weakListeners.remove(listener);
}
}
/**
* Removes all {@link org.vaadin.spring.events.internal.ListenerCollection.Listener}s that pass the specified filter
* and that were previously added by
* {@link #add(org.vaadin.spring.events.internal.ListenerCollection.Listener)}.
*
* @param filter the filter that specifies which listeners to remove, never {@code null}.
*/
void removeAll(ListenerFilter filter) {
synchronized (listeners) {
removeFilteredListenersFromSet(filter, listeners);
}
synchronized (weakListeners) {
removeFilteredListenersFromSet(filter, weakListeners);
}
}
/**
* Removes all {@link org.vaadin.spring.events.internal.ListenerCollection.Listener}s from the collection.
*/
void clear() {
synchronized (listeners) {
listeners.clear();
}
synchronized (weakListeners) {
weakListeners.clear();
}
}
/**
* Publishes the specified {@code event} to all
* {@link org.vaadin.spring.events.internal.ListenerCollection.Listener}s that support it.
*
* @param event the event to publish, never {@code null}.
* @see org.vaadin.spring.events.internal.ListenerCollection.Listener#publish(org.vaadin.spring.events.Event)
* @see org.vaadin.spring.events.internal.ListenerCollection.Listener#supports(org.vaadin.spring.events.Event)
*/
public void publish(Event<?> event) {
Set<Listener> interestedListeners = new HashSet<Listener>();
synchronized (listeners) {
addSupportedListenersToSet(listeners, interestedListeners, event);
}
synchronized (weakListeners) {
addSupportedListenersToSet(weakListeners, interestedListeners, event);
}
if (interestedListeners.isEmpty()) {
logger.debug("No listeners supported event [{}]", event);
} else {
for (Listener listener : interestedListeners) {
logger.trace("Publishing event [{}] to listener [{}]", event, listener);
listener.publish(event);
}
}
}
private <T> void addSupportedListenersToSet(Set<Listener> candidateListeners, Set<Listener> selectedListeners,
Event<T> event) {
for (Listener candidateListener : candidateListeners) {
if (candidateListener.supports(event)) {
logger.trace("Listener [{}] supports event [{}]", candidateListener, event);
selectedListeners.add(candidateListener);
}
}
}
private void removeFilteredListenersFromSet(ListenerFilter filter, Set<Listener> listenerSet) {
for (Iterator<Listener> it = listenerSet.iterator(); it.hasNext();) {
Listener listener = it.next();
if (filter.passes(listener)) {
logger.trace("Removing listener [{}]", listener);
it.remove();
}
}
}
}
================================================
FILE: eventbus/src/main/java/org/vaadin/spring/events/internal/MethodListenerWrapper.java
================================================
/*
* Copyright 2015 The original authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vaadin.spring.events.internal;
import org.vaadin.spring.events.*;
import org.vaadin.spring.events.annotation.EventBusListenerMethod;
import org.vaadin.spring.events.annotation.EventBusListenerTopic;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
/**
* Implementation of {@link org.vaadin.spring.events.internal.AbstractListenerWrapper} that wraps an object
* that contains a method annotated with {@link org.vaadin.spring.events.annotation.EventBusListenerMethod}. If the object
* contains multiple listener methods, multiple instances of this class should be created.
*
* @author Petter Holmström (petter@vaadin.com)
*/
class MethodListenerWrapper extends AbstractListenerWrapper {
private static final long serialVersionUID = -3624543380547361337L;
private final Class<?> payloadType;
private final boolean payloadMethod;
private transient Method listenerMethod;
private final String topic;
MethodListenerWrapper(EventBus owningEventBus, Object listenerTarget, String topic, boolean includingPropagatingEvents, Method listenerMethod) {
super(owningEventBus, listenerTarget, topic, includingPropagatingEvents);
this.topic = topic;
if (listenerMethod.getParameterTypes()[0] == Event.class) {
ParameterizedType type = (ParameterizedType) listenerMethod.getGenericParameterTypes()[0];
payloadType = (Class<?>) type.getActualTypeArguments()[0];
payloadMethod = false;
} else {
payloadType = listenerMethod.getParameterTypes()[0];
payloadMethod = true;
}
this.listenerMethod = listenerMethod;
}
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
ois.defaultReadObject();
// TODO Read listener method info and look up method
}
private void writeObject(ObjectOutputStream oos) throws IOException {
oos.defaultWriteObject();
// TODO Write listener method info
}
@Override
public Class<?> getPayloadType() {
return payloadType;
}
@Override
public void publish(Event<?> event) {
listenerMethod.setAccessible(true);
try {
if (payloadMethod) {
listenerMethod.invoke(getListenerTarget(), event.getPayload());
} else {
listenerMethod.invoke(getListenerTarget(), event);
}
} catch (IllegalAccessException e) {
throw new RuntimeException("Could not access listener method " + listenerMethod.getName());
} catch (InvocationTargetException e) {
Throwable targetException = e.getTargetException();
if (targetException instanceof RuntimeException) {
throw (RuntimeException) targetException;
} else {
throw new RuntimeException("A checked exception occurred while invoking listener method " + listenerMethod.getName(), targetException);
}
}
}
@Override
public boolean supports(Event<?> event) {
boolean supports = super.supports(event);
try {
if (listenerMethod.isAnnotationPresent(EventBusListenerMethod.class)) {
supports = supports && isInterestedListenerMethod(event);
}
if (topic != null) {
return supports;
}
if (listenerMethod.isAnnotationPresent(EventBusListenerTopic.class) && supports) {
supports = isInTopic(event);
} else if (!event.getTopic().isEmpty()) {
supports = false;
}
} catch (Exception e) {
throw new RuntimeException("A checked exception occurred while invoking listener method " + listenerMethod.getName(), e);
}
return supports;
}
private boolean isInterestedListenerMethod(Event<?> event) throws InstantiationException, IllegalAccessException {
EventBusListenerMethod annotation = listenerMethod.getAnnotation(EventBusListenerMethod.class);
EventBusListenerMethodFilter filter = annotation.filter().newInstance();
EventScope scope = annotation.scope();
if (scope.equals(EventScope.UNDEFINED)) {
scope = event.getScope();
}
return filter.filter(event)
&& event.getScope().equals(scope) && isFromSource(event, annotation.source());
}
private boolean isFromSource(Event<?> event, Class<?>[] sources) {
if (sources.length == 0) {
return true;
}
boolean result = false;
for (int i = 0; i < sources.length && !result; i++) {
result |= sources[i].isAssignableFrom(event.getSource().getClass());
}
return result;
}
private boolean isInTopic(Event<?> event) throws InstantiationException, IllegalAccessException {
EventBusListenerTopic annotation = listenerMethod.getAnnotation(EventBusListenerTopic.class);
TopicFilter filter = annotation.filter().newInstance();
return filter.validTopic(event.getTopic(), annotation.topic());
}
}
================================================
FILE: eventbus/src/main/java/org/vaadin/spring/events/internal/ScopedEventBus.java
================================================
/*
* Copyright 2015 The original authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vaadin.spring.events.internal;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.framework.Advised;
import org.springframework.aop.support.AopUtils;
import org.vaadin.spring.events.Event;
import org.vaadin.spring.events.EventBus;
import org.vaadin.spring.events.EventBusListener;
import org.vaadin.spring.events.EventScope;
import org.vaadin.spring.events.annotation.EventBusListenerMethod;
import javax.annotation.PreDestroy;
import java.io.Serializable;
import java.lang.reflect.Method;
/**
* Implementation of {@link org.vaadin.spring.events.EventBus} that publishes events with one specific
* {@link org.vaadin.spring.events.EventScope}.
* A scoped event bus can also have a parent event bus, in which case all events published on the parent bus will
* propagate to the scoped event bus as well.
*
* @author Petter Holmström (petter@vaadin.com)
*/
public abstract class ScopedEventBus implements EventBus, Serializable {
private static final long serialVersionUID = -582697574672947883L;
private final Logger logger = LoggerFactory.getLogger(getClass());
private final EventScope eventScope;
private final ListenerCollection listeners = new ListenerCollection();
private EventBus parentEventBus;
private EventBusListener<Object> parentListener = new EventBusListener<Object>() {
private static final long serialVersionUID = -8276470908536582989L;
@Override
public void onEvent(final Event<Object> event) {
logger.debug("Propagating event [{}] from parent event bus [{}] to event bus [{}]", event, parentEventBus,
ScopedEventBus.this);
listeners.publish(event);
}
};
/**
* @param scope the scope of the events that this event bus handles.
*/
public ScopedEventBus(EventScope scope) {
this(scope, null);
}
/**
* @param scope the scope of the events that this event bus handles.
* @param parentEventBus the parent event bus to use, may be {@code null};
*/
public ScopedEventBus(EventScope scope, EventBus parentEventBus) {
eventScope = scope;
this.parentEventBus = parentEventBus;
if (parentEventBus != null) {
if (AopUtils.isJdkDynamicProxy(parentEventBus)) {
logger.debug("Parent event bus [{}] is proxied, trying to get the real EventBus instance",
parentEventBus);
try {
this.parentEventBus = (EventBus) ((Advised) parentEventBus).getTargetSource().getTarget();
} catch (Exception e) {
logger.error("Could not get target EventBus from proxy", e);
throw new RuntimeException("Could not get parent event bus", e);
}
}
logger.debug("Using parent event bus [{}]", this.parentEventBus);
this.parentEventBus.subscribe(parentListener);
}
}
@PreDestroy
void destroy() {
logger.trace("Destroying event bus [{}] and removing all listeners", this);
listeners.clear();
if (parentEventBus != null) {
parentEventBus.unsubscribe(parentListener);
}
}
@Override
public EventScope getScope() {
return eventScope;
}
@Override
public <T> void publish(Object sender, T payload) {
publish("", sender, payload);
}
@Override
public <T> void publish(String topic, Object sender, T payload) {
logger.debug("Publishing payload [{}] from sender [{}] on event bus [{}] in topic [{}]", payload, sender, this,
topic);
listeners.publish(new Event<T>(this, sender, payload, topic));
}
@Override
public <T> void publish(EventScope scope, Object sender, T payload) throws UnsupportedOperationException {
publish(scope, "", sender, payload);
}
@Override
public <T> void publish(EventScope scope, String topic, Object sender, T payload)
throws UnsupportedOperationException {
logger.debug("Trying to publish payload [{}] from sender [{}] using scope [{}] on event bus [{}] in topic [{}]",
payload, sender, scope, this, topic);
if (eventScope.equals(scope)) {
publish(topic, sender, payload);
} else if (parentEventBus != null) {
parentEventBus.publish(scope, topic, sender, payload);
} else {
logger.warn("Could not publish payload with scope [{}] on event bus [{}]", scope, this);
throw new UnsupportedOperationException("Could not publish event with scope " + scope);
}
}
@Override
public <T> void subscribe(EventBusListener<T> listener) {
subscribe(listener, true);
}
@Override
public <T> void subscribeWithWeakReference(EventBusListener<T> listener) {
subscribeWithWeakReference(listener, true);
}
@Override
public <T> void subscribe(EventBusListener<T> listener, String topic) {
logger.trace("Subscribing listener [{}] to event bus [{}]", listener, this);
listeners.add(new EventBusListenerWrapper(this, listener, topic, true));
}
@Override
public <T> void subscribe(EventBusListener<T> listener, boolean includingPropagatingEvents) {
logger.trace("Subscribing listener [{}] to event bus [{}], includingPropagatingEvents = {}", listener, this,
includingPropagatingEvents);
listeners.add(new EventBusListenerWrapper(this, listener, null, includingPropagatingEvents));
}
@Override
public <T> void subscribeWithWeakReference(EventBusListener<T> listener, String topic) {
logger.trace("Subscribing listener [{}] to event bus [{}] with weak reference",
listener, this);
listeners.addWithWeakReference(new EventBusListenerWrapper(this, listener, topic, true));
}
@Override
public <T> void subscribeWithWeakReference(EventBusListener<T> listener, boolean includingPropagatingEvents) {
logger.trace("Subscribing listener [{}] to event bus [{}] with weak reference, includingPropagatingEvents = {}",
listener, this, includingPropagatingEvents);
listeners.addWithWeakReference(new EventBusListenerWrapper(this, listener, null, includingPropagatingEvents));
}
@Override
public void subscribe(Object listener) {
subscribe(listener, true);
}
@Override
public void subscribe(Object listener, String topic) {
subscribe(listener, topic, true, false);
}
@Override
public void subscribeWithWeakReference(Object listener, String topic) {
subscribe(listener, topic, true, false);
}
@Override
public void subscribeWithWeakReference(Object listener) {
subscribeWithWeakReference(listener, true);
}
@Override
public void subscribe(Object listener, boolean includingPropagatingEvents) {
subscribe(listener, null, includingPropagatingEvents, false);
}
@Override
public void subscribeWithWeakReference(Object listener, boolean includingPropagatingEvents) {
subscribe(listener, null, includingPropagatingEvents, true);
}
private void subscribe(final Object listener, final String topic, final boolean includingPropagatingEvents,
final boolean weakReference) {
logger.trace("Subscribing listener [{}] to event bus [{}], includingPropagatingEvents = {}, weakReference = {}",
listener, this, includingPropagatingEvents, weakReference);
final int[] foundMethods = new int[1];
ClassUtils.visitClassHierarchy(clazz -> {
for (Method m : clazz.getDeclaredMethods()) {
if (m.isAnnotationPresent(EventBusListenerMethod.class)) {
if (m.getParameterTypes().length == 1) {
logger.trace("Found listener method [{}] in listener [{}]", m.getName(), listener);
MethodListenerWrapper l = new MethodListenerWrapper(ScopedEventBus.this, listener, topic,
includingPropagatingEvents, m);
if (weakReference) {
listeners.addWithWeakReference(l);
} else {
listeners.add(l);
}
foundMethods[0]++;
} else {
throw new IllegalArgumentException(
"Listener method " + m.getName() + " does not have the required signature");
}
}
}
}, listener.getClass());
if (foundMethods[0] == 0) {
logger.warn("Listener [{}] did not contain a single listener method!", listener);
}
}
@Override
public <T> void unsubscribe(EventBusListener<T> listener) {
unsubscribe((Object) listener);
}
@Override
public void unsubscribe(final Object listener) {
logger.trace("Unsubscribing listener [{}] from event bus [{}]", listener, this);
listeners.removeAll(l -> (l instanceof AbstractListenerWrapper)
&& (((AbstractListenerWrapper) l).getListenerTarget() == listener));
}
/**
* Gets the parent of this event bus. Events published on the parent bus will also
* propagate to the listeners of this event bus.
*
* @return the parent event bus, or {@code null} if this event bus has no parent.
*/
protected EventBus getParentEventBus() {
return parentEventBus;
}
@Override
public String toString() {
return String.format("%s[id=%x, eventScope=%s, parentEventBus=%s]", getClass().getSimpleName(),
System.identityHashCode(this), eventScope, parentEventBus);
}
/**
* Default implementation of {@link org.vaadin.spring.events.EventBus.ApplicationEventBus}.
*/
public static class DefaultApplicationEventBus extends ScopedEventBus implements ApplicationEventBus {
public DefaultApplicationEventBus() {
super(EventScope.APPLICATION);
}
}
/**
* Default implementation of {@link org.vaadin.spring.events.EventBus.SessionEventBus}.
*/
public static class DefaultSessionEventBus extends ScopedEventBus implements SessionEventBus {
public DefaultSessionEventBus(ApplicationEventBus parentEventBus) {
super(EventScope.SESSION, parentEventBus);
}
}
/**
* Default implementation of {@link org.vaadin.spring.events.EventBus.UIEventBus}.
*/
public static class DefaultUIEventBus extends ScopedEventBus implements UIEventBus {
public DefaultUIEventBus(SessionEventBus parentEventBus) {
super(EventScope.UI, parentEventBus);
}
}
}
================================================
FILE: eventbus/src/main/java/org/vaadin/spring/events/support/ApplicationContextEventBroker.java
================================================
/*
* Copyright 2015 The original authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vaadin.spring.events.support;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.vaadin.spring.events.EventBus;
/**
* An {@link org.springframework.context.ApplicationListener} that will forward all received events to an {@link org.vaadin.spring.events.EventBus}.
*
* @author Petter Holmström (petter@vaadin.com)
*/
public class ApplicationContextEventBroker implements ApplicationListener<ApplicationEvent> {
private Log logger = LogFactory.getLog(getClass());
private final EventBus eventBus;
public ApplicationContextEventBroker(EventBus eventBus) {
this.eventBus = eventBus;
}
@Override
public void onApplicationEvent(ApplicationEvent event) {
logger.debug(String.format("Propagating application event [%s] to event bus [%s]", event, this));
eventBus.publish(event.getSource(), event);
}
}
================================================
FILE: eventbus/src/main/java/org/vaadin/spring/events/support/VaadinEventBusAwareProcessor.java
================================================
/*
* Copyright 2015 The original authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vaadin.spring.events.support;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ConfigurableApplicationContext;
import org.vaadin.spring.events.EventBus;
import org.vaadin.spring.events.EventBusAware;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.PrivilegedAction;
/**
* {@link org.springframework.beans.factory.config.BeanPostProcessor}
* implementation that passes the corresponding EventBus to beans that
* implement the one of the {@link org.vaadin.spring.events.EventBusAware} interfaces
*
* @author Gert-Jan Timmer (gjr.timmer@gmail.com)
* @author Petter Holmström (petter@vaadin.com)
*/
public class VaadinEventBusAwareProcessor implements ApplicationContextAware, BeanPostProcessor {
private ConfigurableApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = (ConfigurableApplicationContext) applicationContext;
}
@Override
public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
AccessControlContext acc = null;
if (System.getSecurityManager() != null && (bean instanceof EventBusAware)) {
acc = this.applicationContext.getBeanFactory().getAccessControlContext();
}
if (acc != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareInterfaces(bean);
return null;
}, acc);
} else {
invokeAwareInterfaces(bean);
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
private void invokeAwareInterfaces(Object bean) {
if (bean instanceof EventBusAware) {
if (bean instanceof EventBusAware.ApplicationEventBusAware) {
((EventBusAware.ApplicationEventBusAware) bean).setApplicationEventBus(this.applicationContext.getBean(EventBus.ApplicationEventBus.class));
}
if (bean instanceof EventBusAware.SessionEventBusAware) {
((EventBusAware.SessionEventBusAware) bean).setSessionEventBus(this.applicationContext.getBean(EventBus.SessionEventBus.class));
}
if (bean instanceof EventBusAware.UIEventBusAware) {
((EventBusAware.UIEventBusAware) bean).setUIEventBus(this.applicationContext.getBean(EventBus.UIEventBus.class));
}
}
}
}
================================================
FILE: eventbus/src/test/java/org/vaadin/spring/events/integration/ScopedEventBusIntegrationTest.java
================================================
package org.vaadin.spring.events.integration;
import com.vaadin.flow.component.UI;
import com.vaadin.flow.server.VaadinService;
import com.vaadin.flow.server.VaadinSession;
import com.vaadin.flow.spring.SpringVaadinSession;
import com.vaadin.flow.spring.annotation.EnableVaadin;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.vaadin.spring.events.EventBus;
import org.vaadin.spring.events.config.EventBusConfiguration;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.when;
/**
* Test cases for the different event bus scopes
*
* @author erik@vaadin.com
* @since 14/02/2019
*/
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {EventBusConfiguration.class, ScopedEventBusIntegrationTest.Config.class})
class ScopedEventBusIntegrationTest {
@Configuration
@EnableVaadin
public static class Config {
}
public static class TestSession extends SpringVaadinSession {
TestSession() {
super(Mockito.mock(VaadinService.class));
}
@Override
public boolean hasLock() {
return true;
}
@Override
public void lock() {
}
@Override
public void unlock() {
}
}
private static int uiId = 0;
@Autowired
ApplicationContext applicationContext;
@BeforeEach
public void setUp() {
MockitoAnnotations.initMocks(this);
VaadinSession.setCurrent(new TestSession());
UI.setCurrent(createMockUI());
}
@Test
void testSameUIReturnsSameUIEventBus() {
EventBus.UIEventBus uiBus = applicationContext.getBean(EventBus.UIEventBus.class);
EventBus.UIEventBus uiBus2 = applicationContext.getBean(EventBus.UIEventBus.class);
assertEquals(uiBus, uiBus2, "Same UI should return same UIEventBus");
}
@Test
void testDifferentUIReturnsDifferentUIEventBus() {
EventBus.UIEventBus uiBus = applicationContext.getBean(EventBus.UIEventBus.class);
UI.setCurrent(createMockUI());
EventBus.UIEventBus uiBus2 = applicationContext.getBean(EventBus.UIEventBus.class);
assertNotEquals(uiBus, uiBus2, "Different UIs should return different UIEventBuses");
}
@Test
void testNoUIThrowsBeanCreationException() {
UI.setCurrent(null);
assertThrows(BeanCreationException.class, () -> applicationContext.getBean(EventBus.UIEventBus.class));
}
@Test
void testSameSessionReturnsSameSessionEventBus() {
EventBus.SessionEventBus sessionBus = applicationContext.getBean(EventBus.SessionEventBus.class);
EventBus.SessionEventBus sessionBus2 = applicationContext.getBean(EventBus.SessionEventBus.class);
assertEquals(sessionBus, sessionBus2, "Same session should return same SessionEventBus");
}
@Test
void testSameSessionDifferentUIReturnsSameSessionEventBus() {
EventBus.SessionEventBus sessionBus = applicationContext.getBean(EventBus.SessionEventBus.class);
UI.setCurrent(createMockUI());
EventBus.SessionEventBus sessionBus2 = applicationContext.getBean(EventBus.SessionEventBus.class);
assertEquals(sessionBus, sessionBus2, "Same session different UIs should return same SessionEventBus");
}
@Test
void testDifferentSessionsReturnDifferentSessionEventBuses() {
EventBus.SessionEventBus sessionBus = applicationContext.getBean(EventBus.SessionEventBus.class);
VaadinSession.setCurrent(new TestSession());
EventBus.SessionEventBus sessionBus2 = applicationContext.getBean(EventBus.SessionEventBus.class);
assertNotEquals(sessionBus, sessionBus2, "Different sessions should return different SessionEventBuses");
}
@Test
void sameApplicationReturnsSameApplicationEventBus() {
EventBus.ApplicationEventBus applicationBus = applicationContext.getBean(EventBus.ApplicationEventBus.class);
EventBus.ApplicationEventBus applicationBus2 = applicationContext.getBean(EventBus.ApplicationEventBus.class);
assertEquals(applicationBus, applicationBus2, "ApplicationEventBus should always be the same");
}
@Test
void sameApplicationDifferentUIReturnsSameApplicationEventBus() {
EventBus.ApplicationEventBus applicationBus = applicationContext.getBean(EventBus.ApplicationEventBus.class);
UI.setCurrent(createMockUI());
EventBus.ApplicationEventBus applicationBus2 = applicationContext.getBean(EventBus.ApplicationEventBus.class);
assertEquals(applicationBus, applicationBus2, "ApplicationEventBus should always be the same");
}
@Test
void sameApplicationDifferentSessionReturnsSameApplicationEventBus() {
EventBus.ApplicationEventBus applicationBus = applicationContext.getBean(EventBus.ApplicationEventBus.class);
VaadinSession.setCurrent(new TestSession());
EventBus.ApplicationEventBus applicationBus2 = applicationContext.getBean(EventBus.ApplicationEventBus.class);
assertEquals(applicationBus, applicationBus2, "ApplicationEventBus should always be the same");
}
/**
* Creates a new mock UI with a unique ID
*/
private UI createMockUI() {
UI ui = Mockito.mock(UI.class);
int id = uiId++;
when(ui.getUIId()).thenReturn(id);
return ui;
}
}
================================================
FILE: eventbus/src/test/java/org/vaadin/spring/events/internal/ScopedEventBusTest.java
================================================
/*
* Copyright 2015 The original authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vaadin.spring.events.internal;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
import org.vaadin.spring.events.Event;
import org.vaadin.spring.events.EventBusListener;
import org.vaadin.spring.events.EventScope;
import org.vaadin.spring.events.HierachyTopicFilter;
import org.vaadin.spring.events.annotation.EventBusListenerMethod;
import org.vaadin.spring.events.annotation.EventBusListenerTopic;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;
/**
* Test case for {@link org.vaadin.spring.events.internal.ScopedEventBus}.
*
* @author Petter Holmström (petter@vaadin.com)
*/
public class ScopedEventBusTest {
ScopedEventBus.DefaultApplicationEventBus applicationEventBus;
ScopedEventBus.DefaultSessionEventBus sessionEventBus;
interface StringListener extends EventBusListener<String> {
}
static class MultipleListeners {
Event<String> theStringEvent;
Event<Integer> theIntegerEvent;
String theStringPayload;
Integer theIntegerPayload;
Event<String> theStringEventWithTopic;
Event<Integer> theIntegerEventWithTopic;
String theStringPayloadWithTopic;
Integer theIntegerPayloadWithTopic;
String theStringPayloadWithTopicFail;
Integer theIntegerPayloadWithTopicFail;
@EventBusListenerMethod
void onStringEvent(Event<String> stringEvent) {
theStringEvent = stringEvent;
}
@EventBusListenerMethod
void onStringPayloadEvent(String stringPayload) {
theStringPayload = stringPayload;
}
@EventBusListenerMethod
void onIntegerEvent(Event<Integer> integerEvent) {
theIntegerEvent = integerEvent;
}
@EventBusListenerMethod
void onIntegerPayloadEvent(Integer integerPayload) {
theIntegerPayload = integerPayload;
}
@EventBusListenerTopic(topic = "shouldSucceed")
@EventBusListenerMethod
void onStringEventWithTopic(Event<String> stringEvent) {
theStringEventWithTopic = stringEvent;
}
@EventBusListenerTopic(topic = "shouldSucceed")
@EventBusListenerMethod
void onStringPayloadEventWithTopic(String stringPayload) {
theStringPayloadWithTopic = stringPayload;
}
@EventBusListenerTopic(topic = "shouldSucceed")
@EventBusListenerMethod
void onIntegerEventWithTopic(Event<Integer> integerEvent) {
theIntegerEventWithTopic = integerEvent;
}
@EventBusListenerTopic(topic = "shouldSucceed", filter = HierachyTopicFilter.class)
@EventBusListenerMethod
void onIntegerPayloadEventWithTopic(Integer integerPayload) {
theIntegerPayloadWithTopic = integerPayload;
}
@EventBusListenerTopic(topic = "shouldFail")
@EventBusListenerMethod
void onStringPayloadEventWithTopicFail(String stringPayload) {
theStringPayloadWithTopicFail = stringPayload;
}
@EventBusListenerTopic(topic = "shouldSucceed.butFail")
@EventBusListenerMethod
void onIntegerPayloadEventWithTopicFail(Integer integerPayload) {
theIntegerPayloadWithTopicFail = integerPayload;
}
}
class TopicStringListener implements EventBusListener<String> {
Event<String> theStringEvent;
@Override
public void onEvent(Event<String> event) {
this.theStringEvent = event;
}
}
class TopicIntegerListener implements EventBusListener<Integer> {
Event<Integer> theIntegerEvent;
@Override
public void onEvent(Event<Integer> event) {
this.theIntegerEvent = event;
}
}
class TopicListeners {
String theStringPayload;
Integer theIntegerPayload;
Event<String> theStringEvent;
Event<Integer> theIntegerEvent;
@EventBusListenerMethod
void onStringEvent(String theStringPayload) {
this.theStringPayload = theStringPayload;
}
@EventBusListenerMethod
void onStringEvent(Event<String> theStringEvent) {
this.theStringEvent = theStringEvent;
}
@EventBusListenerMethod
void onIntegerEvent(Integer theIntegerPayload) {
this.theIntegerPayload = theIntegerPayload;
}
@EventBusListenerMethod
void onIntegerEvent(Event<Integer> theIntegerEvent) {
this.theIntegerEvent = theIntegerEvent;
}
}
static class InvalidListener1 {
@EventBusListenerMethod
void tooFewParameters() {
}
}
static class InvalidListener2 {
@EventBusListenerMethod
void tooManyParameters(String parameter1, Integer parameter2) {
}
}
@BeforeEach
public void setUp() {
applicationEventBus = new ScopedEventBus.DefaultApplicationEventBus();
sessionEventBus = new ScopedEventBus.DefaultSessionEventBus(applicationEventBus);
}
@AfterEach
public void tearDown() {
sessionEventBus.destroy();
applicationEventBus.destroy();
}
@Test
@SuppressWarnings({"unchecked", "rawtypes"})
public void testSubscribeAndPublish() {
StringListener stringListener = mock(StringListener.class);
sessionEventBus.subscribe(stringListener);
sessionEventBus.publish(this, "Hello World");
ArgumentCaptor<Event> event = ArgumentCaptor.forClass(Event.class);
verify(stringListener).onEvent(event.capture());
assertEquals("Hello World", event.getValue().getPayload());
}
@Test
public void testSubscribeAndPublishWithListenerMethods() {
MultipleListeners listener = new MultipleListeners();
sessionEventBus.subscribe(listener);
sessionEventBus.publish(this, "Hello World");
assertNull(listener.theIntegerEvent);
assertNull(listener.theIntegerPayload);
assertNotNull(listener.theStringEvent);
assertEquals("Hello World", listener.theStringEvent.getPayload());
assertEquals("Hello World", listener.theStringPayload);
}
@Test
public void testSubscribeAndPublishWithListenerMethodsWithTopic() {
MultipleListeners listener = new MultipleListeners();
sessionEventBus.subscribe(listener);
sessionEventBus.publish("shouldSucceed", this, "Hello World");
sessionEventBus.publish("shouldSucceed.int", this, 10);
// null because not called with topic
assertNull(listener.theStringPayload);
assertNull(listener.theStringEvent);
assertNull(listener.theIntegerPayload);
assertNull(listener.theIntegerEvent);
// null because topic must fail
assertNull(listener.theStringPayloadWithTopicFail);
assertNull(listener.theIntegerPayloadWithTopicFail);
assertNull(listener.theIntegerEventWithTopic);
assertNotNull(listener.theStringPayloadWithTopic);
assertNotNull(listener.theStringEventWithTopic);
assertEquals("Hello World", listener.theStringPayloadWithTopic);
assertEquals("Hello World", listener.theStringEventWithTopic.getPayload());
assertEquals(10, listener.theIntegerPayloadWithTopic.intValue());
}
@Test
public void testSubscribeToTopicAndPublishWithTopic() {
String topic = "/news";
String payload = "Hello World";
TopicListeners topicListener = new TopicListeners();
applicationEventBus.subscribe(topicListener, topic);
applicationEventBus.publish(topic, this, payload);
assertEquals(payload, topicListener.theStringPayload);
assertEquals(payload, topicListener.theStringEvent.getPayload());
assertNull(topicListener.theIntegerPayload);
assertNull(topicListener.theIntegerEvent);
}
@Test
public void testUnsubscribeFromTopicAndPublishWithTopic() {
String topic = "/news";
String payload = "Hello World";
TopicListeners topicListener = new TopicListeners();
applicationEventBus.subscribe(topicListener, topic);
applicationEventBus.publish(topic, this, payload);
assertEquals(payload, topicListener.theStringPayload);
topicListener.theStringPayload = null;
applicationEventBus.unsubscribe(topicListener);
applicationEventBus.publish(topic, this, payload);
assertNotEquals(payload, topicListener.theStringPayload);
}
@Test
public void testSubscribeToTopicAndPublishWithDifferentTopic() {
String topic = "/news";
String differentTopic = "/different";
String payload = "Hello World";
TopicListeners topicListener = new TopicListeners();
applicationEventBus.subscribe(topicListener, topic);
applicationEventBus.publish(differentTopic, this, payload);
assertNotEquals(payload, topicListener.theStringPayload);
}
@Test
public void testSubscribeTopicListenerForTwoTopicsAndPublishWithThoseTopics() {
String newsTopic = "/news";
String counterTopic = "/counter";
String newsPayload = "Hello World";
Integer counterPayload = 0;
TopicListeners topicListener = new TopicListeners();
applicationEventBus.subscribe(topicListener, newsTopic);
applicationEventBus.subscribe(topicListener, counterTopic);
applicationEventBus.publish(newsTopic, this, newsPayload);
assertEquals(newsPayload, topicListener.theStringPayload);
assertNotEquals(counterPayload, topicListener.theIntegerPayload);
applicationEventBus.publish(counterTopic, this, counterPayload);
assertEquals(counterPayload, topicListener.theIntegerPayload);
}
@Test
public void testTwoTopicListenersSubscribedForSameTopic() {
String topic = "/news";
String payload = "Hello World";
TopicListeners firstTopicListener = new TopicListeners();
TopicListeners secondTopicListener = new TopicListeners();
applicationEventBus.subscribe(firstTopicListener, topic);
applicationEventBus.subscribe(secondTopicListener, topic);
applicationEventBus.publish(topic, this, payload);
assertEquals(payload, firstTopicListener.theStringPayload);
assertEquals(payload, firstTopicListener.theStringEvent.getPayload());
assertEquals(payload, secondTopicListener.theStringPayload);
assertEquals(payload, secondTopicListener.theStringEvent.getPayload());
}
@Test
public void testTwoTopicListenersSubscribedForDifferentTopics() {
String firstTopic = "/first";
String secondTopic = "/second";
String firstPayload = "first";
String secondPayload = "second";
TopicListeners firstTopicListener = new TopicListeners();
TopicListeners secondTopicListener = new TopicListeners();
applicationEventBus.subscribe(firstTopicListener, firstTopic);
applicationEventBus.subscribe(secondTopicListener, secondTopic);
applicationEventBus.publish(firstTopic, this, firstPayload);
assertEquals(firstPayload, firstTopicListener.theStringPayload);
assertEquals(firstPayload, firstTopicListener.theStringEvent.getPayload());
assertNull(secondTopicListener.theStringPayload);
assertNull(secondTopicListener.theStringEvent);
applicationEventBus.publish(secondTopic, this, secondPayload);
assertEquals(secondPayload, secondTopicListener.theStringPayload);
assertEquals(secondPayload, secondTopicListener.theStringEvent.getPayload());
assertNotEquals(secondPayload, firstTopicListener.theStringPayload);
assertNotEquals(secondPayload, firstTopicListener.theStringEvent.getPayload());
}
@Test
public void testSubscribeAndPublishWithTopic() {
String topic = "/news";
String payload = "Hello World";
TopicStringListener stringListener = new TopicStringListener();
sessionEventBus.subscribe(stringListener, topic);
sessionEventBus.publish(topic, this, payload);
assertEquals(payload, stringListener.theStringEvent.getPayload());
}
@Test
public void testSubscribeAndPublishWithDifferentTopic() {
String topic = "/news";
String payload = "Hello World";
String differentTopic = payload + ".extension";
TopicStringListener stringListener = new TopicStringListener();
sessionEventBus.subscribe(stringListener, topic);
sessionEventBus.publish(differentTopic, this, payload);
assertNull(stringListener.theStringEvent);
}
@Test
public void testSubscribeAndPublishWithSameTopicButDifferentPayloadType() {
String topic = "/news";
Integer payload = 0;
TopicStringListener stringListener = new TopicStringListener();
sessionEventBus.subscribe(stringListener, topic);
sessionEventBus.publish(topic, this, payload);
assertNull(stringListener.theStringEvent);
}
@Test
public void testSubscribeTwoTopicListenersForSameTopicWithDifferentPayloadType() {
String topic = "/news";
String stringPayload = "Hello World";
Integer integerPayload = 0;
TopicStringListener stringListener = new TopicStringListener();
TopicIntegerListener integerListener = new TopicIntegerListener();
sessionEventBus.subscribe(stringListener, topic);
sessionEventBus.subscribe(integerListener, topic);
sessionEventBus.publish(topic, this, integerPayload);
assertNotNull(integerListener.theIntegerEvent);
assertNull(stringListener.theStringEvent);
sessionEventBus.publish(topic, this, stringPayload);
assertNotNull(integerListener.theIntegerEvent);
assertNotNull(stringListener.theStringEvent);
}
@Test
public void testSubscribeAndPublishWithListenerMethodsAndTooFewParameters() {
assertThrows(IllegalArgumentException.class, () -> sessionEventBus.subscribe(new InvalidListener1()));
}
@Test
public void testSubscribeAndPublishWithListenerMethodsAndTooManyParameters() {
assertThrows(IllegalArgumentException.class, () -> sessionEventBus.subscribe(new InvalidListener2()));
}
@Test
public void testPublishToInvalidScope() {
assertThrows(UnsupportedOperationException.class, () -> applicationEventBus.publish(EventScope.SESSION, this, "fail"));
}
@Test
@SuppressWarnings({"unchecked", "rawtypes"})
public void testPublishToParentScope() {
StringListener stringListener = mock(StringListener.class);
applicationEventBus.subscribe(stringListener);
sessionEventBus.publish(EventScope.APPLICATION, this, "Hello World");
ArgumentCaptor<Event> event = ArgumentCaptor.forClass(Event.class);
verify(stringListener).onEvent(event.capture());
assertEquals("Hello World", event.getValue().getPayload());
}
@Test
public void testPublishToParentScopeWithListenerMethods() {
MultipleListeners listener = new MultipleListeners();
applicationEventBus.subscribe(listener);
sessionEventBus.publish(EventScope.APPLICATION, this, "Hello World");
assertNull(listener.theIntegerEvent);
assertNull(listener.theIntegerPayload);
assertNotNull(listener.theStringEvent);
assertEquals("Hello World", listener.theStringEvent.getPayload());
assertEquals("Hello World", listener.theStringPayload);
}
@Test
@SuppressWarnings({"unchecked", "rawtypes"})
public void testPropagateToChild() {
StringListener stringListener = mock(StringListener.class);
sessionEventBus.subscribe(stringListener);
applicationEventBus.publish(this, "Hello World");
ArgumentCaptor<Event> event = ArgumentCaptor.forClass(Event.class);
verify(stringListener).onEvent(event.capture());
assertEquals("Hello World", event.getValue().getPayload());
}
@Test
public void testPropagateToChildWithListenerMethods() {
MultipleListeners listener = new MultipleListeners();
applicationEventBus.subscribe(listener);
applicationEventBus.publish(this, "Hello World");
assertNull(listener.theIntegerEvent);
assertNull(listener.theIntegerPayload);
assertNotNull(listener.theStringEvent);
assertEquals("Hello World", listener.theStringEvent.getPayload());
assertEquals("Hello World", listener.theStringPayload);
}
@Test
@SuppressWarnings({"unchecked", "rawtypes"})
public void testNoPropagationToChild() {
StringListener stringListener = mock(StringListener.class);
sessionEventBus.subscribe(stringListener, false);
applicationEventBus.publish(this, "Hello World");
sessionEventBus.publish(this, "Hello World");
ArgumentCaptor<Event> event = ArgumentCaptor.forClass(Event.class);
verify(stringListener, only()).onEvent(event.capture());
verifyNoMoreInteractions(stringListener);
assertEquals("Hello World", event.getValue().getPayload());
}
@Test
public void testNoPropagationToChildWithListenerMethods() {
MultipleListeners listener = new MultipleListeners();
sessionEventBus.subscribe(listener, false);
sessionEventBus.publish(this, "Hello World Session");
applicationEventBus.publish(this, "Hello World Application");
assertNull(listener.theIntegerEvent);
assertNull(listener.theIntegerPayload);
assertNotNull(listener.theStringEvent);
assertEquals("Hello World Session", listener.theStringEvent.getPayload());
assertEquals("Hello World Session", listener.theStringPayload);
}
@Test
public void testSubscribeWithWeakReference() {
StringListener listener = new StringListener() {
int cnt = 0;
@Override
public void onEvent(Event<String> event) {
cnt++;
if (cnt > 1) {
fail("I should have been garbage collected by now");
}
}
};
applicationEventBus.subscribeWithWeakReference(listener);
applicationEventBus.publish(this, "Hello World Application");
listener = null;
System.gc();
applicationEventBus.publish(this, "Hello World Application");
}
}
================================================
FILE: eventbus/src/test/java/org/vaadin/spring/events/support/ApplicationContextEventBrokerTest.java
================================================
/*
* Copyright 2015 The original authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.vaadin.spring.events.support;
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationEvent;
import org.vaadin.spring.events.EventBus;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
/**
* Test case for {@link org.vaadin.spring.events.support.ApplicationContextEventBroker}.
*
* @author Petter Holmström (petter@vaadin.com)
*/
public class ApplicationContextEventBrokerTest {
@Test
public void testOnApplicationEvent() {
ApplicationEvent event = new ApplicationEvent(this) {
private static final long serialVersionUID = 7475015652750718692L;
@Override
public Object getSource() {
return "mySource";
}
};
EventBus eventBus = mock(EventBus.class);
new ApplicationContextEventBroker(eventBus).onApplicationEvent(event);
verify(eventBus).publish("mySource", event);
}
}
================================================
FILE: pom.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.vaadin.spring</groupId>
<artifactId>parent-pom</artifactId>
<version>14.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Vaadin4Spring</name>
<description>
Additions to the official Vaadin Spring add-on.
</description>
<url>https://github.com/peholmst/vaadin4spring</url>
<licenses>
<license>
<name>Apache License 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.html</url>
</license>
</licenses>
<scm>
<url>https://github.com/peholmst/vaadin4spring</url>
<connection>scm:git:git@github.com:peholmst/vaadin4spring.git</connection>
<developerConnection>scm:git:git@github.com:peholmst/vaadin4spring.git</developerConnection>
<tag>HEAD</tag>
</scm>
<distributionManagement>
<snapshotRepository>
<id>sonatype-nexus-snapshots</id>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
</snapshotRepository>
<repository>
<id>sonatype-nexus-staging</id>
<url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
</repository>
</distributionManagement>
<developers>
<!-- In alphabetical order -->
<developer>
<name>Chris Phillipson</name>
<email>fastnsilver@gmail.com</email>
</developer>
<developer>
<name>Erik Lumme</name>
<organization>Vaadin</organization>
<email>erik@vaadin.com</email>
</developer>
<developer>
<name>Gert-Jan Timmer</name>
<email>gjr.timmer@gmail.com</email>
</developer>
<developer>
<name>Idel Pivnitskiy</name>
<email>idel.pivnitskiy@gmail.com</email>
</developer>
<developer>
<name>Josh Long</name>
<email>josh@joshlong.com</email>
</developer>
<developer>
<name>Marco Luthardt</name>
<email>marco.luthardt@iandme.net</email>
</developer>
<developer>
<name>Matti Tahvonen</name>
<organization>Vaadin</organization>
<email>matti@vaadin.com</email>
</developer>
<developer>
<name>Nicolas Frankel</name>
<email>nicolas@frankel.ch</email>
</developer>
<developer>
<name>Peter Lehto</name>
<organization>Vaadin</organization>
<email>peter@vaadin.com</email>
</developer>
<developer>
<name>Petter Holmström</name>
<organization>Vaadin</organization>
<email>petter@vaadin.com</email>
</developer>
<developer>
<name>Tobias Placht</name>
<email>dev@knacht.net</email>
</developer>
</developers>
<properties>
<project.build.encoding>UTF-8</project.build.encoding>
<project.build.target>1.8</project.build.target>
<project.build.source>1.8</project.build.source>
<vaadin.version>14.0.1</vaadin.version>
<!-- Match version used by Vaadin Spring dependency -->
<spring.version>5.1.2.RELEASE</spring.version>
<junit-jupiter.version>5.5.1</junit-jupiter.version>
<mockito.version>3.0.0</mockito.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-bom</artifactId>
<version>${vaadin.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>${mockito.version}</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit-jupiter.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<encoding>${project.build.encoding}</encoding>
<target>${project.build.target}</target>
<source>${project.build.source}</source>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<encoding>${project.build.encoding}</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M3</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.5.3</version>
<configuration>
<tagNameFormat>v@{project.version}</tagNameFormat>
<autoVersionSubmodules>true</autoVersionSubmodules>
<releaseProfiles>release</releaseProfiles>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
<profiles>
<profile>
<id>release</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>attach-sources</id>
<phase>verify</phase>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.1.1</version>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
<configuration>
<links>
<link>http://docs.spring.io/spring/docs/${spring.version}/javadoc-api/</link>
<link>https://vaadin.com/api/platform/${vaadin.version}/</link>
</links>
<additionalparam>-Xdoclint:none</additionalparam>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<modules>
<module>eventbus</module>
</modules>
</project>
gitextract_rbhuxx4x/ ├── .gitignore ├── LICENSE.txt ├── README.md ├── eventbus/ │ ├── README.md │ ├── pom.xml │ └── src/ │ ├── main/ │ │ └── java/ │ │ └── org/ │ │ └── vaadin/ │ │ └── spring/ │ │ └── events/ │ │ ├── Event.java │ │ ├── EventBus.java │ │ ├── EventBusAware.java │ │ ├── EventBusListener.java │ │ ├── EventBusListenerMethodFilter.java │ │ ├── EventScope.java │ │ ├── ExactTopicFilter.java │ │ ├── HierachyTopicFilter.java │ │ ├── NoEventBusListenerMethodFilter.java │ │ ├── TopicFilter.java │ │ ├── annotation/ │ │ │ ├── EnableEventBus.java │ │ │ ├── EventBusListenerMethod.java │ │ │ ├── EventBusListenerTopic.java │ │ │ └── EventBusProxy.java │ │ ├── config/ │ │ │ └── EventBusConfiguration.java │ │ ├── internal/ │ │ │ ├── AbstractListenerWrapper.java │ │ │ ├── ClassUtils.java │ │ │ ├── EventBusListenerWrapper.java │ │ │ ├── ListenerCollection.java │ │ │ ├── MethodListenerWrapper.java │ │ │ └── ScopedEventBus.java │ │ └── support/ │ │ ├── ApplicationContextEventBroker.java │ │ └── VaadinEventBusAwareProcessor.java │ └── test/ │ └── java/ │ └── org/ │ └── vaadin/ │ └── spring/ │ └── events/ │ ├── integration/ │ │ └── ScopedEventBusIntegrationTest.java │ ├── internal/ │ │ └── ScopedEventBusTest.java │ └── support/ │ └── ApplicationContextEventBrokerTest.java └── pom.xml
SYMBOL INDEX (211 symbols across 22 files)
FILE: eventbus/src/main/java/org/vaadin/spring/events/Event.java
class Event (line 26) | public class Event<T> implements Serializable {
method Event (line 40) | public Event(EventBus eventBus, Object source, T payload) {
method Event (line 44) | public Event(EventBus eventBus, Object source, T payload, String topic) {
method getEventBus (line 57) | public EventBus getEventBus() {
method getScope (line 66) | public EventScope getScope() {
method getSource (line 75) | public Object getSource() {
method getTopic (line 84) | public String getTopic() {
method getTimestamp (line 93) | public long getTimestamp() {
method getPayload (line 102) | public T getPayload() {
method toString (line 106) | @Override
FILE: eventbus/src/main/java/org/vaadin/spring/events/EventBus.java
type EventBus (line 51) | public interface EventBus {
method publish (line 61) | <T> void publish(Object sender, T payload);
method publish (line 73) | <T> void publish(String topic, Object sender, T payload);
method publish (line 85) | <T> void publish(EventScope scope, Object sender, T payload) throws Un...
method publish (line 99) | <T> void publish(EventScope scope, String topic, Object sender, T payl...
method getScope (line 107) | EventScope getScope();
method subscribe (line 120) | <T> void subscribe(EventBusListener<T> listener);
method subscribeWithWeakReference (line 125) | <T> void subscribeWithWeakReference(EventBusListener<T> listener);
method subscribe (line 136) | <T> void subscribe(EventBusListener<T> listener, String topic);
method subscribeWithWeakReference (line 142) | <T> void subscribeWithWeakReference(EventBusListener<T> listener, Stri...
method subscribe (line 156) | <T> void subscribe(EventBusListener<T> listener, boolean includingProp...
method subscribeWithWeakReference (line 162) | <T> void subscribeWithWeakReference(EventBusListener<T> listener, bool...
method subscribe (line 177) | void subscribe(Object listener);
method subscribeWithWeakReference (line 182) | void subscribeWithWeakReference(Object listener);
method subscribe (line 199) | void subscribe(Object listener, String topic);
method subscribeWithWeakReference (line 204) | void subscribeWithWeakReference(Object listener, String topic);
method subscribe (line 222) | void subscribe(Object listener, boolean includingPropagatingEvents);
method subscribeWithWeakReference (line 227) | void subscribeWithWeakReference(Object listener, boolean includingProp...
method unsubscribe (line 237) | <T> void unsubscribe(EventBusListener<T> listener);
method unsubscribe (line 247) | void unsubscribe(Object listener);
type ApplicationEventBus (line 254) | interface ApplicationEventBus extends EventBus {
type SessionEventBus (line 262) | interface SessionEventBus extends EventBus {
type UIEventBus (line 270) | interface UIEventBus extends EventBus {
FILE: eventbus/src/main/java/org/vaadin/spring/events/EventBusAware.java
type EventBusAware (line 25) | public interface EventBusAware extends Aware {
type ApplicationEventBusAware (line 31) | interface ApplicationEventBusAware extends EventBusAware {
method setApplicationEventBus (line 35) | void setApplicationEventBus(EventBus.ApplicationEventBus application...
type SessionEventBusAware (line 42) | interface SessionEventBusAware extends EventBusAware {
method setSessionEventBus (line 46) | void setSessionEventBus(EventBus.SessionEventBus sessionEventBus);
type UIEventBusAware (line 53) | interface UIEventBusAware extends EventBusAware {
method setUIEventBus (line 57) | void setUIEventBus(EventBus.UIEventBus uiEventBus);
FILE: eventbus/src/main/java/org/vaadin/spring/events/EventBusListener.java
type EventBusListener (line 26) | public interface EventBusListener<T> extends Serializable {
method onEvent (line 33) | void onEvent(Event<T> event);
FILE: eventbus/src/main/java/org/vaadin/spring/events/EventBusListenerMethodFilter.java
type EventBusListenerMethodFilter (line 34) | public interface EventBusListenerMethodFilter {
method filter (line 42) | boolean filter(Event<?> event);
FILE: eventbus/src/main/java/org/vaadin/spring/events/EventScope.java
type EventScope (line 23) | public enum EventScope {
FILE: eventbus/src/main/java/org/vaadin/spring/events/ExactTopicFilter.java
class ExactTopicFilter (line 24) | public class ExactTopicFilter implements TopicFilter {
method validTopic (line 26) | @Override
FILE: eventbus/src/main/java/org/vaadin/spring/events/HierachyTopicFilter.java
class HierachyTopicFilter (line 32) | public class HierachyTopicFilter implements TopicFilter {
method validTopic (line 34) | @Override
FILE: eventbus/src/main/java/org/vaadin/spring/events/NoEventBusListenerMethodFilter.java
class NoEventBusListenerMethodFilter (line 24) | public class NoEventBusListenerMethodFilter implements EventBusListenerM...
method filter (line 26) | @Override
FILE: eventbus/src/main/java/org/vaadin/spring/events/TopicFilter.java
type TopicFilter (line 28) | public interface TopicFilter {
method validTopic (line 38) | boolean validTopic(String eventTopic, String listenerTopic);
FILE: eventbus/src/main/java/org/vaadin/spring/events/config/EventBusConfiguration.java
class EventBusConfiguration (line 35) | @Configuration
method vaadinEventBusProcessor (line 38) | @Bean
method applicationEventBus (line 43) | @Bean
method proxiedSessionEventBus (line 48) | @Bean
method sessionEventBus (line 55) | @Bean
method proxiedUiEventBus (line 62) | @Bean
method uiEventBus (line 69) | @Bean
FILE: eventbus/src/main/java/org/vaadin/spring/events/internal/AbstractListenerWrapper.java
class AbstractListenerWrapper (line 31) | abstract class AbstractListenerWrapper implements ListenerCollection.Lis...
method AbstractListenerWrapper (line 43) | AbstractListenerWrapper(EventBus owningEventBus, Object listenerTarget...
method getPayloadType (line 53) | protected abstract Class<?> getPayloadType();
method getListenerTarget (line 58) | public Object getListenerTarget() {
method supports (line 62) | @Override
FILE: eventbus/src/main/java/org/vaadin/spring/events/internal/ClassUtils.java
class ClassUtils (line 23) | final class ClassUtils {
method ClassUtils (line 25) | private ClassUtils() {
type ClassVisitor (line 31) | public interface ClassVisitor {
method visit (line 32) | void visit(Class<?> clazz);
method visitClassHierarchy (line 41) | static void visitClassHierarchy(ClassVisitor visitor, Class<?> subClas...
FILE: eventbus/src/main/java/org/vaadin/spring/events/internal/EventBusListenerWrapper.java
class EventBusListenerWrapper (line 30) | class EventBusListenerWrapper extends AbstractListenerWrapper {
method EventBusListenerWrapper (line 35) | EventBusListenerWrapper(EventBus owningEventBus, EventBusListener<?> l...
method getListenerTarget (line 41) | @Override
method getPayloadType (line 47) | @Override
method publish (line 52) | @Override
FILE: eventbus/src/main/java/org/vaadin/spring/events/internal/ListenerCollection.java
class ListenerCollection (line 30) | class ListenerCollection implements Serializable {
type Listener (line 40) | public interface Listener extends Serializable {
method supports (line 48) | boolean supports(Event<?> event);
method publish (line 55) | void publish(Event<?> event);
type ListenerFilter (line 61) | public interface ListenerFilter {
method passes (line 68) | boolean passes(Listener listener);
method add (line 78) | void add(Listener listener) {
method addWithWeakReference (line 93) | void addWithWeakReference(Listener listener) {
method remove (line 108) | void remove(Listener listener) {
method removeAll (line 125) | void removeAll(ListenerFilter filter) {
method clear (line 137) | void clear() {
method publish (line 154) | public void publish(Event<?> event) {
method addSupportedListenersToSet (line 172) | private <T> void addSupportedListenersToSet(Set<Listener> candidateLis...
method removeFilteredListenersFromSet (line 182) | private void removeFilteredListenersFromSet(ListenerFilter filter, Set...
FILE: eventbus/src/main/java/org/vaadin/spring/events/internal/MethodListenerWrapper.java
class MethodListenerWrapper (line 36) | class MethodListenerWrapper extends AbstractListenerWrapper {
method MethodListenerWrapper (line 44) | MethodListenerWrapper(EventBus owningEventBus, Object listenerTarget, ...
method readObject (line 58) | private void readObject(ObjectInputStream ois) throws IOException, Cla...
method writeObject (line 63) | private void writeObject(ObjectOutputStream oos) throws IOException {
method getPayloadType (line 68) | @Override
method publish (line 73) | @Override
method supports (line 94) | @Override
method isInterestedListenerMethod (line 117) | private boolean isInterestedListenerMethod(Event<?> event) throws Inst...
method isFromSource (line 128) | private boolean isFromSource(Event<?> event, Class<?>[] sources) {
method isInTopic (line 142) | private boolean isInTopic(Event<?> event) throws InstantiationExceptio...
FILE: eventbus/src/main/java/org/vaadin/spring/events/internal/ScopedEventBus.java
class ScopedEventBus (line 40) | public abstract class ScopedEventBus implements EventBus, Serializable {
method onEvent (line 53) | @Override
method ScopedEventBus (line 65) | public ScopedEventBus(EventScope scope) {
method ScopedEventBus (line 73) | public ScopedEventBus(EventScope scope, EventBus parentEventBus) {
method destroy (line 92) | @PreDestroy
method getScope (line 101) | @Override
method publish (line 106) | @Override
method publish (line 111) | @Override
method publish (line 118) | @Override
method publish (line 123) | @Override
method subscribe (line 139) | @Override
method subscribeWithWeakReference (line 144) | @Override
method subscribe (line 149) | @Override
method subscribe (line 155) | @Override
method subscribeWithWeakReference (line 162) | @Override
method subscribeWithWeakReference (line 169) | @Override
method subscribe (line 176) | @Override
method subscribe (line 181) | @Override
method subscribeWithWeakReference (line 186) | @Override
method subscribeWithWeakReference (line 191) | @Override
method subscribe (line 196) | @Override
method subscribeWithWeakReference (line 201) | @Override
method subscribe (line 206) | private void subscribe(final Object listener, final String topic, fina...
method unsubscribe (line 238) | @Override
method unsubscribe (line 243) | @Override
method getParentEventBus (line 256) | protected EventBus getParentEventBus() {
method toString (line 260) | @Override
class DefaultApplicationEventBus (line 269) | public static class DefaultApplicationEventBus extends ScopedEventBus ...
method DefaultApplicationEventBus (line 271) | public DefaultApplicationEventBus() {
class DefaultSessionEventBus (line 279) | public static class DefaultSessionEventBus extends ScopedEventBus impl...
method DefaultSessionEventBus (line 281) | public DefaultSessionEventBus(ApplicationEventBus parentEventBus) {
class DefaultUIEventBus (line 289) | public static class DefaultUIEventBus extends ScopedEventBus implement...
method DefaultUIEventBus (line 291) | public DefaultUIEventBus(SessionEventBus parentEventBus) {
FILE: eventbus/src/main/java/org/vaadin/spring/events/support/ApplicationContextEventBroker.java
class ApplicationContextEventBroker (line 29) | public class ApplicationContextEventBroker implements ApplicationListene...
method ApplicationContextEventBroker (line 35) | public ApplicationContextEventBroker(EventBus eventBus) {
method onApplicationEvent (line 39) | @Override
FILE: eventbus/src/main/java/org/vaadin/spring/events/support/VaadinEventBusAwareProcessor.java
class VaadinEventBusAwareProcessor (line 38) | public class VaadinEventBusAwareProcessor implements ApplicationContextA...
method setApplicationContext (line 42) | @Override
method postProcessBeforeInitialization (line 47) | @Override
method postProcessAfterInitialization (line 67) | @Override
method invokeAwareInterfaces (line 72) | private void invokeAwareInterfaces(Object bean) {
FILE: eventbus/src/test/java/org/vaadin/spring/events/integration/ScopedEventBusIntegrationTest.java
class ScopedEventBusIntegrationTest (line 33) | @ExtendWith(SpringExtension.class)
class Config (line 37) | @Configuration
class TestSession (line 42) | public static class TestSession extends SpringVaadinSession {
method TestSession (line 43) | TestSession() {
method hasLock (line 47) | @Override
method lock (line 52) | @Override
method unlock (line 56) | @Override
method setUp (line 66) | @BeforeEach
method testSameUIReturnsSameUIEventBus (line 73) | @Test
method testDifferentUIReturnsDifferentUIEventBus (line 80) | @Test
method testNoUIThrowsBeanCreationException (line 88) | @Test
method testSameSessionReturnsSameSessionEventBus (line 94) | @Test
method testSameSessionDifferentUIReturnsSameSessionEventBus (line 101) | @Test
method testDifferentSessionsReturnDifferentSessionEventBuses (line 109) | @Test
method sameApplicationReturnsSameApplicationEventBus (line 117) | @Test
method sameApplicationDifferentUIReturnsSameApplicationEventBus (line 124) | @Test
method sameApplicationDifferentSessionReturnsSameApplicationEventBus (line 132) | @Test
method createMockUI (line 143) | private UI createMockUI() {
FILE: eventbus/src/test/java/org/vaadin/spring/events/internal/ScopedEventBusTest.java
class ScopedEventBusTest (line 37) | public class ScopedEventBusTest {
type StringListener (line 42) | interface StringListener extends EventBusListener<String> {
class MultipleListeners (line 45) | static class MultipleListeners {
method onStringEvent (line 60) | @EventBusListenerMethod
method onStringPayloadEvent (line 65) | @EventBusListenerMethod
method onIntegerEvent (line 70) | @EventBusListenerMethod
method onIntegerPayloadEvent (line 75) | @EventBusListenerMethod
method onStringEventWithTopic (line 80) | @EventBusListenerTopic(topic = "shouldSucceed")
method onStringPayloadEventWithTopic (line 86) | @EventBusListenerTopic(topic = "shouldSucceed")
method onIntegerEventWithTopic (line 92) | @EventBusListenerTopic(topic = "shouldSucceed")
method onIntegerPayloadEventWithTopic (line 98) | @EventBusListenerTopic(topic = "shouldSucceed", filter = HierachyTop...
method onStringPayloadEventWithTopicFail (line 104) | @EventBusListenerTopic(topic = "shouldFail")
method onIntegerPayloadEventWithTopicFail (line 110) | @EventBusListenerTopic(topic = "shouldSucceed.butFail")
class TopicStringListener (line 117) | class TopicStringListener implements EventBusListener<String> {
method onEvent (line 121) | @Override
class TopicIntegerListener (line 127) | class TopicIntegerListener implements EventBusListener<Integer> {
method onEvent (line 131) | @Override
class TopicListeners (line 137) | class TopicListeners {
method onStringEvent (line 144) | @EventBusListenerMethod
method onStringEvent (line 149) | @EventBusListenerMethod
method onIntegerEvent (line 154) | @EventBusListenerMethod
method onIntegerEvent (line 159) | @EventBusListenerMethod
class InvalidListener1 (line 165) | static class InvalidListener1 {
method tooFewParameters (line 167) | @EventBusListenerMethod
class InvalidListener2 (line 172) | static class InvalidListener2 {
method tooManyParameters (line 174) | @EventBusListenerMethod
method setUp (line 179) | @BeforeEach
method tearDown (line 185) | @AfterEach
method testSubscribeAndPublish (line 191) | @Test
method testSubscribeAndPublishWithListenerMethods (line 204) | @Test
method testSubscribeAndPublishWithListenerMethodsWithTopic (line 218) | @Test
method testSubscribeToTopicAndPublishWithTopic (line 245) | @Test
method testUnsubscribeFromTopicAndPublishWithTopic (line 260) | @Test
method testSubscribeToTopicAndPublishWithDifferentTopic (line 278) | @Test
method testSubscribeTopicListenerForTwoTopicsAndPublishWithThoseTopics (line 291) | @Test
method testTwoTopicListenersSubscribedForSameTopic (line 310) | @Test
method testTwoTopicListenersSubscribedForDifferentTopics (line 328) | @Test
method testSubscribeAndPublishWithTopic (line 354) | @Test
method testSubscribeAndPublishWithDifferentTopic (line 365) | @Test
method testSubscribeAndPublishWithSameTopicButDifferentPayloadType (line 377) | @Test
method testSubscribeTwoTopicListenersForSameTopicWithDifferentPayloadType (line 388) | @Test
method testSubscribeAndPublishWithListenerMethodsAndTooFewParameters (line 408) | @Test
method testSubscribeAndPublishWithListenerMethodsAndTooManyParameters (line 413) | @Test
method testPublishToInvalidScope (line 418) | @Test
method testPublishToParentScope (line 423) | @Test
method testPublishToParentScopeWithListenerMethods (line 436) | @Test
method testPropagateToChild (line 450) | @Test
method testPropagateToChildWithListenerMethods (line 463) | @Test
method testNoPropagationToChild (line 477) | @Test
method testNoPropagationToChildWithListenerMethods (line 492) | @Test
method testSubscribeWithWeakReference (line 507) | @Test
FILE: eventbus/src/test/java/org/vaadin/spring/events/support/ApplicationContextEventBrokerTest.java
class ApplicationContextEventBrokerTest (line 30) | public class ApplicationContextEventBrokerTest {
method testOnApplicationEvent (line 32) | @Test
Condensed preview — 32 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (130K chars).
[
{
"path": ".gitignore",
"chars": 452,
"preview": "*.orig\n\n# Maven\ntarget/\n*.releaseBackup\nrelease.properties\n\n# IntelliJ\n*.iml\n.idea/\n\n# Eclipse\n.settings/\n*.project\n*.cl"
},
{
"path": "LICENSE.txt",
"chars": 11358,
"preview": "\n Apache License\n Version 2.0, January 2004\n "
},
{
"path": "README.md",
"chars": 614,
"preview": "Vaadin4Spring\n=============\n\nThis project started as a prototype of an official Vaadin Spring add-on, back in the day wh"
},
{
"path": "eventbus/README.md",
"chars": 962,
"preview": "The Vaadin4Spring Event Bus\n===========================\n\n**Do not use this event bus in new projects.** This version is "
},
{
"path": "eventbus/pom.xml",
"chars": 1549,
"preview": "<?xml version=\"1.0\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-ins"
},
{
"path": "eventbus/src/main/java/org/vaadin/spring/events/Event.java",
"chars": 3011,
"preview": "/*\n * Copyright 2015 The original authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you m"
},
{
"path": "eventbus/src/main/java/org/vaadin/spring/events/EventBus.java",
"chars": 12487,
"preview": "/*\n * Copyright 2015 The original authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you m"
},
{
"path": "eventbus/src/main/java/org/vaadin/spring/events/EventBusAware.java",
"chars": 1873,
"preview": "/*\n * Copyright 2015 The original authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you m"
},
{
"path": "eventbus/src/main/java/org/vaadin/spring/events/EventBusListener.java",
"chars": 1144,
"preview": "/*\n * Copyright 2015 The original authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you m"
},
{
"path": "eventbus/src/main/java/org/vaadin/spring/events/EventBusListenerMethodFilter.java",
"chars": 1676,
"preview": "/*\n * Copyright 2015 The original authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you m"
},
{
"path": "eventbus/src/main/java/org/vaadin/spring/events/EventScope.java",
"chars": 1215,
"preview": "/*\n * Copyright 2015 The original authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you m"
},
{
"path": "eventbus/src/main/java/org/vaadin/spring/events/ExactTopicFilter.java",
"chars": 1033,
"preview": "/*\n * Copyright 2015 The original authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you m"
},
{
"path": "eventbus/src/main/java/org/vaadin/spring/events/HierachyTopicFilter.java",
"chars": 1448,
"preview": "/*\n * Copyright 2015 The original authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you m"
},
{
"path": "eventbus/src/main/java/org/vaadin/spring/events/NoEventBusListenerMethodFilter.java",
"chars": 1010,
"preview": "/*\n * Copyright 2015 The original authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you m"
},
{
"path": "eventbus/src/main/java/org/vaadin/spring/events/TopicFilter.java",
"chars": 1574,
"preview": "/*\n * Copyright 2015 The original authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you m"
},
{
"path": "eventbus/src/main/java/org/vaadin/spring/events/annotation/EnableEventBus.java",
"chars": 1116,
"preview": "/*\n * Copyright 2015 The original authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you m"
},
{
"path": "eventbus/src/main/java/org/vaadin/spring/events/annotation/EventBusListenerMethod.java",
"chars": 2307,
"preview": "/*\n * Copyright 2015 The original authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you m"
},
{
"path": "eventbus/src/main/java/org/vaadin/spring/events/annotation/EventBusListenerTopic.java",
"chars": 2206,
"preview": "/*\n * Copyright 2015 The original authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you m"
},
{
"path": "eventbus/src/main/java/org/vaadin/spring/events/annotation/EventBusProxy.java",
"chars": 1354,
"preview": "/*\n * Copyright 2015 The original authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you m"
},
{
"path": "eventbus/src/main/java/org/vaadin/spring/events/config/EventBusConfiguration.java",
"chars": 2632,
"preview": "/*\n * Copyright 2015 The original authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you m"
},
{
"path": "eventbus/src/main/java/org/vaadin/spring/events/internal/AbstractListenerWrapper.java",
"chars": 2563,
"preview": "/*\n * Copyright 2015 The original authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you m"
},
{
"path": "eventbus/src/main/java/org/vaadin/spring/events/internal/ClassUtils.java",
"chars": 1588,
"preview": "/*\n * Copyright 2015 The original authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you m"
},
{
"path": "eventbus/src/main/java/org/vaadin/spring/events/internal/EventBusListenerWrapper.java",
"chars": 2092,
"preview": "/*\n * Copyright 2015 The original authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you m"
},
{
"path": "eventbus/src/main/java/org/vaadin/spring/events/internal/ListenerCollection.java",
"chars": 7016,
"preview": "/*\n * Copyright 2015 The original authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you m"
},
{
"path": "eventbus/src/main/java/org/vaadin/spring/events/internal/MethodListenerWrapper.java",
"chars": 5913,
"preview": "/*\n * Copyright 2015 The original authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you m"
},
{
"path": "eventbus/src/main/java/org/vaadin/spring/events/internal/ScopedEventBus.java",
"chars": 11517,
"preview": "/*\n * Copyright 2015 The original authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you m"
},
{
"path": "eventbus/src/main/java/org/vaadin/spring/events/support/ApplicationContextEventBroker.java",
"chars": 1624,
"preview": "/*\n * Copyright 2015 The original authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you m"
},
{
"path": "eventbus/src/main/java/org/vaadin/spring/events/support/VaadinEventBusAwareProcessor.java",
"chars": 3455,
"preview": "/*\n * Copyright 2015 The original authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you m"
},
{
"path": "eventbus/src/test/java/org/vaadin/spring/events/integration/ScopedEventBusIntegrationTest.java",
"chars": 6005,
"preview": "package org.vaadin.spring.events.integration;\n\nimport com.vaadin.flow.component.UI;\nimport com.vaadin.flow.server.Vaadin"
},
{
"path": "eventbus/src/test/java/org/vaadin/spring/events/internal/ScopedEventBusTest.java",
"chars": 19219,
"preview": "/*\n * Copyright 2015 The original authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you m"
},
{
"path": "eventbus/src/test/java/org/vaadin/spring/events/support/ApplicationContextEventBrokerTest.java",
"chars": 1566,
"preview": "/*\n * Copyright 2015 The original authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you m"
},
{
"path": "pom.xml",
"chars": 9313,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2"
}
]
About this extraction
This page contains the full source code of the peholmst/vaadin4spring GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 32 files (120.0 KB), approximately 26.7k tokens, and a symbol index with 211 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.