├── .gitignore
├── LICENSE
├── LICENSE.Apachev2
├── LICENSE.BSD3
├── LICENSE.CC0
├── LICENSE.MIT
├── README.md
├── build.gradle.kts
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── settings.gradle.kts
├── src
└── dorkbox
│ └── messageBus
│ ├── AsyncPublicationMode.java
│ ├── DispatchMode.java
│ ├── MessageBus.java
│ ├── SubscriptionMode.java
│ ├── annotations
│ ├── Listener.java
│ ├── References.java
│ ├── Subscribe.java
│ └── Synchronized.java
│ ├── common
│ ├── ClassTree.java
│ ├── MessageHandler.java
│ └── MultiClass.java
│ ├── dispatch
│ ├── Dispatch.java
│ ├── DispatchExact.java
│ └── DispatchExactWithSuperTypes.java
│ ├── error
│ ├── DeadMessage.java
│ ├── ErrorHandler.java
│ ├── IPublicationErrorHandler.java
│ ├── MessageBusException.java
│ └── PublicationError.java
│ ├── publication
│ ├── ConversantDisruptor.java
│ ├── DirectInvocation.java
│ ├── LmaxDisruptor.java
│ ├── Publisher.java
│ └── disruptor
│ │ ├── EventBusFactory.java
│ │ ├── MessageHandler.java
│ │ ├── MessageHolder.java
│ │ ├── MessageType.java
│ │ └── PublicationExceptionHandler.java
│ └── subscription
│ ├── Entry.java
│ ├── Subscription.java
│ ├── SubscriptionFactory.java
│ ├── SubscriptionManager.java
│ ├── asm
│ ├── AsmFactory.java
│ ├── AsmInvocation.java
│ ├── AsmReflectiveInvocation.java
│ ├── AsmSynchronizedInvocation.java
│ ├── SubscriptionAsmStrong.java
│ └── SubscriptionAsmWeak.java
│ └── reflection
│ ├── ReflectionFactory.java
│ ├── ReflectionInvocation.java
│ ├── ReflectionReflectiveInvocation.java
│ ├── ReflectionSynchronizedInvocation.java
│ ├── SubscriptionReflectionStrong.java
│ └── SubscriptionReflectionWeak.java
├── src9
├── dorkbox
│ └── messageBus
│ │ └── EmptyClass.java
└── module-info.java
└── test
└── dorkbox
└── messagebus
├── AllTests.java
├── AsyncFIFOBusTest.java
├── DeadMessageTest.java
├── MBassadorTest.java
├── MetadataReaderTest.java
├── MethodDispatchTest.java
├── MultiMessageTest.java
├── MultiTreeTest.java
├── SubscriptionManagerTest.java
├── SyncBusTest.java
├── SynchronizedHandlerTest.java
├── common
├── AssertSupport.java
├── ConcurrentExecutor.java
├── ListenerFactory.java
├── MessageBusTest.java
├── MessageManager.java
├── SubscriptionValidator.java
└── TestUtil.java
├── listeners
├── AbstractMessageListener.java
├── ExceptionThrowingListener.java
├── ICountableListener.java
├── IMessageListener.java
├── IMultipartMessageListener.java
├── Listeners.java
├── MessageTypesListener.java
├── MultipartMessageListener.java
├── ObjectListener.java
├── Overloading.java
└── StandardMessageListener.java
└── messages
├── AbstractMessage.java
├── CountableMessage.java
├── ICountable.java
├── IMessage.java
├── IMultipartMessage.java
├── MessageTypes.java
├── MultipartMessage.java
├── StandardMessage.java
├── SubTestMessage.java
└── TestMessage.java
/.gitignore:
--------------------------------------------------------------------------------
1 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
2 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
3 |
4 | # User-specific stuff:
5 | .idea/**/workspace.xml
6 | .idea/**/tasks.xml
7 | .idea/dictionaries
8 | .idea/**/codeStyles/
9 | .idea/**/codeStyleSettings.xml
10 |
11 | # Sensitive or high-churn files:
12 | .idea/**/dataSources/
13 | .idea/**/dataSources.ids
14 | .idea/**/dataSources.xml
15 | .idea/**/dataSources.local.xml
16 | .idea/**/sqlDataSources.xml
17 | .idea/**/dynamic.xml
18 | .idea/**/uiDesigner.xml
19 | .idea/**/shelf/
20 |
21 |
22 | # Gradle:
23 | .idea/**/gradle.xml
24 | .idea/**/libraries
25 |
26 | # CMake
27 | cmake-build-debug/
28 |
29 | # Mongo Explorer plugin:
30 | .idea/**/mongoSettings.xml
31 |
32 | ## File-based project format:
33 | *.iws
34 |
35 | ## Plugin-specific files:
36 |
37 |
38 | # IntelliJ
39 | out/
40 |
41 | # mpeltonen/sbt-idea plugin
42 | .idea_modules/
43 |
44 | # JIRA plugin
45 | atlassian-ide-plugin.xml
46 |
47 | # Cursive Clojure plugin
48 | .idea/replstate.xml
49 |
50 | # Crashlytics plugin (for Android Studio and IntelliJ)
51 | com_crashlytics_export_strings.xml
52 | crashlytics.properties
53 | crashlytics-build.properties
54 | fabric.properties
55 |
56 | ######################
57 | # End JetBrains IDEs #
58 | ######################
59 |
60 |
61 | # From https://github.com/github/gitignore/blob/master/Gradle.gitignore
62 | .gradle
63 | /build/
64 |
65 | # Ignore Gradle GUI config
66 | gradle-app.setting
67 |
68 | # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
69 | !gradle-wrapper.jar
70 | !gradle-wrapper.properties
71 |
72 | # Cache of project
73 | .gradletasknamecache
74 |
75 |
76 |
77 |
78 | # From https://github.com/github/gitignore/blob/master/Java.gitignore
79 | *.class
80 |
81 | # Mobile Tools for Java (J2ME)
82 | .mtj.tmp/
83 |
84 |
85 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
86 | hs_err_pid*
87 |
88 | *.DS_Store
89 | .AppleDouble
90 | .LSOverride
91 |
92 | # Icon must end with two \r
93 | Icon
94 |
95 |
96 | # Thumbnails
97 | ._*
98 |
99 | # Files that might appear in the root of a volume
100 | .DocumentRevisions-V100
101 | .fseventsd
102 | .Spotlight-V100
103 | .TemporaryItems
104 | .Trashes
105 | .VolumeIcon.icns
106 | .com.apple.timemachine.donotpresent
107 |
108 | # Directories potentially created on remote AFP share
109 | .AppleDB
110 | .AppleDesktop
111 | Network Trash Folder
112 | Temporary Items
113 | .apdisk
114 |
115 |
116 |
117 | ##########################################################
118 | # Specific to this module
119 |
120 | # iml files are generated by intellij/gradle now
121 | **/*.iml
122 |
--------------------------------------------------------------------------------
/LICENSE.BSD3:
--------------------------------------------------------------------------------
1 | BSD License
2 |
3 |
4 | Redistribution and use in source and binary forms, with or without
5 | modification, are permitted provided that the following conditions are met:
6 | * Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 |
9 | * Redistributions in binary form must reproduce the above copyright
10 | notice, this list of conditions and the following disclaimer in the
11 | documentation and/or other materials provided with the distribution.
12 |
13 | * Neither the name of the nor the names of its contributors
14 | may be used to endorse or promote products derived from this software
15 | without specific prior written permission.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 | DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY
21 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 |
--------------------------------------------------------------------------------
/LICENSE.MIT:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 |
4 | Permission is hereby granted, free of charge, to any person obtaining
5 | a copy of this software and associated documentation files (the
6 | "Software"), to deal in the Software without restriction, including
7 | without limitation the rights to use, copy, modify, merge, publish,
8 | distribute, sublicense, and/or sell copies of the Software, and to
9 | permit persons to whom the Software is furnished to do so, subject to
10 | the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be
13 | included in all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/build.gradle.kts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 dorkbox, llc
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | ///////////////////////////////
18 | ////// PUBLISH TO SONATYPE / MAVEN CENTRAL
19 | ////// TESTING : (to local maven repo) <'publish and release' - 'publishToMavenLocal'>
20 | ////// RELEASE : (to sonatype/maven central), <'publish and release' - 'publishToSonatypeAndRelease'>
21 | ///////////////////////////////
22 |
23 | gradle.startParameter.showStacktrace = ShowStacktrace.ALWAYS // always show the stacktrace!
24 |
25 | plugins {
26 | id("com.dorkbox.GradleUtils") version "3.18"
27 | id("com.dorkbox.Licensing") version "2.28"
28 | id("com.dorkbox.VersionUpdate") version "2.8"
29 | id("com.dorkbox.GradlePublish") version "1.20"
30 |
31 | kotlin("jvm") version "1.9.0"
32 | }
33 | object Extras {
34 | // set for the project
35 | const val description = "Lightweight, extremely fast, and zero-gc message/event bus for Java 8+"
36 | const val group = "com.dorkbox"
37 | const val version = "2.7"
38 |
39 | // set as project.ext
40 | const val name = "MessageBus"
41 | const val id = "MessageBus"
42 | const val vendor = "Dorkbox LLC"
43 | const val vendorUrl = "https://dorkbox.com"
44 | const val url = "https://git.dorkbox.com/dorkbox/MessageBus"
45 |
46 | val JAVA_VERSION = JavaVersion.VERSION_1_8.toString()
47 | }
48 |
49 | ///////////////////////////////
50 | ///// assign 'Extras'
51 | ///////////////////////////////
52 | GradleUtils.load("$projectDir/../../gradle.properties", Extras)
53 | GradleUtils.defaults()
54 | GradleUtils.compileConfiguration(JavaVersion.VERSION_1_8)
55 | GradleUtils.jpms(JavaVersion.VERSION_1_9)
56 |
57 | licensing {
58 | license(License.APACHE_2) {
59 | author(Extras.vendor)
60 | url(Extras.url)
61 | note(Extras.description)
62 |
63 | extra("MBassador", License.MIT) {
64 | copyright(2012)
65 | author("Benjamin Diedrichsen")
66 | url("https://github.com/bennidi/mbassador")
67 | }
68 | }
69 | }
70 |
71 | tasks.jar.get().apply {
72 | manifest {
73 | // https://docs.oracle.com/javase/tutorial/deployment/jar/packageman.html
74 | attributes["Name"] = Extras.name
75 |
76 | attributes["Specification-Title"] = Extras.name
77 | attributes["Specification-Version"] = Extras.version
78 | attributes["Specification-Vendor"] = Extras.vendor
79 |
80 | attributes["Implementation-Title"] = "${Extras.group}.${Extras.id}"
81 | attributes["Implementation-Version"] = GradleUtils.now()
82 | attributes["Implementation-Vendor"] = Extras.vendor
83 |
84 | attributes["Automatic-Module-Name"] = Extras.id
85 | }
86 | }
87 |
88 | dependencies {
89 | api("com.dorkbox:ClassUtils:1.3")
90 | api("com.dorkbox:Collections:2.4")
91 | api("com.dorkbox:Updates:1.1")
92 | api("com.dorkbox:Utilities:1.46")
93 |
94 | api("com.lmax:disruptor:3.4.4")
95 | api("com.conversantmedia:disruptor:1.2.21")
96 |
97 | api("org.ow2.asm:asm:9.5")
98 | api("com.esotericsoftware:reflectasm:1.11.9")
99 |
100 | implementation("org.slf4j:slf4j-api:2.0.7")
101 |
102 |
103 | testImplementation("junit:junit:4.13.2")
104 | testImplementation("ch.qos.logback:logback-classic:1.4.5")
105 | }
106 |
107 | publishToSonatype {
108 | groupId = Extras.group
109 | artifactId = Extras.id
110 | version = Extras.version
111 |
112 | name = Extras.name
113 | description = Extras.description
114 | url = Extras.url
115 |
116 | vendor = Extras.vendor
117 | vendorUrl = Extras.vendorUrl
118 |
119 | issueManagement {
120 | url = "${Extras.url}/issues"
121 | nickname = "Gitea Issues"
122 | }
123 |
124 | developer {
125 | id = "dorkbox"
126 | name = Extras.vendor
127 | email = "email@dorkbox.com"
128 | }
129 | }
130 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # https://docs.gradle.org/current/userguide/build_environment.html#sec:gradle_configuration_properties
2 | org.gradle.jvmargs=-Dfile.encoding=UTF-8
3 |
4 | #org.gradle.warning.mode=(all,fail,none,summary)
5 | org.gradle.warning.mode=all
6 |
7 | #org.gradle.daemon=false
8 | # default is 3 hours, this is 1 minute
9 | org.gradle.daemon.idletimeout=60000
10 |
11 | #org.gradle.console=(auto,plain,rich,verbose)
12 | org.gradle.console=auto
13 |
14 | #org.gradle.logging.level=(quiet,warn,lifecycle,info,debug)
15 | org.gradle.logging.level=lifecycle
16 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dorkbox/MessageBus/1cccb72313dc6dcc60722468f8ce42be90f39702/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-all.zip
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%"=="" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%"=="" set DIRNAME=.
29 | @rem This is normally unused
30 | set APP_BASE_NAME=%~n0
31 | set APP_HOME=%DIRNAME%
32 |
33 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
34 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
35 |
36 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
37 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
38 |
39 | @rem Find java.exe
40 | if defined JAVA_HOME goto findJavaFromJavaHome
41 |
42 | set JAVA_EXE=java.exe
43 | %JAVA_EXE% -version >NUL 2>&1
44 | if %ERRORLEVEL% equ 0 goto execute
45 |
46 | echo.
47 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
48 | echo.
49 | echo Please set the JAVA_HOME variable in your environment to match the
50 | echo location of your Java installation.
51 |
52 | goto fail
53 |
54 | :findJavaFromJavaHome
55 | set JAVA_HOME=%JAVA_HOME:"=%
56 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
57 |
58 | if exist "%JAVA_EXE%" goto execute
59 |
60 | echo.
61 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
62 | echo.
63 | echo Please set the JAVA_HOME variable in your environment to match the
64 | echo location of your Java installation.
65 |
66 | goto fail
67 |
68 | :execute
69 | @rem Setup the command line
70 |
71 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
72 |
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if %ERRORLEVEL% equ 0 goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | set EXIT_CODE=%ERRORLEVEL%
85 | if %EXIT_CODE% equ 0 set EXIT_CODE=1
86 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
87 | exit /b %EXIT_CODE%
88 |
89 | :mainEnd
90 | if "%OS%"=="Windows_NT" endlocal
91 |
92 | :omega
93 |
--------------------------------------------------------------------------------
/settings.gradle.kts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 dorkbox, llc
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | rootProject.name = "MessageBus"
17 |
--------------------------------------------------------------------------------
/src/dorkbox/messageBus/AsyncPublicationMode.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019 dorkbox, llc
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dorkbox.messageBus;
17 |
18 | public
19 | enum AsyncPublicationMode {
20 |
21 | /**
22 | * This is the default.
23 | *
24 | * This uses the LMAX disruptor for managing the ASYNC publication of messages.
25 | *
26 | * The Conversant Disruptor is shown to be faster, however the LMAX Disruptor DOES NOT generate any garbage when
27 | * running, while the Conversant Disruptor creates new `Runnable` for every invocation.
28 | */
29 | LmaxDisruptor,
30 |
31 | /**
32 | * This uses the Conversant disruptor + (many) runnable for managing the ASYNC publication of messages.
33 | *
34 | * The Conversant Disruptor is shown to be faster than the LMAX disruptor, however the Conversant disruptor
35 | * relies on creating a `new Runnable()` for execution, where the LMAX Disruptor DOES NOT.
36 | */
37 | ConversantDisruptor,
38 | }
39 |
--------------------------------------------------------------------------------
/src/dorkbox/messageBus/DispatchMode.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019 dorkbox, llc
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dorkbox.messageBus;
17 |
18 | public
19 | enum DispatchMode {
20 | /**
21 | * Will only publish to listeners with this exact message signature. This is the fastest
22 | */
23 | Exact,
24 |
25 | /**
26 | * Will publish to listeners with this exact message signature, as well as listeners that match the super class types signatures.
27 | */
28 | ExactWithSuperTypes,
29 | }
30 |
--------------------------------------------------------------------------------
/src/dorkbox/messageBus/SubscriptionMode.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019 dorkbox, llc
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dorkbox.messageBus;
17 |
18 | public
19 | enum SubscriptionMode {
20 | /**
21 | * This is the default.
22 | *
23 | * We use strong references when saving the subscribed listeners (these are the classes & methods that receive messages).
24 | *
25 | * In certain environments (ie: spring), it is desirable to use weak references -- so that there are no memory leaks during
26 | * the container lifecycle (or, more specifically, so one doesn't have to manually manage the memory).
27 | */
28 | StrongReferences,
29 |
30 | /**
31 | * Using weak references is a tad slower than using strong references, since there are additional steps taken when there are orphaned
32 | * references (when GC occurs) that have to be cleaned up. This cleanup occurs during message publication.
33 | */
34 | WeakReferences
35 | }
36 |
--------------------------------------------------------------------------------
/src/dorkbox/messageBus/annotations/Listener.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012 Benjamin Diedrichsen
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining
5 | * a copy of this software and associated documentation files (the
6 | * "Software"), to deal in the Software without restriction, including
7 | * without limitation the rights to use, copy, modify, merge, publish,
8 | * distribute, sublicense, and/or sell copies of the Software, and to
9 | * permit persons to whom the Software is furnished to do so, subject to
10 | * the following conditions:
11 | *
12 | * The above copyright notice and this permission notice shall be
13 | * included in all copies or substantial portions of the Software.
14 | *
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 | package dorkbox.messageBus.annotations;
24 |
25 | import java.lang.annotation.ElementType;
26 | import java.lang.annotation.Inherited;
27 | import java.lang.annotation.Retention;
28 | import java.lang.annotation.RetentionPolicy;
29 | import java.lang.annotation.Target;
30 |
31 | /**
32 | * This annotation is meant to carry configuration that is shared among all instances of the annotated
33 | * listener. Supported configurations are:
34 | *
35 | * Reference type: The bus will use either strong or weak references to its registered listeners,
36 | * depending on which reference type (@see References) is set
37 | *
38 | * @author bennidi
39 | * @author dorkbox, llc
40 | * Date: 2/6/16
41 | */
42 | @Retention(value = RetentionPolicy.RUNTIME)
43 | @Target(value = {ElementType.TYPE, ElementType.ANNOTATION_TYPE})
44 | @Inherited
45 | public
46 | @interface Listener {
47 | /**
48 | * By default, references to message listeners (these are the objects/methods that receive messages) are strong. See {@link dorkbox.messageBus.SubscriptionMode}).
49 | *
50 | * The benefits to use WEAK references, is to eliminate risks of memory leaks in managed environments (such as spring).
51 | *
52 | * the default here "Undefined" here so that the {@link dorkbox.messageBus.SubscriptionMode#StrongReferences} takes priority
53 | */
54 | References references() default References.Undefined;
55 | }
56 |
--------------------------------------------------------------------------------
/src/dorkbox/messageBus/annotations/References.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012 Benjamin Diedrichsen
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining
5 | * a copy of this software and associated documentation files (the
6 | * "Software"), to deal in the Software without restriction, including
7 | * without limitation the rights to use, copy, modify, merge, publish,
8 | * distribute, sublicense, and/or sell copies of the Software, and to
9 | * permit persons to whom the Software is furnished to do so, subject to
10 | * the following conditions:
11 | *
12 | * The above copyright notice and this permission notice shall be
13 | * included in all copies or substantial portions of the Software.
14 | *
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 | package dorkbox.messageBus.annotations;
24 |
25 | /**
26 | * @author bennidi
27 | * Date: 3/29/13
28 | * @author dorkbox, llc
29 | * Date: 2/6/16
30 | */
31 | public enum References {
32 | /** This is the default */
33 | Undefined,
34 |
35 |
36 | /**
37 | * Strong references are faster than weak, as there are no extra steps necessary (to clean up the data structures) during
38 | * mesasge publication.
39 | */
40 | Strong,
41 |
42 | /**
43 | * This is provided so memory management in containers (such as spring) is easier. This is slower access than Strong refs because of
44 | * the additional checks for orphan/GC'd objects in the subscription lists during publication.
45 | */
46 | Weak
47 | }
48 |
--------------------------------------------------------------------------------
/src/dorkbox/messageBus/annotations/Subscribe.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012 Benjamin Diedrichsen
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining
5 | * a copy of this software and associated documentation files (the
6 | * "Software"), to deal in the Software without restriction, including
7 | * without limitation the rights to use, copy, modify, merge, publish,
8 | * distribute, sublicense, and/or sell copies of the Software, and to
9 | * permit persons to whom the Software is furnished to do so, subject to
10 | * the following conditions:
11 | *
12 | * The above copyright notice and this permission notice shall be
13 | * included in all copies or substantial portions of the Software.
14 | *
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | *
23 | *
24 | * Copyright 2015 dorkbox, llc
25 | *
26 | * Licensed under the Apache License, Version 2.0 (the "License");
27 | * you may not use this file except in compliance with the License.
28 | * You may obtain a copy of the License at
29 | *
30 | * http://www.apache.org/licenses/LICENSE-2.0
31 | *
32 | * Unless required by applicable law or agreed to in writing, software
33 | * distributed under the License is distributed on an "AS IS" BASIS,
34 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
35 | * See the License for the specific language governing permissions and
36 | * limitations under the License.
37 | */
38 | package dorkbox.messageBus.annotations;
39 |
40 | import java.lang.annotation.ElementType;
41 | import java.lang.annotation.Inherited;
42 | import java.lang.annotation.Retention;
43 | import java.lang.annotation.RetentionPolicy;
44 | import java.lang.annotation.Target;
45 |
46 | /**
47 | * Marks a method of any subscribed class as a message event handler and configure the handler
48 | * using different properties.
49 | *
50 | * @author bennidi
51 | * Date: 2/8/12
52 | * @author dorkbox
53 | * Date: 2/2/15
54 | */
55 | @Retention(value = RetentionPolicy.RUNTIME)
56 | @Inherited
57 | @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE})
58 | public
59 | @interface Subscribe {
60 |
61 | /**
62 | * Define whether or not the subscription handler accepts sub types of the message type it declares in its
63 | * signature.
64 | */
65 | boolean acceptSubtypes() default true;
66 |
67 | /**
68 | * Enable or disable the subscription. Disabled subscription handlers do not receive any messages.
69 | *
70 | * This property is useful for quick changes in configuration and necessary to subscription disable
71 | * handlers that have been declared by a superclass but do not apply to the subclass
72 | */
73 | boolean enabled() default true;
74 | }
75 |
--------------------------------------------------------------------------------
/src/dorkbox/messageBus/annotations/Synchronized.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012 Benjamin Diedrichsen
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining
5 | * a copy of this software and associated documentation files (the
6 | * "Software"), to deal in the Software without restriction, including
7 | * without limitation the rights to use, copy, modify, merge, publish,
8 | * distribute, sublicense, and/or sell copies of the Software, and to
9 | * permit persons to whom the Software is furnished to do so, subject to
10 | * the following conditions:
11 | *
12 | * The above copyright notice and this permission notice shall be
13 | * included in all copies or substantial portions of the Software.
14 | *
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 | package dorkbox.messageBus.annotations;
24 |
25 | import java.lang.annotation.ElementType;
26 | import java.lang.annotation.Inherited;
27 | import java.lang.annotation.Retention;
28 | import java.lang.annotation.RetentionPolicy;
29 | import java.lang.annotation.Target;
30 |
31 | /**
32 | * A handler marked with this annotation is guaranteed to be invoked in a thread-safe manner, that is, no
33 | * other running message publication will be able to invoke this or any other synchronized handler of the same
34 | * listener until the handler completed. It is equal to wrapping the handler code in a synchronized{} block.
35 | * This feature will reduce performance of message publication. Try to avoid shared mutable state whenever possible
36 | * and use immutable data instead.
37 | *
38 | * Note: Unsynchronized handlers may be invoked concurrently with synchronized ones
39 | *
40 | * @author bennidi
41 | * Date: 3/31/13
42 | */
43 | @Retention(value = RetentionPolicy.RUNTIME)
44 | @Inherited
45 | @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE})
46 | public
47 | @interface Synchronized {}
48 |
--------------------------------------------------------------------------------
/src/dorkbox/messageBus/common/MultiClass.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016 dorkbox, llc
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dorkbox.messageBus.common;
17 |
18 | /**
19 | * @author dorkbox, llc
20 | * Date: 2/3/16
21 | */
22 | public
23 | class MultiClass implements Comparable {
24 | private final int value;
25 |
26 | public
27 | MultiClass(int value) {
28 | this.value = value;
29 | }
30 |
31 | @Override
32 | public
33 | int compareTo(final MultiClass o) {
34 | if (value < o.value) {
35 | return -1;
36 | }
37 | else if (value == o.value) {
38 | return 0;
39 | }
40 | else {
41 | return 1;
42 | }
43 | }
44 |
45 | @Override
46 | public
47 | boolean equals(final Object o) {
48 | if (this == o) {
49 | return true;
50 | }
51 | if (o == null || getClass() != o.getClass()) {
52 | return false;
53 | }
54 |
55 | final MultiClass that = (MultiClass) o;
56 |
57 | return value == that.value;
58 |
59 | }
60 |
61 | @Override
62 | public
63 | int hashCode() {
64 | return value;
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/dorkbox/messageBus/dispatch/Dispatch.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 dorkbox, llc
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dorkbox.messageBus.dispatch;
17 |
18 |
19 | import dorkbox.messageBus.error.ErrorHandler;
20 | import dorkbox.messageBus.publication.Publisher;
21 | import dorkbox.messageBus.subscription.SubscriptionManager;
22 |
23 | /**
24 | * @author dorkbox, llc
25 | * Date: 2/2/15
26 | */
27 | public interface Dispatch {
28 | void publish(Publisher publisher, ErrorHandler errorHandler, SubscriptionManager subscriptionManager, Object message1);
29 | void publish(Publisher publisher, ErrorHandler errorHandler, SubscriptionManager subscriptionManager, Object message1, Object message2);
30 | void publish(Publisher publisher, ErrorHandler errorHandler, SubscriptionManager subscriptionManager, Object message1, Object message2, Object message3);
31 | }
32 |
--------------------------------------------------------------------------------
/src/dorkbox/messageBus/error/DeadMessage.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012 Benjamin Diedrichsen
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining
5 | * a copy of this software and associated documentation files (the
6 | * "Software"), to deal in the Software without restriction, including
7 | * without limitation the rights to use, copy, modify, merge, publish,
8 | * distribute, sublicense, and/or sell copies of the Software, and to
9 | * permit persons to whom the Software is furnished to do so, subject to
10 | * the following conditions:
11 | *
12 | * The above copyright notice and this permission notice shall be
13 | * included in all copies or substantial portions of the Software.
14 | *
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | *
23 | *
24 | * Copyright 2015 dorkbox, llc
25 | *
26 | * Licensed under the Apache License, Version 2.0 (the "License");
27 | * you may not use this file except in compliance with the License.
28 | * You may obtain a copy of the License at
29 | *
30 | * http://www.apache.org/licenses/LICENSE-2.0
31 | *
32 | * Unless required by applicable law or agreed to in writing, software
33 | * distributed under the License is distributed on an "AS IS" BASIS,
34 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
35 | * See the License for the specific language governing permissions and
36 | * limitations under the License.
37 | */
38 | package dorkbox.messageBus.error;
39 |
40 | /**
41 | * The dead message event is published whenever no message handlers could be found for a given message publication.
42 | *
43 | * @author bennidi
44 | * Date: 1/18/13
45 | * @author dorkbox, llc
46 | * Date: 2/2/15
47 | */
48 | public final
49 | class DeadMessage {
50 |
51 | private final Object[] relatedMessages;
52 |
53 | public
54 | DeadMessage(Object message) {
55 | this.relatedMessages = new Object[1];
56 | this.relatedMessages[0] = message;
57 | }
58 |
59 | public
60 | DeadMessage(Object message1, Object message2) {
61 | this.relatedMessages = new Object[2];
62 | this.relatedMessages[0] = message1;
63 | this.relatedMessages[1] = message2;
64 | }
65 |
66 | public
67 | DeadMessage(Object message1, Object message2, Object message3) {
68 | this.relatedMessages = new Object[3];
69 | this.relatedMessages[0] = message1;
70 | this.relatedMessages[1] = message2;
71 | this.relatedMessages[2] = message3;
72 | }
73 |
74 | public
75 | Object[] getMessages() {
76 | return this.relatedMessages;
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/src/dorkbox/messageBus/error/ErrorHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 dorkbox, llc
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dorkbox.messageBus.error;
17 |
18 | import java.util.ArrayDeque;
19 | import java.util.Collection;
20 |
21 | /**
22 | * @author bennidi
23 | */
24 | @SuppressWarnings("Duplicates")
25 | public final
26 | class ErrorHandler {
27 | private static final String LINE_SEPARATOR = System.getProperty("line.separator");
28 |
29 | private static final String ERROR_HANDLER_MSG =
30 | "INFO: No error handler has been configured to handle exceptions during publication." + LINE_SEPARATOR +
31 | "Falling back to console logger." + LINE_SEPARATOR +
32 | "Publication error handlers can be added by calling MessageBus.addErrorHandler()" + LINE_SEPARATOR;
33 |
34 | // this handler will receive all errors that occur during message dispatch or message handling
35 | private final Collection errorHandlers = new ArrayDeque();
36 | private boolean changedDefaults = false;
37 |
38 |
39 | public
40 | ErrorHandler() {
41 | }
42 |
43 | public synchronized
44 | void addErrorHandler(IPublicationErrorHandler handler) {
45 | changedDefaults = true;
46 |
47 | this.errorHandlers.add(handler);
48 | }
49 |
50 | public synchronized
51 | void handlePublicationError(PublicationError error) {
52 | if (!changedDefaults) {
53 | changedDefaults = true;
54 |
55 | // lazy-set the error handler + default message if none have been set
56 | if (this.errorHandlers.isEmpty()) {
57 | this.errorHandlers.add(new IPublicationErrorHandler.ConsoleLogger());
58 | System.out.println(ERROR_HANDLER_MSG);
59 | }
60 | }
61 |
62 | for (IPublicationErrorHandler errorHandler : this.errorHandlers) {
63 | errorHandler.handleError(error);
64 | }
65 | }
66 |
67 | public synchronized
68 | void handleError(final String error, final Class> listenerClass) {
69 | if (!changedDefaults) {
70 | changedDefaults = true;
71 |
72 | // lazy-set the error handler + default message if none have been set
73 | if (this.errorHandlers.isEmpty()) {
74 | this.errorHandlers.add(new IPublicationErrorHandler.ConsoleLogger());
75 | System.out.println(ERROR_HANDLER_MSG);
76 | }
77 | }
78 |
79 | for (IPublicationErrorHandler errorHandler : this.errorHandlers) {
80 | errorHandler.handleError(error, listenerClass);
81 | }
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/src/dorkbox/messageBus/error/IPublicationErrorHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012 Benjamin Diedrichsen
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining
5 | * a copy of this software and associated documentation files (the
6 | * "Software"), to deal in the Software without restriction, including
7 | * without limitation the rights to use, copy, modify, merge, publish,
8 | * distribute, sublicense, and/or sell copies of the Software, and to
9 | * permit persons to whom the Software is furnished to do so, subject to
10 | * the following conditions:
11 | *
12 | * The above copyright notice and this permission notice shall be
13 | * included in all copies or substantial portions of the Software.
14 | *
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 | package dorkbox.messageBus.error;
24 |
25 | /**
26 | * Publication error handlers are provided with a publication error every time an error occurs during message publication.
27 | *
28 | * A handler might fail with an exception, not be accessible because of the presence of a security manager or other reasons might
29 | * lead to failures during the message publication process.
30 | *
31 | *
32 | * @author bennidi
33 | * Date: 2/22/12
34 | */
35 | public
36 | interface IPublicationErrorHandler {
37 |
38 | /**
39 | * Handle the given publication error.
40 | *
41 | * @param error The PublicationError to handle.
42 | */
43 | void handleError(PublicationError error);
44 |
45 | /**
46 | * Handle the given publication error.
47 | *
48 | * @param error The PublicationError to handle.
49 | * @param listenerClass The class that caused the error to occur
50 | */
51 | void handleError(String error, final Class> listenerClass);
52 |
53 |
54 | /**
55 | * The default error handler will simply log to standard out and print the stack trace if available.
56 | */
57 | final
58 | class ConsoleLogger implements IPublicationErrorHandler {
59 | /**
60 | * {@inheritDoc}
61 | */
62 | @Override
63 | public
64 | void handleError(final PublicationError error) {
65 | // Printout the error itself
66 | System.out.println(error);
67 |
68 | // Printout the stacktrace from the cause.
69 | if (error.getCause() != null) {
70 | error.getCause().printStackTrace();
71 | }
72 | }
73 |
74 | /**
75 | * {@inheritDoc}
76 | */
77 | @Override
78 | public
79 | void handleError(final String error, final Class> listenerClass) {
80 | // Printout the error itself
81 | System.out.println(new StringBuilder().append(error).append(": ").append(listenerClass.getSimpleName()).toString());
82 | }
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/src/dorkbox/messageBus/error/MessageBusException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012 Benjamin Diedrichsen
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining
5 | * a copy of this software and associated documentation files (the
6 | * "Software"), to deal in the Software without restriction, including
7 | * without limitation the rights to use, copy, modify, merge, publish,
8 | * distribute, sublicense, and/or sell copies of the Software, and to
9 | * permit persons to whom the Software is furnished to do so, subject to
10 | * the following conditions:
11 | *
12 | * The above copyright notice and this permission notice shall be
13 | * included in all copies or substantial portions of the Software.
14 | *
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 | package dorkbox.messageBus.error;
24 |
25 | /**
26 | * The universal exception type for message bus implementations.
27 | *
28 | * @author bennidi
29 | * Date: 3/29/13
30 | */
31 | public
32 | class MessageBusException extends Exception {
33 | private static final long serialVersionUID = 1L;
34 |
35 | public
36 | MessageBusException() {
37 | }
38 |
39 | public
40 | MessageBusException(String message) {
41 | super(message);
42 | }
43 |
44 | public
45 | MessageBusException(String message, Throwable cause) {
46 | super(message, cause);
47 | }
48 |
49 | public
50 | MessageBusException(Throwable cause) {
51 | super(cause);
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/dorkbox/messageBus/error/PublicationError.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012 Benjamin Diedrichsen
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining
5 | * a copy of this software and associated documentation files (the
6 | * "Software"), to deal in the Software without restriction, including
7 | * without limitation the rights to use, copy, modify, merge, publish,
8 | * distribute, sublicense, and/or sell copies of the Software, and to
9 | * permit persons to whom the Software is furnished to do so, subject to
10 | * the following conditions:
11 | *
12 | * The above copyright notice and this permission notice shall be
13 | * included in all copies or substantial portions of the Software.
14 | *
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | *
23 | *
24 | * Copyright 2015 dorkbox, llc
25 | *
26 | * Licensed under the Apache License, Version 2.0 (the "License");
27 | * you may not use this file except in compliance with the License.
28 | * You may obtain a copy of the License at
29 | *
30 | * http://www.apache.org/licenses/LICENSE-2.0
31 | *
32 | * Unless required by applicable law or agreed to in writing, software
33 | * distributed under the License is distributed on an "AS IS" BASIS,
34 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
35 | * See the License for the specific language governing permissions and
36 | * limitations under the License.
37 | */
38 | package dorkbox.messageBus.error;
39 |
40 | import java.util.Arrays;
41 |
42 | /**
43 | * Publication errors are created when object publication fails
44 | * for some reason and contain details as to the cause and location
45 | * where they occurred.
46 | *
47 | *
48 | * @author bennidi
49 | * Date: 2/22/12
50 | * @author dorkbox, llc
51 | * Date: 2/2/15
52 | */
53 | public
54 | class PublicationError {
55 |
56 | // Internal state
57 | private Throwable cause;
58 | private String message;
59 | private Object[] publishedObjects;
60 |
61 |
62 | /**
63 | * Default constructor.
64 | */
65 | public
66 | PublicationError() {
67 | super();
68 | }
69 |
70 | /**
71 | * @return The Throwable giving rise to this PublicationError.
72 | */
73 | public
74 | Throwable getCause() {
75 | return this.cause;
76 | }
77 |
78 | /**
79 | * Assigns the cause of this PublicationError.
80 | *
81 | * @param cause A Throwable which gave rise to this PublicationError.
82 | * @return This PublicationError.
83 | */
84 | public
85 | PublicationError setCause(Throwable cause) {
86 | this.cause = cause;
87 | return this;
88 | }
89 |
90 | public
91 | String getMessage() {
92 | return this.message;
93 | }
94 |
95 | public
96 | PublicationError setMessage(String message) {
97 | this.message = message;
98 | return this;
99 | }
100 |
101 | public
102 | Object[] getPublishedObject() {
103 | return this.publishedObjects;
104 | }
105 |
106 | public
107 | PublicationError setNoPublishedObject() {
108 | this.publishedObjects = new Object[0];
109 |
110 | return this;
111 | }
112 |
113 | public
114 | PublicationError setPublishedObject(Object publishedObject) {
115 | this.publishedObjects = new Object[1];
116 | this.publishedObjects[0] = publishedObject;
117 |
118 | return this;
119 | }
120 |
121 | public
122 | PublicationError setPublishedObject(Object publishedObject1, Object publishedObject2) {
123 | this.publishedObjects = new Object[2];
124 | this.publishedObjects[0] = publishedObject1;
125 | this.publishedObjects[1] = publishedObject2;
126 |
127 | return this;
128 | }
129 |
130 | public
131 | PublicationError setPublishedObject(Object publishedObject1, Object publishedObject2, Object publishedObject3) {
132 | this.publishedObjects = new Object[3];
133 | this.publishedObjects[0] = publishedObject1;
134 | this.publishedObjects[1] = publishedObject2;
135 | this.publishedObjects[2] = publishedObject3;
136 |
137 | return this;
138 | }
139 |
140 | /**
141 | * {@inheritDoc}
142 | */
143 | @Override
144 | public
145 | String toString() {
146 | String newLine = System.getProperty("line.separator");
147 | return "PublicationError{" +
148 | newLine +
149 | "\tcause=" + this.cause +
150 | newLine +
151 | "\tmessage='" + this.message + '\'' +
152 | newLine +
153 | "\tpublishedObject=" + Arrays.deepToString(this.publishedObjects) +
154 | '}';
155 | }
156 | }
157 |
--------------------------------------------------------------------------------
/src/dorkbox/messageBus/publication/ConversantDisruptor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019 dorkbox, llc
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dorkbox.messageBus.publication;
17 |
18 | import java.lang.reflect.Method;
19 | import java.util.concurrent.ThreadPoolExecutor;
20 | import java.util.concurrent.TimeUnit;
21 |
22 | import com.conversantmedia.util.concurrent.DisruptorBlockingQueue;
23 | import com.conversantmedia.util.concurrent.SpinPolicy;
24 | import com.esotericsoftware.reflectasm.MethodAccess;
25 |
26 | import dorkbox.messageBus.error.ErrorHandler;
27 | import dorkbox.messageBus.subscription.asm.AsmInvocation;
28 | import dorkbox.messageBus.subscription.reflection.ReflectionInvocation;
29 | import dorkbox.util.NamedThreadFactory;
30 |
31 | public
32 | class ConversantDisruptor implements Publisher {
33 |
34 | private final Publisher syncPublisher;
35 | private final ThreadPoolExecutor threadExecutor;
36 | private final DisruptorBlockingQueue workQueue;
37 |
38 | public
39 | ConversantDisruptor(final int numberOfThreads) {
40 | this.syncPublisher = new DirectInvocation();
41 |
42 | // ALWAYS round to the nearest power of 2
43 | int minQueueCapacity = 1 << (32 - Integer.numberOfLeadingZeros(numberOfThreads));
44 |
45 | workQueue = new DisruptorBlockingQueue<>(minQueueCapacity, SpinPolicy.WAITING);
46 | threadExecutor = new ThreadPoolExecutor(numberOfThreads, numberOfThreads,
47 | 0L, TimeUnit.MILLISECONDS, workQueue,
48 | new NamedThreadFactory("MessageBus", true));
49 | }
50 |
51 | public
52 | ConversantDisruptor(final ConversantDisruptor publisher) {
53 | this.syncPublisher = publisher.syncPublisher;
54 | this.threadExecutor = publisher.threadExecutor;
55 | this.workQueue = publisher.workQueue;
56 | }
57 |
58 |
59 | // ASM
60 | @Override
61 | public
62 | void publish(final ErrorHandler errorHandler,
63 | final AsmInvocation invocation, final Object listener, final MethodAccess handler, final int handleIndex,
64 | final Object message) {
65 | threadExecutor.submit(new Runnable() {
66 | @Override
67 | public
68 | void run() {
69 | syncPublisher.publish(errorHandler,invocation, listener, handler, handleIndex, message);
70 | }
71 | });
72 | }
73 |
74 | @Override
75 | public
76 | void publish(final ErrorHandler errorHandler,
77 | final AsmInvocation invocation, final Object listener, final MethodAccess handler, final int handleIndex,
78 | final Object message1,
79 | final Object message2) {
80 |
81 | threadExecutor.submit(new Runnable() {
82 | @Override
83 | public
84 | void run() {
85 | syncPublisher.publish(errorHandler,invocation, listener, handler, handleIndex, message1, message2);
86 | }
87 | });
88 | }
89 |
90 | @Override
91 | public
92 | void publish(final ErrorHandler errorHandler,
93 | final AsmInvocation invocation, final Object listener, final MethodAccess handler, final int handleIndex,
94 | final Object message1, final Object message2, final Object message3) {
95 |
96 | threadExecutor.submit(new Runnable() {
97 | @Override
98 | public
99 | void run() {
100 | syncPublisher.publish(errorHandler,invocation, listener, handler, handleIndex, message1, message2, message3);
101 | }
102 | });
103 | }
104 |
105 |
106 |
107 | // REFLECTION
108 | @Override
109 | public
110 | void publish(final ErrorHandler errorHandler,
111 | final ReflectionInvocation invocation, final Object listener, final Method method,
112 | final Object message) {
113 |
114 | threadExecutor.submit(new Runnable() {
115 | @Override
116 | public
117 | void run() {
118 | syncPublisher.publish(errorHandler,invocation, listener, method, message);
119 | }
120 | });
121 | }
122 |
123 | @Override
124 | public
125 | void publish(final ErrorHandler errorHandler,
126 | final ReflectionInvocation invocation, final Object listener, final Method method,
127 | final Object message1, final Object message2) {
128 |
129 | threadExecutor.submit(new Runnable() {
130 | @Override
131 | public
132 | void run() {
133 | syncPublisher.publish(errorHandler,invocation, listener, method, message1, message2);
134 | }
135 | });
136 | }
137 |
138 | @Override
139 | public
140 | void publish(final ErrorHandler errorHandler,
141 | final ReflectionInvocation invocation, final Object listener, final Method method,
142 | final Object message1, final Object message2, final Object message3) {
143 |
144 | threadExecutor.submit(new Runnable() {
145 | @Override
146 | public
147 | void run() {
148 | syncPublisher.publish(errorHandler,invocation, listener, method, message1, message2, message3);
149 | }
150 | });
151 | }
152 |
153 | @Override
154 | public
155 | boolean hasPendingMessages() {
156 | return threadExecutor.getActiveCount() > 0 || workQueue.isEmpty();
157 | }
158 |
159 | @Override
160 | public
161 | void shutdown() {
162 | // This uses Thread.interrupt()
163 | threadExecutor.shutdownNow();
164 | }
165 | }
166 |
--------------------------------------------------------------------------------
/src/dorkbox/messageBus/publication/DirectInvocation.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019 dorkbox, llc
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dorkbox.messageBus.publication;
17 |
18 | import java.lang.reflect.Method;
19 |
20 | import com.esotericsoftware.reflectasm.MethodAccess;
21 |
22 | import dorkbox.messageBus.error.ErrorHandler;
23 | import dorkbox.messageBus.error.PublicationError;
24 | import dorkbox.messageBus.subscription.asm.AsmInvocation;
25 | import dorkbox.messageBus.subscription.reflection.ReflectionInvocation;
26 |
27 | public
28 | class DirectInvocation implements Publisher {
29 |
30 | public
31 | DirectInvocation() {
32 | }
33 |
34 | // ASM
35 | @Override
36 | public
37 | void publish(final ErrorHandler errorHandler,
38 | final AsmInvocation invocation, final Object listener, final MethodAccess handler, final int handleIndex,
39 | final Object message) {
40 | try {
41 | invocation.invoke(listener, handler, handleIndex, message);
42 | } catch (Throwable e) {
43 | errorHandler.handlePublicationError(new PublicationError().setMessage("Error during publication of message.")
44 | .setCause(e)
45 | .setPublishedObject(message));
46 | }
47 | }
48 |
49 | @Override
50 | public
51 | void publish(final ErrorHandler errorHandler,
52 | final AsmInvocation invocation, final Object listener, final MethodAccess handler, final int handleIndex,
53 | final Object message1,
54 | final Object message2) {
55 |
56 | try {
57 | invocation.invoke(listener, handler, handleIndex, message1, message2);
58 | } catch (Throwable e) {
59 | errorHandler.handlePublicationError(new PublicationError().setMessage("Error during publication of message.")
60 | .setCause(e)
61 | .setPublishedObject(message1, message2));
62 | }
63 |
64 | }
65 |
66 | @Override
67 | public
68 | void publish(final ErrorHandler errorHandler,
69 | final AsmInvocation invocation, final Object listener, final MethodAccess handler, final int handleIndex,
70 | final Object message1, final Object message2, final Object message3) {
71 |
72 |
73 | try {
74 | invocation.invoke(listener, handler, handleIndex, message1, message2, message3);
75 | } catch (Throwable e) {
76 | errorHandler.handlePublicationError(new PublicationError().setMessage("Error during publication of message.")
77 | .setCause(e)
78 | .setPublishedObject(message1, message2, message3));
79 | }
80 | }
81 |
82 |
83 |
84 | // REFLECTION
85 | @Override
86 | public
87 | void publish(final ErrorHandler errorHandler,
88 | final ReflectionInvocation invocation, final Object listener, final Method method,
89 | final Object message) {
90 |
91 | try {
92 | invocation.invoke(listener, method, message);
93 | } catch (Throwable e) {
94 | errorHandler.handlePublicationError(new PublicationError().setMessage("Error during publication of message.")
95 | .setCause(e)
96 | .setPublishedObject(message));
97 | }
98 | }
99 |
100 | @Override
101 | public
102 | void publish(final ErrorHandler errorHandler,
103 | final ReflectionInvocation invocation, final Object listener, final Method method,
104 | final Object message1, final Object message2) {
105 |
106 | try {
107 | invocation.invoke(listener, method, message1, message2);
108 | } catch (Throwable e) {
109 | errorHandler.handlePublicationError(new PublicationError().setMessage("Error during publication of message.")
110 | .setCause(e)
111 | .setPublishedObject(message1, message2));
112 | }
113 | }
114 |
115 | @Override
116 | public
117 | void publish(final ErrorHandler errorHandler,
118 | final ReflectionInvocation invocation, final Object listener, final Method method,
119 | final Object message1, final Object message2, final Object message3) {
120 |
121 | try {
122 | invocation.invoke(listener, method, message1, message2, message3);
123 | } catch (Throwable e) {
124 | errorHandler.handlePublicationError(new PublicationError().setMessage("Error during publication of message.")
125 | .setCause(e)
126 | .setPublishedObject(message1, message2, message3));
127 | }
128 | }
129 |
130 |
131 | public
132 | boolean hasPendingMessages() {
133 | return false;
134 | }
135 |
136 | @Override
137 | public
138 | void shutdown() {
139 | }
140 | }
141 |
--------------------------------------------------------------------------------
/src/dorkbox/messageBus/publication/Publisher.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019 dorkbox, llc
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dorkbox.messageBus.publication;
17 |
18 | import java.lang.reflect.Method;
19 |
20 | import com.esotericsoftware.reflectasm.MethodAccess;
21 |
22 | import dorkbox.messageBus.error.ErrorHandler;
23 | import dorkbox.messageBus.subscription.asm.AsmInvocation;
24 | import dorkbox.messageBus.subscription.reflection.ReflectionInvocation;
25 |
26 | public
27 | interface Publisher {
28 | // ASM
29 | void publish(final ErrorHandler errorHandler,
30 | final AsmInvocation invocation, final Object listener, final MethodAccess handler, final int handleIndex,
31 | final Object message);
32 |
33 | void publish(final ErrorHandler errorHandler,
34 | final AsmInvocation invocation, final Object listener, final MethodAccess handler, final int handleIndex,
35 | final Object message1,
36 | final Object message2);
37 |
38 | void publish(final ErrorHandler errorHandler,
39 | final AsmInvocation invocation, final Object listener, final MethodAccess handler, final int handleIndex,
40 | final Object message1, final Object message2, final Object message3);
41 |
42 | // REFLECTION
43 | void publish(final ErrorHandler errorHandler,
44 | final ReflectionInvocation invocation, final Object listener, final Method method,
45 | final Object message);
46 |
47 | void publish(final ErrorHandler errorHandler,
48 | final ReflectionInvocation invocation, final Object listener, final Method method,
49 | final Object message1, final Object message2);
50 |
51 | void publish(final ErrorHandler errorHandler,
52 | final ReflectionInvocation invocation, final Object listener, final Method method,
53 | final Object message1, final Object message2, final Object message3);
54 |
55 |
56 | boolean hasPendingMessages();
57 | void shutdown();
58 | }
59 |
--------------------------------------------------------------------------------
/src/dorkbox/messageBus/publication/disruptor/EventBusFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 dorkbox, llc
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dorkbox.messageBus.publication.disruptor;
17 |
18 | import com.lmax.disruptor.EventFactory;
19 |
20 | /**
21 | * @author dorkbox, llc
22 | * Date: 2/2/15
23 | */
24 | public class EventBusFactory implements EventFactory {
25 |
26 | public EventBusFactory() {
27 | }
28 |
29 | @Override
30 | public
31 | MessageHolder newInstance() {
32 | return new MessageHolder();
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/dorkbox/messageBus/publication/disruptor/MessageHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 dorkbox, llc
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dorkbox.messageBus.publication.disruptor;
17 |
18 | import java.util.concurrent.atomic.AtomicBoolean;
19 |
20 | import com.lmax.disruptor.LifecycleAware;
21 | import com.lmax.disruptor.WorkHandler;
22 |
23 | import dorkbox.messageBus.publication.Publisher;
24 |
25 | /**
26 | * @author dorkbox, llc Date: 2/2/15
27 | */
28 | public
29 | class MessageHandler implements WorkHandler, LifecycleAware {
30 |
31 | private final AtomicBoolean shutdown = new AtomicBoolean(false);
32 | private final Publisher syncPublisher;
33 |
34 | public
35 | MessageHandler(final Publisher syncPublisher) {
36 | this.syncPublisher = syncPublisher;
37 | }
38 |
39 | @Override
40 | public
41 | void onEvent(final MessageHolder event) throws Exception {
42 | switch (event.type) {
43 | // ASM INVOCATION
44 | case MessageType.ASM_ONE:
45 | // this is by far the most common case.
46 | syncPublisher.publish(event.errorHandler, event.asmInvocation, event.listener, event.handler, event.handleIndex, event.message1);
47 | event.clear();
48 | return;
49 | case MessageType.ASM_TWO:
50 | syncPublisher.publish(event.errorHandler, event.asmInvocation, event.listener, event.handler, event.handleIndex, event.message1, event.message2);
51 | event.clear();
52 | return;
53 | case MessageType.ASM_THREE:
54 | syncPublisher.publish(event.errorHandler, event.asmInvocation, event.listener, event.handler, event.handleIndex, event.message1, event.message2, event.message3);
55 | event.clear();
56 | return;
57 |
58 | // REFLECT INVOCATION
59 | case MessageType.REFLECT_ONE:
60 | syncPublisher.publish(event.errorHandler, event.reflectionInvocation, event.listener, event.method, event.message1);
61 | event.clear();
62 | return;
63 | case MessageType.REFLECT_TWO:
64 | syncPublisher.publish(event.errorHandler, event.reflectionInvocation, event.listener, event.method, event.message1, event.message2);
65 | event.clear();
66 | return;
67 | case MessageType.REFLECT_THREE:
68 | syncPublisher.publish(event.errorHandler, event.reflectionInvocation, event.listener, event.method, event.message1, event.message2, event.message3);
69 | event.clear();
70 | //noinspection UnnecessaryReturnStatement
71 | return;
72 | }
73 | }
74 |
75 | @Override
76 | public
77 | void onStart() {
78 | }
79 |
80 | @Override
81 | public synchronized
82 | void onShutdown() {
83 | shutdown.set(true);
84 | }
85 |
86 | public
87 | boolean isShutdown() {
88 | return shutdown.get();
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/src/dorkbox/messageBus/publication/disruptor/MessageHolder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 dorkbox, llc
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dorkbox.messageBus.publication.disruptor;
17 |
18 | import java.lang.reflect.Method;
19 |
20 | import com.esotericsoftware.reflectasm.MethodAccess;
21 |
22 | import dorkbox.messageBus.error.ErrorHandler;
23 | import dorkbox.messageBus.subscription.asm.AsmInvocation;
24 | import dorkbox.messageBus.subscription.reflection.ReflectionInvocation;
25 |
26 | /**
27 | * @author dorkbox, llc Date: 2/2/15
28 | */
29 | public
30 | class MessageHolder {
31 | public int type = MessageType.ASM_ONE;
32 |
33 | public Object message1 = null;
34 | public Object message2 = null;
35 | public Object message3 = null;
36 |
37 | public ErrorHandler errorHandler = null;
38 |
39 | public AsmInvocation asmInvocation = null;
40 | public ReflectionInvocation reflectionInvocation = null;
41 | public Object listener = null;
42 | public Method method = null;
43 | public MethodAccess handler = null;
44 | public int handleIndex = 0;
45 |
46 | public
47 | MessageHolder() {}
48 |
49 | /**
50 | * Make sure objects do not live longer than they are supposed to
51 | */
52 | public
53 | void clear() {
54 | type = MessageType.ASM_ONE;
55 |
56 | message1 = null;
57 | message2 = null;
58 | message3 = null;
59 |
60 | errorHandler = null;
61 | asmInvocation = null;
62 | reflectionInvocation = null;
63 | listener = null;
64 | method = null;
65 |
66 | handler = null;
67 | handleIndex = 0;
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/src/dorkbox/messageBus/publication/disruptor/MessageType.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 dorkbox, llc
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dorkbox.messageBus.publication.disruptor;
17 |
18 | /**
19 | * @author dorkbox, llc Date: 2/2/15
20 | */
21 | public final class MessageType {
22 | public static final int ASM_ONE = 1;
23 | public static final int REFLECT_ONE = 2;
24 |
25 | public static final int ASM_TWO = 3;
26 | public static final int REFLECT_TWO = 4;
27 |
28 | public static final int ASM_THREE = 5;
29 | public static final int REFLECT_THREE = 6;
30 |
31 | private MessageType() {
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/dorkbox/messageBus/publication/disruptor/PublicationExceptionHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016 dorkbox, llc
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dorkbox.messageBus.publication.disruptor;
17 |
18 | import com.lmax.disruptor.ExceptionHandler;
19 |
20 | import dorkbox.messageBus.error.ErrorHandler;
21 | import dorkbox.messageBus.error.PublicationError;
22 |
23 | /**
24 | * @author dorkbox, llc Date: 2/3/16
25 | */
26 | public final class PublicationExceptionHandler implements ExceptionHandler {
27 | private final ErrorHandler errorHandler;
28 |
29 | public PublicationExceptionHandler(ErrorHandler errorHandler) {
30 | this.errorHandler = errorHandler;
31 | }
32 |
33 | @Override
34 | public void handleEventException(final Throwable e, final long sequence, final T event) {
35 | this.errorHandler.handlePublicationError(new PublicationError()
36 | .setMessage("Exception on lmax disruptor processing: " + sequence + " " + event.getClass() + "(" + event + ")")
37 | .setCause(e));
38 | }
39 |
40 | @Override
41 | public void handleOnStartException(final Throwable e) {
42 | this.errorHandler.handlePublicationError(new PublicationError()
43 | .setMessage("Error starting the lmax disruptor")
44 | .setCause(e));
45 | }
46 |
47 | @Override
48 | public void handleOnShutdownException(final Throwable e) {
49 | this.errorHandler.handlePublicationError(new PublicationError()
50 | .setMessage("Error stopping the lmax disruptor")
51 | .setCause(e));
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/dorkbox/messageBus/subscription/Entry.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 dorkbox, llc
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dorkbox.messageBus.subscription;
17 |
18 | //
19 | // not thread-safe!!!
20 | //
21 |
22 |
23 | /**
24 | * @author bennidi
25 | * @author dorkbox, llc Date: 2/3/16
26 | */
27 | public
28 | class Entry {
29 | private final T value;
30 |
31 | private Entry next;
32 | private Entry prev;
33 |
34 | public
35 | Entry(T value, Entry next) {
36 | if (next != null) {
37 | this.next = next;
38 | next.prev = this;
39 | }
40 |
41 | this.value = value;
42 | }
43 |
44 | public
45 | void remove() {
46 | if (this.prev != null) {
47 | this.prev.next = this.next;
48 | if (this.next != null) {
49 | this.next.prev = this.prev;
50 | }
51 | }
52 | else if (this.next != null) {
53 | this.next.prev = null;
54 | }
55 |
56 | // can not nullify references to help GC since running iterators might not see the entire set
57 | // if this element is their current element
58 | //next = null;
59 | //predecessor = null;
60 | }
61 |
62 | public
63 | Entry next() {
64 | return this.next;
65 | }
66 |
67 | public
68 | void clear() {
69 | this.next = null;
70 | }
71 |
72 |
73 | public
74 | T getValue() {
75 | return value;
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/src/dorkbox/messageBus/subscription/SubscriptionFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016 dorkbox, llc
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dorkbox.messageBus.subscription;
17 |
18 | import dorkbox.messageBus.common.MessageHandler;
19 |
20 | /**
21 | * @author dorkbox, llc Date: 2/3/16
22 | */
23 | public
24 | interface SubscriptionFactory {
25 | Subscription> create(final Class> listenerClass, final MessageHandler handler);
26 | }
27 |
--------------------------------------------------------------------------------
/src/dorkbox/messageBus/subscription/asm/AsmFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016 dorkbox, llc
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package dorkbox.messageBus.subscription.asm;
17 |
18 | import dorkbox.messageBus.common.MessageHandler;
19 | import dorkbox.messageBus.subscription.Subscription;
20 | import dorkbox.messageBus.subscription.SubscriptionFactory;
21 |
22 | /**
23 | * @author dorkbox, llc Date: 2/3/16
24 | */
25 | public
26 | class AsmFactory implements SubscriptionFactory {
27 |
28 | private final boolean useStrongReferencesByDefault;
29 |
30 | public
31 | AsmFactory(final boolean useStrongReferencesByDefault) {
32 | this.useStrongReferencesByDefault = useStrongReferencesByDefault;
33 | }
34 |
35 | @Override
36 | public
37 | Subscription> create(final Class> listenerClass, final MessageHandler handler) {
38 | // figure out what kind of references we want to use by default, as specified by MessageBus.useStrongReferencesByDefault
39 | final int referenceType = handler.getReferenceType();
40 | if (referenceType == MessageHandler.UNDEFINED) {
41 | if (useStrongReferencesByDefault) {
42 | return new SubscriptionAsmStrong(listenerClass, handler);
43 | }
44 | else {
45 | return new SubscriptionAsmWeak(listenerClass, handler);
46 | }
47 | }
48 | else if (referenceType == MessageHandler.WEAK) {
49 | return new SubscriptionAsmWeak(listenerClass, handler);
50 | }
51 | else {
52 | return new SubscriptionAsmStrong(listenerClass, handler);
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/dorkbox/messageBus/subscription/asm/AsmInvocation.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012 Benjamin Diedrichsen
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining
5 | * a copy of this software and associated documentation files (the
6 | * "Software"), to deal in the Software without restriction, including
7 | * without limitation the rights to use, copy, modify, merge, publish,
8 | * distribute, sublicense, and/or sell copies of the Software, and to
9 | * permit persons to whom the Software is furnished to do so, subject to
10 | * the following conditions:
11 | *
12 | * The above copyright notice and this permission notice shall be
13 | * included in all copies or substantial portions of the Software.
14 | *
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | *
23 | *
24 | * Copyright 2015 dorkbox, llc
25 | *
26 | * Licensed under the Apache License, Version 2.0 (the "License");
27 | * you may not use this file except in compliance with the License.
28 | * You may obtain a copy of the License at
29 | *
30 | * http://www.apache.org/licenses/LICENSE-2.0
31 | *
32 | * Unless required by applicable law or agreed to in writing, software
33 | * distributed under the License is distributed on an "AS IS" BASIS,
34 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
35 | * See the License for the specific language governing permissions and
36 | * limitations under the License.
37 | */
38 | package dorkbox.messageBus.subscription.asm;
39 |
40 | import com.esotericsoftware.reflectasm.MethodAccess;
41 |
42 | /**
43 | * A handler invocation encapsulates the logic that is used to invoke a single
44 | * message handler to process a given message.
45 | *
46 | * A handler invocation might come in different flavours and can be composed
47 | * of various independent invocations by means of delegation (-> decorator pattern)
48 | *
49 | * If an exception is thrown during handler invocation it is wrapped and propagated
50 | * as a publication error
51 | *
52 | * @author bennidi
53 | * Date: 11/23/12
54 | * @author dorkbox, llc
55 | * Date: 2/2/15
56 | */
57 | public
58 | interface AsmInvocation {
59 |
60 | /**
61 | * Invoke the message delivery logic of this handler
62 | *
63 | * @param listener The listener that will receive the message. This can be a reference to a method object
64 | * from the java reflection api or any other wrapper that can be used to invoke the handler
65 | * @param message The message to be delivered to the handler. This can be any object compatible with the object
66 | * type that the handler consumes
67 | * @param handler The handler (method) that will be called via reflection
68 | */
69 | void invoke(Object listener, MethodAccess handler, int methodIndex, Object message) throws Throwable;
70 |
71 | /**
72 | * Invoke the message delivery logic of this handler
73 | *
74 | * @param listener The listener that will receive the message. This can be a reference to a method object
75 | * from the java reflection api or any other wrapper that can be used to invoke the handler
76 | * @param message1 The message to be delivered to the handler. This can be any object compatible with the object
77 | * type that the handler consumes
78 | * @param handler The handler (method) that will be called via reflection
79 | */
80 | void invoke(Object listener, MethodAccess handler, int methodIndex, Object message1, Object message2) throws Throwable;
81 |
82 | /**
83 | * Invoke the message delivery logic of this handler
84 | *
85 | * @param listener The listener that will receive the message. This can be a reference to a method object
86 | * from the java reflection api or any other wrapper that can be used to invoke the handler
87 | * @param message1 The message to be delivered to the handler. This can be any object compatible with the object
88 | * type that the handler consumes
89 | * @param handler The handler (method) that will be called via reflection
90 | */
91 | void invoke(Object listener, MethodAccess handler, int methodIndex, Object message1, Object message2, Object message3) throws Throwable;
92 | }
93 |
--------------------------------------------------------------------------------
/src/dorkbox/messageBus/subscription/asm/AsmReflectiveInvocation.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012 Benjamin Diedrichsen
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining
5 | * a copy of this software and associated documentation files (the
6 | * "Software"), to deal in the Software without restriction, including
7 | * without limitation the rights to use, copy, modify, merge, publish,
8 | * distribute, sublicense, and/or sell copies of the Software, and to
9 | * permit persons to whom the Software is furnished to do so, subject to
10 | * the following conditions:
11 | *
12 | * The above copyright notice and this permission notice shall be
13 | * included in all copies or substantial portions of the Software.
14 | *
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | *
23 | *
24 | * Copyright 2015 dorkbox, llc
25 | *
26 | * Licensed under the Apache License, Version 2.0 (the "License");
27 | * you may not use this file except in compliance with the License.
28 | * You may obtain a copy of the License at
29 | *
30 | * http://www.apache.org/licenses/LICENSE-2.0
31 | *
32 | * Unless required by applicable law or agreed to in writing, software
33 | * distributed under the License is distributed on an "AS IS" BASIS,
34 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
35 | * See the License for the specific language governing permissions and
36 | * limitations under the License.
37 | */
38 | package dorkbox.messageBus.subscription.asm;
39 |
40 | import com.esotericsoftware.reflectasm.MethodAccess;
41 |
42 | /**
43 | * Uses reflection to invoke a message handler for a given message.
44 | *
45 | * @author bennidi
46 | * Date: 11/23/12
47 | * @author dorkbox, llc
48 | * Date: 2/2/15
49 | */
50 | public
51 | class AsmReflectiveInvocation implements AsmInvocation {
52 |
53 | public
54 | AsmReflectiveInvocation() {
55 | super();
56 | }
57 |
58 | @Override
59 | public
60 | void invoke(final Object listener, final MethodAccess handler, final int methodIndex, final Object message) throws Throwable {
61 | handler.invoke(listener, methodIndex, message);
62 | }
63 |
64 | @Override
65 | public
66 | void invoke(final Object listener, final MethodAccess handler, final int methodIndex, final Object message1, final Object message2) throws Throwable {
67 | handler.invoke(listener, methodIndex, message1, message2);
68 | }
69 |
70 | @Override
71 | public
72 | void invoke(final Object listener, final MethodAccess handler, final int methodIndex, final Object message1, final Object message2, final Object message3) throws Throwable {
73 | handler.invoke(listener, methodIndex, message1, message2, message3);
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/src/dorkbox/messageBus/subscription/asm/AsmSynchronizedInvocation.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012 Benjamin Diedrichsen
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining
5 | * a copy of this software and associated documentation files (the
6 | * "Software"), to deal in the Software without restriction, including
7 | * without limitation the rights to use, copy, modify, merge, publish,
8 | * distribute, sublicense, and/or sell copies of the Software, and to
9 | * permit persons to whom the Software is furnished to do so, subject to
10 | * the following conditions:
11 | *
12 | * The above copyright notice and this permission notice shall be
13 | * included in all copies or substantial portions of the Software.
14 | *
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | *
23 | *
24 | * Copyright 2015 dorkbox, llc
25 | *
26 | * Licensed under the Apache License, Version 2.0 (the "License");
27 | * you may not use this file except in compliance with the License.
28 | * You may obtain a copy of the License at
29 | *
30 | * http://www.apache.org/licenses/LICENSE-2.0
31 | *
32 | * Unless required by applicable law or agreed to in writing, software
33 | * distributed under the License is distributed on an "AS IS" BASIS,
34 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
35 | * See the License for the specific language governing permissions and
36 | * limitations under the License.
37 | */
38 | package dorkbox.messageBus.subscription.asm;
39 |
40 | import com.esotericsoftware.reflectasm.MethodAccess;
41 |
42 | /**
43 | * Synchronizes message handler invocations for all handlers that specify @Synchronized
44 | *
45 | * @author bennidi
46 | * Date: 3/31/13
47 | * @author dorkbox, llc
48 | * Date: 2/2/15
49 | */
50 | public
51 | class AsmSynchronizedInvocation implements AsmInvocation {
52 |
53 | private final AsmInvocation delegate;
54 |
55 | public
56 | AsmSynchronizedInvocation(AsmInvocation delegate) {
57 | this.delegate = delegate;
58 | }
59 |
60 | @Override
61 | public
62 | void invoke(final Object listener, final MethodAccess handler, final int methodIndex, final Object message) throws Throwable {
63 | synchronized (listener) {
64 | this.delegate.invoke(listener, handler, methodIndex, message);
65 | }
66 | }
67 |
68 | @Override
69 | public
70 | void invoke(final Object listener, final MethodAccess handler, int methodIndex, final Object message1, final Object message2) throws Throwable {
71 | synchronized (listener) {
72 | this.delegate.invoke(listener, handler, methodIndex, message1, message2);
73 | }
74 | }
75 |
76 | @Override
77 | public
78 | void invoke(final Object listener, final MethodAccess handler, final int methodIndex, final Object message1, final Object message2, final Object message3) throws Throwable {
79 | synchronized (listener) {
80 | this.delegate.invoke(listener, handler, methodIndex, message1, message2, message3);
81 | }
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/src/dorkbox/messageBus/subscription/asm/SubscriptionAsmStrong.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012 Benjamin Diedrichsen
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining
5 | * a copy of this software and associated documentation files (the
6 | * "Software"), to deal in the Software without restriction, including
7 | * without limitation the rights to use, copy, modify, merge, publish,
8 | * distribute, sublicense, and/or sell copies of the Software, and to
9 | * permit persons to whom the Software is furnished to do so, subject to
10 | * the following conditions:
11 | *
12 | * The above copyright notice and this permission notice shall be
13 | * included in all copies or substantial portions of the Software.
14 | *
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | *
23 | *
24 | * Copyright 2015 dorkbox, llc
25 | *
26 | * Licensed under the Apache License, Version 2.0 (the "License");
27 | * you may not use this file except in compliance with the License.
28 | * You may obtain a copy of the License at
29 | *
30 | * http://www.apache.org/licenses/LICENSE-2.0
31 | *
32 | * Unless required by applicable law or agreed to in writing, software
33 | * distributed under the License is distributed on an "AS IS" BASIS,
34 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
35 | * See the License for the specific language governing permissions and
36 | * limitations under the License.
37 | */
38 | package dorkbox.messageBus.subscription.asm;
39 |
40 | import java.lang.reflect.Method;
41 |
42 | import com.esotericsoftware.reflectasm.MethodAccess;
43 |
44 | import dorkbox.messageBus.common.MessageHandler;
45 | import dorkbox.messageBus.error.ErrorHandler;
46 | import dorkbox.messageBus.subscription.Entry;
47 | import dorkbox.messageBus.publication.Publisher;
48 | import dorkbox.messageBus.subscription.Subscription;
49 |
50 | /**
51 | * A subscription is a container that manages exactly one message handler of all registered
52 | * message listeners of the same class, i.e. all subscribed instances (excluding subclasses) of a message
53 | * will be referenced in the subscription created for a message.
54 | *
55 | * There will be as many unique subscription objects per message listener class as there are message handlers
56 | * defined in the message listeners class hierarchy.
57 | *
58 | * This class uses the "single writer principle", so that the subscription are only MODIFIED by a single thread,
59 | * but are READ by X number of threads (in a safe way). This uses object thread visibility/publication to work.
60 | *
61 | * @author bennidi
62 | * @author dorkbox, llc
63 | * Date: 2/2/15
64 | */
65 | @SuppressWarnings("Duplicates")
66 | final
67 | class SubscriptionAsmStrong extends Subscription