├── .github ├── FUNDING.yml └── workflows │ └── gradle.yml ├── .gitignore ├── CONTRIBUTING.md ├── LICENSE ├── README.adoc ├── build.gradle ├── diagrams ├── diagrams.gradle └── src │ └── docs │ └── asciidoc │ └── index.adoc ├── gradle.properties ├── gradle ├── LICENSE_HEADER └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── jsr377-api ├── gradle.properties ├── jsr377-api.gradle └── src │ └── main │ ├── java │ └── javax │ │ └── application │ │ ├── Application.java │ │ ├── ApplicationPhase.java │ │ ├── ExceptionHandler.java │ │ ├── ExitState.java │ │ ├── ShutdownHandler.java │ │ ├── action │ │ ├── AbortActionExecution.java │ │ ├── Action.java │ │ ├── ActionExecutionStatus.java │ │ ├── ActionHandler.java │ │ ├── ActionInterceptor.java │ │ ├── ActionMetadata.java │ │ ├── ActionParameter.java │ │ └── package-info.java │ │ ├── configuration │ │ ├── Configuration.java │ │ ├── Configured.java │ │ └── package-info.java │ │ ├── converter │ │ ├── ConversionException.java │ │ ├── Converter.java │ │ ├── ConverterRegistry.java │ │ ├── NoopConverter.java │ │ ├── package-info.java │ │ └── spi │ │ │ ├── ConverterProvider.java │ │ │ └── package-info.java │ │ ├── event │ │ ├── EventBus.java │ │ ├── EventFilter.java │ │ ├── EventHandler.java │ │ ├── EventMetadata.java │ │ └── package-info.java │ │ ├── i18n │ │ ├── MessageSource.java │ │ ├── NoSuchMessageException.java │ │ └── package-info.java │ │ ├── package-info.java │ │ ├── resources │ │ ├── InjectedResource.java │ │ ├── NoSuchResourceException.java │ │ ├── ResourceInjector.java │ │ ├── ResourceResolver.java │ │ └── package-info.java │ │ └── threading │ │ ├── Threading.java │ │ ├── ThreadingHandler.java │ │ └── package-info.java │ └── module │ └── module-info.java ├── jsr377-spec ├── CONTRIBUTING.adoc ├── jsr377-spec.gradle └── src │ └── docs │ └── asciidoc │ ├── _license_asl2.adoc │ ├── _license_jcp.adoc │ ├── _links.adoc │ ├── architecture.adoc │ ├── index.adoc │ ├── preface.adoc │ └── references.adoc └── settings.gradle /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | patreon: aalmiray 2 | github: aalmiray 3 | -------------------------------------------------------------------------------- /.github/workflows/gradle.yml: -------------------------------------------------------------------------------- 1 | # 2 | # SPDX-License-Identifier: Apache-2.0 3 | # 4 | # Copyright 2015-2021 the original author or authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | name: Build 20 | 21 | on: [push, pull_request] 22 | 23 | jobs: 24 | build: 25 | name: Build 26 | runs-on: ubuntu-latest 27 | env: 28 | CI: true 29 | steps: 30 | - uses: actions/checkout@v2 31 | 32 | - name: Set up JDK 1.8 33 | uses: actions/setup-java@v1 34 | with: 35 | java-version: 8 36 | distribution: 'zulu' 37 | 38 | - uses: actions/cache@v2 39 | with: 40 | path: ~/.gradle/caches 41 | key: ${{ runner.os }}-gradle-cache-${{ hashFiles('**/*.gradle') }}-${{ hashFiles('**/gradle.properties') }} 42 | restore-keys: | 43 | ${{ runner.os }}-gradle- 44 | 45 | - uses: actions/cache@v2 46 | with: 47 | path: ~/.gradle/wrapper 48 | key: ${{ runner.os }}-gradle-wrapper-${{ hashFiles('**/gradlew') }} 49 | restore-keys: | 50 | ${{ runner.os }}-gradlew- 51 | 52 | - name: Build with Gradle 53 | run: ./gradlew build -S 54 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # gradle 2 | .gradle 3 | build/ 4 | 5 | # Ignore Gradle GUI config 6 | gradle-app.setting 7 | 8 | # intellij 9 | .idea 10 | out/ 11 | *.iml 12 | *.ipr 13 | *.iws 14 | 15 | # eclipse 16 | .project 17 | .classpath 18 | .settings/ 19 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contribution Guidelines 2 | 3 | We love to see contributions to the project and have tried to make it easy to 4 | do so, for example by keeping its scope small and the code equally so. If you 5 | wish to contribute code, then please keep to the following guidelines to 6 | ensure consistency within the codebase and that we have happy users. 7 | 8 | ## Conribution License Agreement 9 | 10 | Please make sure to sign the [JSR-377 CLA](https://www.clahub.com/agreements/jsr377/jsr377-api) first if you want to make 11 | any contributions to the specification. 12 | 13 | ## Philosophy 14 | 15 | Our approach to the project is to keep it small and narrowly focused. Expect new 16 | features to be discussed in-depth before being accepted (or rejected). 17 | 18 | ## Documentation 19 | 20 | If you contribute anything that changes the behaviour of the application, 21 | document it in the README! This includes new features, additional variants 22 | of behaviour and breaking changes. 23 | 24 | Make a note of breaking changes in the pull request because they will need 25 | to go into the release notes. 26 | 27 | ## Commit messages 28 | 29 | It may seem anal to request a particular format for commit messages, but these 30 | are a historical record of what's happening in the code base and consistency 31 | makes investigating that history much easier. 32 | 33 | Please follow the advice of the [Phonegap guys](https://github.com/phonegap/phonegap/wiki/Git-Commit-Message-Format) 34 | when crafting commit messages. The advice basically comes down to: 35 | 36 | * First line should be maximum 50 characters long 37 | * It should summarise the change and use imperative present tense 38 | * The rest of the commit message should come after a blank line 39 | * We encourage you to use Markdown syntax in the rest of the commit message 40 | * Preferably keep to an 80 character limit on lines in the rest of the message. 41 | 42 | If a commit is related to a particular issue, put the issue number after a 43 | hash (#) somewhere in the detail. You can put the issue number in the first 44 | line summary, but only if you can also fit in a useful summary of what was 45 | changed in the commit. 46 | 47 | Here's an example git message: 48 | 49 | > Fix UI thread usage document. 50 | > 51 | > Fixes issue #3. The examples for async and sync usages were mixed up. 52 | > Also, fixed a few typos. 53 | 54 | ## Formatting 55 | 56 | The rules are simple: use the same formatting as the rest of the code. The 57 | following is a list of the styles we are particularly particular about: 58 | 59 | * 4 space indent, no tabs 60 | * a space between if/elseif/catch/etc. keywords and the parenthesis 61 | * elseif/else/catch on their own lines 62 | 63 | If in doubt, submit the change and mention in the pull request that you're not 64 | sure about a particular style you used. We'd rather have the contribution and 65 | fix any minor problems than not have the contribution at all. 66 | 67 | Ultimately, be aware that the maintainers don't have much time to dedicate to 68 | processing pull requests, so the less work they have to do the more likely and 69 | quickly they can merge those pull requests in. 70 | 71 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. -------------------------------------------------------------------------------- /README.adoc: -------------------------------------------------------------------------------- 1 | = JSR 377 - Desktop|Embedded Application API 2 | :linkattrs: 3 | :project-owner: jsr377 4 | :project-name: jsr377-api 5 | 6 | Contains the specification and API sources for link:https://jcp.org/en/jsr/detail?id=377[JSR-377]. 7 | 8 | image:https://github.com/{project-owner}/{project-name}/workflows/Build/badge.svg["Build Status", link="https://github.com/{project-owner}/{project-name}/actions"] 9 | image:https://badges.gitter.im/Join%20Chat.svg[Gitter, link="https://gitter.im/jsr377/jsr377-api?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge"] 10 | image:http://img.shields.io/badge/license-ASF2-blue.svg["Apache License 2", link="http://www.apache.org/licenses/LICENSE-2.0.txt"] 11 | 12 | == Contributing 13 | 14 | - All contributions made by JSR377 Expert Group members are governed by the JSPA. 15 | - All contributions made by non Expert Group members are governed by the Apache Software License v2. 16 | 17 | If you'd like to join the EG then please send your nomination to link:https://jcp.org/en/jsr/egnom?id=377[https://jcp.org/en/jsr/egnom?id=377, window="_blank"] Please bear in mind that you must be a JCP member and have signed the JSPA. You may require an additional signed Exhibit B depending on your membership type. 18 | 19 | To get started (non-EG contributors), link:https://www.clahub.com/agreements/{project-owner}/jsr377-api[sign the Contributor License Agreement, window="_blank"]. 20 | 21 | == Additional resources 22 | 23 | * link:http://jsr377.github.io/site/[JSR377 website, window="_blank"] 24 | * link:http://jsr377-api.40747.n7.nabble.com[Forum / Mailing List, window="_blank"] 25 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Copyright 2015-2021 the original author or authors. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | plugins { 19 | id 'org.kordamp.gradle.java-project' 20 | } 21 | 22 | if (!project.hasProperty('sonatypeUsername')) ext.sonatypeUsername = '**undefined**' 23 | if (!project.hasProperty('sonatypePassword')) ext.sonatypePassword = '**undefined**' 24 | 25 | config { 26 | release = (rootProject.findProperty('release') ?: false).toBoolean() 27 | 28 | info { 29 | name = 'jsr377-api' 30 | vendor = 'JSR-377' 31 | description = 'JSR 377 - Desktop|Embedded Application API' 32 | inceptionYear = '2015' 33 | tags = ['desktop', 'java', 'jsr377'] 34 | 35 | links { 36 | website = 'https://github.com/jsr377/jsr377-api' 37 | issueTracker = 'https://github.com/jsr377/jsr377-api/issues' 38 | scm = 'https://github.com/jsr377/jsr377-api.git' 39 | } 40 | 41 | people { 42 | person { 43 | id = 'aalmiray' 44 | name = 'Andres Almiray' 45 | roles = ['Spec Lead', 'Developer'] 46 | } 47 | } 48 | 49 | specification { 50 | title = 'JSR-377 API' 51 | } 52 | 53 | implementation { enabled = false } 54 | 55 | credentials { 56 | sonatype { 57 | username = project.sonatypeUsername 58 | password = project.sonatypePassword 59 | } 60 | } 61 | } 62 | 63 | licensing { 64 | licenses { 65 | license { 66 | id = 'Apache-2.0' 67 | } 68 | } 69 | } 70 | 71 | stats { 72 | formats = ['xml', 'txt'] 73 | } 74 | 75 | docs { 76 | javadoc { 77 | autoLinks { 78 | enabled = false 79 | } 80 | } 81 | } 82 | } 83 | 84 | allprojects { 85 | apply plugin: 'idea' 86 | 87 | repositories { 88 | mavenCentral() 89 | } 90 | } 91 | 92 | idea { 93 | project { 94 | jdkName rootProject.sourceCompatibility 95 | languageLevel rootProject.sourceCompatibility 96 | } 97 | } 98 | 99 | subprojects { subproj -> 100 | plugins.withType(JavaPlugin) { 101 | subproj.tasks.withType(JavaCompile) { 102 | sourceCompatibility = rootProject.sourceCompatibility 103 | targetCompatibility = rootProject.sourceCompatibility 104 | options.compilerArgs = ['-Xlint:all', '-Xlint:deprecation', '-Xlint:unchecked'] 105 | } 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /diagrams/diagrams.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Copyright 2015-2021 the original author or authors. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | plugins { 20 | id 'org.asciidoctor.jvm.convert' 21 | } 22 | 23 | asciidoctorj { 24 | options doctype: 'book' 25 | 26 | modules { 27 | diagram.use() 28 | diagram.version '2.1.0' 29 | } 30 | 31 | attributes 'source-highlighter' : 'coderay', 32 | 'coderay-linenums-mode' : 'table', 33 | imagesdir : 'images', 34 | toc : 'left', 35 | icon : 'font', 36 | linkattrs : true, 37 | encoding : 'utf-8' 38 | } 39 | -------------------------------------------------------------------------------- /diagrams/src/docs/asciidoc/index.adoc: -------------------------------------------------------------------------------- 1 | = Document Title 2 | 3 | [ditaa,target="javax/application/application-phases"] 4 | ---- 5 | +------------+ 6 | | | 7 | | Initialize |--------------+ 8 | | | | 9 | +------------+ | 10 | | | 11 | v | 12 | +------------+ | 13 | | | | 14 | | Startup |--------------+ 15 | | | | 16 | +------------+ | 17 | | | 18 | v | 19 | +------------+ | 20 | | | | 21 | | Ready |--------------+ 22 | | | | 23 | +------------+ | 24 | | | 25 | v v 26 | +------------+ +------------+ 27 | | | | | 28 | | Main |------->| Shutdown | 29 | | | | | 30 | +------------+ +------------+ 31 | ---- 32 | 33 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # 2 | # SPDX-License-Identifier: Apache-2.0 3 | # 4 | # Copyright 2015-2021 the original author or authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | version = 1.0.0-SNAPSHOT 20 | group = javax.application 21 | sourceCompatibility = 1.8 22 | targetCompatibility = 1.8 23 | 24 | asciidoctorVersion = 3.3.2 25 | kordampPluginVersion = 0.46.0 26 | 27 | org.gradle.daemon = true 28 | org.gradle.caching = true 29 | org.gradle.parallel = false 30 | -------------------------------------------------------------------------------- /gradle/LICENSE_HEADER: -------------------------------------------------------------------------------- 1 | SPDX-License-Identifier: Apache-2.0 2 | 3 | Copyright ${copyrightYear} the original author or authors. 4 | 5 | Licensed under the Apache License, Version 2.0 (the "License"); 6 | you may not use this file except in compliance with the License. 7 | You may obtain a copy of the License at 8 | 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | Unless required by applicable law or agreed to in writing, software 12 | distributed under the License is distributed on an "AS IS" BASIS, 13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | See the License for the specific language governing permissions and 15 | limitations under the License. 16 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jsr377/jsr377-api/b71fc9a6cc8c0b2211b9d37d3a4eb6bde76c7a72/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-6.9-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # 4 | # Copyright 2015 the original author or authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | ## 21 | ## Gradle start up script for UN*X 22 | ## 23 | ############################################################################## 24 | 25 | # Attempt to set APP_HOME 26 | # Resolve links: $0 may be a link 27 | PRG="$0" 28 | # Need this for relative symlinks. 29 | while [ -h "$PRG" ] ; do 30 | ls=`ls -ld "$PRG"` 31 | link=`expr "$ls" : '.*-> \(.*\)$'` 32 | if expr "$link" : '/.*' > /dev/null; then 33 | PRG="$link" 34 | else 35 | PRG=`dirname "$PRG"`"/$link" 36 | fi 37 | done 38 | SAVED="`pwd`" 39 | cd "`dirname \"$PRG\"`/" >/dev/null 40 | APP_HOME="`pwd -P`" 41 | cd "$SAVED" >/dev/null 42 | 43 | APP_NAME="Gradle" 44 | APP_BASE_NAME=`basename "$0"` 45 | 46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 48 | 49 | # Use the maximum available, or set MAX_FD != -1 to use that value. 50 | MAX_FD="maximum" 51 | 52 | warn () { 53 | echo "$*" 54 | } 55 | 56 | die () { 57 | echo 58 | echo "$*" 59 | echo 60 | exit 1 61 | } 62 | 63 | # OS specific support (must be 'true' or 'false'). 64 | cygwin=false 65 | msys=false 66 | darwin=false 67 | nonstop=false 68 | case "`uname`" in 69 | CYGWIN* ) 70 | cygwin=true 71 | ;; 72 | Darwin* ) 73 | darwin=true 74 | ;; 75 | MINGW* ) 76 | msys=true 77 | ;; 78 | NONSTOP* ) 79 | nonstop=true 80 | ;; 81 | esac 82 | 83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 84 | 85 | 86 | # Determine the Java command to use to start the JVM. 87 | if [ -n "$JAVA_HOME" ] ; then 88 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 89 | # IBM's JDK on AIX uses strange locations for the executables 90 | JAVACMD="$JAVA_HOME/jre/sh/java" 91 | else 92 | JAVACMD="$JAVA_HOME/bin/java" 93 | fi 94 | if [ ! -x "$JAVACMD" ] ; then 95 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 96 | 97 | Please set the JAVA_HOME variable in your environment to match the 98 | location of your Java installation." 99 | fi 100 | else 101 | JAVACMD="java" 102 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 103 | 104 | Please set the JAVA_HOME variable in your environment to match the 105 | location of your Java installation." 106 | fi 107 | 108 | # Increase the maximum file descriptors if we can. 109 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 110 | MAX_FD_LIMIT=`ulimit -H -n` 111 | if [ $? -eq 0 ] ; then 112 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 113 | MAX_FD="$MAX_FD_LIMIT" 114 | fi 115 | ulimit -n $MAX_FD 116 | if [ $? -ne 0 ] ; then 117 | warn "Could not set maximum file descriptor limit: $MAX_FD" 118 | fi 119 | else 120 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 121 | fi 122 | fi 123 | 124 | # For Darwin, add options to specify how the application appears in the dock 125 | if $darwin; then 126 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 127 | fi 128 | 129 | # For Cygwin or MSYS, switch paths to Windows format before running java 130 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then 131 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 132 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 133 | 134 | JAVACMD=`cygpath --unix "$JAVACMD"` 135 | 136 | # We build the pattern for arguments to be converted via cygpath 137 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 138 | SEP="" 139 | for dir in $ROOTDIRSRAW ; do 140 | ROOTDIRS="$ROOTDIRS$SEP$dir" 141 | SEP="|" 142 | done 143 | OURCYGPATTERN="(^($ROOTDIRS))" 144 | # Add a user-defined pattern to the cygpath arguments 145 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 146 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 147 | fi 148 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 149 | i=0 150 | for arg in "$@" ; do 151 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 152 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 153 | 154 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 155 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 156 | else 157 | eval `echo args$i`="\"$arg\"" 158 | fi 159 | i=`expr $i + 1` 160 | done 161 | case $i in 162 | 0) set -- ;; 163 | 1) set -- "$args0" ;; 164 | 2) set -- "$args0" "$args1" ;; 165 | 3) set -- "$args0" "$args1" "$args2" ;; 166 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;; 167 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 168 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 169 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 170 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 171 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 172 | esac 173 | fi 174 | 175 | # Escape application args 176 | save () { 177 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 178 | echo " " 179 | } 180 | APP_ARGS=`save "$@"` 181 | 182 | # Collect all arguments for the java command, following the shell quoting and substitution rules 183 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 184 | 185 | exec "$JAVACMD" "$@" 186 | -------------------------------------------------------------------------------- /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 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /jsr377-api/gradle.properties: -------------------------------------------------------------------------------- 1 | # 2 | # SPDX-License-Identifier: Apache-2.0 3 | # 4 | # Copyright 2015-2021 the original author or authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | javaCompatibility = 8 20 | project_description = JSR 377 - Desktop|Embedded Application API -------------------------------------------------------------------------------- /jsr377-api/jsr377-api.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Copyright 2015-2021 the original author or authors. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | plugins { 19 | id 'java-library' 20 | id 'org.beryx.jar' 21 | } 22 | 23 | evaluationDependsOn(':diagrams') 24 | 25 | task copyDiagrams(type: Copy) { 26 | dependsOn project(':diagrams').asciidoctor 27 | from project(':diagrams').file('build/asciidoc/html5/images') 28 | into javadoc.destinationDir 29 | } 30 | 31 | javadoc.finalizedBy copyDiagrams 32 | 33 | jar { 34 | moduleInfoPath = 'src/main/module/module-info.java' 35 | } -------------------------------------------------------------------------------- /jsr377-api/src/main/java/javax/application/Application.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Copyright 2015-2021 the original author or authors. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package javax.application; 19 | 20 | import javax.application.configuration.Configuration; 21 | import java.util.Locale; 22 | 23 | /** 24 | * @author Andres Almiray 25 | */ 26 | public interface Application { 27 | /** 28 | * Lifecycle method. Signals the application to bootstrap itself and load its configuration. 29 | * {@code ApplicationPhase} should be set automatically to {@code ApplicationPhase.INITIALIZE}. 30 | */ 31 | void initialize(); 32 | 33 | /** 34 | * Lifecycle method. Signals the application to assemble its components/artifacts. 35 | * {@code ApplicationPhase} should be set automatically to {@code ApplicationPhase.STARTUP}. 36 | */ 37 | void startup(); 38 | 39 | /** 40 | * Lifecycle method. Signals the application to display its main entry point (Window). 41 | * {@code ApplicationPhase} should be set automatically to {@code ApplicationPhase.READY}, followed 42 | * immediately with {@code ApplicationPhase.MAIN} once the ready sequence has finished. 43 | */ 44 | void ready(); 45 | 46 | /** 47 | * Lifecycle method. Shutdowns the application gracefully. 48 | * {@code ApplicationPhase} should be set automatically to {@code ApplicationPhase.SHUTDOWN}. 49 | * 50 | * @return the exit code that may be sent to the underlying platform process as exit value. Never returns {@code null}. 51 | */ 52 | ExitState shutdown(); 53 | 54 | /** 55 | * Queries any available {@code ShutdownHandler}s do determine if the application can be shutdown. 56 | * 57 | * @return {@code true} if the shutdown sequence can proceed, (@code false} otherwise 58 | */ 59 | boolean canShutdown(); 60 | 61 | /** 62 | * Registers a {@code ShutdownHandler} on this application 63 | * 64 | * @param handler the shutdown handler to be registered. Must not be {@code null}. 65 | * Duplicate values must be ignored. 66 | */ 67 | void addShutdownHandler(ShutdownHandler handler); 68 | 69 | /** 70 | * Removes a {@code ShutdownHandler} from this application 71 | * 72 | * @param handler the shutdown handler to be removed. Must not be {@code null}. 73 | * Duplicate values must be ignored. 74 | */ 75 | void removeShutdownHandler(ShutdownHandler handler); 76 | 77 | /** 78 | * Retrieves the {@code Configuration} of this application. 79 | * 80 | * @return the {@code Configuration} used by this application. Never returns {@code null}. 81 | */ 82 | Configuration getConfiguration(); 83 | 84 | /** 85 | * Returns the current phase. 86 | * 87 | * @return returns the current {@code ApplicationPhase}. Never returns {@code null}. 88 | */ 89 | ApplicationPhase getPhase(); 90 | 91 | /** 92 | * Gets the application locale. 93 | * 94 | * @return the current Locale used by the application. Never returns {@code null}. 95 | */ 96 | Locale getLocale(); 97 | 98 | /** 99 | * Returns the arguments set on the command line (if any).

100 | * 101 | * @return an array of command line arguments. Never returns {@code null}. 102 | */ 103 | String[] getStartupArguments(); 104 | } 105 | -------------------------------------------------------------------------------- /jsr377-api/src/main/java/javax/application/ApplicationPhase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Copyright 2015-2021 the original author or authors. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package javax.application; 19 | 20 | /** 21 | * Defines the application's life-cycle phases.

22 | *

Every instance of {@code javax.application.Application} must follow this life-cycle.

23 | * The life-cycle has few transitions between phases, as shown by the following diagram. 24 | * 25 | * application-phases 26 | * 27 | * @author Andres Almiray 28 | */ 29 | public enum ApplicationPhase { 30 | /** 31 | * 1st phase. All applications start with this one 32 | */ 33 | INITIALIZE, 34 | /** 35 | * 2nd phase. This is where MVC groups are created 36 | */ 37 | STARTUP, 38 | /** 39 | * 3rd phase. Called after main window is shown 40 | */ 41 | READY, 42 | /** 43 | * Main phase. 44 | */ 45 | MAIN, 46 | /** 47 | * Last phase. 48 | */ 49 | SHUTDOWN 50 | } 51 | -------------------------------------------------------------------------------- /jsr377-api/src/main/java/javax/application/ExceptionHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Copyright 2015-2021 the original author or authors. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package javax.application; 19 | 20 | /** 21 | * {@code ExceptionHandler} is responsible for handling exceptions and throwables in a centralized manner. 22 | * 23 | * @author Andres Almiray 24 | */ 25 | public interface ExceptionHandler { 26 | /** 27 | * Processes a {@code Throwable} thrown by application code but that was not caught earlier. 28 | * Implementors must guarantee that no further exceptions or throwables will be thrown 29 | * from this method. 30 | * 31 | * @param thread the {@code Thread} on which the throwable was thrown. Must not be {@code null}. 32 | * @param throwable an uncaught throwable. Must not be {@code null}. 33 | */ 34 | void handleUncaught(Thread thread, Throwable throwable); 35 | } 36 | -------------------------------------------------------------------------------- /jsr377-api/src/main/java/javax/application/ExitState.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Copyright 2015-2021 the original author or authors. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package javax.application; 19 | 20 | /** 21 | * @author Andres Almiray 22 | */ 23 | public interface ExitState { 24 | /** 25 | * Returns the integer value for this code. 26 | * 27 | * @return an integer. 28 | */ 29 | int exitCode(); 30 | 31 | /** 32 | * Finds out if this exit code is allowed to shutdown the application. 33 | * 34 | * @return {@code true} if the application can shutdown, {@code false} otherwise. 35 | */ 36 | default boolean canShutdown() { 37 | return true; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /jsr377-api/src/main/java/javax/application/ShutdownHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Copyright 2015-2021 the original author or authors. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package javax.application; 19 | 20 | /** 21 | * @author Andres Almiray 22 | */ 23 | public interface ShutdownHandler { 24 | /** 25 | * Asks this handler if the application's shutdown sequence can proceed or not.

26 | * Returns {@code false} if the shutdown sequence must be aborted. 27 | * 28 | * @param application the current running application. Must not be {@code null}. 29 | * 30 | * @return {@code true} if the shutdown sequence can proceed, {@code false} otherwise 31 | */ 32 | default boolean canShutdown(Application application) { 33 | return true; 34 | } 35 | 36 | /** 37 | * Called when the shutdown sequence continues. 38 | * 39 | * @param application the current running application. Must not be {@code null}. 40 | */ 41 | void onShutdown(Application application); 42 | } 43 | -------------------------------------------------------------------------------- /jsr377-api/src/main/java/javax/application/action/AbortActionExecution.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Copyright 2015-2021 the original author or authors. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package javax.application.action; 19 | 20 | /** 21 | * Marker Exception used to abort execution of a controller action during the 22 | * BEFORE phase of a ActionHandler. 23 | * 24 | * @author Andres Almiray 25 | */ 26 | public class AbortActionExecution extends RuntimeException { 27 | private static final long serialVersionUID = -8090900669443696189L; 28 | } 29 | -------------------------------------------------------------------------------- /jsr377-api/src/main/java/javax/application/action/Action.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Copyright 2015-2021 the original author or authors. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package javax.application.action; 19 | 20 | /** 21 | * @author Andres Almiray 22 | */ 23 | public interface Action { 24 | String PROPERTY_ID= "id"; 25 | String PROPERTY_NAME = "name"; 26 | String PROPERTY_ENABLED = "enabled"; 27 | 28 | /** 29 | * Returns the metadata associated with this action. 30 | * 31 | * @return a non-null value. 32 | */ 33 | ActionMetadata getActionMetadata(); 34 | 35 | /** 36 | * Returns the owner of this action, this will typically be a (@code Controller} or {@code Presenter}. 37 | * 38 | * @return a non-null value. 39 | */ 40 | Object getOwner(); 41 | 42 | /** 43 | * Returns the id of this action. 44 | * The value for this property must not be null. 45 | * 46 | * @return the id of this action. 47 | */ 48 | String getId(); 49 | 50 | /** 51 | * Sets the id of this action. 52 | * 53 | * @param id the id of this action. Must not be {@code null}, empty, nor blank. 54 | */ 55 | void setId(String id); 56 | 57 | /** 58 | * Returns the name of this action. 59 | * The value for this property may be empty but not null. 60 | * 61 | * @return the name of this action. 62 | */ 63 | String getName(); 64 | 65 | /** 66 | * Sets the name of this action. 67 | * 68 | * @param name the name of this action. Must not be {@code null} but may be emtpy. 69 | */ 70 | void setName(String name); 71 | 72 | /** 73 | * Finds ouf if this action is enabled or not. 74 | * 75 | * @return {@code true} if the action is enabled, {@code false} otherwise. 76 | */ 77 | boolean isEnabled(); 78 | 79 | /** 80 | * Toggles the enabled tate of this action. 81 | * 82 | * @param enabled {@code true} to enabled, {@code false} to disable. 83 | */ 84 | void setEnabled(boolean enabled); 85 | 86 | /** 87 | * Executes the action with the given arguments. 88 | * Executing an action in this way will trigger all {@code ActionHandler}s that may be registered with the application. 89 | * 90 | * @param args a set of arguments. Mey be {@code null}. 91 | */ 92 | void execute(Object... args); 93 | } 94 | -------------------------------------------------------------------------------- /jsr377-api/src/main/java/javax/application/action/ActionExecutionStatus.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Copyright 2015-2021 the original author or authors. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package javax.application.action; 19 | 20 | /** 21 | * @author Andres Almiray 22 | */ 23 | public enum ActionExecutionStatus { 24 | /** 25 | * The Action was successfully executed 26 | */ 27 | OK, 28 | 29 | /** 30 | * An action interceptor aborted execution during before() 31 | */ 32 | ABORTED, 33 | 34 | /** 35 | * The Action threw an exception during its execution 36 | */ 37 | EXCEPTION 38 | } 39 | -------------------------------------------------------------------------------- /jsr377-api/src/main/java/javax/application/action/ActionHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Copyright 2015-2021 the original author or authors. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package javax.application.action; 19 | 20 | import java.lang.annotation.Documented; 21 | import java.lang.annotation.ElementType; 22 | import java.lang.annotation.Inherited; 23 | import java.lang.annotation.Retention; 24 | import java.lang.annotation.RetentionPolicy; 25 | import java.lang.annotation.Target; 26 | 27 | /** 28 | * @author Andres Almiray 29 | */ 30 | @Documented 31 | @Inherited 32 | @Retention(RetentionPolicy.RUNTIME) 33 | @Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD}) 34 | public @interface ActionHandler { 35 | /** 36 | * Defines the action's id. 37 | */ 38 | String value() default ""; 39 | 40 | /** 41 | * Defines the action's name. 42 | */ 43 | String name() default ""; 44 | 45 | /** 46 | * Defines the action's enabled state. 47 | */ 48 | boolean enabled() default true; 49 | } 50 | -------------------------------------------------------------------------------- /jsr377-api/src/main/java/javax/application/action/ActionInterceptor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Copyright 2015-2021 the original author or authors. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package javax.application.action; 19 | 20 | import java.lang.reflect.Method; 21 | 22 | /** 23 | * @author Andres Almiray 24 | */ 25 | public interface ActionInterceptor { 26 | /** 27 | * Update the action's properties. 28 | * 29 | * @param action the action to be updated. Must not be {@code null}. 30 | */ 31 | void update(Action action); 32 | 33 | /** 34 | * Inspect the action during the configuration phase. 35 | *

36 | * This is the perfect time to search for annotations or any other information 37 | * required by the action. interceptors have the option to cache such inspections 38 | * and recall them during {@code before()}, {@code after()} and {@code exception()}. 39 | * 40 | * @param action the action to be configured. Must not be {@code null}. 41 | * @param method the method that represents the action itself. Must not be {@code null}. 42 | */ 43 | void configure(Action action, Method method); 44 | 45 | /** 46 | * Called before an action is executed. 47 | *

48 | * Implementors have the choice of throwing an {@code AbortActionExecution} in 49 | * order to signal that the action should not be invoked. In any case this method 50 | * returns the arguments to be sent to the action, thus allowing the action interceptor 51 | * to modify the arguments as it deem necessary. Failure to return an appropriate 52 | * value will most likely cause an error during the action's execution. 53 | * 54 | * @param action the action to execute. Must not be {@code null}. 55 | * @param args the action's arguments. Must not be {@code null}. 56 | * 57 | * @return arguments to be sent to the action 58 | * 59 | * @throws AbortActionExecution if action execution should be aborted. 60 | */ 61 | Object[] before(Action action, Object[] args); 62 | 63 | /** 64 | * Called after the action has been aborted or executed, even if an exception 65 | * occurred during execution. 66 | *

67 | * 68 | * @param status a flag that indicates the execution status of the action. Must not be {@code null}. 69 | * @param action the action to execute. Must not be {@code null}. 70 | * @param args the arguments sent to the action. Must not be {@code null}. 71 | * @param result the result of executing the action. May be {@code null}. 72 | */ 73 | Object after(ActionExecutionStatus status, Action action, Object[] args, Object result); 74 | 75 | /** 76 | * Called after the action has been executed, when an exception occurred 77 | * during execution. 78 | *

79 | * The exception must be rethrown if was not handled by any action interceptor. 80 | * 81 | * @param exception the exception thrown during the action's execution. Must not be {@code null}. 82 | * @param action the action to execute. Must not be {@code null}. 83 | * @param args the arguments sent to the action during execution. Must not be {@code null}. 84 | * 85 | * @return {@code true} if the exception was handled successfully, 86 | * {@code false} otherwise. 87 | */ 88 | boolean exception(Exception exception, Action action, Object[] args); 89 | } 90 | -------------------------------------------------------------------------------- /jsr377-api/src/main/java/javax/application/action/ActionMetadata.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Copyright 2015-2021 the original author or authors. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package javax.application.action; 19 | 20 | import java.lang.annotation.Annotation; 21 | 22 | /** 23 | * @author Andres Almiray 24 | */ 25 | public interface ActionMetadata { 26 | /** 27 | * Returns the set of annotations attached to the method related to an action. 28 | * 29 | * @return a non-null array of annotations. 30 | */ 31 | Annotation[] getAnnotations(); 32 | 33 | /** 34 | * Returns the type associated with the method related to an action. 35 | * 36 | * @return a non-null type. 37 | */ 38 | Class getReturnType(); 39 | 40 | /** 41 | * Returns the set of parameters of the method related to an action. 42 | * 43 | * @return a non-null array of parameters. 44 | */ 45 | ActionParameter[] getParameters(); 46 | 47 | /** 48 | * Returns the id for the action. 49 | * This value is computed from the name of the method associated with an action. 50 | * Example, invoking this method returns "{@code click}" given an action defined as follows: 51 | *

 52 |      *     package org.example;
 53 |      *
 54 |      *     public class SampleController {
 55 |      *         @ActionHandler
 56 |      *         public class click(ActionEvent event) {
 57 |      *             ...
 58 |      *         }
 59 |      *     }
 60 |      * 
61 | * 62 | * @return a non-null name. 63 | */ 64 | String getActionId(); 65 | 66 | /** 67 | * Returns the simple name for the action. 68 | * This value is computed from the name of the method associated with an action. 69 | * Example, invoking this method returns "{@code click}" given an action defined as follows: 70 | *
 71 |      *     package org.example;
 72 |      *
 73 |      *     public class SampleController {
 74 |      *         @ActionHandler
 75 |      *         public class click(ActionEvent event) {
 76 |      *             ...
 77 |      *         }
 78 |      *     }
 79 |      * 
80 | * 81 | * The computed value may be overridden by supplying a different value to the {@code name} attribute 82 | * of the {@code @ActionHandler} annotation, in the following example the result of invoking this method 83 | * is "{@code clickAndGo}" 84 | *
 85 |      *     package org.example;
 86 |      *
 87 |      *     public class SampleController {
 88 |      *         @ActionHandler(name = "clickAndGo")
 89 |      *         public class click(ActionEvent event) {
 90 |      *             ...
 91 |      *         }
 92 |      *     }
 93 |      * 
94 | * 95 | * @return a non-null name. 96 | */ 97 | String getActionName(); 98 | 99 | /** 100 | * Returns the name of the action with the fully qualified class name of its owner as prefix.

101 | * Example, invoking this method returns "{@code org.example.SampleController.click}" given an action defined as follows: 102 | *
103 |      *     package org.example;
104 |      *
105 |      *     public class SampleController {
106 |      *         @ActionHandler
107 |      *         public class click(ActionEvent event) {
108 |      *             ...
109 |      *         }
110 |      *     }
111 |      * 
112 | *

113 | * 114 | * @return a non-null name. 115 | */ 116 | String getFullyQualifiedName(); 117 | 118 | /** 119 | * Finds out if there are any contextual arguments defined in the method's arguments. 120 | * 121 | * @return {@code true} if any parameter is annotated with {@code Contextual}, {@code false} otherwise. 122 | */ 123 | boolean hasContextualArgs(); 124 | } 125 | -------------------------------------------------------------------------------- /jsr377-api/src/main/java/javax/application/action/ActionParameter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Copyright 2015-2021 the original author or authors. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package javax.application.action; 19 | 20 | import java.lang.annotation.Annotation; 21 | 22 | /** 23 | * @author Andres Almiray 24 | */ 25 | public interface ActionParameter { 26 | /** 27 | * Returns the index of this parameter in the array of parameters for an action. 28 | * 29 | * @return a number equal or greater than {@code 0}. 30 | */ 31 | int getIndex(); 32 | 33 | /** 34 | * Returns the set of annotations attached to parameter. 35 | * 36 | * @return a non-null array of annotations. 37 | */ 38 | Annotation[] getAnnotations(); 39 | 40 | /** 41 | * Returns the type of this parameter. 42 | * 43 | * @return a non-null type. 44 | */ 45 | Class getType(); 46 | 47 | /** 48 | * Returns the name of this parameter. 49 | * 50 | * @return a non-null name. 51 | */ 52 | String getName(); 53 | 54 | /** 55 | * Finds out if this parameter is a contextual one, ie., it's annotated with {@code Contextual}. 56 | * 57 | * @return {@code true} if annotated with {@code Contextual}, {@code false} otherwise. 58 | */ 59 | boolean isContextual(); 60 | 61 | /** 62 | * Finds out if this parameter accepts null values. 63 | * 64 | * @return {@code true} if annotated with an implementation specific qualifier that identifies this parameter as nullable, 65 | * {@code false} otherwise. 66 | */ 67 | boolean isNullable(); 68 | } 69 | -------------------------------------------------------------------------------- /jsr377-api/src/main/java/javax/application/action/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Copyright 2015-2021 the original author or authors. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package javax.application.action; 19 | -------------------------------------------------------------------------------- /jsr377-api/src/main/java/javax/application/configuration/Configuration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Copyright 2015-2021 the original author or authors. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package javax.application.configuration; 19 | 20 | /** 21 | * @author Andres Almiray 22 | */ 23 | public interface Configuration { 24 | /** 25 | * Searches for the key in this configuration. 26 | * 27 | * @param key the key to search. Must not be {@code null}. 28 | * 29 | * @return {@code true} if the context (or its parent) contains the given key, {@code false} otherwise. 30 | */ 31 | boolean containsKey(String key); 32 | 33 | /** 34 | * /** 35 | * Finds a value associated with the given key. The value is 36 | * blindly cast to type {@code T} if found. 37 | * 38 | * @param key the key to search. Must not be {@code null}. 39 | * 40 | * @return the value associated with {@code key}, {@code null} otherwise. 41 | * 42 | * @throws ClassCastException if the value is not of the expected type. 43 | */ 44 | T get(String key); 45 | 46 | /** 47 | * Finds a value associated with the given key. The value is 48 | * blindly cast to type {@code T} if found. If not found then the 49 | * supplied {@code defaultValue} will be returned. 50 | * 51 | * @param key the key to search. Must not be {@code null}. 52 | * @param defaultValue the value to be returned if the key is not found. May be {@code null}. 53 | * 54 | * @return the value associated with {@code key}, or {@code defaultValue} if it was not found. 55 | * 56 | * @throws ClassCastException if the value is not of the expected type. 57 | */ 58 | T get(String key, T defaultValue); 59 | 60 | /** 61 | * Finds a value associated with the given key. The value is 62 | * converted to a {@code boolean} if found. 63 | * 64 | * @param key the key to search. Must not be {@code null}. 65 | * 66 | * @return the value associated with {@code key}, or {@code false} if it was not found. 67 | * 68 | * @throws javax.application.converter.ConversionException if the resource could not be converted to a {@code boolean}. 69 | */ 70 | boolean getAsBoolean(String key); 71 | 72 | /** 73 | * Finds a value associated with the given key. The value is 74 | * converted to a {@code boolean} if found. If not found then the 75 | * supplied {@code defaultValue} will be returned. 76 | * 77 | * @param key the key to search. Must not be {@code null}. 78 | * @param defaultValue the value to be returned if the key is not found. 79 | * 80 | * @return the value associated with {@code key}, or {@code defaultValue} if it was not found. 81 | * 82 | * @throws javax.application.converter.ConversionException if the resource could not be converted to a {@code boolean}. 83 | */ 84 | boolean getAsBoolean(String key, boolean defaultValue); 85 | 86 | /** 87 | * Finds a value associated with the given key. The value is 88 | * converted to an {@code int} if found. 89 | * 90 | * @param key the key to search. Must not be {@code null}. 91 | * 92 | * @return the value associated with {@code key}, or {@code 0} if it was not found. 93 | * 94 | * @throws javax.application.converter.ConversionException if the resource could not be converted to an {@code int}. 95 | */ 96 | int getAsInt(String key); 97 | 98 | /** 99 | * Finds a value associated with the given key. The value is 100 | * converted to an {@code int} if found. If not found then the 101 | * supplied {@code defaultValue} will be returned. 102 | * 103 | * @param key the key to search. Must not be {@code null}. 104 | * @param defaultValue the value to be returned if the key is not found. 105 | * 106 | * @return the value associated with {@code key}, or {@code defaultValue} if it was not found. 107 | * 108 | * @throws javax.application.converter.ConversionException if the resource could not be converted to an {@code int}. 109 | */ 110 | int getAsInt(String key, int defaultValue); 111 | 112 | /** 113 | * Finds a value associated with the given key. The value is 114 | * converted to a {@code long} if found. 115 | * 116 | * @param key the key to search. Must not be {@code null}. 117 | * 118 | * @return the value associated with {@code key}, or {@code 0L} if it was not found. 119 | * 120 | * @throws javax.application.converter.ConversionException if the resource could not be converted to a {@code long}. 121 | */ 122 | long getAsLong(String key); 123 | 124 | /** 125 | * Finds a value associated with the given key. The value is 126 | * converted to a {@code long} if found. If not found then the 127 | * supplied {@code defaultValue} will be returned. 128 | * 129 | * @param key the key to search. Must not be {@code null}. 130 | * @param defaultValue the value to be returned if the key is not found. 131 | * 132 | * @return the value associated with {@code key}, or {@code defaultValue} if it was not found. 133 | * 134 | * @throws javax.application.converter.ConversionException if the resource could not be converted to a {@code long}. 135 | */ 136 | long getAsLong(String key, long defaultValue); 137 | 138 | /** 139 | * Finds a value associated with the given key. The value is 140 | * converted to a {@code float} if found. 141 | * 142 | * @param key the key to search. Must not be {@code null}. 143 | * 144 | * @return the value associated with {@code key}, or {@code 0.0f} if it was not found. 145 | * 146 | * @throws javax.application.converter.ConversionException if the resource could not be converted to a {@code float}. 147 | */ 148 | float getAsFloat(String key); 149 | 150 | /** 151 | * Finds a value associated with the given key. The value is 152 | * converted to a {@code float} if found. If not found then the 153 | * supplied {@code defaultValue} will be returned. 154 | * 155 | * @param key the key to search. Must not be {@code null}. 156 | * @param defaultValue the value to be returned if the key is not found. 157 | * 158 | * @return the value associated with {@code key}, or {@code defaultValue} if it was not found. 159 | * 160 | * @throws javax.application.converter.ConversionException if the resource could not be converted to a {@code float}. 161 | */ 162 | float getAsFloat(String key, float defaultValue); 163 | 164 | /** 165 | * Finds a value associated with the given key. The value is 166 | * converted to a {@code double} if found. 167 | * 168 | * @param key the key to search. Must not be {@code null}. 169 | * 170 | * @return the value associated with {@code key}, or {@code 0.0d} if it was not found. 171 | * 172 | * @throws javax.application.converter.ConversionException if the resource could not be converted to a {@code double}. 173 | */ 174 | double getAsDouble(String key); 175 | 176 | /** 177 | * Finds a value associated with the given key. The value is 178 | * converted to a {@code double} if found. If not found then the 179 | * supplied {@code defaultValue} will be returned. 180 | * 181 | * @param key the key to search. Must not be {@code null}. 182 | * @param defaultValue the value to be returned if the key is not found. 183 | * 184 | * @return the value associated with {@code key}, or {@code defaultValue} if it was not found. 185 | * 186 | * @throws javax.application.converter.ConversionException if the resource could not be converted to a {@code double}. 187 | */ 188 | double getAsDouble(String key, double defaultValue); 189 | 190 | /** 191 | * Finds a value associated with the given key. The value is 192 | * converted to a {@code String} if found. 193 | * 194 | * @param key the key to search. Must not be {@code null}. 195 | * 196 | * @return the literal value associated with {@code key}, or {@code null} if it was not found. 197 | */ 198 | String getAsString(String key); 199 | 200 | /** 201 | * Finds a value associated with the given key. The value is 202 | * converted to a {@code String} if found. If not found then the 203 | * supplied {@code defaultValue} will be returned. 204 | * 205 | * @param key the key to search. Must not be {@code null}. 206 | * @param defaultValue the value to be returned if the key is not found. May be {@code null}. 207 | * 208 | * @return the value associated with {@code key}, or {@code defaultValue} if it was not found. 209 | */ 210 | String getAsString(String key, String defaultValue); 211 | 212 | /** 213 | * Finds a value associated with the given key. The value is 214 | * converted to type {@code T} if found using a {@code Converter}. 215 | * 216 | * @param key the key to search. Must not be {@code null}. 217 | * @param type the type to be returned. Must not be {@code null}. 218 | * 219 | * @return the value associated with {@code key}, or {@code defaultValue} if it was not found. 220 | * 221 | * @throws javax.application.converter.ConversionException if the resource could not be converted to the target type {@code T}. 222 | */ 223 | T getConverted(String key, Class type); 224 | 225 | /** 226 | * Finds a value associated with the given key. The value is 227 | * converted to type {@code T}if found using a {@code Converter}. 228 | * 229 | * @param key the key to search. Must not be {@code null}. 230 | * @param type the type to be returned. Must not be {@code null}. 231 | * @param format format used to convert the value. Must not be {@code null}. 232 | * 233 | * @return the value associated with {@code key}, {@code null} otherwise. 234 | * 235 | * @throws javax.application.converter.ConversionException if the resource could not be converted to the target type {@code T}. 236 | */ 237 | T getConverted(String key, Class type, String format); 238 | 239 | /** 240 | * Finds a value associated with the given key. The value is 241 | * converted to type {@code T} if found using a {@code Converter}. 242 | * If not found then the supplied {@code defaultValue} will be returned. 243 | * 244 | * @param key the key to search. Must not be {@code null}. 245 | * @param type the type to be returned. Must not be {@code null}. 246 | * @param defaultValue the value to be returned if the key is not found. May be {@code null}. 247 | * 248 | * @return the value associated with {@code key}, or {@code defaultValue} if it was not found. 249 | * 250 | * @throws javax.application.converter.ConversionException if the resource could not be converted to the target type {@code T}. 251 | */ 252 | T getConverted(String key, Class type, T defaultValue); 253 | 254 | /** 255 | * Finds a value associated with the given key. The value is 256 | * converted to type {@code T} if found using a {@code Converter}. 257 | * If not found then the supplied {@code defaultValue} will be returned. 258 | * 259 | * @param key the key to search. Must not be {@code null}. 260 | * @param type the type to be returned. Must not be {@code null}. 261 | * @param format format used to convert the value. Must not be {@code null}. 262 | * @param defaultValue the value to be returned if the key is not found. May be {@code null}. 263 | * 264 | * @return the value associated with {@code key}, or {@code defaultValue} if it was not found. 265 | * 266 | * @throws javax.application.converter.ConversionException if the resource could not be converted to the target type {@code T}. 267 | */ 268 | T getConverted(String key, Class type, String format, T defaultValue); 269 | } 270 | -------------------------------------------------------------------------------- /jsr377-api/src/main/java/javax/application/configuration/Configured.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Copyright 2015-2021 the original author or authors. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package javax.application.configuration; 19 | 20 | import javax.application.converter.Converter; 21 | import javax.application.converter.NoopConverter; 22 | import java.lang.annotation.Documented; 23 | import java.lang.annotation.ElementType; 24 | import java.lang.annotation.Inherited; 25 | import java.lang.annotation.Retention; 26 | import java.lang.annotation.RetentionPolicy; 27 | import java.lang.annotation.Target; 28 | 29 | /** 30 | * @author Andres Almiray 31 | */ 32 | @Documented 33 | @Inherited 34 | @Retention(RetentionPolicy.RUNTIME) 35 | @Target({ElementType.FIELD, ElementType.METHOD}) 36 | public @interface Configured { 37 | String NO_VALUE = "javax.application.configuration.Configured.NO_VALUE"; 38 | 39 | String value(); 40 | 41 | String[] args() default {}; 42 | 43 | String defaultValue() default NO_VALUE; 44 | 45 | String format() default ""; 46 | 47 | Class> converter() default NoopConverter.class; 48 | 49 | String configuration() default ""; 50 | } -------------------------------------------------------------------------------- /jsr377-api/src/main/java/javax/application/configuration/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Copyright 2015-2021 the original author or authors. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package javax.application.configuration; 19 | -------------------------------------------------------------------------------- /jsr377-api/src/main/java/javax/application/converter/ConversionException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Copyright 2015-2021 the original author or authors. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package javax.application.converter; 19 | 20 | /* 21 | * @author Andres Almiray 22 | */ 23 | public class ConversionException extends RuntimeException { 24 | private static final long serialVersionUID = -9122143348121235390L; 25 | 26 | private final transient Object value; 27 | private Class type; 28 | 29 | public ConversionException(Object value) { 30 | this(value, (Exception) null); 31 | } 32 | 33 | public ConversionException(Object value, Class type) { 34 | this(value, type, null); 35 | } 36 | 37 | public ConversionException(Object value, Class type, Exception cause) { 38 | super("Can't convert '" + value + "' into " + type.getName(), cause); 39 | this.value = value; 40 | this.type = type; 41 | } 42 | 43 | public ConversionException(Object value, Exception cause) { 44 | super("Can't convert '" + value + "'", cause); 45 | this.value = value; 46 | } 47 | 48 | public Object getValue() { 49 | return value; 50 | } 51 | 52 | public Class getType() { 53 | return type; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /jsr377-api/src/main/java/javax/application/converter/Converter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Copyright 2015-2021 the original author or authors. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package javax.application.converter; 19 | 20 | import java.util.Objects; 21 | 22 | /** 23 | * @author Andres Almiray 24 | */ 25 | public interface Converter { 26 | /** 27 | * Converts the input argument to the given type {@code T}. 28 | * 29 | * @param value the value to be converted. May be {@code null}. 30 | * 31 | * @return the converted value. May be {@code null}. 32 | * 33 | * @throws ConversionException if the given value could not be converted to the target type. 34 | */ 35 | T fromObject(Object value) throws ConversionException; 36 | 37 | /** 38 | * Converts the input argument to the a {@code String}. 39 | * 40 | * @param value the value to be converted. May be {@code null}. 41 | * 42 | * @return the {@code String} representation of the given value. May be {@code null}. 43 | * 44 | * @throws ConversionException if the given value could not be converted to a String. 45 | */ 46 | default String toString(T value) throws ConversionException { 47 | return Objects.toString(value, null); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /jsr377-api/src/main/java/javax/application/converter/ConverterRegistry.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Copyright 2015-2021 the original author or authors. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package javax.application.converter; 19 | 20 | /** 21 | * The ConverterRegistry can be used to locate a converter for 22 | * any given type name. Converters must support the 23 | * {@code javax.application.converter.Converter} interface for converting a given value. 24 | *

25 | * 26 | * @author Andres Almiray 27 | */ 28 | public interface ConverterRegistry { 29 | /** 30 | * Registers a converter class used to convert values of the given target class. 31 | * 32 | * @param targetType the class object of the type to be converted. Must not be {@code null} 33 | * @param converterClass the class object of the converter class. Must not be {@code null} 34 | */ 35 | void registerConverter(Class targetType, Class> converterClass); 36 | 37 | /** 38 | * Unregisters a converter class used to convert values of the given target class. 39 | * If the given {@code converterClass} is {@code null} then all registrations matching {@code targetType} 40 | * are removed. 41 | * 42 | * @param targetType the class object of the type to be converted. Must not be {@code null} 43 | * @param converterClass the class object of the converter class. May be {@code null} 44 | */ 45 | void unregisterConverter(Class targetType, Class> converterClass); 46 | 47 | /** 48 | * Locates a value converter for a given target type. 49 | * 50 | * @param targetType The Class object for the type to be converter. Must not be {@code null} 51 | * 52 | * @return A converter object for the given target class. 53 | * The result is {@code null} if no suitable converter can be found. 54 | */ 55 | Converter findConverter(Class targetType); 56 | 57 | /** 58 | * Removes all currently registered converters. 59 | */ 60 | void clear(); 61 | } 62 | -------------------------------------------------------------------------------- /jsr377-api/src/main/java/javax/application/converter/NoopConverter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Copyright 2015-2021 the original author or authors. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package javax.application.converter; 19 | 20 | /** 21 | * A {@code Converter} that performs no cconversion; it simply returns the given value as is. 22 | * 23 | * @author Andres Almiray 24 | */ 25 | public class NoopConverter implements Converter { 26 | @Override 27 | public Object fromObject(Object value) throws ConversionException { 28 | return value; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /jsr377-api/src/main/java/javax/application/converter/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Copyright 2015-2021 the original author or authors. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package javax.application.converter; 19 | -------------------------------------------------------------------------------- /jsr377-api/src/main/java/javax/application/converter/spi/ConverterProvider.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Copyright 2015-2021 the original author or authors. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package javax.application.converter.spi; 19 | 20 | import javax.application.converter.Converter; 21 | 22 | /** 23 | * @author Andres Almiray 24 | */ 25 | public interface ConverterProvider { 26 | Class getTargetType(); 27 | 28 | Class> getConverterType(); 29 | } 30 | -------------------------------------------------------------------------------- /jsr377-api/src/main/java/javax/application/converter/spi/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Copyright 2015-2021 the original author or authors. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package javax.application.converter.spi; 19 | -------------------------------------------------------------------------------- /jsr377-api/src/main/java/javax/application/event/EventBus.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Copyright 2015-2021 the original author or authors. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package javax.application.event; 19 | 20 | /** 21 | * Base contract for classes that can publish events. 22 | *

23 | * Events can be published int two ways: synchronous (publishEvent) and asynchronous (publishEventAsync). In synchronous 24 | * publishing, the event emitter will wait for all matching event handlers to be called and finish handling the event. In 25 | * asynchronous publishing the event emitter continues its work immediately after firing the event and does not wait for 26 | * matching event handlers. 27 | *

28 | * An event handler is a class that has at least one method annotated with {@code EventHandler} and a 29 | * single argument that defines the type of event hat can be handled, for example 30 | *

31 |  * public class CustomEventHandler {
32 |  *     @EventHandler
33 |  *     private void handleEvent(CustomEvent event) {
34 |  *         ...
35 |  *     }
36 |  * }
37 |  * 
38 | *

39 | * Event handlers may define more than one method. The method name is not important and its visibility modifier may be any 40 | * of the supported modifiers by the Java platform. 41 | * 42 | * @author Andres Almiray 43 | */ 44 | public interface EventBus { 45 | /** 46 | * Adds an event handler.

47 | * An event handler is a class that has at least one method annotated with {@code EventHandler} and a 48 | * single argument that defines the type of event hat can be handled. 49 | * 50 | * @param handler an event handler. Must not be {@code null}. 51 | */ 52 | void subscribe(Object handler); 53 | 54 | /** 55 | * Removes an event handler.

56 | * 57 | * @param handler an event handler. Must not be {@code null}. 58 | */ 59 | void unsubscribe(Object handler); 60 | 61 | /** 62 | * Publishes an event.

63 | * Handlers will be notified in the same thread as the publisher. 64 | * 65 | * @param event the event to be published. Must not be {@code null}. 66 | */ 67 | void publishEvent(E event); 68 | 69 | /** 70 | * Publishes an event.

71 | * Handlers will be notified in a background thread. 72 | * 73 | * @param event the event to be published. Must not be {@code null}. 74 | */ 75 | void publishEventAsync(E event); 76 | } 77 | -------------------------------------------------------------------------------- /jsr377-api/src/main/java/javax/application/event/EventFilter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Copyright 2015-2021 the original author or authors. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package javax.application.event; 19 | 20 | import java.util.function.Function; 21 | 22 | /** 23 | * Annotation to define a filter for an {@link EventHandler}. 24 | * 25 | * @author Andres Almiray 26 | * @author Hendrik Ebbers 27 | */ 28 | public interface EventFilter extends Function, Boolean> { 29 | } 30 | -------------------------------------------------------------------------------- /jsr377-api/src/main/java/javax/application/event/EventHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Copyright 2015-2021 the original author or authors. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package javax.application.event; 19 | 20 | import java.lang.annotation.Documented; 21 | import java.lang.annotation.ElementType; 22 | import java.lang.annotation.Inherited; 23 | import java.lang.annotation.Retention; 24 | import java.lang.annotation.RetentionPolicy; 25 | import java.lang.annotation.Target; 26 | 27 | /** 28 | * @author Andres Almiray 29 | */ 30 | @Documented 31 | @Inherited 32 | @Retention(value = RetentionPolicy.RUNTIME) 33 | @Target(value = {ElementType.METHOD}) 34 | public @interface EventHandler { 35 | /** 36 | * Defines filters for this event handler. All filters are evaluated before the handler is invoked, which 37 | * can only happen if all filters return {@code true}. 38 | */ 39 | Class>[] filters() default {}; 40 | 41 | /** 42 | * Event handlers should be invoked by priority, where higher numbers takes precedence over lower numbers, 43 | * in other words, event handlers should be sorted in descending order of priority. 44 | * 45 | * @return the priority for this event handler. 46 | */ 47 | int priority() default 0; 48 | } 49 | -------------------------------------------------------------------------------- /jsr377-api/src/main/java/javax/application/event/EventMetadata.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Copyright 2015-2021 the original author or authors. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package javax.application.event; 19 | 20 | import java.time.Instant; 21 | 22 | /** 23 | * Defines metadata of an event. This type provides additional information that can be used in a {@link EventFilter} 24 | * 25 | * @param type of the event 26 | * 27 | * @author Hendrik Ebbers 28 | * @author Andres Almiray 29 | */ 30 | public interface EventMetadata { 31 | /** 32 | * The point in time when this event was published. 33 | * 34 | * @return Never returns {@code null}. 35 | */ 36 | Instant getTimestamp(); 37 | 38 | /** 39 | * The event that was published. 40 | * 41 | * @return Never returns {@code null}. 42 | */ 43 | E getEvent(); 44 | } 45 | -------------------------------------------------------------------------------- /jsr377-api/src/main/java/javax/application/event/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Copyright 2015-2021 the original author or authors. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package javax.application.event; 19 | -------------------------------------------------------------------------------- /jsr377-api/src/main/java/javax/application/i18n/MessageSource.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Copyright 2015-2021 the original author or authors. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package javax.application.i18n; 19 | 20 | import java.util.Locale; 21 | import java.util.ResourceBundle; 22 | 23 | /** 24 | * @author Andres Almiray 25 | */ 26 | public interface MessageSource { 27 | /** 28 | * Attempt to resolve a message. 29 | * 30 | * @param key Key to lookup, such as 'log4j.appenders.console'. Must not be {@code null}. 31 | * 32 | * @return The resolved message at the given key for the default locale. 33 | * 34 | * @throws NoSuchMessageException if no message is found. 35 | */ 36 | String getMessage(String key) throws NoSuchMessageException; 37 | 38 | /** 39 | * Attempt to resolve a message. 40 | * 41 | * @param key Key to lookup, such as 'log4j.appenders.console'. Must not be {@code null}. 42 | * @param locale Locale in which to lookup. Must not be {@code null}. 43 | * 44 | * @return The resolved message at the given key for the given locale. 45 | * 46 | * @throws NoSuchMessageException if no message is found. 47 | */ 48 | String getMessage(String key, Locale locale) throws NoSuchMessageException; 49 | 50 | /** 51 | * Attempt to resolve a message. 52 | * 53 | * @param key Key to lookup, such as 'log4j.appenders.console'. Must not be {@code null}. 54 | * @param args Arguments that will be filled in for params within the message (params look like "{0}" within a 55 | * message, but this might differ between implementations), or {@code null} if none. 56 | * 57 | * @return The resolved message at the given key for the default locale. 58 | * 59 | * @throws NoSuchMessageException if no message is found. 60 | */ 61 | String getMessage(String key, Object[] args) throws NoSuchMessageException; 62 | 63 | /** 64 | * Attempt to resolve a message. 65 | * 66 | * @param key Key to lookup, such as 'log4j.appenders.console'. Must not be {@code null}. 67 | * @param args Arguments that will be filled in for params within the message (params look like "{0}" within a 68 | * message, but this might differ between implementations), or {@code null} if none. 69 | * @param locale Locale in which to lookup. Must not be {@code null}. 70 | * 71 | * @return The resolved message at the given key for the given locale. 72 | * 73 | * @throws NoSuchMessageException if no message is found. 74 | */ 75 | String getMessage(String key, Object[] args, Locale locale) throws NoSuchMessageException; 76 | 77 | /** 78 | * Resolves a message. Returns {@code defaultMessage} if no message was found. 79 | * 80 | * @param key Key to lookup, such as 'log4j.appenders.console'. Must not be {@code null}. 81 | * @param defaultMessage Message to return if the lookup fails. 82 | * 83 | * @return The resolved message at the given key for the default locale. 84 | */ 85 | String getMessage(String key, String defaultMessage); 86 | 87 | /** 88 | * Resolves a message. Returns {@code defaultMessage} if no message was found. 89 | * 90 | * @param key Key to lookup, such as 'log4j.appenders.console'. Must not be {@code null}. 91 | * @param locale Locale in which to lookup. Must not be {@code null}. 92 | * @param defaultMessage Message to return if the lookup fails. 93 | * 94 | * @return The resolved message at the given key for the given locale. 95 | */ 96 | String getMessage(String key, Locale locale, String defaultMessage); 97 | 98 | /** 99 | * Resolves a message. Returns {@code defaultMessage} if no message was found. 100 | * 101 | * @param key Key to lookup, such as 'log4j.appenders.console'. Must not be {@code null}. 102 | * @param args Arguments that will be filled in for params within the message (params look like "{0}" 103 | * within a message, but this might differ between implementations), or {@code null} if none. 104 | * @param defaultMessage Message to return if the lookup fails. 105 | * 106 | * @return The resolved message at the given key for the default locale. 107 | */ 108 | String getMessage(String key, Object[] args, String defaultMessage); 109 | 110 | /** 111 | * Resolves a message. Returns {@code defaultMessage} if no message was found. 112 | * 113 | * @param key Key to lookup, such as 'log4j.appenders.console'. Must not be {@code null}. 114 | * @param args Arguments that will be filled in for params within the message (params look like "{0}" 115 | * within a message, but this might differ between implementations), or {@code null} if none. 116 | * @param locale Locale in which to lookup. Must not be {@code null}. 117 | * @param defaultMessage Message to return if the lookup fails. 118 | * 119 | * @return The resolved message at the given key for the given locale. 120 | */ 121 | String getMessage(String key, Object[] args, Locale locale, String defaultMessage); 122 | 123 | /** 124 | * Formats the given message using supplied args to substitute placeholders. 125 | * 126 | * @param message The message following a predefined format. Must not be {@code null}. 127 | * @param args Arguments that will be filled in for params within the message (params look like "{0}" 128 | * within a message, but this might differ between implementations), or {@code null} if none. 129 | * 130 | * @return the formatted message with all matching placeholders with their substituted values. 131 | */ 132 | String formatMessage(String message, Object[] args); 133 | 134 | /** 135 | * Offers a view of this {@code MessageSource} as a {@code ResourceBundle}. 136 | * 137 | * @return a {@code ResourceBundle} containing the keys this {@code MessageSource} 138 | * can resolve. Never returns {@code null}. 139 | */ 140 | ResourceBundle asResourceBundle(); 141 | } 142 | -------------------------------------------------------------------------------- /jsr377-api/src/main/java/javax/application/i18n/NoSuchMessageException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Copyright 2015-2021 the original author or authors. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package javax.application.i18n; 19 | 20 | import java.util.Locale; 21 | 22 | import static java.util.Objects.requireNonNull; 23 | 24 | /** 25 | * @author Andres Almiray 26 | */ 27 | public class NoSuchMessageException extends RuntimeException { 28 | private static final long serialVersionUID = -3197770339868054069L; 29 | 30 | private final String key; 31 | private final Locale locale; 32 | 33 | /** 34 | * Create a new exception. 35 | * 36 | * @param key key that could not be resolved for given locale. Must not be {@code null}. 37 | * @param locale locale that was used to search for the code within. Must not be {@code null}. 38 | */ 39 | public NoSuchMessageException(String key, Locale locale) { 40 | this(key, locale, null); 41 | } 42 | 43 | /** 44 | * Create a new exception. 45 | * 46 | * @param key key that could not be resolved for given locale. Must not be {@code null}. 47 | */ 48 | public NoSuchMessageException(String key) { 49 | this(key, Locale.getDefault()); 50 | } 51 | 52 | /** 53 | * Create a new exception. 54 | * 55 | * @param key key that could not be resolved for given locale. Must not be {@code null}. 56 | * @param cause throwable that caused this exception. May be {@code null}. 57 | */ 58 | public NoSuchMessageException(String key, Throwable cause) { 59 | this(key, Locale.getDefault(), cause); 60 | } 61 | 62 | /** 63 | * Create a new exception. 64 | * 65 | * @param key key that could not be resolved for given locale. Must not be {@code null}. 66 | * @param locale locale that was used to search for the code within. Must not be {@code null}. 67 | * @param cause throwable that caused this exception. May be {@code null}. 68 | */ 69 | public NoSuchMessageException(String key, Locale locale, Throwable cause) { 70 | super("No message found under key '" + requireNonNull(key, "key") + "' for locale '" + requireNonNull(locale, "locale") + "'.", cause); 71 | this.key = key; 72 | this.locale = locale; 73 | } 74 | 75 | /** 76 | * Get the key without a valid value 77 | * 78 | * @return The key. Never returns {@code null}. 79 | */ 80 | public String getKey() { 81 | return key; 82 | } 83 | 84 | /** 85 | * Get the locale without a valid value 86 | * 87 | * @return The locale. Never returns {@code null}. 88 | */ 89 | public Locale getLocale() { 90 | return locale; 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /jsr377-api/src/main/java/javax/application/i18n/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Copyright 2015-2021 the original author or authors. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package javax.application.i18n; 19 | -------------------------------------------------------------------------------- /jsr377-api/src/main/java/javax/application/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Copyright 2015-2021 the original author or authors. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package javax.application; 19 | -------------------------------------------------------------------------------- /jsr377-api/src/main/java/javax/application/resources/InjectedResource.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Copyright 2015-2021 the original author or authors. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package javax.application.resources; 19 | 20 | import javax.application.converter.Converter; 21 | import javax.application.converter.NoopConverter; 22 | import java.lang.annotation.Documented; 23 | import java.lang.annotation.ElementType; 24 | import java.lang.annotation.Inherited; 25 | import java.lang.annotation.Retention; 26 | import java.lang.annotation.RetentionPolicy; 27 | import java.lang.annotation.Target; 28 | 29 | /** 30 | * @author Andres Almiray 31 | */ 32 | @Documented 33 | @Inherited 34 | @Retention(RetentionPolicy.RUNTIME) 35 | @Target({ElementType.FIELD, ElementType.METHOD}) 36 | public @interface InjectedResource { 37 | String NO_VALUE = "javax.application.resources.InjectedResource.NO_VALUE"; 38 | 39 | String value() default ""; 40 | 41 | String[] args() default {}; 42 | 43 | String defaultValue() default NO_VALUE; 44 | 45 | String format() default ""; 46 | 47 | Class> converter() default NoopConverter.class; 48 | } 49 | -------------------------------------------------------------------------------- /jsr377-api/src/main/java/javax/application/resources/NoSuchResourceException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Copyright 2015-2021 the original author or authors. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package javax.application.resources; 19 | 20 | import java.util.Locale; 21 | 22 | import static java.util.Objects.requireNonNull; 23 | 24 | /** 25 | * @author Andres Almiray 26 | */ 27 | public class NoSuchResourceException extends RuntimeException { 28 | private static final long serialVersionUID = -3764590132204577975L; 29 | 30 | private final String key; 31 | private final Locale locale; 32 | 33 | /** 34 | * Create a new exception. 35 | * 36 | * @param key key that could not be resolved for given locale. Must not be {@code null}. 37 | * @param locale locale that was used to search for the code within. Must not be {@code null}. 38 | */ 39 | public NoSuchResourceException(String key, Locale locale) { 40 | this(key, locale, null); 41 | } 42 | 43 | /** 44 | * Create a new exception. 45 | * 46 | * @param key key that could not be resolved for given locale. Must not be {@code null}. 47 | */ 48 | public NoSuchResourceException(String key) { 49 | this(key, Locale.getDefault()); 50 | } 51 | 52 | /** 53 | * Create a new exception. 54 | * 55 | * @param key key that could not be resolved for given locale. Must not be {@code null}. 56 | * @param cause throwable that caused this exception. May be {@code null}. 57 | */ 58 | public NoSuchResourceException(String key, Throwable cause) { 59 | this(key, Locale.getDefault(), cause); 60 | } 61 | 62 | /** 63 | * Create a new exception. 64 | * 65 | * @param key key that could not be resolved for given locale. Must not be {@code null}. 66 | * @param locale locale that was used to search for the code within. Must not be {@code null}. 67 | * @param cause throwable that caused this exception. May be {@code null}. 68 | */ 69 | public NoSuchResourceException(String key, Locale locale, Throwable cause) { 70 | super("No resource found under key '" + requireNonNull(key, "key") + "' for locale '" + requireNonNull(locale, "locale") + "'.", cause); 71 | this.key = key; 72 | this.locale = locale; 73 | } 74 | 75 | /** 76 | * Get the key without a valid value 77 | * 78 | * @return The key. Never returns {@code null}. 79 | */ 80 | public String getKey() { 81 | return key; 82 | } 83 | 84 | /** 85 | * Get the locale without a valid value 86 | * 87 | * @return The locale. Never returns {@code null}. 88 | */ 89 | public Locale getLocale() { 90 | return locale; 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /jsr377-api/src/main/java/javax/application/resources/ResourceInjector.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Copyright 2015-2021 the original author or authors. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package javax.application.resources; 19 | 20 | /** 21 | * @author Andres Almiray 22 | */ 23 | public interface ResourceInjector { 24 | /** 25 | * Performs resource injection into the given instance. Candidates for resource injection must be annotated with 26 | * {@code @javax.annotation.resources.InjectedResource}. 27 | * 28 | * @param instance the instance on which resource injection will be executed. Must not be {@code null}. 29 | */ 30 | void injectResources(Object instance); 31 | } 32 | -------------------------------------------------------------------------------- /jsr377-api/src/main/java/javax/application/resources/ResourceResolver.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Copyright 2015-2021 the original author or authors. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package javax.application.resources; 19 | 20 | import java.util.Locale; 21 | 22 | /** 23 | * @author Andres Almiray 24 | */ 25 | public interface ResourceResolver { 26 | /** 27 | * Attempt to resolve the resource. 28 | * 29 | * @param key Key to lookup, such as 'sample.SampleModel.icon'. Must not be {@code null}. 30 | * 31 | * @return The resolved resource at the given key for the default locale. 32 | * 33 | * @throws NoSuchResourceException if no resource is found. 34 | * @throws ClassCastException if the resource is not of the expected type. 35 | */ 36 | T resolveResource(String key) throws NoSuchResourceException; 37 | 38 | /** 39 | * Attempt to resolve the resource. 40 | * 41 | * @param key Key to lookup, such as 'sample.SampleModel.icon'. Must not be {@code null}. 42 | * @param locale Locale in which to lookup. Must not be {@code null}. 43 | * 44 | * @return The resolved resource at the given key for the given locale. 45 | * 46 | * @throws NoSuchResourceException if no resource is found. 47 | * @throws ClassCastException if the resource is not of the expected type. 48 | */ 49 | T resolveResource(String key, Locale locale) throws NoSuchResourceException; 50 | 51 | /** 52 | * Attempt to resolve the resource. 53 | * 54 | * @param key Key to lookup, such as 'sample.SampleModel.icon'. Must not be {@code null}. 55 | * @param args Arguments that will be filled in for params within the resource (params look like "{0}" within a 56 | * resource, but this might differ between implementations). Must not be {@code null}. 57 | * 58 | * @return The resolved resource at the given key for the default locale. 59 | * 60 | * @throws NoSuchResourceException if no resource is found. 61 | * @throws ClassCastException if the resource is not of the expected type. 62 | */ 63 | T resolveResource(String key, Object[] args) throws NoSuchResourceException; 64 | 65 | /** 66 | * Attempt to resolve the resource. 67 | * 68 | * @param key Key to lookup, such as 'sample.SampleModel.icon'. Must not be {@code null}. 69 | * @param args Arguments that will be filled in for params within the resource (params look like "{0}" within a 70 | * resource, but this might differ between implementations), or {@code null} if none. 71 | * @param locale Locale in which to lookup. Must not be {@code null}. 72 | * 73 | * @return The resolved resource at the given key for the given locale. 74 | * 75 | * @throws NoSuchResourceException if no resource is found. 76 | * @throws ClassCastException if the resource is not of the expected type. 77 | */ 78 | T resolveResource(String key, Object[] args, Locale locale) throws NoSuchResourceException; 79 | 80 | /** 81 | * Attempt to resolve the resource. Return default resource if no resource was found. 82 | * 83 | * @param key Key to lookup, such as 'sample.SampleModel.icon'. Must not be {@code null}. 84 | * @param defaultValue value to return if the lookup fails. May be {@code null}. 85 | * 86 | * @return The resolved resource at the given key for the default locale. 87 | * 88 | * @throws ClassCastException if the resource is not of the expected type. 89 | */ 90 | T resolveResource(String key, T defaultValue); 91 | 92 | /** 93 | * Attempt to resolve the resource. Return default resource if no resource was found. 94 | * 95 | * @param key Key to lookup, such as 'sample.SampleModel.icon'. Must not be {@code null}. 96 | * @param locale Locale in which to lookup. Must not be {@code null}. 97 | * @param defaultValue value to return if the lookup fails. May be {@code null}. 98 | * 99 | * @return The resolved resource at the given key for the given locale. 100 | * 101 | * @throws ClassCastException if the resource is not of the expected type. 102 | */ 103 | T resolveResource(String key, Locale locale, T defaultValue); 104 | 105 | /** 106 | * Attempt to resolve the resource. Return default resource if no resource was found. 107 | * 108 | * @param key Key to lookup, such as 'sample.SampleModel.icon'. Must not be {@code null}. 109 | * @param args Arguments that will be filled in for params within the resource (params look like "{0}" within a 110 | * resource, but this might differ between implementations). Must not be {@code null}. 111 | * @param defaultValue value to return if the lookup fails. May be {@code null}. 112 | * 113 | * @return The resolved resource at the given key for the default locale. 114 | * 115 | * @throws ClassCastException if the resource is not of the expected type. 116 | */ 117 | T resolveResource(String key, Object[] args, T defaultValue); 118 | 119 | /** 120 | * Attempt to resolve the resource. Return default resource if no resource was found. 121 | * 122 | * @param key Key to lookup, such as 'sample.SampleModel.icon'. Must not be {@code null}. 123 | * @param args Arguments that will be filled in for params within the resource (params look like "{0}" within a 124 | * resource, but this might differ between implementations). Must not be {@code null}. 125 | * @param locale Locale in which to lookup. Must not be {@code null}. 126 | * @param defaultValue value to return if the lookup fails. May be {@code null}. 127 | * 128 | * @return The resolved resource at the given key for the given locale. 129 | * 130 | * @throws ClassCastException if the resource is not of the expected type. 131 | */ 132 | T resolveResource(String key, Object[] args, Locale locale, T defaultValue); 133 | 134 | /** 135 | * Attempt to resolve the resource. The value is converted to type {@code T} if found using a {@code Converter}. 136 | * 137 | * @param key Key to lookup, such as 'sample.SampleModel.icon'. Must not be {@code null}. 138 | * @param type Type to be returned. Must not be {@code null}. 139 | * 140 | * @return The resolved resource at the given key for the default locale. 141 | * 142 | * @throws NoSuchResourceException if no resource is found. 143 | * @throws javax.application.converter.ConversionException if the resource could not be converted to the target type {@code T}. 144 | */ 145 | T resolveResourceConverted(String key, Class type) throws NoSuchResourceException; 146 | 147 | /** 148 | * Attempt to resolve the resource. The value is converted to type {@code T} if found using a {@code Converter}. 149 | * 150 | * @param key Key to lookup, such as 'sample.SampleModel.icon'. Must not be {@code null}. 151 | * @param locale Locale in which to lookup. Must not be {@code null}. 152 | * @param type Type to be returned. Must not be {@code null}. 153 | * 154 | * @return The resolved resource at the given key for the given locale. 155 | * 156 | * @throws NoSuchResourceException if no resource is found. 157 | * @throws javax.application.converter.ConversionException if the resource could not be converted to the target type {@code T}. 158 | */ 159 | T resolveResourceConverted(String key, Locale locale, Class type) throws NoSuchResourceException; 160 | 161 | /** 162 | * Attempt to resolve the resource. The value is converted to type {@code T} if found using a {@code Converter}. 163 | * 164 | * @param key Key to lookup, such as 'sample.SampleModel.icon'. Must not be {@code null}. 165 | * @param args Arguments that will be filled in for params within the resource (params look like "{0}" within a 166 | * resource, but this might differ between implementations). Must not be {@code null}. 167 | * @param type Type to be returned. Must not be {@code null}. 168 | * 169 | * @return The resolved resource at the given key for the default locale. 170 | * 171 | * @throws NoSuchResourceException if no resource is found. 172 | * @throws javax.application.converter.ConversionException if the resource could not be converted to the target type {@code T}. 173 | */ 174 | T resolveResourceConverted(String key, Object[] args, Class type) throws NoSuchResourceException; 175 | 176 | /** 177 | * Attempt to resolve the resource. The value is converted to type {@code T} if found using a {@code Converter}. 178 | * 179 | * @param key Key to lookup, such as 'sample.SampleModel.icon'. Must not be {@code null}. 180 | * @param args Arguments that will be filled in for params within the resource (params look like "{0}" within a 181 | * resource, but this might differ between implementations). Must not be {@code null}. 182 | * @param locale Locale in which to lookup. Must not be {@code null}. 183 | * @param type Type to be returned. Must not be {@code null}. 184 | * 185 | * @return The resolved resource at the given key for the given locale. 186 | * 187 | * @throws NoSuchResourceException if no resource is found. 188 | * @throws javax.application.converter.ConversionException if the resource could not be converted to the target type {@code T}. 189 | */ 190 | T resolveResourceConverted(String key, Object[] args, Locale locale, Class type) throws NoSuchResourceException; 191 | 192 | /** 193 | * Attempt to resolve the resource. Returns default value if no resource was found. 194 | * The value is converted to type {@code T} if found using a {@code Converter}. 195 | * 196 | * @param key Key to lookup, such as 'sample.SampleModel.icon'. Must not be {@code null}. 197 | * @param defaultValue value to return if the lookup fails. 198 | * @param type Type to be returned. Must not be {@code null}. 199 | * 200 | * @return The resolved resource at the given key for the default locale. 201 | * 202 | * @throws javax.application.converter.ConversionException if the resource could not be converted to the target type {@code T}. 203 | */ 204 | T resolveResourceConverted(String key, T defaultValue, Class type); 205 | 206 | /** 207 | * Attempt to resolve the resource. Returns default value if no resource was found. 208 | * The value is converted to type {@code T} if found using a {@code Converter}. 209 | * 210 | * @param key Key to lookup, such as 'sample.SampleModel.icon'. Must not be {@code null}. 211 | * @param locale Locale in which to lookup. Must not be {@code null}. 212 | * @param defaultValue value to return if the lookup fails. May be {@code null}. 213 | * @param type Type to be returned. Must not be {@code null}. 214 | * 215 | * @return The resolved resource at the given key for the given locale. 216 | * 217 | * @throws javax.application.converter.ConversionException if the resource could not be converted to the target type {@code T}. 218 | */ 219 | T resolveResourceConverted(String key, Locale locale, T defaultValue, Class type); 220 | 221 | /** 222 | * Attempt to resolve the resource. Returns default value if no resource was found. 223 | * The value is converted to type {@code T} if found using a {@code Converter}. 224 | * 225 | * @param key Key to lookup, such as 'sample.SampleModel.icon'. Must not be {@code null}. 226 | * @param args Arguments that will be filled in for params within the resource (params look like "{0}" within a 227 | * resource, but this might differ between implementations). Must not be {@code null}. 228 | * @param defaultValue value to return if the lookup fails. May be {@code null}. 229 | * @param type Type to be returned. Must not be {@code null}. 230 | * 231 | * @return The resolved resource at the given key for the default locale. 232 | * 233 | * @throws javax.application.converter.ConversionException if the resource could not be converted to the target type {@code T}. 234 | */ 235 | T resolveResourceConverted(String key, Object[] args, T defaultValue, Class type); 236 | 237 | /** 238 | * Attempt to resolve the resource. Returns default value if no resource was found. 239 | * The value is converted to type {@code T} if found using a {@code Converter}. 240 | * 241 | * @param key Key to lookup, such as 'sample.SampleModel.icon'. Must not be {@code null}. 242 | * @param args Arguments that will be filled in for params within the resource (params look like "{0}" within a 243 | * resource, but this might differ between implementations). Must not be {@code null}. 244 | * @param locale Locale in which to lookup. Must not be {@code null}. 245 | * @param defaultValue value to return if the lookup fails. May be {@code null}. 246 | * @param type Type to be returned. Must not be {@code null}. 247 | * 248 | * @return The resolved resource at the given key for the given locale. 249 | * 250 | * @throws javax.application.converter.ConversionException if the resource could not be converted to the target type {@code T}. 251 | */ 252 | T resolveResourceConverted(String key, Object[] args, Locale locale, T defaultValue, Class type); 253 | 254 | /** 255 | * Formats the given resource using supplied args to substitute placeholders. 256 | * 257 | * @param resource The resource following a predefined format. Must not be {@code null}. 258 | * @param args Arguments that will be filled in for params within the resource (params look like "{0}" within a 259 | * resource, but this might differ between implementations). Must not be {@code null}. 260 | * 261 | * @return the formatted resource with all matching placeholders with their substituted values. 262 | */ 263 | String formatResource(String resource, Object[] args); 264 | } 265 | -------------------------------------------------------------------------------- /jsr377-api/src/main/java/javax/application/resources/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Copyright 2015-2021 the original author or authors. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package javax.application.resources; 19 | -------------------------------------------------------------------------------- /jsr377-api/src/main/java/javax/application/threading/Threading.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Copyright 2015-2021 the original author or authors. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package javax.application.threading; 19 | 20 | import java.lang.annotation.Documented; 21 | import java.lang.annotation.ElementType; 22 | import java.lang.annotation.Inherited; 23 | import java.lang.annotation.Retention; 24 | import java.lang.annotation.RetentionPolicy; 25 | import java.lang.annotation.Target; 26 | 27 | /** 28 | * @author Andres Almiray 29 | * @see Threading.Policy 30 | */ 31 | @Documented 32 | @Inherited 33 | @Retention(RetentionPolicy.RUNTIME) 34 | @Target({ElementType.TYPE, ElementType.METHOD}) 35 | public @interface Threading { 36 | /** 37 | * Defines the threading hint to be used when executing the annotated element. 38 | */ 39 | Policy value() default Policy.OUTSIDE_UITHREAD; 40 | 41 | /** 42 | * Indicates the type of threading management for a method or property.

43 | * The following values apply 44 | *
    45 | *
  • {@code SKIP} - no threading management will be performed.
  • 46 | *
  • {@code OUTSIDE_UITHREAD} - code should be invoked outside of the UI thread.
  • 47 | *
  • {@code OUTSIDE_UITHREAD_ASYNC} - code should be invoked on a background thread, always.
  • 48 | *
  • {@code INSIDE_UITHREAD_SYNC} - code should be invoked inside the UI thread using a synchronous call.
  • 49 | *
  • {@code INSIDE_UITHREAD_ASYNC} - code should be invoked inside the UI thread using an asynchronous call.
  • 50 | *
51 | * 52 | * @author Andres Almiray 53 | * @see Threading 54 | */ 55 | enum Policy { 56 | /** 57 | * Skip threading injection 58 | */ 59 | SKIP, 60 | /** 61 | * Inject runOutsideUI wrapper 62 | */ 63 | OUTSIDE_UITHREAD, 64 | /** 65 | * Inject runOutsideUIAsync wrapper 66 | */ 67 | OUTSIDE_UITHREAD_ASYNC, 68 | /** 69 | * Inject runInsideUISync wrapper 70 | */ 71 | INSIDE_UITHREAD_SYNC, 72 | /** 73 | * Inject runInsideUIAsync wrapper 74 | */ 75 | INSIDE_UITHREAD_ASYNC 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /jsr377-api/src/main/java/javax/application/threading/ThreadingHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Copyright 2015-2021 the original author or authors. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package javax.application.threading; 19 | 20 | import java.util.concurrent.Callable; 21 | import java.util.concurrent.CompletionStage; 22 | 23 | /** 24 | * @author Andres Almiray 25 | */ 26 | public interface ThreadingHandler { 27 | /** 28 | * True if the current thread is the UI thread. 29 | */ 30 | boolean isUIThread(); 31 | 32 | /** 33 | * Executes a code block asynchronously on the UI thread. 34 | * 35 | * @param runnable block of code that must be executed. Must not be {@code null}. 36 | */ 37 | void executeInsideUIAsync(Runnable runnable); 38 | 39 | /** 40 | * Executes a code block synchronously on the UI thread. 41 | * 42 | * @param runnable block of code that must be executed. Must not be {@code null}. 43 | */ 44 | void executeInsideUISync(Runnable runnable); 45 | 46 | /** 47 | * Executes a code block synchronously on the UI thread. 48 | * 49 | * @param callable block of code that must be executed. Must not be {@code null}. 50 | * 51 | * @return return value from the executed block. May be {@code null}. 52 | */ 53 | R executeInsideUISync(Callable callable); 54 | 55 | /** 56 | * Executes a code block outside of the UI thread. 57 | * The {@code runnable} will be invoked on the same thread as the caller if the caller 58 | * is already outside the UI thread. 59 | * 60 | * @param runnable block of code that must be executed. Must not be {@code null}. 61 | */ 62 | void executeOutsideUI(Runnable runnable); 63 | 64 | /** 65 | * Executes a code block on a background thread, always. 66 | * The {@code runnable} will be invoked on a different thread regardless of the thread 67 | * where the caller issued the call. 68 | * 69 | * @param runnable block of code that must be executed. Must not be {@code null}. 70 | */ 71 | void executeOutsideUIAsync(Runnable runnable); 72 | 73 | /** 74 | * Executes a code block on a background thread, always. 75 | * The {@code callable} will be invoked on a different thread regardless of the thread 76 | * where the caller issued the call. 77 | * 78 | * @param callable block of code that must be executed. Must not be {@code null}. 79 | * 80 | * @return a {@code CompletionStage} that can be used to signal the resolution or rejection of the code block. Never returns {@code null}. 81 | */ 82 | CompletionStage executeOutsideUIAsync(Callable callable); 83 | 84 | /** 85 | * Executes a code block asynchronously on the UI thread. 86 | * 87 | * @param callable block of code that must be executed. Must not be {@code null}. 88 | * 89 | * @return a {@code CompletionStage} that can be used to signal the resolution or rejection of the code block. Never returns {@code null}. 90 | */ 91 | CompletionStage executeInsideUIAsync(Callable callable); 92 | } 93 | -------------------------------------------------------------------------------- /jsr377-api/src/main/java/javax/application/threading/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Copyright 2015-2021 the original author or authors. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package javax.application.threading; 19 | -------------------------------------------------------------------------------- /jsr377-api/src/main/module/module-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Copyright 2015-2020 the original author or authors. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | module javax.application { 20 | exports javax.application; 21 | exports javax.application.action; 22 | exports javax.application.configuration; 23 | exports javax.application.converter; 24 | exports javax.application.converter.spi; 25 | exports javax.application.event; 26 | exports javax.application.i18n; 27 | exports javax.application.resources; 28 | exports javax.application.threading; 29 | } -------------------------------------------------------------------------------- /jsr377-spec/CONTRIBUTING.adoc: -------------------------------------------------------------------------------- 1 | = Contribution Guidelines 2 | 3 | We love to see contributions to the project and have tried to make it easy to 4 | do so. If you wish to contribute documentation, then please keep to the following 5 | guidelines to ensure consistency within the sources and that we have happy users. 6 | 7 | == Guidelines 8 | 9 | . A single page per chapter. This allows reviewers to have a quick glance at the 10 | whole content without having to browse additional files. 11 | . Please insert a blank line at the top and at the end of each document. This allows 12 | inclusion of files without adding so much white space in between. For example, without 13 | these blank lines one would have to write the following to include two files 14 | .... 15 | 16 | include::chapter1.adoc[] 17 | 18 | include::chapter2.adoc[] 19 | 20 | .... 21 | 22 | where as adding the blank lines removes the need to define them in the including document 23 | 24 | .... 25 | include::chapter1.adoc[] 26 | include::chapter2.adoc[] 27 | .... 28 | -------------------------------------------------------------------------------- /jsr377-spec/jsr377-spec.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Copyright 2015-2021 the original author or authors. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | plugins { 20 | id 'org.asciidoctor.jvm.convert' 21 | id 'org.asciidoctor.jvm.pdf' 22 | } 23 | 24 | asciidoctorj { 25 | options doctype: 'book' 26 | 27 | modules { 28 | diagram.use() 29 | diagram.version '2.1.0' 30 | } 31 | 32 | attributes 'source-highlighter' : 'coderay', 33 | 'coderay-linenums-mode' : 'table', 34 | imagesdir : 'images', 35 | toc : 'left', 36 | icon : 'font', 37 | linkattrs : true, 38 | encoding : 'utf-8' 39 | 40 | } 41 | 42 | asciidoctor { 43 | dependsOn project(':diagrams').asciidoctor 44 | 45 | baseDirFollowsSourceDir() 46 | 47 | sources { 48 | include 'index.adoc' 49 | } 50 | 51 | resources { 52 | from file('src/resources') 53 | from(project(':diagrams').file('build/docs/asciidoc/images')) { 54 | into 'images' 55 | } 56 | } 57 | } 58 | 59 | build.dependsOn(asciidoctor) -------------------------------------------------------------------------------- /jsr377-spec/src/docs/asciidoc/_license_asl2.adoc: -------------------------------------------------------------------------------- 1 | 2 | .... 3 | Specification: JSR-377 Desktop|Embedded Application API 4 | 5 | Version: 1.0 6 | 7 | Status: Pre-FCS Public Release 8 | 9 | Release: 10 | 11 | Copyright 2015 Andres Almiray 12 | 13 | All rights reserved. 14 | 15 | Licensed under the Apache License, Version 2.0 (the "License"); 16 | you may not use this file except in compliance with the License. 17 | You may obtain a copy of the License at 18 | 19 | http://www.apache.org/licenses/LICENSE-2.0 20 | 21 | Unless required by applicable law or agreed to in writing, software 22 | distributed under the License is distributed on an "AS IS" BASIS, 23 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 24 | See the License for the specific language governing permissions and 25 | limitations under the License. 26 | .... 27 | -------------------------------------------------------------------------------- /jsr377-spec/src/docs/asciidoc/_license_jcp.adoc: -------------------------------------------------------------------------------- 1 | 2 | .... 3 | Andres Almiray IS WILLING TO LICENSE THIS SPECIFICATION TO YOU ONLY UPON THE CONDITION THAT YOU ACCEPT ALL OF THE TERMS CONTAINED IN THIS LICENSE AGREEMENT ("AGREEMENT"). PLEASE READ THE TERMS AND CONDITIONS OF THIS AGREEMENT CAREFULLY. BY DOWNLOADING THIS SPECIFICATION, YOU ACCEPT THE TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU ARE NOT WILLING TO BE BOUND BY THEM, SELECT THE "DECLINE" BUTTON AT THE BOTTOM OF THIS PAGE AND THE DOWNLOADING PROCESS WILL NOT CONTINUE. 4 | 5 | Specification: JSR-377 Desktop|Embedded Application API 6 | 7 | Version: 1.0 8 | 9 | Status: Pre-FCS Public Release 10 | 11 | Release: 12 | 13 | Copyright 2015 Andres Almiray 14 | 15 | All rights reserved. 16 | 17 | 18 | NOTICE 19 | 20 | The Specification is protected by copyright and the information described therein may be protected by one or more U.S. patents, foreign patents, or pending applications. Except as provided under the following license, no part of the Specification may be reproduced in any form by any means without the prior written authorization of Andres Almiray and its licensors, if any. Any use of the Specification and the information described therein will be governed by the terms and conditions of this Agreement. 21 | 22 | Subject to the terms and conditions of this license, including your compliance with Paragraphs 1, 2 and 3 below, Andres Almiray hereby grants you a fully-paid, non-exclusive, non-transferable, limited license (without the right to sublicense) under Andres Almiray's intellectual property rights to: 23 | 24 | 1. Review the Specification for the purposes of evaluation. This includes: (i) developing implementations of the Specification for your internal, non-commercial use; (ii) discussing the Specification with any third party; and (iii) excerpting brief portions of the Specification in oral or written communications which discuss the Specification provided that such excerpts do not in the aggregate constitute a significant portion of the Specification. 25 | 2. Distribute implementations of the Specification to third parties for their testing and evaluation use, provided that any such implementation: 26 | 27 | (i) does not modify, subset, superset or otherwise extend the Licensor Name Space, or include any public or protected packages, classes, Java interfaces, fields or methods within the Licensor Name Space other than those required/authorized by the Specification or Specifications being implemented; 28 | (ii) is clearly and prominently marked with the word "UNTESTED" or "EARLY ACCESS" or "INCOMPATIBLE" or "UNSTABLE" or "BETA" in any list of available builds and in proximity to every link initiating its download, where the list or link is under Licensee's control; and 29 | (iii) includes the following notice: 30 | 31 | "This is an implementation of an early-draft specification developed under the Java Community Process (JCP) and is made available for testing and evaluation purposes only. The code is not compatible with any specification of the JCP." 32 | 33 | 3. Distribute applications written to the Specification to third parties for their testing and evaluation use, provided that any such application includes the following notice: 34 | 35 | "This is an application written to interoperate with an early-draft specification developed under the Java Community Process (JCP) and is made available for testing and evaluation purposes only. The code is not compatible with any specification of the JCP." 36 | 37 | The grant set forth above concerning your distribution of implementations of the Specification is contingent upon your agreement to terminate development and distribution of your implementation of early draft upon final completion of the Specification. If you fail to do so, the foregoing grant shall be considered null and void. 38 | Other than this limited license, you acquire no right, title or interest in or to the Specification or any other Andres Almiray intellectual property, and the Specification may only be used in accordance with the license terms set forth herein. This license will expire on the earlier of: (a) two (2) years from the date of Release listed above; (b) the date on which the final version of the Specification is publicly released; or (c) the date on which the Java Specification Request (JSR) to which the Specification corresponds is withdrawn. In addition, this license will terminate immediately without notice from Andres Almiray if you fail to comply with any provision of this license. Upon termination, you must cease use of or destroy the Specification. 39 | 40 | "Licensor Name Space" means the public class or interface declarations whose names begin with "java", "javax" or their equivalents in any subsequent naming convention adopted through the Java Community Process, or any recognized successors or replacements thereof 41 | 42 | TRADEMARKS 43 | 44 | No right, title, or interest in or to any trademarks, service marks, or trade names of Andres Almiray or Andres Almiray's licensors is granted hereunder. Java and Java-related logos, marks and names are trademarks or registered trademarks of Oracle America, Inc. in the U.S. and other countries. 45 | 46 | 47 | DISCLAIMER OF WARRANTIES 48 | 49 | THE SPECIFICATION IS PROVIDED "AS IS" AND IS EXPERIMENTAL AND MAY CONTAIN DEFECTS OR DEFICIENCIES WHICH CANNOT OR WILL NOT BE CORRECTED BY Andres Almiray. Andres Almiray MAKES NO REPRESENTATIONS OR WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT THAT THE CONTENTS OF THE SPECIFICATION ARE SUITABLE FOR ANY PURPOSE OR THAT ANY PRACTICE OR IMPLEMENTATION OF SUCH CONTENTS WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADE SECRETS OR OTHER RIGHTS. This document does not represent any commitment to release or implement any portion of the Specification in any product. 50 | 51 | 52 | THE SPECIFICATION COULD INCLUDE TECHNICAL INACCURACIES OR TYPOGRAPHICAL ERRORS. CHANGES ARE PERIODICALLY ADDED TO THE INFORMATION THEREIN; THESE CHANGES WILL BE INCORPORATED INTO NEW VERSIONS OF THE SPECIFICATION, IF ANY. Andres Almiray MAY MAKE IMPROVEMENTS AND/OR CHANGES TO THE PRODUCT(S) AND/OR THE PROGRAM(S) DESCRIBED IN THE SPECIFICATION AT ANY TIME. Any use of such changes in the Specification will be governed by the then-current license for the applicable version of the Specification. 53 | 54 | 55 | LIMITATION OF LIABILITY 56 | 57 | TO THE EXTENT NOT PROHIBITED BY LAW, IN NO EVENT WILL Andres Almiray OR ITS LICENSORS BE LIABLE FOR ANY DAMAGES, INCLUDING WITHOUT LIMITATION, LOST REVENUE, PROFITS OR DATA, OR FOR SPECIAL, INDIRECT, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF OR RELATED TO ANY FURNISHING, PRACTICING, MODIFYING OR ANY USE OF THE SPECIFICATION, EVEN IF Andres Almiray AND/OR ITS LICENSORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 58 | 59 | 60 | You will hold Andres Almiray (and its licensors) harmless from any claims based on your use of the Specification for any purposes other than the limited right of evaluation as described above, and from any claims that later versions or releases of any Specification furnished to you are incompatible with the Specification provided to you under this license. 61 | 62 | 63 | RESTRICTED RIGHTS LEGEND 64 | 65 | If this Software is being acquired by or on behalf of the U.S. Government or by a U.S. Government prime contractor or subcontractor (at any tier), then the Government's rights in the Software and accompanying documentation shall be only as set forth in this license; this is in 66 | 67 | accordance with 48 C.F.R. 227.7201 through 227.7202-4 (for Department of Defense (DoD) acquisitions) and with 48 C.F.R. 2.101 and 12.212 (for non-DoD acquisitions). 68 | 69 | 70 | REPORT 71 | 72 | You may wish to report any ambiguities, inconsistencies or inaccuracies you may find in connection with your evaluation of the Specification ("Feedback"). To the extent that you provide Andres Almiray with any Feedback, you hereby: (i) agree that such Feedback is provided on a non-proprietary and non-confidential basis, and (ii) grant Andres Almiray a perpetual, non-exclusive, worldwide, fully paid-up, irrevocable license, with the right to sublicense through multiple levels of sublicensees, to incorporate, disclose, and use without limitation the Feedback for any purpose related to the Specification and future versions, implementations, and test suites thereof. 73 | 74 | 75 | GENERAL TERMS 76 | 77 | Any action related to this Agreement will be governed by California law and controlling U.S. federal law. The U.N. Convention for the International Sale of Goods and the choice of law rules of any jurisdiction will not apply. 78 | 79 | 80 | The Specification is subject to U.S. export control laws and may be subject to export or import regulations in other countries. Licensee agrees to comply strictly with all such laws and regulations and acknowledges that it has the responsibility to obtain such licenses to export, re-export or import as may be required after delivery to Licensee. 81 | 82 | 83 | This Agreement is the parties' entire agreement relating to its subject matter. It supersedes all prior or contemporaneous oral or written communications, proposals, conditions, representations and warranties and prevails over any conflicting or additional terms of any quote, order, acknowledgment, or other communication between the parties relating to its subject matter during the term of this Agreement. No modification to this Agreement will be binding, unless in writing and signed by an authorized representative of each party. 84 | .... 85 | 86 | -------------------------------------------------------------------------------- /jsr377-spec/src/docs/asciidoc/_links.adoc: -------------------------------------------------------------------------------- 1 | 2 | :link_jsr330: link:https://jcp.org/en/jsr/detail?id=330[JSR-300, window="_blank"] 3 | :link_resource_bundle: link:https://docs.oracle.com/javase/8/docs/api/java/util/ResourceBundle.html[ResourceBundle, window="_blank"] 4 | :link_message_format: link:http://docs.oracle.com/javase/8/docs/api/java/text/MessageFormat.html[MessageFormat, window="_blank"] 5 | -------------------------------------------------------------------------------- /jsr377-spec/src/docs/asciidoc/architecture.adoc: -------------------------------------------------------------------------------- 1 | 2 | [[architecture]] 3 | = Architecture 4 | 5 | This specification defines a powerful set of complementary services that help improve the structure of application code. 6 | 7 | * dependency injection via JSR-330. 8 | * common application structure. 9 | * application life-cycle. 10 | * localized resources. 11 | * resource injection. 12 | * localized configuration. 13 | * decouple state from UI (binding). 14 | * persistence session state (preferences). 15 | * action management. 16 | * component life-cycle. 17 | * light-weight event bus. 18 | * honor threading concerns (specific to UI toolkit). 19 | 20 | The facilities defined by this specification allow developers to write applications with clear separation of concerns between 21 | business logic and UI. In this way, application code becomes more flexible, enabling components to be built with low coupling 22 | and high cohesion. 23 | 24 | == Contracts 25 | 26 | This specification defines the responsibilities of: 27 | 28 | * the application developer who uses these services, and 29 | * the vendor who implements the functionality defined by this specification and provides a runtime environment in which 30 | the application executes. 31 | 32 | The application's runtime is in charge of directing the application through each one of its phases. Each phases describes 33 | the behavior that may be executed at that particular point in time during the application's lifetime. The application's 34 | lifecycle is thus controlled by these phases. 35 | 36 | == Relationship to other specifications 37 | 38 | This sections identifies how JSR-377 relates to other existing specifications defined under the JCP. 39 | 40 | === Relationship to Dependency Injection for Java 41 | 42 | The Dependency Injection for Java specification (JSR-330) defines a set of annotations for the declaring injected fields, 43 | methods and constructors of a bean. The dependency injection service required by JSR-377 compliant applications makes use 44 | of these annotations. It's possible to combine JSR-377 with Contexts and Dependency Injection for Java 2.0 (known as JSR-365 45 | or CDI 2.0 for short) as long as the implementing framework complies with CDI as well. 46 | 47 | === Relationship to Configuration API 1.0 48 | 49 | The Configuration API 1.0 (known as JSR-382) provides an API to obtain configuration properties through several environment-aware 50 | sources both internal and external to the application and made available through dependency injection or lookup. This API 51 | may be used by an implementing framework provided sensible defaults are put in place to bridge it with JSR-377's own 52 | configuration API, as the former is more generic and the latter is more powerful and delivers specific upgrades required 53 | by desktop applications. 54 | 55 | == Introductory Example 56 | 57 | The following example relies on JavaFX as the UI toolkit of choice and the MVC pattern to separate business logic from any 58 | UI concerns. The Controller defines behavior via actions; the Model holds the data shared between Controller and View; the 59 | View defines the looks via UI widgets and relies on data binding to display data provided by the Model. The UI for this 60 | example looks like this 61 | 62 | [source] 63 | ---- 64 | +------------------------+ 65 | | Name: ________________ | 66 | | | 67 | | +--------------+ | 68 | | | Greeting! | | 69 | | +--------------+ | 70 | | | 71 | | ...................... | 72 | +------------------------+ 73 | ---- 74 | 75 | That's a label with the text "Name:"; a textfield where you'll input a name; a button with the text "Greeting!" which should 76 | trigger a 'greeting' action; a non-editable output (the dotted lines) that will display the computed greeting. The rules 77 | for computing the value of the greeting are: 78 | 79 | 1. If a non-blank name is given then the greeting results in "Hello $name!". 80 | 2. If a blank name is given then the greeting results in "Howdy stranger". 81 | 82 | Assuming there's an implementing framework that provides MVC support, where each member of the MVC triad is bound/grouped 83 | to an instance of MVCGroup, the Controller contains action definitions, the Model provides data between Controller and View, 84 | the View displays the data and routes user events to the actions. We can start with the Controller as it's the one that's 85 | closely tied to this JSR due to actions 86 | 87 | .com/acme/GreetingController.java 88 | [source,java] 89 | ---- 90 | package com.acme; 91 | import javax.application.action.ActionHandler; 92 | import javax.application.i18n.MessageSource; 93 | 94 | public class GreetingController { 95 | @Inject private MessageSource messageSource; 96 | @Inject private GreetingModel model; 97 | 98 | @ActionHandler 99 | public void greeting() { 100 | String input = model.getInput(); 101 | if (StringUtils.isBlank(input)) { 102 | model.setOutput(messageSource.getMessage("greeting.default")); 103 | } else { 104 | model.setOutput(messageSource.getMessage("greeting.parameterized", new Object[]{ input })); 105 | } 106 | } 107 | } 108 | ---- 109 | 110 | Assume that there's a `StringUtils` class provided by the framework or some other utility. Also, it doesn't matter what 111 | type of dependency injection is used (constructor, field, setter). 112 | We can gather the following bits from this example so far 113 | 114 | - there's a single action whose identifier is "greeting". 115 | - the fully qualified identifier for this action is "com.acme.GreetingController.greeting". 116 | - the Controller requires the Model to have to String based properties: input and output. 117 | - the framework injects the application's default `MessageSource` into the Controller. Alternatively the framework could 118 | provide a base/abstract Controller class with some common dependencies already injected such as the `Application` 119 | instance, `MessageSource`, `EventBus`, etc. 120 | - the framework injects the corresponding Model member of the MVC group. It does so using JSR-330's `@Inject` annotation, 121 | however it could do so with a different set of annotations if the implementing framework so requires. 122 | - the `MessageSource` will resolve messages based on its configured resources, which may be a properties file, JSON, YAML, 123 | XML, etc; from the POV of the Controller is does not matter. 124 | 125 | The Model is implemented as a container for two observable properties using standard JavaFX support, in other words 126 | 127 | .com/acme/GreetingModel.java 128 | [source,java] 129 | ---- 130 | package com.acme; 131 | import javafx.beans.property.SimpleStringProperty; 132 | import javafx.beans.property.StringProperty; 133 | 134 | public class GreetingModel { 135 | private final StringProperty input = new SimpleStringProperty(this, "input"); 136 | private final StringProperty output = new SimpleStringProperty(this, "output"); 137 | // getters & setters 138 | } 139 | ---- 140 | 141 | Nothing exciting here, nothing specific to this JSR either as these properties are related to the chosen UI toolkit. 142 | Finally we arrive to the View where the Model and Controller are hooked into the UI, which could look like this 143 | 144 | .com/acme/GreetingView.java 145 | [source,java] 146 | ---- 147 | package com.acme; 148 | import javax.application.threading.ThreadingHandler; 149 | 150 | public class GreetingView { 151 | @Inject private GreetingController controller; 152 | @Inject private GreetingModel model; 153 | @Inject private ThreadingHandler threadingHandler; 154 | 155 | @PostConstruct 156 | public void init() { 157 | threadingHandler.executeInsideUISync(this::buildUI); 158 | } 159 | 160 | private void buildUI() { 161 | // 1. build UI programmatically and/or load FXML 162 | // 2. bind textfield to model.input 163 | // 3. bind label to model.output 164 | // 4. find and wire greeting action to button 165 | } 166 | } 167 | ---- 168 | 169 | Building the UI (most importantly, attaching the nodes to the SceneGraph) must happen inside the UI thread, thus we wrap 170 | the initialization code with a call to `ThreadingHandler.executeInsideUISync`, because we want the UI to be finished 171 | building itself before the application continues. Items #1, #2, #3 are UI specific and do not require any kind of support 172 | from this JSR. Item #4 is a bit of a gray area as it requires an implementation of `javax.application.action.Action` that 173 | has a relationship with the "greeting" action defined in the Controller. JSR377 does not define how Actions must be 174 | discovered, stored, and retrieved; this is a task left to implementors. 175 | 176 | The last step is to find a way to bootstrap and launch the application, this could be done using a framework class that 177 | understands the life cycle of `javax.application.Application`, such as an hypothetical AcmeJavaFXApplication. 178 | 179 | .com/acme/Launcher.java 180 | [source,java] 181 | ---- 182 | package com.acme; 183 | 184 | public class Launcher { 185 | public static void main(String[] args) { 186 | AcmeJavaFXApplication.run(args); 187 | } 188 | } 189 | ---- 190 | 191 | It's the job of this implementor specific class to locate the configuration, bootstrap and configure the DI container, 192 | switch the application's phases from INITIALIZE->STARTUP->READY->MAIN as it moves through the setup. From the POV of the 193 | developer the whole application is comprised of (at least) 5 files 194 | 195 | - Controller 196 | - Model 197 | - View 198 | - Launcher 199 | - a properties file that contains the i18n messages to be resolved 200 | 201 | Additional files such as Dependency Injection configuration (think a Google Guice `Module` or a Spring `@Configuration` 202 | file), services files, or others may be required by the particular implementing framework. 203 | 204 | == Core APIs 205 | 206 | === Application 207 | 208 | ==== The Application interface 209 | 210 | Lorem ipsum 211 | 212 | ==== Application Phases 213 | 214 | The application's lifecycle is determined by `javax.application.ApplicationPhase` and its transitions as shown in the 215 | following diagram: 216 | 217 | image::javax/application/application-phases.png[alt="application-phases"] 218 | 219 | The expected behavior of each of the phases is described next: 220 | 221 | [horizontal] 222 | INITIALIZE:: The initialization phase is the first to be called by the application's life cycle. 223 | The application instance has just been created and its configuration has been read. 224 | This phase is typically used to tweak the application for the current platform, 225 | including its Look & Feel. The {link_jsr330} compatible Dependecy Injection container should 226 | be initialized at this point. 227 | STARTUP:: This phase is responsible for instantiating all internal components required by the implementing 228 | framework as well as any application specific components such as MVC groups, resource allocation 229 | such as database connections, network clients, etc. 230 | READY:: This phase will be called right after `STARTUP` with the condition that no pending 231 | events are available in the UI queue. The application's main window should be displayed 232 | at the end of this phase. 233 | MAIN:: The application should be fully operational at this point. 234 | SHUTDOWN:: Called when the application should close. Any application component can invoke the shutdown 235 | sequence by calling `shutdown()` on the `javax.application.Application` instance. 236 | 237 | ==== Exit Status 238 | 239 | Lorem ipsum 240 | 241 | ==== Shutdown Handlers 242 | 243 | Applications have the option to let particular components abort the shutdown sequence and/or perform a task while the 244 | shutdown sequence is in process. Components that desire to be part of the shutdown sequence should implement the 245 | `javax.application.ShutdownHandler` interface and register themselves with the application instance. 246 | 247 | The contract of a `javax.application.ShutdownHandler` is very simple: 248 | 249 | * `boolean canShutdown(Application application)` - return *`false`* to abort the shutdown sequence. 250 | * `void onShutdown(Application application)` - called if the shutdown sequence was not aborted. 251 | 252 | ``javax.application.ShutdownHandler``s will be called in the same order as they were registered. 253 | 254 | === Configuration 255 | 256 | TBD 257 | 258 | ==== The Configuration Interface 259 | 260 | Lorem ipsum 261 | 262 | ==== Injected Configuration 263 | 264 | Lorem ipsum 265 | 266 | ==== Relationship with JSR-382 267 | 268 | Lorem ipsum 269 | 270 | === Actions 271 | 272 | TBD 273 | 274 | ==== The Action Interface 275 | 276 | Lorem ipsum 277 | 278 | ==== Action Metadata 279 | 280 | Lorem ipsum 281 | 282 | ==== Action Handlers 283 | 284 | Lorem ipsum 285 | 286 | ==== Action Interceptors 287 | 288 | Lorem ipsum 289 | 290 | === Internationalization (I18N) 291 | 292 | This section describes the Internationalization (`I18N`) features available to all applications. 293 | 294 | ==== The MessageSource Interface 295 | 296 | Applications have the ability to resolve internationalizable messages by leveraging the behavior provided by 297 | `javax.application.i18n.MessageSource`. This interface exposes the following methods: 298 | 299 | - String getMessage(String key) 300 | - String getMessage(String key, Locale locale) 301 | - String getMessage(String key, Object[] args) 302 | - String getMessage(String key, Object[] args, Locale locale) 303 | - String formatMessage(String message, Object[] args) 304 | - ResourceBundle asResourceBundle() 305 | 306 | The first set throws a `NoSuchMessageException` if a message could not be resolved given the key sent as argument. 307 | The following methods take an additional `defaultMessage` parameter that may be used if no configured message is found. 308 | If this optional parameter is null, then the `key` should used as the message; in other words, these methods never throw 309 | a `NoSuchMessageException` nor return `null` unless the passed in `key` is null. 310 | 311 | - String getMessage(String key, String defaultMessage) 312 | - String getMessage(String key, Locale locale, String defaultMessage) 313 | - String getMessage(String key, Object[] args, String defaultMessage) 314 | - String getMessage(String key, Object[] args, Locale locale, String defaultMessage) 315 | 316 | The simplest way to resolve a message is as follows: 317 | 318 | [source,java,options="nowrap"] 319 | ---- 320 | MessageSource messageSource = ... // grab it from DI container 321 | messageSource.getMessage("some.key") 322 | ---- 323 | 324 | ==== Resource Files 325 | 326 | There are no restrictions on the type of resources files that may be used to resolve messages. The usage of properties 327 | files is prevalent, typically these files are read using a `{link_resource_bundle}` implementation, this being said, 328 | implementors may pick additional file formats such as Groovy and or Kotlin scripts, JSON, YAML, XML, or more. 329 | 330 | ==== Message Formats 331 | 332 | Implementors are free to choose the message format to be used in the source files, at the very least they should support 333 | the standar format as defined by the JDK `{link_message_format}` facilities. These formats must work with all versions 334 | of the `getMessage()` method defined by `MessageSource`. An example of this message format follows, first the file that 335 | contains message definitions 336 | 337 | [source,java,linenums,options="nowrap"] 338 | .messages.properties 339 | ---- 340 | healthy.proverb = An {0} a day keeps the {1} away 341 | yoda.says = {0} is the path to the dark side. {0} leads to {1}. {1} leads to {2}. {2} leads to suffering. 342 | ---- 343 | 344 | Then the code used to resolve these messages looks like this: 345 | 346 | [source,java,options="nowrap"] 347 | ---- 348 | String quote = messageSource.getMessage("yoday.says", new Object[]{"Fear", "Anger", "Hate"}); 349 | assertEquals(quote, "Fear is the path to the dark side. Fear leads to Anger. Anger leads to Hate. Hate leads to suffering"); 350 | ---- 351 | 352 | === Resources 353 | 354 | This section describes resource management and injection features available to all applications. 355 | 356 | ==== The ResourceResolver Interface 357 | 358 | Applications have the ability to resolve internationalizable messages by leveraging the behavior provided by 359 | `javax.application.resources.ResourceResolver`. This interface exposes the following methods: 360 | 361 | - Object resolveResource(String key) 362 | - Object resolveResource(String key, Locale locale) 363 | - Object resolveResource(String key, Object[] args) 364 | - Object resolveResource(String key, Object[] args, Locale locale) 365 | - String formatResource(String resource, Object[] args) 366 | 367 | The first set throws `NoSuchResourceException` if a message could not be resolved given the key sent as argument. The 368 | following methods take an additional `defaultValue` parameter which will be used if no configured resource is found. If 369 | this optional parameter were to be null, then the `key` should be used as the literal value of the resource; in other words, 370 | these methods never throw `NoSuchResourceException` nor return `null` unless the passed-in `key` is null. 371 | 372 | - Object resolveResource(String key, Object defaultValue) 373 | - Object resolveResource(String key, Locale locale, Object defaultValue) 374 | - Object resolveResource(String key, Object[] args, Object defaultValue) 375 | - Object resolveResource(String key, Object[] args, Locale locale, Object defaultValue) 376 | 377 | There is also another set of methods which convert the resource value using ``Converter``s: 378 | 379 | - T resolveResourceConverted(String key, Class type) 380 | - T resolveResourceConverted(String key, Locale locale, Class type) 381 | - T resolveResourceConverted(String key, Object[] args, Class type) 382 | - T resolveResourceConverted(String key, Object[] args, Locale locale, Class type) 383 | 384 | with default value support too: 385 | 386 | - T resolveResourceConverted(String key, Object defaultValue, Class type) 387 | - T resolveResourceConverted(String key, Locale locale, Object defaultValue, Class type) 388 | - T resolveResourceConverted(String key, Object[] args, Object defaultValue, Class type) 389 | - T resolveResourceConverted(String key, Object[] args, Locale locale, Object defaultValue, Class type) 390 | 391 | The simplest way to resolve a message is thus 392 | 393 | [source,java,options="nowrap"] 394 | ---- 395 | ResourceResolver resourceResolver = ... // grab it from DI container 396 | resourceResolver.resolveResource("menu.icon"); 397 | ---- 398 | 399 | ==== Resource Files 400 | 401 | There are no restrictions on the type of resources files that may be used to resolve messages. The usage of properties 402 | files is prevalent, typically these files are read using a `{link_resource_bundle}` implementation, this being said, 403 | implementors may pick additional file formats such as Groovy and or Kotlin scripts, JSON, YAML, XML, or more. 404 | 405 | ==== Message Formats 406 | 407 | Implementors are free to choose the message format to be used in the source files, at the very least they should support 408 | the standar format as defined by the JDK `{link_message_format}` facilities. These formats must work with all versions 409 | of the `resolveResource()` method defined by `ResourceResolver`. An example of this message format follows, first the 410 | file that contains message definitions 411 | 412 | [source,java,options="nowrap"] 413 | .resources.properties 414 | ---- 415 | menu.icon = /img/icons/menu-{0}.png 416 | ---- 417 | 418 | Assuming there are three icon files available in the classpath whose filenames are `menu-small.png`, `menu-medium.png` and 419 | `menu-large.png`, a component may resolve any of them with 420 | 421 | [source,java,options="nowrap"] 422 | ---- 423 | Icon smallIcon = resourceResolver.resolveResourceConverted("menu.icon", new Object[]{"small"], Icon.class); 424 | Icon mediumIcon = resourceResolver.resolveResourceConverted("menu.icon", new Object[]{"medium"], Icon.class); 425 | Icon largeIcon = resourceResolver.resolveResourceConverted("menu.icon", new Object[]{"large"], Icon.class); 426 | ---- 427 | 428 | ==== Type Conversion 429 | 430 | Note that the return value of the `resolveResource` methods is marked as `T`, but you'll get, You'll have to rely on 431 | converters in order to transform the value into the correct type. <<_resources_injected_resources,Injected resources>> 432 | are automatically transformed to the expected type. 433 | 434 | Here's how it can be done: 435 | 436 | [source,java,options="nowrap"] 437 | ---- 438 | import javax.swing.Icon; 439 | import javax.application.converter.Converter; 440 | import javax.application.converter.ConverterRegistry; 441 | ... 442 | Object iconValue = resourceResolver.resolveResource("menu.icon", new Object[]{"large"]); 443 | Converter converter = ConverterRegistry.findConverter(Icon); 444 | Icon icon = converter.fromObject(String.valueOf(iconValue)); 445 | ---- 446 | 447 | As an alternative you may call `resolveResourceConverted` instead which automatically locates a suitable `Converter`. 448 | 449 | [[_resources_injected_resources]] 450 | ==== Injected Resources 451 | 452 | Resources may be automatically injected into any instance created via the application's Dependency Injector container. 453 | Injection points must be annotated with `@javax.application.resources.InjectedResource` which may be applied on fields 454 | or setter methods. The following example shows a class named `SampleModel` that's managed by the application's Dependency 455 | Injection container 456 | 457 | [source,java,options="nowrap"] 458 | .resources.properties 459 | ---- 460 | sample.SampleModel.logo = /jsr377-logo-48x48.png 461 | logo = /jsr377-logo-{0}x{0}.png 462 | ---- 463 | 464 | [source,groovy,linenums,options="nowrap"] 465 | .src/main/java/sample/SampleModel.java 466 | ---- 467 | package sample; 468 | 469 | import javax.application.resources.InjectedResource; 470 | import javax.swing.Icon; 471 | 472 | public class SampleModel { 473 | @InjectedResource private Icon logo; 474 | 475 | @InjectedResource(value="logo", args={"16"}) 476 | private Icon smallLogo; 477 | 478 | @InjectedResource(value="logo", args={"64"}) 479 | private Icon largeLogo; 480 | } 481 | ---- 482 | 483 | `@InjectedResource` assumes a naming convention in order to determine the resource key to use. These are the rules applied 484 | by the default by `javax.application.resources.ResourceInjector`: 485 | 486 | - If a value is specified for the `value` argument, then use it as is. 487 | - otherwise, construct a key based in the field name prefixed with the full qualified 488 | class name of the field's owner. 489 | 490 | You may also specify a default value if the resource definition is not found; however, be aware that this value must be set 491 | as a `String`, thus guaranteeing a type conversion. An optional `format` value may be specified as a hint to the `Converter` 492 | used during value conversion, for example: 493 | 494 | [source,groovy,linenums,options="nowrap"] 495 | .src/main/java/sample/SampleModel.java 496 | ---- 497 | package sample; 498 | 499 | import java.util.Date; 500 | import javax.application.resources.InjectedResource; 501 | 502 | public class SampleModel { 503 | @InjectedResource(defaultValue="10.04.2013 2:30 PM", format="dd.MM.yyyy h:mm a") 504 | private Date date; 505 | } 506 | ---- 507 | 508 | The next table describes all properties pertaining `@InjectedResource` 509 | 510 | [cols="4*", header] 511 | |=== 512 | 513 | | Property 514 | | Type 515 | | Default Value 516 | | Responsibility 517 | 518 | | value 519 | | String 520 | | "" 521 | | Defines a explicit key used to locate the resource. 522 | 523 | | args 524 | | String[] 525 | | 526 | | Arguments that may be used to format the literal resource value before conversion takes place. 527 | 528 | | defaultValue 529 | | String 530 | | 531 | | Resource value to be used if no configured value may be found. 532 | 533 | | format 534 | | String 535 | | "" 536 | | Additional format that may be used to parse the literal resource value. 537 | 538 | | converter 539 | | Class> 540 | | javax.application.converter.NoopConverter 541 | | Explicit `Converter` that may be used to convert the literal resource value into a specific type. 542 | 543 | |=== 544 | 545 | === Type Conversion 546 | 547 | TBD 548 | 549 | ==== The Converter Interface 550 | 551 | Lorem ipsum 552 | 553 | ==== Converter Registry 554 | 555 | Lorem ipsum 556 | 557 | === Events 558 | 559 | TBD 560 | 561 | === Threading 562 | 563 | Building a well-behaved multi-threaded desktop application has been a hard task for many years; however, it does not have 564 | to be that way anymore. The following sections explain the threading facilities provided by this JSR. 565 | 566 | ==== The Threading Handler Interface 567 | 568 | The `javax.application.threading.ThreadingHandler` defines the contract that every component must follow to interact with 569 | the toolkit specific UI thread and remaining threads. This interface defines methods that execute code inside and outside 570 | of the UI thread, in synchronously and asynchronoulsy fashions. For the following examples it's assumed that the implementing 571 | framework provides a base type `AbstractFrameworkController` that implements the `ThreadingHandler` interface and that of its 572 | methods marked with `@ActionHandler` are executed outside of the UI thread by default. 573 | 574 | ==== Synchronous Calls 575 | 576 | Synchronous calls inside the UI thread are made by invoking the `executeInsideUISync` methods. There are two variants of 577 | this method, one that returns no value and one that does. Implementors should take note that invocations of these methods 578 | must be re-entrant safe, that is, if the caller is already inside the UI thread then the invocation proceeds normally, the 579 | reason for this note is that UI toolkits such as Swing prevent such invocations to take place 580 | 581 | [source,java,linenums,options="nowrap"] 582 | ---- 583 | package sample; 584 | 585 | import com.acme.mvc.AbstractFrameworkController; 586 | import javax.application.action.ActionHandler; 587 | 588 | public class SampleController extends AbstractFrameworkController { 589 | @ActionHandler 590 | public void work) { 591 | // will be invoked outside of the UI thread by default 592 | // do some calculations 593 | executeInsideUISync(() -> { 594 | // back inside the UI thread 595 | }); 596 | // the following code waits for the previous block to finish its execution 597 | } 598 | } 599 | ---- 600 | 601 | The following are the method signatures that provide blocking execution (synchronous) inside the UI thread: 602 | 603 | [source,java] 604 | ---- 605 | void executeInsideUISync(Runnable runnable); 606 | R executeInsideUISync(Callable callable); 607 | ---- 608 | 609 | ==== Asynchronous Calls 610 | 611 | Similarly to synchronous calls, asynchronous calls inside the UI thread are made by invoking the `executeInsideUIAsync` 612 | methods. These methods should post an event into the UI queue and return immediately; their behavior is equivalent to calling 613 | `SwingUtilities.invokeLater()` when using Swing or `Platform.runLater()` when using JavaFX. 614 | 615 | [source,java,linenums,options="nowrap"] 616 | ---- 617 | package sample; 618 | 619 | import com.acme.mvc.AbstractFrameworkController; 620 | import javax.application.action.ActionHandler; 621 | 622 | public class SampleController extends AbstractFrameworkController { 623 | @ActionHandler 624 | public void work) { 625 | // will be invoked outside of the UI thread by default 626 | // do some calculations 627 | executeInsideUIAsync(() ->{ 628 | // back inside the UI Thread 629 | }); 630 | // the following code is executed immediately and do not waits for the previous block 631 | } 632 | } 633 | ---- 634 | 635 | There are two variants, one that does not return a value, another one that returns a `CompletionStage`. The method 636 | signatures are as follows: 637 | 638 | [source,java] 639 | ---- 640 | void executeInsideUIAsync(Runnable runnable); 641 | CompletionStage executeInsideUIAsync(Callable callable); 642 | ---- 643 | 644 | ==== Outside UI Thread Synchronous Calls 645 | 646 | Making sure a block of code is executed outside the UI thread is accomplished by invoking the `executeOutsideUI` method. 647 | Implementations of this method should be smart enough to figure out if the unit of work is already outside of the UI thread, 648 | in which case execution occurs in the same calling thread; otherwise it instructs the implemnting runtime to run the unit 649 | in a different thread. This is usually performed by a helper `java.util.concurrent.ExecutorService` or some other thread 650 | utilities. 651 | 652 | [source,java,linenums,options="nowrap"] 653 | ---- 654 | package sample; 655 | 656 | import com.acme.mvc.AbstractFrameworkController; 657 | import javax.application.action.ActionHandler; 658 | 659 | public class SampleController extends AbstractFrameworkController { 660 | @ActionHandler 661 | public void work) { 662 | // will be invoked outside of the UI thread by default 663 | // do some calculations 664 | executeInsideUIAsync(() ->{ 665 | // back inside the UI Thread 666 | executeOutsideUI(() -> { 667 | // do more calculations 668 | }); 669 | }); 670 | } 671 | } 672 | ---- 673 | 674 | The method signature is as follows 675 | 676 | [source,java] 677 | ---- 678 | void executeOutsideUI(Runnable runnable) 679 | ---- 680 | 681 | ==== Outside UI Thread Asynchronous Calls 682 | 683 | Lastly, making sure a block of code is executed on a background thread is accomplished by invoking the `executeOutsideUIAsync` 684 | methods. These methods always run the code on a background thread regardless of the caller/invoking thread. This is usually 685 | performed by a helper `java.util.concurrent.ExecutorService` or some other thread utilities. 686 | 687 | [source,java,linenums,options="nowrap"] 688 | ---- 689 | package sample; 690 | 691 | import com.acme.mvc.AbstractFrameworkController; 692 | import javax.application.action.ActionHandler; 693 | 694 | public class SampleController extends AbstractFrameworkController { 695 | @ActionHandler 696 | public void work) { 697 | // will be invoked outside of the UI thread by default 698 | // do some calculations 699 | executeInsideUIAsync(() ->{ 700 | // back inside the UI Thread 701 | CompletionStage promise = executeOutsideUIAsync(() -> { 702 | // do more calculations 703 | return "value"; 704 | }); 705 | promise.thenAccept(s -> { 706 | // executed inside UI Thread 707 | }); 708 | }); 709 | } 710 | } 711 | ---- 712 | 713 | The following are the method signatures that provide blocking execution (synchronous) inside the UI thread: 714 | 715 | [source,java] 716 | ---- 717 | void executeOutsideUIAsync(Runnable runnable); 718 | CompletionStage executeOutsideUIAsync(Callable callable); 719 | ---- 720 | 721 | === Exception Handling 722 | 723 | TBD 724 | 725 | ==== The Exception Handler Interface 726 | 727 | Lorem ipsum 728 | 729 | -------------------------------------------------------------------------------- /jsr377-spec/src/docs/asciidoc/index.adoc: -------------------------------------------------------------------------------- 1 | = JSR377 {project-version} Specification 2 | :toclevels: 3 3 | :numbered: 4 | 5 | include::_links.adoc[] 6 | 7 | :leveloffset: 1 8 | include::preface.adoc[] 9 | include::architecture.adoc[] 10 | include::references.adoc[] 11 | 12 | -------------------------------------------------------------------------------- /jsr377-spec/src/docs/asciidoc/preface.adoc: -------------------------------------------------------------------------------- 1 | 2 | :numbered!: 3 | ["preface",sectnum="0"] 4 | 5 | = Preface 6 | 7 | == Evaluation license 8 | 9 | include::_license_jcp.adoc[] 10 | 11 | == Foreword 12 | 13 | Desktop|Embedded Application API 1.0 defines a set of APIs for commonly used behavior observed in desktop and embedded 14 | applications written with JVM languages. 15 | 16 | == Conventions and Terms 17 | 18 | === Typography 19 | 20 | A fixed width, non-serif typeface (`sample`) indicates the term is a Java package, class, interface, or member name. Text written in this typeface is always related to coding. 21 | Emphasis (_sample_) is used the first time an important concept is introduced. Its explanation usually follows directly after the introduction. 22 | 23 | === Key Words 24 | 25 | This specification consistently uses the words may, should, and must. Their meaning is well-defined in <<_ref_1,[1]>> _Bradner, S., Key words for use in RFCs to Indicate Requirement Levels_. A summary follows. 26 | 27 | * _must_ – An absolute requirement. Both the Framework implementation and bundles have obligations that are required to be fulfilled to conform to this specification. 28 | * _should_ – Recommended. It is strongly recommended to follow the description, but reasons may exist to deviate from this recommendation. 29 | * _may_ or _can_ – Optional. Implementations must still be interoperable when these items are not implemented. 30 | 31 | :numbered: 32 | -------------------------------------------------------------------------------- /jsr377-spec/src/docs/asciidoc/references.adoc: -------------------------------------------------------------------------------- 1 | 2 | = References 3 | 4 | [[_ref_1]] 5 | [1] _Bradner, S., Key words for use in RFCs to Indicate Requirement Levels_ + 6 | http://tools.ietf.org/html/rfc2119 7 | 8 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: Apache-2.0 3 | * 4 | * Copyright 2015-2021 the original author or authors. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | pluginManagement { 19 | repositories { 20 | mavenLocal() 21 | gradlePluginPortal() 22 | mavenCentral() 23 | } 24 | plugins { 25 | id 'org.kordamp.gradle.java-project' version kordampPluginVersion 26 | id 'org.beryx.jar' version '1.2.0' 27 | id 'org.asciidoctor.jvm.convert' version asciidoctorVersion 28 | id 'org.asciidoctor.jvm.pdf' version asciidoctorVersion 29 | } 30 | } 31 | 32 | buildscript { 33 | repositories { 34 | mavenLocal() 35 | gradlePluginPortal() 36 | mavenCentral() 37 | } 38 | dependencies { 39 | classpath "org.kordamp.gradle:settings-gradle-plugin:$kordampPluginVersion" 40 | } 41 | } 42 | apply plugin: 'org.kordamp.gradle.settings' 43 | 44 | rootProject.name = 'jsr377-parent' 45 | 46 | projects { 47 | layout = 'standard' 48 | } 49 | --------------------------------------------------------------------------------