├── .github ├── ISSUE_TEMPLATE │ └── tck_challenge.md └── workflows │ └── main.yml ├── .gitignore ├── .travis.yml ├── .travis ├── deploy-settings.xml └── deploy-spec-html.sh ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── api ├── findbugs-exclude.xml ├── mvc-tck-sigtest-3.0.0.sigfile ├── pom.xml └── src │ └── main │ ├── java │ ├── jakarta │ │ └── mvc │ │ │ ├── Controller.java │ │ │ ├── Models.java │ │ │ ├── MvcContext.java │ │ │ ├── RedirectScoped.java │ │ │ ├── UriRef.java │ │ │ ├── View.java │ │ │ ├── binding │ │ │ ├── BindingError.java │ │ │ ├── BindingResult.java │ │ │ ├── MvcBinding.java │ │ │ ├── ParamError.java │ │ │ ├── ValidationError.java │ │ │ └── package-info.java │ │ │ ├── engine │ │ │ ├── ViewEngine.java │ │ │ ├── ViewEngineContext.java │ │ │ ├── ViewEngineException.java │ │ │ └── package-info.java │ │ │ ├── event │ │ │ ├── AfterControllerEvent.java │ │ │ ├── AfterProcessViewEvent.java │ │ │ ├── BeforeControllerEvent.java │ │ │ ├── BeforeProcessViewEvent.java │ │ │ ├── ControllerRedirectEvent.java │ │ │ ├── MvcEvent.java │ │ │ └── package-info.java │ │ │ ├── form │ │ │ ├── FormMethodOverwriter.java │ │ │ └── package-info.java │ │ │ ├── locale │ │ │ ├── LocaleResolver.java │ │ │ ├── LocaleResolverContext.java │ │ │ └── package-info.java │ │ │ ├── package-info.java │ │ │ └── security │ │ │ ├── Csrf.java │ │ │ ├── CsrfProtected.java │ │ │ ├── CsrfValidationException.java │ │ │ ├── Encoders.java │ │ │ └── package-info.java │ └── module-info.java │ └── javadoc │ └── doc-files │ └── speclicense.html ├── pom.xml └── spec ├── pom.xml └── src └── main ├── asciidoc ├── chapters │ ├── annotations.asciidoc │ ├── applications.asciidoc │ ├── controllers.asciidoc │ ├── data-binding.asciidoc │ ├── engines.asciidoc │ ├── events.asciidoc │ ├── form-method-overwrite.asciidoc │ ├── i18n.asciidoc │ ├── intro.asciidoc │ ├── license.asciidoc │ ├── refs.asciidoc │ ├── revision.asciidoc │ └── security.asciidoc ├── images │ └── jakarta_ee_logo_schooner_color_stacked_default.png ├── license-efsl.adoc ├── mvc-spec.asciidoc └── spec.asciidoc └── xsl └── tck-audit.xsl /.github/ISSUE_TEMPLATE/tck_challenge.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: TCK Challenge 3 | about: Create a TCK Challenge 4 | title: '' 5 | labels: 'challenge' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Challenged tests** 11 | List the challenged tests with the fully qualified classnames and then the test methods, e.g.' 12 | ee.jakarta.tck.mvc.common.DefaultApplication.java 13 | ee.jakarta.tck.mvc.tests.mvc.response.ResponseFeaturesTest#responseAllowsSettingHeaders 14 | 15 | **TCK Version** 16 | Specify the version of the TCK, e.g. Jakarta MVC 2.0.x 17 | 18 | **Description** 19 | A clear and concise description of why you think the tests are wrong. 20 | 21 | **Additional context** 22 | Add any other context about the challenge here. -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a Java project with Maven 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven 3 | 4 | name: Java CI with Maven 5 | 6 | on: 7 | push: 8 | branches: 9 | - master 10 | - feature/* 11 | - bugfix/* 12 | - releases/* 13 | pull_request: 14 | branches: [ master ] 15 | 16 | jobs: 17 | build: 18 | 19 | runs-on: ubuntu-latest 20 | 21 | steps: 22 | - uses: actions/checkout@v2 23 | - name: Set up JDK 22 24 | uses: actions/setup-java@v2 25 | with: 26 | java-version: '22' 27 | distribution: 'temurin' 28 | - name: Build with Maven 29 | run: mvn -B package --file pom.xml -DskipSBOM 30 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | target 3 | .DS_Store 4 | nbactions.xml 5 | nb-configuration.xml 6 | *.iml 7 | site.zip 8 | 9 | .project 10 | .classpath 11 | .settings/ 12 | .vscode/ -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | jdk: 3 | - openjdk11 4 | 5 | cache: 6 | directories: 7 | - $HOME/.m2 8 | 9 | env: 10 | global: 11 | - BUILD_PROFILE= 12 | # - BUILD_PROFILE=-Pstaging 13 | 14 | 15 | jobs: 16 | include: 17 | - stage: build 18 | script: mvn -B -V clean install ${BUILD_PROFILE} 19 | 20 | #deploy: 21 | # - provider: script 22 | # script: mvn -s .travis/deploy-settings.xml -DperformRelease -DskipTests -Dgpg.skip=true deploy 23 | # skip_cleanup: true 24 | # on: 25 | # repo: eclipse-ee4j/mvc-spec 26 | # branch: master 27 | # jdk: openjdk11 28 | # - provider: script 29 | # script: .travis/deploy-spec-html.sh 30 | # skip_cleanup: true 31 | # on: 32 | # repo: eclipse-ee4j/mvc-spec 33 | # branch: master 34 | # jdk: openjdk11 35 | # 36 | #env: 37 | # global: 38 | # - secure: "iJFl971N9L3Bi1+2Z8DGexI+5VObaenykZB9+xohWEKSwzRjusa6/pmzk9+1Cm7RicwDubmx5kmcJvkZki5EF5wVP7lnuHodM2d281052qq/2TcaCN3/DmyGg1QuunCDvZpVWfu1e1F5KMwmp+brt6yaUQVPVN/ehKyT++niO7ZOlhjaB2Gn02bPwW8BZ8aEUt2mNPNwSOJ7R1g4yV+Ji7lleWTIMbJCa1bmg9YncHLyCU8un5vm/fok5fcmwZwrtnckbSU2fgIo8GDXKbblsHOSC2FeYfQFhFzMjh3+bhPhKHmQN7IG4puseNhsuJHGWAzK9hXdaacl+yZ+3WvPr7jf8E4ZL2RinCLaZwxkgHiImrm9Ay9FGMckyyobaPL3Uos1T2MBkhAIle9bh7GAw8GUYbZbCz+IUESTyloQn8Tg4Nspw7xna3W5uBzYySEBgJWKDnQBuWF9HOhJTzJunNWFfLrQEOXaQkyYks5+1VzMm2kKL10hJ55TwG/9zKA7AWspdeaK53ZdtzEfuVLfLymkpKZbtp872sdHbfveV8eeRwFoD4b8TF9K5oxMDQYzeP3N3zlpFsvXtjzQoAOxRE96n/1FiYTQQvbbiTf43lW/HI4QqyA6sV897zjdX5qhnTJT6iFZWxkCgt63Acnrz+CzMdFtL8CCEXnfJi/oIbY=" 39 | # - secure: "SPvU5ZPDcFpIGScO42HXWrGoUw/s8IIDJrj9Ne343ag7dNXq91Kd2sxYE3EyYiZVt/6YIneYv4adezzfD94xHL2apiaIRy+OzheG8ohgU5nSxra4jXi+gUQMjrmIybL6qyQe7rDxI6zkUvjB6h10i3bZw4a6lf1afqFwmrHST6dXBqIKgmOJ668nzmOqxozjQ1PfbgS1N5D5s5Oh0zncIq7dqP26fK3lrytHfq+cfjMolNeE99CXDwy2HJkFoYtmjCCrT6mi5WzVUGa2g3w1nidDGqIIOIWImu4GLdgaKCZb55XFbtgTNzzYf8SXvmgqTxqftCL8pyLk1vMX3dxctn/E9AdwkhpcXouCJkDvSJ2LznYAjX0CwDIAK34/T7Ad60sjBpZGK17QcNRkvqyG6A8434GKbaY8sRXSQJIyTHgPNqDYTuYKJDehiKY2xF5zeG3aVjHO5jzoeNNMlgeOT3tjGZAK6z5szDQXSInMozMHqdu93pHSBzKn17e3pVGuelOo42B1bxsPSHQVbSWXIl0n2fhNe1B2k5PI++D4qwEBJ0Cpe9nwGmUJ0SB1u5omSDOiW2+cueE7dsUV6KWLvXolD8h37fVOkbgpULbIsJXLcwYnjP3Zvj4pf9KEPPSi5vgBYCOh0R1bLDh2emzcMPWlHlvZaeRCucTT7eJ4etI=" 40 | # - secure: "oI7mgMf86wdd095VmfhrAHr0HQRXmBJqhLK0lvuXnNvRczS2lS/rQpNgzC1tuKdap47YPaTzo/zS0bKMnHfejwNoOPh2bvizHVYZXBXLAAY0lPAJZ0+ZV8WyLTVHfM+krsq5aJs2XHzbOr4oeEvNoVwyVKi0nD5Z+i7fT+9lawrak2P0CF0jTIe2noQiiQ51z/kIY46UJlEXw+0miN/MPLsfzAIMGldaemg+CbjKjUeMBD/RgOwN0J+95FnqKfM0IZ6HeT4jN/YTUJVgusWnu+kGUjJA4zIdT0xMMHqLdHyvOV0sogntwiBLjYkknNSmSQ7vpz4otzRcbeDFupmnUoeWRgNUZ86Gi3UCXz5DJgbwduufv52v2ne8CVElGKqrYst9ne+qxdWyPOOPRkIsvV1/BZjrHQaMLu11MgzB/2MLWXTTU9vVuvTJn43j7q1sdL99OPVF7mLKaVqIAXbRUCFs8dD/ZhmXbahQmhpt5If8g6+HPcz0FbXTkj4XjmuHH8RkJM4vpsNSPU/VzsCAciypnEIvsRBE2jO7njL0hBw2NSV0MwJT9IreqjTTz+jX72BvApxTlTIGbstOnaGY15QDhz3PAP4/pT/QHdt8vaRnePtCE0CGec9iGD7UJYlQt7eUpMHlEM+ACw6Ate2zmgKsg6r1VBr9qZORbWaQpsk=" 41 | -------------------------------------------------------------------------------- /.travis/deploy-settings.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | ossrh 7 | ${env.SONATYPE_USERNAME} 8 | ${env.SONATYPE_PASSWORD} 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.travis/deploy-spec-html.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -euo pipefail 4 | 5 | BASEDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )/../" && pwd )" 6 | 7 | echo "Creating site archive..." 8 | cd ${BASEDIR}/spec/target/generated-docs/ 9 | zip -q -r ${BASEDIR}/site.zip * 10 | 11 | echo "Uploading archive..." 12 | cd ${BASEDIR} 13 | curl -s -H "Content-Type: application/zip" \ 14 | -H "Authorization: Bearer ${NETLIFY_TOKEN}" \ 15 | --data-binary "@site.zip" \ 16 | https://api.netlify.com/api/v1/sites/a36b2588-c345-47ea-95ed-3dbcfcd5cee9/deploys \ 17 | > /dev/null 18 | 19 | echo "Done" 20 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Jakarta MVC 2 | 3 | Thanks for your interest in this project! 4 | 5 | ## Developer resources 6 | 7 | Information regarding source code management, builds, coding standards, and 8 | more. 9 | 10 | * https://projects.eclipse.org/projects/ee4j.mvc/developer 11 | 12 | The project maintains the following source code repositories 13 | 14 | * https://github.com/eclipse-ee4j/mvc-api 15 | * https://github.com/eclipse-ee4j/mvc-tck 16 | 17 | ## Eclipse Development Process 18 | 19 | This Eclipse Foundation open project is governed by the Eclipse Foundation 20 | Development Process and operates under the terms of the Eclipse IP Policy. 21 | 22 | The Jakarta EE Specification Committee has adopted the Jakarta EE Specification 23 | Process (JESP) in accordance with the Eclipse Foundation Specification Process 24 | v1.2 (EFSP) to ensure that the specification process is complied with by all 25 | Jakarta EE specification projects. 26 | 27 | * https://eclipse.org/projects/dev_process 28 | * https://www.eclipse.org/org/documents/Eclipse_IP_Policy.pdf 29 | * https://jakarta.ee/about/jesp/ 30 | * https://www.eclipse.org/legal/efsp_non_assert.php 31 | 32 | ## Eclipse Contributor Agreement 33 | 34 | Before your contribution can be accepted by the project team contributors must 35 | electronically sign the Eclipse Contributor Agreement (ECA). 36 | 37 | * http://www.eclipse.org/legal/ECA.php 38 | 39 | Commits that are provided by non-committers must have a Signed-off-by field in 40 | the footer indicating that the author is aware of the terms by which the 41 | contribution has been provided to the project. The non-committer must 42 | additionally have an Eclipse Foundation account and must have a signed Eclipse 43 | Contributor Agreement (ECA) on file. 44 | 45 | For more information, please see the Eclipse Committer Handbook: 46 | https://www.eclipse.org/projects/handbook/#resources-commit 47 | 48 | ## Contact 49 | 50 | Contact the project developers via the project's "dev" list. 51 | 52 | * https://accounts.eclipse.org/mailing-list/mvc-dev -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Eclipse Public License - v 2.0 2 | 3 | THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE 4 | PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION 5 | OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 6 | 7 | 1. DEFINITIONS 8 | 9 | "Contribution" means: 10 | 11 | a) in the case of the initial Contributor, the initial content 12 | Distributed under this Agreement, and 13 | 14 | b) in the case of each subsequent Contributor: 15 | i) changes to the Program, and 16 | ii) additions to the Program; 17 | where such changes and/or additions to the Program originate from 18 | and are Distributed by that particular Contributor. A Contribution 19 | "originates" from a Contributor if it was added to the Program by 20 | such Contributor itself or anyone acting on such Contributor's behalf. 21 | Contributions do not include changes or additions to the Program that 22 | are not Modified Works. 23 | 24 | "Contributor" means any person or entity that Distributes the Program. 25 | 26 | "Licensed Patents" mean patent claims licensable by a Contributor which 27 | are necessarily infringed by the use or sale of its Contribution alone 28 | or when combined with the Program. 29 | 30 | "Program" means the Contributions Distributed in accordance with this 31 | Agreement. 32 | 33 | "Recipient" means anyone who receives the Program under this Agreement 34 | or any Secondary License (as applicable), including Contributors. 35 | 36 | "Derivative Works" shall mean any work, whether in Source Code or other 37 | form, that is based on (or derived from) the Program and for which the 38 | editorial revisions, annotations, elaborations, or other modifications 39 | represent, as a whole, an original work of authorship. 40 | 41 | "Modified Works" shall mean any work in Source Code or other form that 42 | results from an addition to, deletion from, or modification of the 43 | contents of the Program, including, for purposes of clarity any new file 44 | in Source Code form that contains any contents of the Program. Modified 45 | Works shall not include works that contain only declarations, 46 | interfaces, types, classes, structures, or files of the Program solely 47 | in each case in order to link to, bind by name, or subclass the Program 48 | or Modified Works thereof. 49 | 50 | "Distribute" means the acts of a) distributing or b) making available 51 | in any manner that enables the transfer of a copy. 52 | 53 | "Source Code" means the form of a Program preferred for making 54 | modifications, including but not limited to software source code, 55 | documentation source, and configuration files. 56 | 57 | "Secondary License" means either the GNU General Public License, 58 | Version 2.0, or any later versions of that license, including any 59 | exceptions or additional permissions as identified by the initial 60 | Contributor. 61 | 62 | 2. GRANT OF RIGHTS 63 | 64 | a) Subject to the terms of this Agreement, each Contributor hereby 65 | grants Recipient a non-exclusive, worldwide, royalty-free copyright 66 | license to reproduce, prepare Derivative Works of, publicly display, 67 | publicly perform, Distribute and sublicense the Contribution of such 68 | Contributor, if any, and such Derivative Works. 69 | 70 | b) Subject to the terms of this Agreement, each Contributor hereby 71 | grants Recipient a non-exclusive, worldwide, royalty-free patent 72 | license under Licensed Patents to make, use, sell, offer to sell, 73 | import and otherwise transfer the Contribution of such Contributor, 74 | if any, in Source Code or other form. This patent license shall 75 | apply to the combination of the Contribution and the Program if, at 76 | the time the Contribution is added by the Contributor, such addition 77 | of the Contribution causes such combination to be covered by the 78 | Licensed Patents. The patent license shall not apply to any other 79 | combinations which include the Contribution. No hardware per se is 80 | licensed hereunder. 81 | 82 | c) Recipient understands that although each Contributor grants the 83 | licenses to its Contributions set forth herein, no assurances are 84 | provided by any Contributor that the Program does not infringe the 85 | patent or other intellectual property rights of any other entity. 86 | Each Contributor disclaims any liability to Recipient for claims 87 | brought by any other entity based on infringement of intellectual 88 | property rights or otherwise. As a condition to exercising the 89 | rights and licenses granted hereunder, each Recipient hereby 90 | assumes sole responsibility to secure any other intellectual 91 | property rights needed, if any. For example, if a third party 92 | patent license is required to allow Recipient to Distribute the 93 | Program, it is Recipient's responsibility to acquire that license 94 | before distributing the Program. 95 | 96 | d) Each Contributor represents that to its knowledge it has 97 | sufficient copyright rights in its Contribution, if any, to grant 98 | the copyright license set forth in this Agreement. 99 | 100 | e) Notwithstanding the terms of any Secondary License, no 101 | Contributor makes additional grants to any Recipient (other than 102 | those set forth in this Agreement) as a result of such Recipient's 103 | receipt of the Program under the terms of a Secondary License 104 | (if permitted under the terms of Section 3). 105 | 106 | 3. REQUIREMENTS 107 | 108 | 3.1 If a Contributor Distributes the Program in any form, then: 109 | 110 | a) the Program must also be made available as Source Code, in 111 | accordance with section 3.2, and the Contributor must accompany 112 | the Program with a statement that the Source Code for the Program 113 | is available under this Agreement, and informs Recipients how to 114 | obtain it in a reasonable manner on or through a medium customarily 115 | used for software exchange; and 116 | 117 | b) the Contributor may Distribute the Program under a license 118 | different than this Agreement, provided that such license: 119 | i) effectively disclaims on behalf of all other Contributors all 120 | warranties and conditions, express and implied, including 121 | warranties or conditions of title and non-infringement, and 122 | implied warranties or conditions of merchantability and fitness 123 | for a particular purpose; 124 | 125 | ii) effectively excludes on behalf of all other Contributors all 126 | liability for damages, including direct, indirect, special, 127 | incidental and consequential damages, such as lost profits; 128 | 129 | iii) does not attempt to limit or alter the recipients' rights 130 | in the Source Code under section 3.2; and 131 | 132 | iv) requires any subsequent distribution of the Program by any 133 | party to be under a license that satisfies the requirements 134 | of this section 3. 135 | 136 | 3.2 When the Program is Distributed as Source Code: 137 | 138 | a) it must be made available under this Agreement, or if the 139 | Program (i) is combined with other material in a separate file or 140 | files made available under a Secondary License, and (ii) the initial 141 | Contributor attached to the Source Code the notice described in 142 | Exhibit A of this Agreement, then the Program may be made available 143 | under the terms of such Secondary Licenses, and 144 | 145 | b) a copy of this Agreement must be included with each copy of 146 | the Program. 147 | 148 | 3.3 Contributors may not remove or alter any copyright, patent, 149 | trademark, attribution notices, disclaimers of warranty, or limitations 150 | of liability ("notices") contained within the Program from any copy of 151 | the Program which they Distribute, provided that Contributors may add 152 | their own appropriate notices. 153 | 154 | 4. COMMERCIAL DISTRIBUTION 155 | 156 | Commercial distributors of software may accept certain responsibilities 157 | with respect to end users, business partners and the like. While this 158 | license is intended to facilitate the commercial use of the Program, 159 | the Contributor who includes the Program in a commercial product 160 | offering should do so in a manner which does not create potential 161 | liability for other Contributors. Therefore, if a Contributor includes 162 | the Program in a commercial product offering, such Contributor 163 | ("Commercial Contributor") hereby agrees to defend and indemnify every 164 | other Contributor ("Indemnified Contributor") against any losses, 165 | damages and costs (collectively "Losses") arising from claims, lawsuits 166 | and other legal actions brought by a third party against the Indemnified 167 | Contributor to the extent caused by the acts or omissions of such 168 | Commercial Contributor in connection with its distribution of the Program 169 | in a commercial product offering. The obligations in this section do not 170 | apply to any claims or Losses relating to any actual or alleged 171 | intellectual property infringement. In order to qualify, an Indemnified 172 | Contributor must: a) promptly notify the Commercial Contributor in 173 | writing of such claim, and b) allow the Commercial Contributor to control, 174 | and cooperate with the Commercial Contributor in, the defense and any 175 | related settlement negotiations. The Indemnified Contributor may 176 | participate in any such claim at its own expense. 177 | 178 | For example, a Contributor might include the Program in a commercial 179 | product offering, Product X. That Contributor is then a Commercial 180 | Contributor. If that Commercial Contributor then makes performance 181 | claims, or offers warranties related to Product X, those performance 182 | claims and warranties are such Commercial Contributor's responsibility 183 | alone. Under this section, the Commercial Contributor would have to 184 | defend claims against the other Contributors related to those performance 185 | claims and warranties, and if a court requires any other Contributor to 186 | pay any damages as a result, the Commercial Contributor must pay 187 | those damages. 188 | 189 | 5. NO WARRANTY 190 | 191 | EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT 192 | PERMITTED BY APPLICABLE LAW, THE PROGRAM IS PROVIDED ON AN "AS IS" 193 | BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR 194 | IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF 195 | TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR 196 | PURPOSE. Each Recipient is solely responsible for determining the 197 | appropriateness of using and distributing the Program and assumes all 198 | risks associated with its exercise of rights under this Agreement, 199 | including but not limited to the risks and costs of program errors, 200 | compliance with applicable laws, damage to or loss of data, programs 201 | or equipment, and unavailability or interruption of operations. 202 | 203 | 6. DISCLAIMER OF LIABILITY 204 | 205 | EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT 206 | PERMITTED BY APPLICABLE LAW, NEITHER RECIPIENT NOR ANY CONTRIBUTORS 207 | SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 208 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST 209 | PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 210 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 211 | ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE 212 | EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE 213 | POSSIBILITY OF SUCH DAMAGES. 214 | 215 | 7. GENERAL 216 | 217 | If any provision of this Agreement is invalid or unenforceable under 218 | applicable law, it shall not affect the validity or enforceability of 219 | the remainder of the terms of this Agreement, and without further 220 | action by the parties hereto, such provision shall be reformed to the 221 | minimum extent necessary to make such provision valid and enforceable. 222 | 223 | If Recipient institutes patent litigation against any entity 224 | (including a cross-claim or counterclaim in a lawsuit) alleging that the 225 | Program itself (excluding combinations of the Program with other software 226 | or hardware) infringes such Recipient's patent(s), then such Recipient's 227 | rights granted under Section 2(b) shall terminate as of the date such 228 | litigation is filed. 229 | 230 | All Recipient's rights under this Agreement shall terminate if it 231 | fails to comply with any of the material terms or conditions of this 232 | Agreement and does not cure such failure in a reasonable period of 233 | time after becoming aware of such noncompliance. If all Recipient's 234 | rights under this Agreement terminate, Recipient agrees to cease use 235 | and distribution of the Program as soon as reasonably practicable. 236 | However, Recipient's obligations under this Agreement and any licenses 237 | granted by Recipient relating to the Program shall continue and survive. 238 | 239 | Everyone is permitted to copy and distribute copies of this Agreement, 240 | but in order to avoid inconsistency the Agreement is copyrighted and 241 | may only be modified in the following manner. The Agreement Steward 242 | reserves the right to publish new versions (including revisions) of 243 | this Agreement from time to time. No one other than the Agreement 244 | Steward has the right to modify this Agreement. The Eclipse Foundation 245 | is the initial Agreement Steward. The Eclipse Foundation may assign the 246 | responsibility to serve as the Agreement Steward to a suitable separate 247 | entity. Each new version of the Agreement will be given a distinguishing 248 | version number. The Program (including Contributions) may always be 249 | Distributed subject to the version of the Agreement under which it was 250 | received. In addition, after a new version of the Agreement is published, 251 | Contributor may elect to Distribute the Program (including its 252 | Contributions) under the new version. 253 | 254 | Except as expressly stated in Sections 2(a) and 2(b) above, Recipient 255 | receives no rights or licenses to the intellectual property of any 256 | Contributor under this Agreement, whether expressly, by implication, 257 | estoppel or otherwise. All rights in the Program not expressly granted 258 | under this Agreement are reserved. Nothing in this Agreement is intended 259 | to be enforceable by any entity that is not a Contributor or Recipient. 260 | No third-party beneficiary rights are created under this Agreement. 261 | 262 | Exhibit A - Form of Secondary Licenses Notice 263 | 264 | "This Source Code may also be made available under the following 265 | Secondary Licenses when the conditions for such availability set forth 266 | in the Eclipse Public License, v. 2.0 are satisfied: {name license(s), 267 | version(s), and exceptions or additional permissions here}." 268 | 269 | Simply including a copy of this Agreement, including this Exhibit A 270 | is not sufficient to license the Source Code under Secondary Licenses. 271 | 272 | If it is not possible or desirable to put the notice in a particular 273 | file, then You may include the notice in a location (such as a LICENSE 274 | file in a relevant directory) where a recipient would be likely to 275 | look for such a notice. 276 | 277 | You may add additional accurate notices of copyright ownership. 278 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Java CI with Maven](https://github.com/eclipse-ee4j/mvc-api/actions/workflows/main.yml/badge.svg)](https://github.com/eclipse-ee4j/mvc-api/actions/workflows/main.yml) 2 | 3 | # Jakarta MVC Specification and API 4 | 5 | This project contains the specification document and Java API sources. The project 6 | is organized into two modules: _api_ and _spec_. 7 | The _api_ module contains the Java API sources, which may be used to generate the 8 | API JAR and JavaDoc. 9 | The _spec_ module contains the specification document sources, which may be used 10 | to generate the specification document. 11 | 12 | ## Generating the API and JavaDoc 13 | 14 | Just enter `mvn clean install` at the command line. Maven will generate the following artifacts. 15 | 16 | API Jar:: 17 | * The jar containing the api interfaces and classes. 18 | * In the directory: `/api/target` 19 | 20 | API JavaDoc:: 21 | * The JavaDoc for the api interfaces and classes. 22 | * In the directory: `api/target/apidocs` 23 | 24 | ## Generating the Specification 25 | 26 | run `mvn clean install` in the `spec` directory 27 | 28 | The PDF and HTML will be generated in `spec/target/generated-docs/` 29 | 30 | ## Tagging phrases for the TCK 31 | 32 | The [Jakarta MVC TCK](https://github.com/eclipse-ee4j/mvc-tck) is a suite of unit 33 | tests for validating the compliance of MVC implementations with the specification. 34 | 35 | The tests of the TCK are based on assertions representing sentences and phrases in this 36 | specification. Labels on specific text elements of the specification are used to mark those which 37 | should lead to an assertion in the TCK. The following values are allowed: 38 | 39 | * `tck-testable`: The tagged element must be represented by a testable assertion in the TCK 40 | * `tck-not-testable`: The tagged element must be represented by a non-testable assertion in the 41 | TCK (e.g. assertions regarding thread safety) 42 | * `tck-ignore`: The tagged element must be excluded when creating a TCK assertion for an outer 43 | element. Can be used to exlude explanatory phrases contained in an element marked as `tck-testable`. 44 | * `tck-needs-update`: The tagged element must be marked with a note in the TCK audit file saying 45 | that the tests for this assertion need to be updated, e.g. due to a spec update. Can be used 46 | together with `tck-testable` and `tck-not-testable`: `[tck-testable tck-needs-update]#Some sentence...#`. 47 | * `tck-id-SOME_ID`: This tag defines an ID that has to be used to reference this particular assertion 48 | in the TCK. SOME_ID can be any text, number or special character`- anything up to the next space " " or 49 | closing bracket ]` will be taken as the ID. Can be used together with `tck-testable`: 50 | `[tck-testable tck-id-http://some.issue.tracker/url]#Some sentence...#`. `tck-testable` without a 51 | defined id will get a letter assigned as their ID, in the order of apperance within their section 52 | (a, b, c, ...) 53 | 54 | ## Audit XML to calculate spec coverage in tests 55 | 56 | `mvn clean install` (or just `mvn generate-resources`) in the `spec` directory will create a `tck-audit.xml` file under 57 | `target/generated-docs`. This file contains the `[tck-testable]` assertions found in the spec (asciidoc), 58 | and is used in the TCK project to analyse the spec coverage in tests. 59 | 60 | The process is copied and adapted from the beanvalidation spec project 61 | (https://github.com/eclipse-ee4j/beanvalidation-api). 62 | 63 | ## TCK Challenge and resolution process for Jakarta MVC 64 | 65 | Test challenges for Jakarta MVC may be resolved through Lazy Consensus. Please see the TCK Users Guide for Jakarta MVC for more details. 66 | -------------------------------------------------------------------------------- /api/findbugs-exclude.xml: -------------------------------------------------------------------------------- 1 | 18 | 19 | 23 | 24 | 25 | 26 | 27 | 30 | 31 | 32 | 33 | 34 | 38 | 39 | 40 | 41 | 42 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 57 | 58 | 59 | 60 | 61 | 65 | 66 | 67 | 68 | 69 | 75 | 76 | 77 | 78 | 79 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | -------------------------------------------------------------------------------- /api/src/main/java/jakarta/mvc/Controller.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. 3 | * Copyright (c) 2016-2018 JSR 371 expert group and contributors 4 | * Copyright (c) 2020 Contributors to the Eclipse Foundation 5 | * 6 | * This program and the accompanying materials are made available under the 7 | * terms of the Eclipse Public License v. 2.0, which is available at 8 | * http://www.eclipse.org/legal/epl-2.0. 9 | * 10 | * This Source Code may also be made available under the following Secondary 11 | * Licenses when the conditions for such availability set forth in the 12 | * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, 13 | * version 2 with the GNU Classpath Exception, which is available at 14 | * https://www.gnu.org/software/classpath/license.html. 15 | * 16 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 17 | */ 18 | package jakarta.mvc; 19 | 20 | import jakarta.ws.rs.NameBinding; 21 | import java.lang.annotation.Documented; 22 | import java.lang.annotation.Inherited; 23 | import java.lang.annotation.Retention; 24 | import java.lang.annotation.Target; 25 | 26 | import static java.lang.annotation.RetentionPolicy.*; 27 | import static java.lang.annotation.ElementType.*; 28 | 29 | /** 30 | *

Declares a method as a controller. If declared at the type level, 31 | * it applies to all methods in the type.

32 | * 33 | *

A controller method that returns void is required to be annotated with 34 | * {@link View}. A controller method can return a view path 35 | * as a {@link java.lang.String} or a {@link jakarta.ws.rs.core.Response}. If a controller 36 | * returns {@code null} and it is annotated with {@link View}, 37 | * then the value of this annotation is used as a default.

38 | * 39 | *

Example: 40 | *


41 |  *     @Controller
42 |  *     public String sayHello() {
43 |  *         return "hello.jsp";
44 |  *     }
45 |  * 
46 | * 47 | * @author Santiago Pericas-Geertsen 48 | * @author Ivar Grimstad 49 | * @see View 50 | * @see jakarta.ws.rs.core.Response 51 | * @since 1.0 52 | */ 53 | @NameBinding 54 | @Target( { METHOD, TYPE } ) 55 | @Retention( RUNTIME ) 56 | @Documented 57 | @Inherited 58 | public @interface Controller { 59 | } 60 | 61 | -------------------------------------------------------------------------------- /api/src/main/java/jakarta/mvc/Models.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. 3 | * Copyright (c) 2016-2018 JSR 371 expert group and contributors 4 | * Copyright (c) 2020 Contributors to the Eclipse Foundation 5 | * 6 | * This program and the accompanying materials are made available under the 7 | * terms of the Eclipse Public License v. 2.0, which is available at 8 | * http://www.eclipse.org/legal/epl-2.0. 9 | * 10 | * This Source Code may also be made available under the following Secondary 11 | * Licenses when the conditions for such availability set forth in the 12 | * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, 13 | * version 2 with the GNU Classpath Exception, which is available at 14 | * https://www.gnu.org/software/classpath/license.html. 15 | * 16 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 17 | */ 18 | package jakarta.mvc; 19 | 20 | import java.util.Map; 21 | 22 | /** 23 | *

A map of name to model instances used by a {@link jakarta.mvc.engine.ViewEngine} 24 | * to process a view. Instances implementing this interface must be injectable using 25 | * {@link jakarta.inject.Inject} and are {@link jakarta.enterprise.context.RequestScoped}. 26 | * 27 | *

Note that certain view engines, such as the engine for Jakarta Server Pages, support 28 | * model binding via {@link jakarta.inject.Named} in which case the use of Models is 29 | * optional. 30 | * 31 | * @author Santiago Pericas-Geertsen 32 | * @author Christian Kaltepoth 33 | * @author Ivar Grimstad 34 | * @see jakarta.inject.Named 35 | * @see jakarta.enterprise.context.RequestScoped 36 | * @since 1.0 37 | */ 38 | public interface Models extends Iterable { 39 | 40 | /** 41 | * Stores a new model in the map. 42 | * 43 | * @param name name of the model 44 | * @param model model to store in the map 45 | * @return the current instance to allow method chaining 46 | */ 47 | Models put(String name, Object model); 48 | 49 | /** 50 | * Retrieve a model by name. 51 | * 52 | * @param name name of the model 53 | * @return the model or null 54 | */ 55 | Object get(String name); 56 | 57 | /** 58 | * Retrieve a model by name in a type-safe way. 59 | * 60 | * @param name name of the model 61 | * @param clazz type of the model 62 | * @param type of the model 63 | * @return The model or null 64 | */ 65 | T get(String name, Class clazz); 66 | 67 | /** 68 | * Returns a unmodifiable view of the models map. 69 | * 70 | * @return unmodifiable map 71 | */ 72 | Map asMap(); 73 | 74 | } 75 | -------------------------------------------------------------------------------- /api/src/main/java/jakarta/mvc/MvcContext.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. 3 | * Copyright (c) 2016-2018 JSR 371 expert group and contributors 4 | * Copyright (c) 2020 Contributors to the Eclipse Foundation 5 | * 6 | * This program and the accompanying materials are made available under the 7 | * terms of the Eclipse Public License v. 2.0, which is available at 8 | * http://www.eclipse.org/legal/epl-2.0. 9 | * 10 | * This Source Code may also be made available under the following Secondary 11 | * Licenses when the conditions for such availability set forth in the 12 | * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, 13 | * version 2 with the GNU Classpath Exception, which is available at 14 | * https://www.gnu.org/software/classpath/license.html. 15 | * 16 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 17 | */ 18 | package jakarta.mvc; 19 | 20 | import jakarta.mvc.security.Csrf; 21 | import jakarta.mvc.security.Encoders; 22 | import jakarta.ws.rs.core.Configuration; 23 | import jakarta.ws.rs.core.UriBuilder; 24 | import java.net.URI; 25 | import java.util.Locale; 26 | import java.util.Map; 27 | 28 | /** 29 | *

This class provides contextual information such as context and application 30 | * paths as well as access to the Jakarta RESTful Web Services application configuration object. 31 | * In addition, it provides access to the security-related beans {@link 32 | * jakarta.mvc.security.Csrf} and {@link jakarta.mvc.security.Encoders}.

33 | * 34 | *

Implementations of this class are injectable, must be 35 | * {@link jakarta.enterprise.context.RequestScoped} and accessible from Jakarta Expression Language using 36 | * the name {@code mvc}. For example, the CSRF token name and value can be 37 | * accessed in Jakarta Expression Language using the expressions {@code mvc.csrf.name} 38 | * and {@code 39 | * mvc.csrf.token}, respectively.

40 | * 41 | * @author Santiago Pericas-Geertsen 42 | * @author Ivar Grimstad 43 | * @see jakarta.ws.rs.core.Configuration 44 | * @since 1.0 45 | */ 46 | public interface MvcContext { 47 | 48 | /** 49 | * Get the Jakarta RESTful Web Services application configuration object. 50 | * All application-defined properties are accessible via this object. 51 | * 52 | * @return the configuration object. 53 | */ 54 | Configuration getConfig(); 55 | 56 | /** 57 | *

Get the application's base path which is defined as the concatenation of context 58 | * and application paths. It follows that the value returned by this method always 59 | * starts with a slash but never ends with one.

60 | * 61 | * @return the application's base path. 62 | */ 63 | String getBasePath(); 64 | 65 | /** 66 | * Get the CSRF object. 67 | * 68 | * @return the CSRF object. 69 | */ 70 | Csrf getCsrf(); 71 | 72 | /** 73 | * Get the name of the hidden field that is required for the {@link jakarta.mvc.form.FormMethodOverwriter}. 74 | * 75 | * @return the custom name set by using {@link jakarta.mvc.form.FormMethodOverwriter#HIDDEN_FIELD_NAME} 76 | * or the default value in {@link jakarta.mvc.form.FormMethodOverwriter#DEFAULT_HIDDEN_FIELD_NAME}. 77 | */ 78 | String getHiddenMethodFieldName(); 79 | 80 | /** 81 | * Get the built-in encoders. 82 | * 83 | * @return instance of encoders. 84 | */ 85 | Encoders getEncoders(); 86 | 87 | /** 88 | * Returns the locale of the current request. 89 | * 90 | * @return The request locale 91 | */ 92 | Locale getLocale(); 93 | 94 | /** 95 | *

Creates an URI to be matched by a controller method. This is aimed primarily 96 | * for use in view rendering technologies to avoid duplicating the values of the 97 | * {@link jakarta.ws.rs.Path} annotations.

98 | * 99 | *

The controller method can either be identified by the simple name of the controller class 100 | * and the method name separated by '#' (MyController#myMethod) or by the value 101 | * of the {@link UriRef} annotation.

102 | * 103 | *

The created URI includes context- and application path.

104 | * 105 | *

This method assumes that there is no parameter in the URI-template.

106 | * 107 | *

For example in Jakarta Server Pages:

108 | *
${mvc.uri('MyController#myMethod')}
109 | * 110 | * @param identifier for the controller method. 111 | * @return the constructed URI including context- and application path. 112 | */ 113 | URI uri(String identifier); 114 | 115 | /** 116 | *

Creates an URI to be matched by a controller method. This is aimed primarily 117 | * for use in view rendering technologies to avoid duplicating the values of the 118 | * {@link jakarta.ws.rs.Path} annotations.

119 | * 120 | *

The controller method can either be identified by the simple name of the controller class 121 | * and the method name separated by '#' (MyController#myMethod) or by the value 122 | * of the {@link UriRef} annotation.

123 | * 124 | *

The created URI includes context- and application path.

125 | * 126 | *

Any {@link jakarta.ws.rs.PathParam}, {@link jakarta.ws.rs.QueryParam} 127 | * and {@link jakarta.ws.rs.MatrixParam} which could apply for given target 128 | * method will be replaced if a matching key is found in the supplied Map. 129 | * Please note that the map must contain values for all path parameters 130 | * as they are required for building the URI. All other parameters are optional.

131 | * 132 | *

For example in Jakarta Server Pages:

133 | *
${mvc.uri('MyController#myMethod', {'foo': 'bar', 'id': 42})}
134 | * 135 | * @param identifier for the controller method. 136 | * @param params a map of path-, query- and matrix parameters. 137 | * @return the constructed URI including context- and application path. 138 | * @throws IllegalArgumentException if there are any URI template parameters without a supplied value, or if a value is {@code null}. 139 | */ 140 | URI uri(String identifier, Map params); 141 | 142 | /** 143 | *

Returns a {@link UriBuilder} for building URIs to be matched 144 | * by a controller method. This is aimed primarily for use in Java classes.

145 | * 146 | *

The controller method can either be identified by the simple name of the controller class 147 | * and the method name separated by '#' (MyController#myMethod) or by the value 148 | * of the {@link UriRef} annotation.

149 | * 150 | * @param identifier for the controller method. 151 | * @return a reference to a {@link UriBuilder}. 152 | */ 153 | UriBuilder uriBuilder(String identifier); 154 | 155 | } 156 | -------------------------------------------------------------------------------- /api/src/main/java/jakarta/mvc/RedirectScoped.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014-2015 Oracle and/or its affiliates. All rights reserved. 3 | * Copyright (c) 2016-2018 JSR 371 expert group and contributors 4 | * Copyright (c) 2020 Contributors to the Eclipse Foundation 5 | * 6 | * This program and the accompanying materials are made available under the 7 | * terms of the Eclipse Public License v. 2.0, which is available at 8 | * http://www.eclipse.org/legal/epl-2.0. 9 | * 10 | * This Source Code may also be made available under the following Secondary 11 | * Licenses when the conditions for such availability set forth in the 12 | * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, 13 | * version 2 with the GNU Classpath Exception, which is available at 14 | * https://www.gnu.org/software/classpath/license.html. 15 | * 16 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 17 | */ 18 | package jakarta.mvc; 19 | 20 | import jakarta.enterprise.context.NormalScope; 21 | import java.lang.annotation.Documented; 22 | import java.lang.annotation.ElementType; 23 | import java.lang.annotation.Inherited; 24 | import java.lang.annotation.Retention; 25 | import java.lang.annotation.RetentionPolicy; 26 | import java.lang.annotation.Target; 27 | 28 | /** 29 | * An annotation that defines a new Jakarta Contexts and Dependency Injection-based 30 | * scope supported by the Jakarta MVC API. 31 | * Beans in this scope are automatically created and destroyed by correlating 32 | * a redirect and the request that follows. The exact mechanism by which requests 33 | * are correlated is implementation dependent, but popular techniques include URL 34 | * rewrites and cookies. 35 | * 36 | * @author Manfred Riem (manfred.riem at oracle.com) 37 | * @author Ivar Grimstad 38 | */ 39 | @NormalScope(passivating = true) 40 | @Inherited 41 | @Documented 42 | @Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD}) 43 | @Retention(value = RetentionPolicy.RUNTIME) 44 | public @interface RedirectScoped { 45 | } 46 | -------------------------------------------------------------------------------- /api/src/main/java/jakarta/mvc/UriRef.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2018 JSR 371 expert group and contributors 3 | * Copyright (c) 2020 Contributors to the Eclipse Foundation 4 | * 5 | * This program and the accompanying materials are made available under the 6 | * terms of the Eclipse Public License v. 2.0, which is available at 7 | * http://www.eclipse.org/legal/epl-2.0. 8 | * 9 | * This Source Code may also be made available under the following Secondary 10 | * Licenses when the conditions for such availability set forth in the 11 | * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, 12 | * version 2 with the GNU Classpath Exception, which is available at 13 | * https://www.gnu.org/software/classpath/license.html. 14 | * 15 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 16 | */ 17 | package jakarta.mvc; 18 | 19 | import java.lang.annotation.ElementType; 20 | import java.lang.annotation.Retention; 21 | import java.lang.annotation.RetentionPolicy; 22 | import java.lang.annotation.Target; 23 | 24 | /** 25 | *

Defines a symbolic name for a controller method to be referenced by one of the 26 | * {@link MvcContext#uri} methods.

27 | * 28 | *

The same value of @UriRef can only be used multiple times on different methods 29 | * if these methods are using the same URI-template with different HTTP verbs.

30 | * 31 | * @author Florian Hirsch 32 | * @see MvcContext#uri 33 | * @since 1.0 34 | */ 35 | @Target(ElementType.METHOD) 36 | @Retention(RetentionPolicy.RUNTIME) 37 | public @interface UriRef { 38 | 39 | /** 40 | * The symbolic name 41 | * @return symbolic reference 42 | */ 43 | String value(); 44 | 45 | } 46 | -------------------------------------------------------------------------------- /api/src/main/java/jakarta/mvc/View.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. 3 | * Copyright (c) 2016-2018 JSR 371 expert group and contributors 4 | * Copyright (c) 2020 Contributors to the Eclipse Foundation 5 | * 6 | * This program and the accompanying materials are made available under the 7 | * terms of the Eclipse Public License v. 2.0, which is available at 8 | * http://www.eclipse.org/legal/epl-2.0. 9 | * 10 | * This Source Code may also be made available under the following Secondary 11 | * Licenses when the conditions for such availability set forth in the 12 | * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, 13 | * version 2 with the GNU Classpath Exception, which is available at 14 | * https://www.gnu.org/software/classpath/license.html. 15 | * 16 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 17 | */ 18 | package jakarta.mvc; 19 | 20 | import java.lang.annotation.Documented; 21 | import java.lang.annotation.Inherited; 22 | import java.lang.annotation.Retention; 23 | import java.lang.annotation.Target; 24 | 25 | import static java.lang.annotation.ElementType.METHOD; 26 | import static java.lang.annotation.ElementType.TYPE; 27 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 28 | 29 | /** 30 | *

Declares a view for a controller that returns void, or for a controller 31 | * that may return {@code null} and wants to declare a default value. 32 | * If declared at the type level, it applies to all controller methods in the type and 33 | * can be overridden by another instance of this annotation at the method level. 34 | * 35 | *

Example: 36 | *


37 |  *     @Controller
38 |  *     @View("hello.jsp")
39 |  *     public void sayHello() {
40 |  *         ...
41 |  *     }
42 |  * 
43 | * 44 | * @author Santiago Pericas-Geertsen 45 | * @see Controller 46 | * @since 1.0 47 | */ 48 | @Target({METHOD, TYPE}) 49 | @Retention(RUNTIME) 50 | @Documented 51 | @Inherited 52 | public @interface View { 53 | 54 | /** 55 | * The name of the view 56 | * 57 | * @return view name 58 | */ 59 | String value(); 60 | 61 | } 62 | 63 | -------------------------------------------------------------------------------- /api/src/main/java/jakarta/mvc/binding/BindingError.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. 3 | * Copyright (c) 2016-2018 JSR 371 expert group and contributors 4 | * Copyright (c) 2020 Contributors to the Eclipse Foundation 5 | * 6 | * This program and the accompanying materials are made available under the 7 | * terms of the Eclipse Public License v. 2.0, which is available at 8 | * http://www.eclipse.org/legal/epl-2.0. 9 | * 10 | * This Source Code may also be made available under the following Secondary 11 | * Licenses when the conditions for such availability set forth in the 12 | * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, 13 | * version 2 with the GNU Classpath Exception, which is available at 14 | * https://www.gnu.org/software/classpath/license.html. 15 | * 16 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 17 | */ 18 | package jakarta.mvc.binding; 19 | 20 | /** 21 | *

Represents a single error that occurred while binding a parameter to a controller 22 | * method argument or controller field using a binding annotation like 23 | * {@link jakarta.ws.rs.FormParam}.

24 | * 25 | * @author Christian Kaltepoth 26 | * @author Ivar Grimstad 27 | * @since 1.0 28 | */ 29 | public interface BindingError extends ParamError { 30 | 31 | /** 32 | * Provides access to the raw submitted value of the parameter which caused the 33 | * binding to fail. 34 | * 35 | * @return The raw value submitted for the parameter 36 | */ 37 | String getSubmittedValue(); 38 | 39 | } 40 | -------------------------------------------------------------------------------- /api/src/main/java/jakarta/mvc/binding/BindingResult.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. 3 | * Copyright (c) 2016-2018 JSR 371 expert group and contributors 4 | * Copyright (c) 2020 Contributors to the Eclipse Foundation 5 | * 6 | * This program and the accompanying materials are made available under the 7 | * terms of the Eclipse Public License v. 2.0, which is available at 8 | * http://www.eclipse.org/legal/epl-2.0. 9 | * 10 | * This Source Code may also be made available under the following Secondary 11 | * Licenses when the conditions for such availability set forth in the 12 | * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, 13 | * version 2 with the GNU Classpath Exception, which is available at 14 | * https://www.gnu.org/software/classpath/license.html. 15 | * 16 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 17 | */ 18 | package jakarta.mvc.binding; 19 | 20 | import java.util.List; 21 | import java.util.Set; 22 | 23 | /** 24 | *

Describes the binding result of all controller fields and controller 25 | * method parameters which are annotated with a binding annotation like 26 | * {@link jakarta.ws.rs.FormParam}.

27 | * 28 | *

A binding can fail because of type conversion issues or in case of validation 29 | * errors. The former can for example happen if the binding annotation is placed on 30 | * a numeric type but the value cannot be converted to that type. The latter may be 31 | * caused by constraint violations detected during validation. 32 | *

33 | * 34 | *

Controller methods which declare a parameter of this type will be executed 35 | * even if the binding for fields and method parameters fails.

36 | * 37 | * @author Christian Kaltepoth 38 | * @author Ivar Grimstad 39 | * @since 1.0 40 | */ 41 | public interface BindingResult { 42 | 43 | /** 44 | * Returns true if there is at least one parameter error. 45 | * 46 | * @return true if there is at least one parameter error 47 | */ 48 | boolean isFailed(); 49 | 50 | /** 51 | * Returns an immutable list of all messages representing both binding and 52 | * validation errors. This method is a shortcut for: 53 | * 54 | *
55 |      * getAllErrors().stream().map(ParamError::getMessage).collect(Collectors.toList())
56 |      * 
57 | * 58 | * @return A list of human-readable messages 59 | */ 60 | List getAllMessages(); 61 | 62 | /** 63 | * Returns an immutable set of all binding and validation errors. 64 | * 65 | * @return All binding and validation errors. 66 | */ 67 | Set getAllErrors(); 68 | 69 | /** 70 | * Returns an immutable set of all binding and validation errors for 71 | * a specific parameter. 72 | * 73 | * @param param parameter name 74 | * @return All binding and validation errors for the parameter. 75 | */ 76 | Set getErrors(String param); 77 | 78 | } 79 | -------------------------------------------------------------------------------- /api/src/main/java/jakarta/mvc/binding/MvcBinding.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2018 JSR 371 expert group and contributors 3 | * Copyright (c) 2020 Contributors to the Eclipse Foundation 4 | * 5 | * This program and the accompanying materials are made available under the 6 | * terms of the Eclipse Public License v. 2.0, which is available at 7 | * http://www.eclipse.org/legal/epl-2.0. 8 | * 9 | * This Source Code may also be made available under the following Secondary 10 | * Licenses when the conditions for such availability set forth in the 11 | * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, 12 | * version 2 with the GNU Classpath Exception, which is available at 13 | * https://www.gnu.org/software/classpath/license.html. 14 | * 15 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 16 | */ 17 | package jakarta.mvc.binding; 18 | 19 | import java.lang.annotation.Documented; 20 | import java.lang.annotation.ElementType; 21 | import java.lang.annotation.Retention; 22 | import java.lang.annotation.RetentionPolicy; 23 | import java.lang.annotation.Target; 24 | 25 | /** 26 | * This annotation is used to enable Jakarta MVC-specific binding rules for a Jakarta RESTful Web Services parameter binding. It can 27 | * be placed on fields and method parameters together with Jakarta RESTful Web Services binding annotations such as 28 | * {@link jakarta.ws.rs.FormParam}, {@link jakarta.ws.rs.QueryParam}, etc. 29 | *

30 | * MVC parameter binding differs from traditional Jakarta RESTful Web Services parameter binding in the following aspects: 31 | *

    32 | *
  • In Jakarta RESTful Web Services binding and validation errors result in an exception being thrown which can 33 | * only be handled by a corresponding exception mapper. This usually doesn't make sense for web 34 | * applications, because errors must be processed by the controller, so they can be 35 | * displayed on the resulting HTML page. In case of Jakarta MVC bindings such errors don't prevent the controller 36 | * from being invoked and are instead made available via the injectable {@link BindingResult} class.
  • 37 | *
  • Jakarta RESTful Web Services parameter type conversion isn't locale-aware. The standard Jakarta RESTful Web Services converters 38 | * always use a fixed locale to parse numbers and dates. In MVC applications users typically 39 | * enter data into forms in their native locale. Therefore, Jakarta MVC bindings perform data type 40 | * conversion by respecting the request locale resolved via {@link jakarta.mvc.locale.LocaleResolver}.
  • 41 | *
42 | * 43 | * @author Christian Kaltepoth 44 | * @author Ivar Grimstad 45 | * @see BindingResult 46 | * @see jakarta.mvc.locale.LocaleResolver 47 | * @since 1.0 48 | */ 49 | @Retention(RetentionPolicy.RUNTIME) 50 | @Target({ElementType.PARAMETER, ElementType.METHOD, ElementType.FIELD}) 51 | @Documented 52 | public @interface MvcBinding {} 53 | 54 | -------------------------------------------------------------------------------- /api/src/main/java/jakarta/mvc/binding/ParamError.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 JSR 371 expert group and contributors 3 | * Copyright (c) 2020 Contributors to the Eclipse Foundation 4 | * 5 | * This program and the accompanying materials are made available under the 6 | * terms of the Eclipse Public License v. 2.0, which is available at 7 | * http://www.eclipse.org/legal/epl-2.0. 8 | * 9 | * This Source Code may also be made available under the following Secondary 10 | * Licenses when the conditions for such availability set forth in the 11 | * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, 12 | * version 2 with the GNU Classpath Exception, which is available at 13 | * https://www.gnu.org/software/classpath/license.html. 14 | * 15 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 16 | */ 17 | package jakarta.mvc.binding; 18 | 19 | /** 20 | * Base interface for errors related to parameter data binding 21 | * 22 | * @author Christian Kaltepoth 23 | * @author Ivar Grimstad 24 | * @since 1.0 25 | */ 26 | public interface ParamError { 27 | 28 | /** 29 | * Returns a human-readable error message for this error. 30 | * 31 | * @return The human-readable error message 32 | */ 33 | String getMessage(); 34 | 35 | /** 36 | * The parameter name of the value that caused the error. This is usually 37 | * the name specified in the binding annotation (i.e. {@link jakarta.ws.rs.FormParam}). 38 | * 39 | * @return The name of the parameter which caused the error 40 | */ 41 | String getParamName(); 42 | 43 | } 44 | -------------------------------------------------------------------------------- /api/src/main/java/jakarta/mvc/binding/ValidationError.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2018 JSR 371 expert group and contributors 3 | * Copyright (c) 2020 Contributors to the Eclipse Foundation 4 | * 5 | * This program and the accompanying materials are made available under the 6 | * terms of the Eclipse Public License v. 2.0, which is available at 7 | * http://www.eclipse.org/legal/epl-2.0. 8 | * 9 | * This Source Code may also be made available under the following Secondary 10 | * Licenses when the conditions for such availability set forth in the 11 | * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, 12 | * version 2 with the GNU Classpath Exception, which is available at 13 | * https://www.gnu.org/software/classpath/license.html. 14 | * 15 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 16 | */ 17 | package jakarta.mvc.binding; 18 | 19 | import jakarta.validation.ConstraintViolation; 20 | 21 | /** 22 | *

Represents a single validation error detected for a parameter. A validation error always 23 | * corresponds to exactly one {@link ConstraintViolation}.

24 | * 25 | * @author Christian Kaltepoth 26 | * @author Ivar Grimstad 27 | * @since 1.0 28 | */ 29 | public interface ValidationError extends ParamError { 30 | 31 | /** 32 | * The underlying {@link ConstraintViolation} detected for the parameter. 33 | * 34 | * @return The violation detected for the parameter 35 | */ 36 | ConstraintViolation getViolation(); 37 | 38 | } 39 | -------------------------------------------------------------------------------- /api/src/main/java/jakarta/mvc/binding/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. 3 | * Copyright (c) 2016-2017 JSR 371 expert group and contributors 4 | * Copyright (c) 2020 Contributors to the Eclipse Foundation 5 | * 6 | * This program and the accompanying materials are made available under the 7 | * terms of the Eclipse Public License v. 2.0, which is available at 8 | * http://www.eclipse.org/legal/epl-2.0. 9 | * 10 | * This Source Code may also be made available under the following Secondary 11 | * Licenses when the conditions for such availability set forth in the 12 | * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, 13 | * version 2 with the GNU Classpath Exception, which is available at 14 | * https://www.gnu.org/software/classpath/license.html. 15 | * 16 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 17 | */ 18 | /** 19 | * Types related to the handling of data binding and validation. 20 | * 21 | * @version 1.0 22 | */ 23 | package jakarta.mvc.binding; -------------------------------------------------------------------------------- /api/src/main/java/jakarta/mvc/engine/ViewEngine.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. 3 | * Copyright (c) 2016-2018 JSR 371 expert group and contributors 4 | * Copyright (c) 2020 Contributors to the Eclipse Foundation 5 | * 6 | * This program and the accompanying materials are made available under the 7 | * terms of the Eclipse Public License v. 2.0, which is available at 8 | * http://www.eclipse.org/legal/epl-2.0. 9 | * 10 | * This Source Code may also be made available under the following Secondary 11 | * Licenses when the conditions for such availability set forth in the 12 | * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, 13 | * version 2 with the GNU Classpath Exception, which is available at 14 | * https://www.gnu.org/software/classpath/license.html. 15 | * 16 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 17 | */ 18 | package jakarta.mvc.engine; 19 | 20 | /** 21 | *

View engines are responsible for processing views and are discovered 22 | * using Jakarta Contexts and Dependency Injection. Implementations must look up all instances of this interface, 23 | * and process a view as follows: 24 | *

    25 | *
  1. Gather the set of candidate view engines by calling {@link #supports(String)} 26 | * and discarding engines that return false.
  2. 27 | *
  3. Sort the resulting set of candidates using priorities. View engines 28 | * can be decorated with {@link jakarta.annotation.Priority} to indicate 29 | * their priority; otherwise the priority is assumed to be {@link ViewEngine#PRIORITY_APPLICATION}.
  4. 30 | *
  5. If more than one candidate is available, choose one in an 31 | * implementation-defined manner.
  6. 32 | *
  7. Fire a {@link jakarta.mvc.event.BeforeProcessViewEvent} event.
  8. 33 | *
  9. Call method {@link #processView(ViewEngineContext)} to process view.
  10. 34 | *
  11. Fire a {@link jakarta.mvc.event.AfterProcessViewEvent} event.
  12. 35 | *
36 | *

The default view engine for Jakarta Server Pages uses file extensions to determine 37 | * support. Namely, the default Jakarta Server Pages view engine supports views with extensions jsp 38 | * and jspx.

39 | * 40 | * @author Santiago Pericas-Geertsen 41 | * @author Ivar Grimstad 42 | * @see jakarta.annotation.Priority 43 | * @see jakarta.mvc.event.BeforeProcessViewEvent 44 | * @since 1.0 45 | */ 46 | @SuppressWarnings("unused") 47 | public interface ViewEngine { 48 | 49 | /** 50 | * Name of property that can be set to override the root location for views in an archive. 51 | * 52 | * @see jakarta.ws.rs.core.Application#getProperties() 53 | */ 54 | String VIEW_FOLDER = "jakarta.mvc.engine.ViewEngine.viewFolder"; 55 | 56 | /** 57 | * The default view file extension that is used to fetch templates. For example, if this setting is set to .jsp, 58 | * instead of returning index.jsp only index is required. 59 | * 60 | * @see jakarta.ws.rs.core.Application#getProperties() 61 | */ 62 | String VIEW_EXTENSION = "jakarta.mvc.engine.ViewEngine.defaultViewFileExtension"; 63 | 64 | /** 65 | * Default value for property {@link #VIEW_FOLDER}. 66 | */ 67 | String DEFAULT_VIEW_FOLDER = "/WEB-INF/views/"; 68 | 69 | /** 70 | * Priority for all built-in view engines. 71 | */ 72 | int PRIORITY_BUILTIN = 1000; 73 | 74 | /** 75 | * Recommended priority for all view engines provided by frameworks built 76 | * on top of MVC implementations. 77 | */ 78 | int PRIORITY_FRAMEWORK = 2000; 79 | 80 | /** 81 | * Recommended priority for all application-provided view engines (default). 82 | */ 83 | int PRIORITY_APPLICATION = 3000; 84 | 85 | /** 86 | * Returns true if this engine can process the view or false 87 | * otherwise. 88 | * 89 | * @param view the view. 90 | * @return outcome of supports test. 91 | */ 92 | boolean supports(String view); 93 | 94 | /** 95 | *

Process a view given a {@link jakarta.mvc.engine.ViewEngineContext}. Processing 96 | * a view involves merging the model and template data and writing 97 | * the result to an output stream.

98 | * 99 | *

Following the Jakarta EE threading model, the underlying view engine implementation 100 | * must support this method being called by different threads. Any resources allocated 101 | * during view processing must be released before the method returns.

102 | * 103 | * @param context the context needed for processing. 104 | * @throws ViewEngineException if an error occurs during processing. 105 | */ 106 | void processView(ViewEngineContext context) throws ViewEngineException; 107 | } 108 | -------------------------------------------------------------------------------- /api/src/main/java/jakarta/mvc/engine/ViewEngineContext.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. 3 | * Copyright (c) 2016-2018 JSR 371 expert group and contributors 4 | * Copyright (c) 2020 Contributors to the Eclipse Foundation 5 | * 6 | * This program and the accompanying materials are made available under the 7 | * terms of the Eclipse Public License v. 2.0, which is available at 8 | * http://www.eclipse.org/legal/epl-2.0. 9 | * 10 | * This Source Code may also be made available under the following Secondary 11 | * Licenses when the conditions for such availability set forth in the 12 | * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, 13 | * version 2 with the GNU Classpath Exception, which is available at 14 | * https://www.gnu.org/software/classpath/license.html. 15 | * 16 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 17 | */ 18 | package jakarta.mvc.engine; 19 | 20 | import jakarta.mvc.Models; 21 | import jakarta.ws.rs.container.ResourceInfo; 22 | import jakarta.ws.rs.core.Configuration; 23 | import jakarta.ws.rs.core.MediaType; 24 | import jakarta.ws.rs.core.MultivaluedMap; 25 | import jakarta.ws.rs.core.UriInfo; 26 | import java.io.OutputStream; 27 | import java.util.Locale; 28 | 29 | /** 30 | *

Contextual data used by a {@link jakarta.mvc.engine.ViewEngine} to process a view. 31 | * This includes the view name, the models instance and the request and response 32 | * objects from the container, among other data.

33 | * 34 | * @author Santiago Pericas-Geertsen 35 | * @author Christian Kaltepoth 36 | * @author Ivar Grimstad 37 | * @see jakarta.mvc.engine.ViewEngine 38 | * @since 1.0 39 | */ 40 | public interface ViewEngineContext { 41 | 42 | /** 43 | * Returns the view. 44 | * 45 | * @return the view. 46 | */ 47 | String getView(); 48 | 49 | /** 50 | * Returns the models instance needed to process the view. 51 | * 52 | * @return the models instance. 53 | */ 54 | Models getModels(); 55 | 56 | /** 57 | * Returns the request locale resolved for the current request. 58 | * 59 | * @return the request locale 60 | */ 61 | Locale getLocale(); 62 | 63 | /** 64 | * Returns the HTTP request object from the container. The type of the request object 65 | * depends on the environment. In a servlet environment you can use this method to get 66 | * the HttpServletRequest object. 67 | * 68 | * @param type The expected type of the HTTP request object. 69 | * @param The expected type of the HTTP request object 70 | * @return HTTP request object. 71 | */ 72 | T getRequest(Class type); 73 | 74 | /** 75 | *

Returns the HTTP response object from the container. The type of the response object 76 | * depends on the environment. In a servlet environment you can use this method to get 77 | * the HttpServletResponse object.

78 | * 79 | *

Please note that you should generally prefer using {@link #getOutputStream()} 80 | * and {@link #getResponseHeaders()} to write the result of processing the view, because 81 | * these methods are guaranteed to work in all supported environments.

82 | * 83 | * @param type The expected type of the HTTP response object. 84 | * @param The expected type of the HTTP request object 85 | * @return HTTP response object. 86 | */ 87 | T getResponse(Class type); 88 | 89 | /** 90 | * Get the mutable response headers multivalued map. This map can be modified 91 | * to change the HTTP response headers. Please note that changing the map will only have 92 | * an effect on the headers if modifications are performed before data is written 93 | * to the output stream obtained from {@link #getOutputStream()}. 94 | * 95 | * @return mutable multivalued map of response headers. 96 | */ 97 | MultivaluedMap getResponseHeaders(); 98 | 99 | /** 100 | * The output stream which should be used to write the result of processing a view. 101 | * 102 | * @return The output stream 103 | */ 104 | OutputStream getOutputStream(); 105 | 106 | /** 107 | * The media type to use for the response. Please note that {@link ViewEngine} 108 | * implementations should respect the charset parameter of the media type when 109 | * writing data to the output stream obtained from {@link #getOutputStream()}. 110 | * 111 | * @return The media type 112 | */ 113 | MediaType getMediaType(); 114 | 115 | /** 116 | * Returns the {@link jakarta.ws.rs.core.UriInfo} instance containing information 117 | * about the current request URI. 118 | * 119 | * @return the URI info for the current request. 120 | * @see jakarta.ws.rs.core.UriInfo 121 | */ 122 | UriInfo getUriInfo(); 123 | 124 | /** 125 | * Returns the {@link jakarta.ws.rs.container.ResourceInfo} instance containing 126 | * information about the controller method matched in the current request. 127 | * 128 | * @return the resource info for the current request. 129 | * @see jakarta.ws.rs.container.ResourceInfo 130 | */ 131 | ResourceInfo getResourceInfo(); 132 | 133 | /** 134 | * Returns the application's configuration. The configuration provides access 135 | * to properties such as {@link jakarta.mvc.engine.ViewEngine#VIEW_FOLDER}, which 136 | * view engines must use to locate views. 137 | * 138 | * @return application's configuration. 139 | * @see jakarta.ws.rs.core.Configuration 140 | */ 141 | Configuration getConfiguration(); 142 | } 143 | -------------------------------------------------------------------------------- /api/src/main/java/jakarta/mvc/engine/ViewEngineException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. 3 | * Copyright (c) 2016-2017 JSR 371 expert group and contributors 4 | * Copyright (c) 2020 Contributors to the Eclipse Foundation 5 | * 6 | * This program and the accompanying materials are made available under the 7 | * terms of the Eclipse Public License v. 2.0, which is available at 8 | * http://www.eclipse.org/legal/epl-2.0. 9 | * 10 | * This Source Code may also be made available under the following Secondary 11 | * Licenses when the conditions for such availability set forth in the 12 | * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, 13 | * version 2 with the GNU Classpath Exception, which is available at 14 | * https://www.gnu.org/software/classpath/license.html. 15 | * 16 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 17 | */ 18 | package jakarta.mvc.engine; 19 | 20 | /** 21 | *

Exception thrown by {@link jakarta.mvc.engine.ViewEngine#processView(ViewEngineContext)} 22 | * when unable to process a view.

23 | * 24 | * @author Santiago Pericas-Geertsen 25 | * @see Exception#getMessage() 26 | * @see Exception#getCause() 27 | * @since 1.0 28 | */ 29 | public class ViewEngineException extends Exception { 30 | 31 | private static final long serialVersionUID = -429507729780110056L; 32 | 33 | /** 34 | * Construct an instance using a message. 35 | * 36 | * @param message the message. 37 | */ 38 | public ViewEngineException(String message) { 39 | super(message); 40 | } 41 | 42 | /** 43 | * Construct an instance using a message and a cause. 44 | * 45 | * @param message the message. 46 | * @param cause the underlying cause. 47 | */ 48 | public ViewEngineException(String message, Throwable cause) { 49 | super(message, cause); 50 | } 51 | 52 | /** 53 | * Construct an instance using a cause. 54 | * 55 | * @param cause the underlying cause. 56 | */ 57 | public ViewEngineException(Throwable cause) { 58 | super(cause); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /api/src/main/java/jakarta/mvc/engine/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. 3 | * Copyright (c) 2017 JSR 371 expert group and contributors 4 | * Copyright (c) 2020 Contributors to the Eclipse Foundation 5 | * 6 | * This program and the accompanying materials are made available under the 7 | * terms of the Eclipse Public License v. 2.0, which is available at 8 | * http://www.eclipse.org/legal/epl-2.0. 9 | * 10 | * This Source Code may also be made available under the following Secondary 11 | * Licenses when the conditions for such availability set forth in the 12 | * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, 13 | * version 2 with the GNU Classpath Exception, which is available at 14 | * https://www.gnu.org/software/classpath/license.html. 15 | * 16 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 17 | */ 18 | /** 19 | * The view engine SPI. 20 | * 21 | * @version 1.0 22 | */ 23 | package jakarta.mvc.engine; -------------------------------------------------------------------------------- /api/src/main/java/jakarta/mvc/event/AfterControllerEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. 3 | * Copyright (c) 2016-2018 JSR 371 expert group and contributors 4 | * Copyright (c) 2020 Contributors to the Eclipse Foundation 5 | * 6 | * This program and the accompanying materials are made available under the 7 | * terms of the Eclipse Public License v. 2.0, which is available at 8 | * http://www.eclipse.org/legal/epl-2.0. 9 | * 10 | * This Source Code may also be made available under the following Secondary 11 | * Licenses when the conditions for such availability set forth in the 12 | * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, 13 | * version 2 with the GNU Classpath Exception, which is available at 14 | * https://www.gnu.org/software/classpath/license.html. 15 | * 16 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 17 | */ 18 | package jakarta.mvc.event; 19 | 20 | import jakarta.ws.rs.container.ResourceInfo; 21 | import jakarta.ws.rs.core.UriInfo; 22 | 23 | /** 24 | *

Event fired after a controller method returns. This event is always fired, 25 | * even if the controller methods fails with an exception. Must be fired after 26 | * {@link jakarta.mvc.event.BeforeControllerEvent}.

27 | * 28 | *

For example: 29 | *

    public class EventObserver {
30 |  *         public void afterControllerEvent(@Observes AfterControllerEvent e) {
31 |  *            ...
32 |  *        }
33 |  *    }
34 | * 35 | * @author Santiago Pericas-Geertsen 36 | * @author Christian Kaltepoth 37 | * @author Ivar Grimstad 38 | * @see jakarta.enterprise.event.Observes 39 | * @since 1.0 40 | */ 41 | public interface AfterControllerEvent extends MvcEvent { 42 | 43 | /** 44 | * Access to the current request URI information. 45 | * 46 | * @return URI info. 47 | * @see jakarta.ws.rs.core.UriInfo 48 | */ 49 | UriInfo getUriInfo(); 50 | 51 | /** 52 | * Access to the current request controller information. 53 | * 54 | * @return resources info. 55 | * @see jakarta.ws.rs.container.ResourceInfo 56 | */ 57 | ResourceInfo getResourceInfo(); 58 | } 59 | -------------------------------------------------------------------------------- /api/src/main/java/jakarta/mvc/event/AfterProcessViewEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. 3 | * Copyright (c) 2016-2018 JSR 371 expert group and contributors 4 | * Copyright (c) 2020 Contributors to the Eclipse Foundation 5 | * 6 | * This program and the accompanying materials are made available under the 7 | * terms of the Eclipse Public License v. 2.0, which is available at 8 | * http://www.eclipse.org/legal/epl-2.0. 9 | * 10 | * This Source Code may also be made available under the following Secondary 11 | * Licenses when the conditions for such availability set forth in the 12 | * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, 13 | * version 2 with the GNU Classpath Exception, which is available at 14 | * https://www.gnu.org/software/classpath/license.html. 15 | * 16 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 17 | */ 18 | package jakarta.mvc.event; 19 | 20 | import jakarta.mvc.engine.ViewEngine; 21 | 22 | /** 23 | *

Event fired after the view engine method 24 | * {@link jakarta.mvc.engine.ViewEngine#processView(jakarta.mvc.engine.ViewEngineContext)} 25 | * returns. This event is always fired, even if the view engine fails with an exception. 26 | * Must be fired after {@link jakarta.mvc.event.BeforeProcessViewEvent}.

27 | * 28 | *

For example: 29 | *

    public class EventObserver {
30 |  *         public void afterProcessView(@Observes AfterProcessViewEvent e) {
31 |  *            ...
32 |  *        }
33 |  *    }
34 | * 35 | * @author Santiago Pericas-Geertsen 36 | * @author Christian Kaltepoth 37 | * @author Ivar Grimstad 38 | * @see jakarta.enterprise.event.Observes 39 | * @since 1.0 40 | */ 41 | public interface AfterProcessViewEvent extends MvcEvent { 42 | 43 | /** 44 | * Returns the view being processed. 45 | * 46 | * @return the view. 47 | */ 48 | String getView(); 49 | 50 | /** 51 | * Returns the {@link jakarta.mvc.engine.ViewEngine} selected by the implementation. 52 | * 53 | * @return the view engine selected. 54 | */ 55 | Class getEngine(); 56 | } 57 | -------------------------------------------------------------------------------- /api/src/main/java/jakarta/mvc/event/BeforeControllerEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. 3 | * Copyright (c) 2016-2018 JSR 371 expert group and contributors 4 | * Copyright (c) 2020 Contributors to the Eclipse Foundation 5 | * 6 | * This program and the accompanying materials are made available under the 7 | * terms of the Eclipse Public License v. 2.0, which is available at 8 | * http://www.eclipse.org/legal/epl-2.0. 9 | * 10 | * This Source Code may also be made available under the following Secondary 11 | * Licenses when the conditions for such availability set forth in the 12 | * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, 13 | * version 2 with the GNU Classpath Exception, which is available at 14 | * https://www.gnu.org/software/classpath/license.html. 15 | * 16 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 17 | */ 18 | package jakarta.mvc.event; 19 | 20 | import jakarta.ws.rs.container.ResourceInfo; 21 | import jakarta.ws.rs.core.UriInfo; 22 | 23 | /** 24 | *

Event fired before a controller is called but after it has been matched.

25 | * 26 | *

For example: 27 | *

    public class EventObserver {
28 |  *         public void beforeControllerEvent(@Observes BeforeControllerEvent e) {
29 |  *            ...
30 |  *        }
31 |  *    }
32 | * 33 | * @author Santiago Pericas-Geertsen 34 | * @author Ivar Grimstad 35 | * @see jakarta.enterprise.event.Observes 36 | * @since 1.0 37 | */ 38 | public interface BeforeControllerEvent extends MvcEvent { 39 | 40 | /** 41 | * Access to the current request URI information. 42 | * 43 | * @return URI info. 44 | * @see jakarta.ws.rs.core.UriInfo 45 | */ 46 | UriInfo getUriInfo(); 47 | 48 | /** 49 | * Access to the current request controller information. 50 | * 51 | * @return resources info. 52 | * @see jakarta.ws.rs.container.ResourceInfo 53 | */ 54 | ResourceInfo getResourceInfo(); 55 | } 56 | -------------------------------------------------------------------------------- /api/src/main/java/jakarta/mvc/event/BeforeProcessViewEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. 3 | * Copyright (c) 2016-2018 JSR 371 expert group and contributors 4 | * Copyright (c) 2020 Contributors to the Eclipse Foundation 5 | * 6 | * This program and the accompanying materials are made available under the 7 | * terms of the Eclipse Public License v. 2.0, which is available at 8 | * http://www.eclipse.org/legal/epl-2.0. 9 | * 10 | * This Source Code may also be made available under the following Secondary 11 | * Licenses when the conditions for such availability set forth in the 12 | * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, 13 | * version 2 with the GNU Classpath Exception, which is available at 14 | * https://www.gnu.org/software/classpath/license.html. 15 | * 16 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 17 | */ 18 | package jakarta.mvc.event; 19 | 20 | import jakarta.mvc.engine.ViewEngine; 21 | 22 | /** 23 | *

Event fired after a view engine has been selected but before its 24 | * {@link jakarta.mvc.engine.ViewEngine#processView(jakarta.mvc.engine.ViewEngineContext)} 25 | * method is called. Must be fired after {@link jakarta.mvc.event.ControllerRedirectEvent}, 26 | * or if that event is not fired, after {@link jakarta.mvc.event.AfterControllerEvent}.

27 | * 28 | *

For example: 29 | *

    public class EventObserver {
30 |  *         public void beforeProcessView(@Observes BeforeProcessViewEvent e) {
31 |  *            ...
32 |  *        }
33 |  *    }
34 | * 35 | * @author Santiago Pericas-Geertsen 36 | * @author Ivar Grimstad 37 | * @see jakarta.enterprise.event.Observes 38 | * @since 1.0 39 | */ 40 | public interface BeforeProcessViewEvent extends MvcEvent { 41 | 42 | /** 43 | * Returns the view being processed. 44 | * 45 | * @return the view. 46 | */ 47 | String getView(); 48 | 49 | /** 50 | * Returns the {@link jakarta.mvc.engine.ViewEngine} selected by the implementation. 51 | * 52 | * @return the view engine selected. 53 | */ 54 | Class getEngine(); 55 | } 56 | -------------------------------------------------------------------------------- /api/src/main/java/jakarta/mvc/event/ControllerRedirectEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. 3 | * Copyright (c) 2016-2018 JSR 371 expert group and contributors 4 | * Copyright (c) 2020 Contributors to the Eclipse Foundation 5 | * 6 | * This program and the accompanying materials are made available under the 7 | * terms of the Eclipse Public License v. 2.0, which is available at 8 | * http://www.eclipse.org/legal/epl-2.0. 9 | * 10 | * This Source Code may also be made available under the following Secondary 11 | * Licenses when the conditions for such availability set forth in the 12 | * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, 13 | * version 2 with the GNU Classpath Exception, which is available at 14 | * https://www.gnu.org/software/classpath/license.html. 15 | * 16 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 17 | */ 18 | package jakarta.mvc.event; 19 | 20 | import jakarta.ws.rs.container.ResourceInfo; 21 | import jakarta.ws.rs.core.UriInfo; 22 | import java.net.URI; 23 | 24 | /** 25 | *

Event fired when a controller triggers a redirect. Only the 26 | * status codes 301 (moved permanently), 302 (found), 303 (see other) and 27 | * 307 (temporary redirect) are REQUIRED to be reported. Note that the 28 | * JAX-RS methods 29 | * {@link jakarta.ws.rs.core.Response#seeOther(java.net.URI)}} and 30 | * {@link jakarta.ws.rs.core.Response#temporaryRedirect(java.net.URI)}} 31 | * use the status codes to 303 and 307, respectively. Must be 32 | * fired after {@link jakarta.mvc.event.AfterControllerEvent}.

33 | * 34 | *

For example: 35 | *

    public class EventObserver {
36 |  *         public void onControllerRedirect(@Observes ControllerRedirectEvent e) {
37 |  *            ...
38 |  *        }
39 |  *    }
40 | * 41 | * @author Santiago Pericas-Geertsen 42 | * @author Ivar Grimstad 43 | * @see jakarta.enterprise.event.Observes 44 | * @since 1.0 45 | */ 46 | public interface ControllerRedirectEvent extends MvcEvent { 47 | 48 | /** 49 | * Access to the current request URI information. 50 | * 51 | * @return URI info. 52 | * @see jakarta.ws.rs.core.UriInfo 53 | */ 54 | UriInfo getUriInfo(); 55 | 56 | /** 57 | * Access to the current request controller information. 58 | * 59 | * @return resources info. 60 | * @see jakarta.ws.rs.container.ResourceInfo 61 | */ 62 | ResourceInfo getResourceInfo(); 63 | 64 | /** 65 | * The target of the redirection. 66 | * 67 | * @return URI of redirection. 68 | */ 69 | URI getLocation(); 70 | } 71 | -------------------------------------------------------------------------------- /api/src/main/java/jakarta/mvc/event/MvcEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. 3 | * Copyright (c) 2016-2018 JSR 371 expert group and contributors 4 | * Copyright (c) 2020 Contributors to the Eclipse Foundation 5 | * 6 | * This program and the accompanying materials are made available under the 7 | * terms of the Eclipse Public License v. 2.0, which is available at 8 | * http://www.eclipse.org/legal/epl-2.0. 9 | * 10 | * This Source Code may also be made available under the following Secondary 11 | * Licenses when the conditions for such availability set forth in the 12 | * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, 13 | * version 2 with the GNU Classpath Exception, which is available at 14 | * https://www.gnu.org/software/classpath/license.html. 15 | * 16 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 17 | */ 18 | package jakarta.mvc.event; 19 | 20 | /** 21 | *

Base type for all Jakarta MVC events. Every Jakarta MVC event type must extend this interface.

22 | * 23 | * @author Santiago Pericas-Geertsen 24 | * @since 1.0 25 | */ 26 | public interface MvcEvent { 27 | 28 | } 29 | -------------------------------------------------------------------------------- /api/src/main/java/jakarta/mvc/event/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. 3 | * Copyright (c) 2016-2018 JSR 371 expert group and contributors 4 | * Copyright (c) 2020 Contributors to the Eclipse Foundation 5 | * 6 | * This program and the accompanying materials are made available under the 7 | * terms of the Eclipse Public License v. 2.0, which is available at 8 | * http://www.eclipse.org/legal/epl-2.0. 9 | * 10 | * This Source Code may also be made available under the following Secondary 11 | * Licenses when the conditions for such availability set forth in the 12 | * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, 13 | * version 2 with the GNU Classpath Exception, which is available at 14 | * https://www.gnu.org/software/classpath/license.html. 15 | * 16 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 17 | */ 18 | /** 19 | * Jakarta Contexts and Dependency Injection events fired by implementations and observable by applications. 20 | * 21 | * @version 1.0 22 | */ 23 | package jakarta.mvc.event; -------------------------------------------------------------------------------- /api/src/main/java/jakarta/mvc/form/FormMethodOverwriter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Contributors to the Eclipse Foundation 3 | * 4 | * This program and the accompanying materials are made available under the 5 | * terms of the Eclipse Public License v. 2.0, which is available at 6 | * http://www.eclipse.org/legal/epl-2.0. 7 | * 8 | * This Source Code may also be made available under the following Secondary 9 | * Licenses when the conditions for such availability set forth in the 10 | * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, 11 | * version 2 with the GNU Classpath Exception, which is available at 12 | * https://www.gnu.org/software/classpath/license.html. 13 | * 14 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 15 | */ 16 | package jakarta.mvc.form; 17 | 18 | /** 19 | *

Form method overwriter is used to overwrite a HTML form's HTTP method to be able to use 20 | * other verbs such as {@code PATCH} or {@code DELETE}. 21 | *

22 | * 23 | * @author Tobias Erdle 24 | * @since 2.1 25 | */ 26 | public final class FormMethodOverwriter { 27 | 28 | /** 29 | * Property that can be used to enable the Form method overwrite mechanism for an application. 30 | * Values of this property must be of type {@link FormMethodOverwriter.Options}. 31 | */ 32 | public static final String FORM_METHOD_OVERWRITE = "jakarta.mvc.form.FormMethodOverwrite"; 33 | 34 | /** 35 | * Property that can be used to configure the name of the hidden form input to get the targeted HTTP method. 36 | */ 37 | public static final String HIDDEN_FIELD_NAME = "jakarta.mvc.form.HiddenFieldName"; 38 | 39 | /** 40 | * The default name of the hidden form field used to overwrite the HTTP method. 41 | */ 42 | public static final String DEFAULT_HIDDEN_FIELD_NAME = "_method"; 43 | 44 | /** 45 | * Options for property {@link FormMethodOverwriter#FORM_METHOD_OVERWRITE}. 46 | */ 47 | public enum Options { 48 | /** 49 | * Form method overwrite is not enabled. 50 | */ 51 | DISABLED, 52 | 53 | /** 54 | * Form method overwrite is enabled. Each request will be checked for potential overwrites. 55 | */ 56 | ENABLED 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /api/src/main/java/jakarta/mvc/form/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Contributors to the Eclipse Foundation 3 | * 4 | * This program and the accompanying materials are made available under the 5 | * terms of the Eclipse Public License v. 2.0, which is available at 6 | * http://www.eclipse.org/legal/epl-2.0. 7 | * 8 | * This Source Code may also be made available under the following Secondary 9 | * Licenses when the conditions for such availability set forth in the 10 | * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, 11 | * version 2 with the GNU Classpath Exception, which is available at 12 | * https://www.gnu.org/software/classpath/license.html. 13 | * 14 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 15 | */ 16 | /** 17 | * This package contains types related to HTML forms. 18 | * 19 | * @version 2.1 20 | */ 21 | package jakarta.mvc.form; 22 | -------------------------------------------------------------------------------- /api/src/main/java/jakarta/mvc/locale/LocaleResolver.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2017 JSR 371 expert group and contributors 3 | * Copyright (c) 2020 Contributors to the Eclipse Foundation 4 | * 5 | * This program and the accompanying materials are made available under the 6 | * terms of the Eclipse Public License v. 2.0, which is available at 7 | * http://www.eclipse.org/legal/epl-2.0. 8 | * 9 | * This Source Code may also be made available under the following Secondary 10 | * Licenses when the conditions for such availability set forth in the 11 | * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, 12 | * version 2 with the GNU Classpath Exception, which is available at 13 | * https://www.gnu.org/software/classpath/license.html. 14 | * 15 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 16 | */ 17 | package jakarta.mvc.locale; 18 | 19 | import jakarta.mvc.MvcContext; 20 | import java.util.Locale; 21 | 22 | /** 23 | *

Locale resolvers are used to determine the locale of the current request and are discovered 24 | * using Jakarta Contexts and Dependency Injection.

25 | * 26 | *

The Jakarta MVC implementation is required to resolve the locale for each request following this 27 | * algorithm:

28 | * 29 | *
    30 | *
  1. Gather the set of all implementations of this interface available for injection via 31 | * CDI.
  2. 32 | *
  3. Sort the set of implementations using priorities in descending order. Locale resolvers 33 | * can be decorated with {@link jakarta.annotation.Priority} to indicate their priority. If no 34 | * priority is explicitly defined, the priority is assumed to be 1000.
  4. 35 | *
  5. Call the method {@link #resolveLocale(LocaleResolverContext)}. If the resolver returns 36 | * a valid locale, use this locale as the request locale. If the resolver returns 37 | * null, proceed with the next resolver in the ordered set.
  6. 38 | *
39 | * 40 | *

Controllers, view engines and other components can access the resolved locale by calling 41 | * {@link MvcContext#getLocale()}.

42 | * 43 | *

The MVC implementation is required to provide a default locale resolver with a priority 44 | * of 0 which uses the Accept-Language request header to obtain the 45 | * locale. If resolving the locale this way isn't possible, the default resolver must return 46 | * {@link Locale#getDefault()}.

47 | * 48 | * @author Christian Kaltepoth 49 | * @author Ivar Grimstad 50 | * @see jakarta.mvc.locale.LocaleResolverContext 51 | * @see MvcContext#getLocale() 52 | * @see java.util.Locale 53 | * @since 1.0 54 | */ 55 | public interface LocaleResolver { 56 | 57 | /** 58 | *

Resolve the locale of the current request given a {@link LocaleResolverContext}.

59 | * 60 | *

If the implementation is able to resolve the locale for the request, the corresponding 61 | * locale must be returned. If the implementation cannot resolve the locale, it must return 62 | * null. In this case the resolving process will continue with the next 63 | * resolver.

64 | * 65 | * @param context the context needed for processing. 66 | * @return The resolved locale or null. 67 | */ 68 | Locale resolveLocale(LocaleResolverContext context); 69 | 70 | } 71 | -------------------------------------------------------------------------------- /api/src/main/java/jakarta/mvc/locale/LocaleResolverContext.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2017 JSR 371 expert group and contributors 3 | * Copyright (c) 2020 Contributors to the Eclipse Foundation 4 | * 5 | * This program and the accompanying materials are made available under the 6 | * terms of the Eclipse Public License v. 2.0, which is available at 7 | * http://www.eclipse.org/legal/epl-2.0. 8 | * 9 | * This Source Code may also be made available under the following Secondary 10 | * Licenses when the conditions for such availability set forth in the 11 | * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, 12 | * version 2 with the GNU Classpath Exception, which is available at 13 | * https://www.gnu.org/software/classpath/license.html. 14 | * 15 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 16 | */ 17 | package jakarta.mvc.locale; 18 | 19 | import jakarta.ws.rs.core.Configuration; 20 | import jakarta.ws.rs.core.Cookie; 21 | import jakarta.ws.rs.core.Request; 22 | import jakarta.ws.rs.core.UriInfo; 23 | import java.util.List; 24 | import java.util.Locale; 25 | 26 | /** 27 | *

Contextual data used by a {@link jakarta.mvc.locale.LocaleResolver} to resolve the request 28 | * locale.

29 | * 30 | * @author Christian Kaltepoth 31 | * @author Ivar Grimstad 32 | * @see jakarta.mvc.locale.LocaleResolver 33 | * @since 1.0 34 | */ 35 | public interface LocaleResolverContext { 36 | 37 | /** 38 | * Returns the application's configuration. 39 | * 40 | * @return application's configuration. 41 | * @see jakarta.ws.rs.core.Configuration 42 | */ 43 | Configuration getConfiguration(); 44 | 45 | /** 46 | * Get a list of languages that are acceptable for the response according to the 47 | * Accept-Language HTTP header sent by the client. 48 | * 49 | * @return a read-only list of languages ordered by their q-value. 50 | * @see Locale 51 | */ 52 | List getAcceptableLanguages(); 53 | 54 | /** 55 | * Get the Jakarta RESTful Web Services {@link Request} instance. 56 | * 57 | * @return the Jakarta RESTful Web Services {@link Request} instance. 58 | * @see Request 59 | */ 60 | Request getRequest(); 61 | 62 | /** 63 | * Get request URI information. 64 | * 65 | * @return request URI information 66 | * @see UriInfo 67 | */ 68 | UriInfo getUriInfo(); 69 | 70 | /** 71 | * Returns the cookie with the given name. 72 | * 73 | * @param name the name of the cookie 74 | * @return the cookie or null if no cookie with this name exists 75 | * @see Cookie 76 | */ 77 | Cookie getCookie(String name); 78 | 79 | /** 80 | * Get the request header as a single string value. 81 | * 82 | * @param name the name of the request header 83 | * @return the request header value. If the request header is not present then 84 | * {@code null} is returned. If the request header is present more than once then the values 85 | * of joined together and separated by a ',' character. 86 | */ 87 | String getHeaderString(String name); 88 | 89 | } 90 | -------------------------------------------------------------------------------- /api/src/main/java/jakarta/mvc/locale/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2017 JSR 371 expert group and contributors 3 | * Copyright (c) 2020 Contributors to the Eclipse Foundation 4 | * 5 | * This program and the accompanying materials are made available under the 6 | * terms of the Eclipse Public License v. 2.0, which is available at 7 | * http://www.eclipse.org/legal/epl-2.0. 8 | * 9 | * This Source Code may also be made available under the following Secondary 10 | * Licenses when the conditions for such availability set forth in the 11 | * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, 12 | * version 2 with the GNU Classpath Exception, which is available at 13 | * https://www.gnu.org/software/classpath/license.html. 14 | * 15 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 16 | */ 17 | /** 18 | * This package contains types related to the request locale. 19 | * 20 | * @version 1.0 21 | */ 22 | package jakarta.mvc.locale; -------------------------------------------------------------------------------- /api/src/main/java/jakarta/mvc/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. 3 | * Copyright (c) 2016-2017 JSR 371 expert group and contributors 4 | * Copyright (c) 2020 Contributors to the Eclipse Foundation 5 | * 6 | * This program and the accompanying materials are made available under the 7 | * terms of the Eclipse Public License v. 2.0, which is available at 8 | * http://www.eclipse.org/legal/epl-2.0. 9 | * 10 | * This Source Code may also be made available under the following Secondary 11 | * Licenses when the conditions for such availability set forth in the 12 | * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, 13 | * version 2 with the GNU Classpath Exception, which is available at 14 | * https://www.gnu.org/software/classpath/license.html. 15 | * 16 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 17 | */ 18 | /** 19 | * The root Jakarta MVC API package. 20 | * 21 | * @version 1.0 22 | */ 23 | package jakarta.mvc; -------------------------------------------------------------------------------- /api/src/main/java/jakarta/mvc/security/Csrf.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014-2015 Oracle and/or its affiliates. All rights reserved. 3 | * Copyright (c) 2016-2019 JSR 371 expert group and contributors 4 | * Copyright (c) 2020 Contributors to the Eclipse Foundation 5 | * 6 | * This program and the accompanying materials are made available under the 7 | * terms of the Eclipse Public License v. 2.0, which is available at 8 | * http://www.eclipse.org/legal/epl-2.0. 9 | * 10 | * This Source Code may also be made available under the following Secondary 11 | * Licenses when the conditions for such availability set forth in the 12 | * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, 13 | * version 2 with the GNU Classpath Exception, which is available at 14 | * https://www.gnu.org/software/classpath/license.html. 15 | * 16 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 17 | */ 18 | package jakarta.mvc.security; 19 | 20 | import jakarta.mvc.MvcContext; 21 | 22 | /** 23 | * Cross Site Request Forgery (CSRF) interface with access to the CSRF header name 24 | * and the CSRF token value. Implementations of this interface are injectable 25 | * and accessible from EL via the {@link MvcContext} class as {@code mvc.csrf}. 26 | * 27 | * @author Santiago Pericas-Geertsen 28 | * @author Christian Kaltepoth 29 | * @see CsrfProtected 30 | * @since 1.0 31 | */ 32 | public interface Csrf { 33 | 34 | /** 35 | * Property that can be used to globally enable CSRF protection for an application. 36 | * Values of this property must be of type {@link Csrf.CsrfOptions}. 37 | */ 38 | String CSRF_PROTECTION = "jakarta.mvc.security.CsrfProtection"; 39 | 40 | /** 41 | * Property that can be used to configure the name of the HTTP header used for 42 | * the CSRF token. 43 | */ 44 | String CSRF_HEADER_NAME = "jakarta.mvc.security.CsrfHeaderName"; 45 | 46 | /** 47 | * The default value for {@link #CSRF_HEADER_NAME}. 48 | */ 49 | String DEFAULT_CSRF_HEADER_NAME = "X-CSRF-TOKEN"; 50 | 51 | /** 52 | * Options for property {@link Csrf#CSRF_PROTECTION}. 53 | */ 54 | enum CsrfOptions { 55 | /** 56 | * CSRF protection not enabled. 57 | */ 58 | OFF, 59 | /** 60 | * Enabling CSRF requires use of {@link CsrfProtected} explicitly. 61 | */ 62 | EXPLICIT, 63 | /** 64 | * CSRF enabled automatically for all controllers (default). 65 | */ 66 | IMPLICIT 67 | }; 68 | 69 | /** 70 | * Returns the name of the CSRF form field or HTTP request header. This name is typically a constant. 71 | * 72 | * @return name of CSRF header. 73 | */ 74 | String getName(); 75 | 76 | /** 77 | * Returns the value of the CSRF token. 78 | * 79 | * @return value of CSRF token. 80 | */ 81 | String getToken(); 82 | } 83 | -------------------------------------------------------------------------------- /api/src/main/java/jakarta/mvc/security/CsrfProtected.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014-2015 Oracle and/or its affiliates. All rights reserved. 3 | * Copyright (c) 2016-2018 JSR 371 expert group and contributors 4 | * Copyright (c) 2020 Contributors to the Eclipse Foundation 5 | * 6 | * This program and the accompanying materials are made available under the 7 | * terms of the Eclipse Public License v. 2.0, which is available at 8 | * http://www.eclipse.org/legal/epl-2.0. 9 | * 10 | * This Source Code may also be made available under the following Secondary 11 | * Licenses when the conditions for such availability set forth in the 12 | * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, 13 | * version 2 with the GNU Classpath Exception, which is available at 14 | * https://www.gnu.org/software/classpath/license.html. 15 | * 16 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 17 | */ 18 | package jakarta.mvc.security; 19 | 20 | import java.lang.annotation.Documented; 21 | import java.lang.annotation.Inherited; 22 | import java.lang.annotation.Retention; 23 | import java.lang.annotation.Target; 24 | 25 | import static java.lang.annotation.ElementType.METHOD; 26 | import static java.lang.annotation.ElementType.TYPE; 27 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 28 | 29 | /** 30 | *

A controller annotation to validate a CSRF token value received 31 | * in a request whenever the property {@link jakarta.mvc.security.Csrf#CSRF_PROTECTION} 32 | * is set to {@link jakarta.mvc.security.Csrf.CsrfOptions#EXPLICIT}. If the 33 | * property {@link jakarta.mvc.security.Csrf#CSRF_PROTECTION} is set to 34 | * {@link jakarta.mvc.security.Csrf.CsrfOptions#IMPLICIT}, then the use of this 35 | * annotation is redundant. Jakarta MVC implementations are only REQUIRED to enforce CSRF 36 | * for POST controllers that consume payloads of type 37 | * {@link jakarta.ws.rs.core.MediaType#APPLICATION_FORM_URLENCODED_TYPE}, but 38 | * other HTTP methods and payloads may be optionally supported by the 39 | * underlying implementation. If declared at the type level, it applies 40 | * to all methods in the type.

41 | * 42 | * @author Santiago Pericas-Geertsen 43 | * @author Ivar Grimstad 44 | * @see jakarta.mvc.security.Csrf 45 | * @since 1.0 46 | */ 47 | @Target({METHOD, TYPE}) 48 | @Retention(RUNTIME) 49 | @Documented 50 | @Inherited 51 | public @interface CsrfProtected { 52 | } 53 | -------------------------------------------------------------------------------- /api/src/main/java/jakarta/mvc/security/CsrfValidationException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 JSR 371 expert group and contributors 3 | * Copyright (c) 2020 Contributors to the Eclipse Foundation 4 | * 5 | * This program and the accompanying materials are made available under the 6 | * terms of the Eclipse Public License v. 2.0, which is available at 7 | * http://www.eclipse.org/legal/epl-2.0. 8 | * 9 | * This Source Code may also be made available under the following Secondary 10 | * Licenses when the conditions for such availability set forth in the 11 | * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, 12 | * version 2 with the GNU Classpath Exception, which is available at 13 | * https://www.gnu.org/software/classpath/license.html. 14 | * 15 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 16 | */ 17 | package jakarta.mvc.security; 18 | 19 | /** 20 | * This exception is thrown by the MVC implementation if the CSRF token validation fails. 21 | * By default, this will result in a 403 status code sent to the client. The application 22 | * can provide a custom exception mapper for this exception type to customize this 23 | * default behavior. 24 | * 25 | * @author Christian Kaltepoth 26 | * @since 1.0 27 | */ 28 | public class CsrfValidationException extends RuntimeException { 29 | 30 | private static final long serialVersionUID = -1083828917314728056L; 31 | 32 | /** 33 | * Create a new CsrfValidationException 34 | * 35 | * @param message the detail message 36 | */ 37 | public CsrfValidationException(String message) { 38 | super(message); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /api/src/main/java/jakarta/mvc/security/Encoders.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014-2015 Oracle and/or its affiliates. All rights reserved. 3 | * Copyright (c) 2016-2019 JSR 371 expert group and contributors 4 | * Copyright (c) 2020 Contributors to the Eclipse Foundation 5 | * 6 | * This program and the accompanying materials are made available under the 7 | * terms of the Eclipse Public License v. 2.0, which is available at 8 | * http://www.eclipse.org/legal/epl-2.0. 9 | * 10 | * This Source Code may also be made available under the following Secondary 11 | * Licenses when the conditions for such availability set forth in the 12 | * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, 13 | * version 2 with the GNU Classpath Exception, which is available at 14 | * https://www.gnu.org/software/classpath/license.html. 15 | * 16 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 17 | */ 18 | package jakarta.mvc.security; 19 | 20 | import jakarta.mvc.MvcContext; 21 | 22 | /** 23 | * Interface that provides encoders to escape code in JavaScript, HTML, 24 | * etc. Encoding data is a way to prevent XSS attacks by ensuring it is not 25 | * misinterpreted as running code. Implementations of this interface are injectable 26 | * and accessible from EL via the {@link MvcContext} class as {@code mvc.encoders}. 27 | * 28 | * @author Santiago Pericas-Geertsen 29 | * @see OWASP Encoder Project 30 | * @since 1.0 31 | */ 32 | public interface Encoders { 33 | 34 | /** 35 | *

Encoding for JavaScript code in attributes or script blocks. It MUST support 36 | * encoding of (at least) the following characters:

37 | * 38 | * 39 | * 40 | * 41 | * 42 | * 43 | * 44 | * 45 | * 46 | * 47 | * 48 | * 49 | * 50 | * 51 | * 52 | * 53 | * 54 | * 55 | * 56 | *
Encoding Table
Input CharacterEncoding
U+0008 (BS)\b
U+0009 (HT)\t
U+000A (LF)\n
U+000C (FF)\f
U+000D (CR)\r
/\/
\\\
"\x22
&\x26
'\x27
U+0000-U001F\x##
57 | * 58 | * @param s string to encode. 59 | * @return encoded string. 60 | */ 61 | String js(String s); 62 | 63 | /** 64 | *

Encoding for HTML code in attributes or content. It MUST support encoding of 65 | * (at least) the following characters:

66 | * 67 | * 68 | * 69 | * 70 | * 71 | * 72 | * 73 | * 74 | * 75 | * 76 | * 77 | * 78 | * 79 | *
Encoding Table
Input CharacterEncoding
&&
<&lt;
>&gt;
"&#34;
'&#39;
80 | * 81 | * @param s string to encode. 82 | * @return encoded string. 83 | */ 84 | String html(String s); 85 | } 86 | -------------------------------------------------------------------------------- /api/src/main/java/jakarta/mvc/security/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. 3 | * Copyright (c) 2016-2018 JSR 371 expert group and contributors 4 | * Copyright (c) 2020 Contributors to the Eclipse Foundation 5 | * 6 | * This program and the accompanying materials are made available under the 7 | * terms of the Eclipse Public License v. 2.0, which is available at 8 | * http://www.eclipse.org/legal/epl-2.0. 9 | * 10 | * This Source Code may also be made available under the following Secondary 11 | * Licenses when the conditions for such availability set forth in the 12 | * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, 13 | * version 2 with the GNU Classpath Exception, which is available at 14 | * https://www.gnu.org/software/classpath/license.html. 15 | * 16 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 17 | */ 18 | /** 19 | * Types related to Jakarta MVC security features. 20 | * 21 | * @version 1.0 22 | */ 23 | package jakarta.mvc.security; -------------------------------------------------------------------------------- /api/src/main/java/module-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2022 Contributors to the Eclipse Foundation 3 | * 4 | * See the NOTICE file(s) distributed with this work for additional 5 | * information regarding copyright ownership. 6 | * 7 | * This program and the accompanying materials are made available under the 8 | * terms of the Eclipse Public License v. 2.0 which is available at 9 | * https://www.eclipse.org/legal/epl-2.0. 10 | * 11 | * This Source Code may also be made available under the following Secondary 12 | * Licenses when the conditions for such availability set forth in the Eclipse 13 | * Public License v. 2.0 are satisfied: (secondary) GPL-2.0 with 14 | * Classpath-exception-2.0 which is available at 15 | * https://openjdk.java.net/legal/gplv2+ce.html. 16 | * 17 | * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only with 18 | * Classpath-exception-2.0 19 | */ 20 | module jakarta.mvc { 21 | 22 | exports jakarta.mvc; 23 | exports jakarta.mvc.binding; 24 | exports jakarta.mvc.engine; 25 | exports jakarta.mvc.event; 26 | exports jakarta.mvc.form; 27 | exports jakarta.mvc.locale; 28 | exports jakarta.mvc.security; 29 | 30 | requires jakarta.annotation; 31 | requires jakarta.cdi; 32 | requires jakarta.validation; 33 | requires jakarta.ws.rs; 34 | } -------------------------------------------------------------------------------- /api/src/main/javadoc/doc-files/speclicense.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Eclipse Foundation Specification License - v1.1 4 | 5 | 6 | 7 |

Eclipse Foundation Specification License - v1.1

8 |

By using and/or copying this document, or the Eclipse Foundation 9 | document from which this statement is linked or incorporated by reference, you (the licensee) agree 10 | that you have read, understood, and will comply with the following 11 | terms and conditions:

12 | 13 |

Permission to copy, and distribute the contents of this document, or 14 | the Eclipse Foundation document from which this statement is linked, in 15 | any medium for any purpose and without fee or royalty is hereby 16 | granted, provided that you include the following on ALL copies of the 17 | document, or portions thereof, that you use:

18 | 19 |
    20 |
  • link or URL to the original Eclipse Foundation document.
  • 21 |
  • All existing copyright notices, or if one does not exist, a notice 22 | (hypertext is preferred, but a textual representation is permitted) 23 | of the form: "Copyright © [$date-of-document] 24 | Eclipse Foundation AISBL <<url to this license>> 25 | " 26 |
  • 27 |
28 | 29 |

Inclusion of the full text of this NOTICE must be provided. We 30 | request that authorship attribution be provided in any software, 31 | documents, or other items or products that you create pursuant to the 32 | implementation of the contents of this document, or any portion 33 | thereof.

34 | 35 |

No right to create modifications or derivatives of Eclipse Foundation 36 | documents is granted pursuant to this license, except anyone may 37 | prepare and distribute derivative works and portions of this document 38 | in software that implements the specification, in supporting materials 39 | accompanying such software, and in documentation of such software, 40 | PROVIDED that all such works include the notice below. HOWEVER, the 41 | publication of derivative works of this document for use as a technical 42 | specification is expressly prohibited.

43 | 44 |

The notice is:

45 | 46 |

"Copyright © [$date-of-document] Eclipse Foundation AISBL. This software or 47 | document includes material copied from or derived from [title and URI 48 | of the Eclipse Foundation specification document]."

49 | 50 |

Disclaimers

51 | 52 |

THIS DOCUMENT IS PROVIDED "AS IS," AND TO THE EXTENT PERMITTED BY APPLICABLE LAW THE COPYRIGHT 53 | HOLDERS AND THE ECLIPSE FOUNDATION AISBL MAKE NO REPRESENTATIONS OR 54 | WARRANTIES, EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 55 | WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, 56 | NON-INFRINGEMENT, OR TITLE; THAT THE CONTENTS OF THE DOCUMENT ARE 57 | SUITABLE FOR ANY PURPOSE; NOR THAT THE IMPLEMENTATION OF SUCH CONTENTS 58 | WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR 59 | OTHER RIGHTS.

60 | 61 |

TO THE EXTENT PERMITTED BY APPLICABLE LAW THE COPYRIGHT HOLDERS AND THE ECLIPSE FOUNDATION AISBL WILL NOT BE LIABLE 62 | FOR ANY DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT 63 | OF ANY USE OF THE DOCUMENT OR THE PERFORMANCE OR IMPLEMENTATION OF THE 64 | CONTENTS THEREOF.

65 | 66 |

The name and trademarks of the copyright holders or the Eclipse 67 | Foundation AISBL may NOT be used in advertising or publicity pertaining to 68 | this document or its contents without specific, written prior 69 | permission. Title to copyright in this document will at all times 70 | remain with copyright holders.

71 | 72 | 73 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 4.0.0 22 | jakarta.mvc 23 | jakarta.mvc-parent 24 | 3.1.0-SNAPSHOT 25 | pom 26 | Jakarta MVC Parent 27 | Jakarta MVC Parent 28 | https://www.mvc-spec.org/ 29 | 30 | 31 | org.eclipse.ee4j 32 | project 33 | 1.0.9 34 | 35 | 36 | 37 | 38 | Eclipse Foundation 39 | https://www.eclipse.org/org/foundation/ 40 | 41 | 42 | 43 | github 44 | https://github.com/jakartaeej/mvc/issues 45 | 46 | 47 | 48 | 49 | Jakarta MVC Devloper Mailing List 50 | https://accounts.eclipse.org/mailing-list/mvc-dev 51 | 52 | 53 | 54 | 55 | scm:git:ssh://git@github.com/jakartaee/mvc.git 56 | scm:git:ssh://git@github.com/jakartaee/mvc.git 57 | 58 | 59 | 60 | 61 | EPL-2.0 62 | http://www.eclipse.org/legal/epl-2.0 63 | repo 64 | 65 | 66 | GPL-2.0-with-classpath-exception 67 | https://www.gnu.org/software/classpath/license.html 68 | repo 69 | 70 | 71 | 72 | 73 | 74 | developers 75 | Jakarta MVC Team 76 | mvc-dev@eclipse.org 77 | https://projects.eclipse.org/projects/ee4j.mvc/who 78 | 79 | 80 | 81 | 82 | UTF-8 83 | 17 84 | false 85 | 3.1 86 | true 87 | Draft 88 | 89 | 90 | 91 | spec 92 | api 93 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /spec/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 4.0.0 22 | 23 | jakarta.mvc-spec 24 | pom 25 | Jakarta MVC Spec 26 | Jakarta MVC Spec 27 | https://www.mvc-spec.org/ 28 | 29 | 30 | jakarta.mvc 31 | jakarta.mvc-parent 32 | 3.1.0-SNAPSHOT 33 | ../pom.xml 34 | 35 | 36 | 37 | true 38 | MMMM dd, yyyy 39 | ${maven.build.timestamp} 40 | 41 | 42 | 43 | 44 | 45 | org.asciidoctor 46 | asciidoctor-maven-plugin 47 | 48 | 49 | org.asciidoctor 50 | asciidoctorj-pdf 51 | 2.3.19 52 | 53 | 54 | 55 | 56 | output-html 57 | generate-resources 58 | 59 | process-asciidoc 60 | 61 | 62 | highlightjs 63 | html5 64 | 65 | 66 | false 67 | ${project.version} 68 | ${spec.version} 69 | ${spec.status} 70 | ${revisiondate} 71 | 72 | ${project.build.directory}/generated-docs/index.html 73 | 74 | 75 | 76 | output-pdf 77 | generate-resources 78 | 79 | process-asciidoc 80 | 81 | 82 | pdf 83 | book 84 | slim 85 | true 86 | false 87 | 88 | 89 | ${project.version} 90 | true 91 | true 92 | false 93 | true 94 | ${spec.version} 95 | ${spec.status} 96 | ${revisiondate} 97 | 98 | 99 | 100 | 101 | output-docbook 102 | generate-resources 103 | 104 | process-asciidoc 105 | 106 | 107 | docbook 108 | article 109 | 110 | images 111 | 112 | 113 | 114 | 115 | 116 | src/main/asciidoc 117 | spec.asciidoc 118 | true 119 | 120 | 121 | 122 | org.codehaus.mojo 123 | xml-maven-plugin 124 | 1.1.0 125 | 126 | 127 | 128 | transform 129 | 130 | 131 | 132 | 133 | 134 | 135 | ${project.build.directory}/generated-docs 136 | ${project.build.directory}/tck-audit 137 | spec.xml 138 | 139 | 140 | spec.xml 141 | tck-audit.xml 142 | 143 | 144 | src/main/xsl/tck-audit.xsl 145 | 146 | 147 | currentDate 148 | ${maven.build.timestamp} 149 | 150 | 151 | revision 152 | ${project.version} 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | -------------------------------------------------------------------------------- /spec/src/main/asciidoc/chapters/annotations.asciidoc: -------------------------------------------------------------------------------- 1 | [appendix] 2 | [[annotation_table]] 3 | Summary of Annotations 4 | ---------------------- 5 | 6 | 7 | [cols="1,1,2", options="header"] 8 | |=== 9 | |Annotation 10 | |Target 11 | |Description 12 | 13 | |`Controller` 14 | |Type or method 15 | |Defines a resource method as a Jakarta MVC controller. If 16 | specified at the type level, it defines all methods in a class 17 | as controllers. 18 | 19 | |`View` 20 | |Type or method 21 | |Declares a view for a controller method that returns void. 22 | If specified at the type level, it applies to all controller 23 | methods that return void in a class. 24 | 25 | |`CsrfValid` 26 | |Method 27 | |States that a CSRF token must be validated before 28 | invoking the controller. Failure to validate the CSRF 29 | token results in a `ForbiddenException` thrown. 30 | 31 | |`RedirectScoped` 32 | |Type, method or field 33 | |Specifies that a certain bean is in redirect scope. 34 | 35 | |`UriRef` 36 | |Method 37 | |Defines a symbolic name for a controller method. 38 | 39 | |`MvcBinding` 40 | |Field, method or parameter 41 | |Declares that constraint violations will be handled by a 42 | controller through `BindingResult` instead of triggering 43 | a `ConstraintViolationException`. 44 | |=== 45 | -------------------------------------------------------------------------------- /spec/src/main/asciidoc/chapters/applications.asciidoc: -------------------------------------------------------------------------------- 1 | [[applications]] 2 | Applications 3 | ------------ 4 | 5 | This chapter introduces the notion of a Jakarta MVC application and explains how it relates to a Jakarta RESTful Web Services application. 6 | 7 | [[mvc_applications]] 8 | MVC Applications 9 | ~~~~~~~~~~~~~~~~ 10 | 11 | A Jakarta MVC application consists of one or more Jakarta RESTful Web Services resources that are annotated with `@Controller` and, just like Jakarta RESTful Web Services applications, zero or more providers. 12 | If no resources are annotated with `@Controller`, then the resulting application is a Jakarta RESTful Web Services application instead. 13 | In general, everything that applies to a Jakarta RESTful Web Services application also applies to a Jakarta MVC application. 14 | Some Jakarta MVC applications may be _hybrid_ and include a mix of Jakarta MVC controllers and Jakarta RESTful Web Services resource methods. 15 | 16 | [tck-testable tck-id-application-class]#The controllers and providers that make up an application are configured via an application-supplied subclass of `Application` from Jakarta RESTful Web Services#. 17 | An implementation MAY provide alternate mechanisms for locating controllers, but as in Jakarta RESTful Web Services, the use of an `Application` subclass is the only way to guarantee portability. 18 | 19 | [tck-testable tck-id-url-space]#The path in the application's URL space in which Jakarta MVC controllers live must be specified either using the `@ApplicationPath` annotation on the application subclass or in the web.xml as part of the `url-pattern` element#. 20 | Jakarta MVC applications SHOULD use a non-empty path or pattern: i.e., _"/"_ or _"/*"_ should be avoided whenever possible. 21 | The reason for this is that Jakarta MVC implementations often forward requests to the Servlet container, 22 | and the use of the aforementioned values may result in the unwanted processing of the forwarded request by the Jakarta RESTful Web Services servlet once again. 23 | 24 | [[mvc_context]] 25 | MVC Context 26 | ~~~~~~~~~~~ 27 | 28 | [tck-testable tck-id-injection]#MVC applications can inject an instance of `MvcContext` to access configuration, security and path-related information#. 29 | [tck-testable tck-id-request-scope]#Instances of `MvcContext` are provided by implementations and are always in request scope#. 30 | [tck-testable tck-id-el-access]#For convenience, the `MvcContext` instance is also available using the name `mvc` in EL#. 31 | 32 | As an example, a view can refer to a controller by using the base path available in the `MvcContext` object as follows: 33 | 34 | [source,html] 35 | ---- 36 | Click here 37 | ---- 38 | 39 | For more information on security see the Chapter on <>; for more information about the `MvcContext` in general, refer to the Javadoc for the type. 40 | 41 | [[providers_in_mvc]] 42 | Providers in MVC 43 | ~~~~~~~~~~~~~~~~ 44 | 45 | Implementations are free to use their own providers in order to modify the standard Jakarta RESTful Web Services pipeline for the purpose of implementing the MVC semantics. 46 | Whenever mixing implementation and application providers, care should be taken to ensure the correct execution order using priorities. 47 | 48 | [[annotation_inheritance]] 49 | Annotation Inheritance 50 | ~~~~~~~~~~~~~~~~~~~~~~ 51 | 52 | Jakarta MVC applications MUST follow the annotation inheritance rules defined by Jakarta RESTful Web Services. 53 | Namely, Jakarta MVC annotations may be used on methods of a super-class or an implemented interface. 54 | [tck-testable tck-id-inheritance]#Such annotations are inherited by a corresponding sub-class or implementation class method provided that the method does not have any Jakarta MVC or Jakarta RESTful Web Services annotations of its own#: 55 | i.e., if a subclass or implementation method has any Jakarta MVC or Jakarta RESTful Web Services annotations then all of the annotations on the superclass or interface method are ignored. 56 | 57 | [tck-testable tck-id-class-vs-iface]#Annotations on a super-class take precedence over those on an implemented interface#. 58 | The precedence over conflicting annotations defined in multiple implemented interfaces is implementation dependent. 59 | Note that, in accordance to the Jakarta RESTful Web Services rules, inheritance of class or interface annotations is not supported. 60 | 61 | [[configuration_in_mvc]] 62 | Configuration in MVC 63 | ~~~~~~~~~~~~~~~~~~~~ 64 | 65 | Implementations MUST support configuration via the native Jakarta RESTful Web Services configuration mechanism but MAY support other configuration sources. 66 | 67 | There are concrete configurations, that all Jakarta MVC the implementations are `REQUIRED` the support such as: 68 | 69 | - `ViewEngine.VIEW_FOLDER` 70 | - `Csrf.CSRF_PROTECTION` 71 | - `Csrf.CSRF_HEADER_NAME` 72 | 73 | Here's a simple example of how you can configure a custom location for the view folder other than the `/WEB-INF/views`, simply by overwriting the `getProperties` method of the subclass `Application`: 74 | 75 | [source,java,numbered] 76 | ---- 77 | @ApplicationPath("resources") 78 | public class MyApplication extends Application { 79 | 80 | @Override 81 | public Map getProperties() { 82 | final Map map = new HashMap<>(); 83 | map.put(ViewEngine.VIEW_FOLDER, "/jsp/"); 84 | return map; 85 | } 86 | } 87 | ---- 88 | -------------------------------------------------------------------------------- /spec/src/main/asciidoc/chapters/controllers.asciidoc: -------------------------------------------------------------------------------- 1 | [[mvc]] 2 | Models, Views and Controllers 3 | ----------------------------- 4 | 5 | This chapter introduces the three components that comprise the 6 |  architectural pattern: models, views and controllers. 7 | 8 | [[controllers]] 9 | Controllers 10 | ~~~~~~~~~~~ 11 | 12 | [tck-testable tck-id-ctrl-method]#A _Jakarta MVC controller_ is a Jakarta RESTful Web Services [<>] resource method decorated by `@Controller`#. 13 | [tck-testable tck-id-ctrl-class]#If this annotation is applied to a class, then all resource methods in it are regarded as controllers#. 14 | [tck-testable tck-id-ctrl-hybrid]#Using the `@Controller` annotation on a subset of methods defines a hybrid class in which certain methods are controllers and others are traditional Jakarta RESTful Web Services resource methods.# 15 | 16 | A simple hello-world controller can be defined as follows: 17 | 18 | [source,java,numbered] 19 | ---- 20 | @Path("hello") 21 | public class HelloController { 22 | 23 | @GET 24 | @Controller 25 | public String hello(){ 26 | return "hello.jsp"; 27 | } 28 | } 29 | ---- 30 | In this example, `hello` is a controller method that returns a path to a Jakarta Server Page. 31 | The semantics of controller methods differ slightly from Jakarta RESTful Web Services resource methods; 32 | [tck-testable tck-id-return-string]#in particular, a return type of `String` is interpreted as a view path rather than text content#. 33 | [tck-testable tck-id-default-mediatype]#Moreover, the default media type for a response is assumed to be `text/html`, but otherwise can be declared using `@Produces` just like in Jakarta RESTful Web Services#. 34 | 35 | A controller’s method return type determines how its result is processed: 36 | 37 | void:: [tck-testable tck-id-return-void]#A controller method that returns void is REQUIRED to be decorated by `@View`#. 38 | String:: [tck-testable tck-id-return-string2]#A string returned is interpreted as a view path#. 39 | Response:: [tck-testable tck-id-return-response]#A Jakarta RESTful Web Services `Response` whose entity’s type is one of the above#. 40 | 41 | The following class defines equivalent controller methods: 42 | 43 | 44 | [source,java,numbered] 45 | ---- 46 | @Controller 47 | @Path("hello") 48 | public class HelloController { 49 | 50 | @GET @Path("void") 51 | @View("hello.jsp") 52 | public void helloVoid() { 53 | } 54 | 55 | @GET @Path("string") 56 | public String helloString() { 57 | return "hello.jsp"; 58 | } 59 | 60 | @GET @Path("response") 61 | public Response helloResponse() { 62 | return Response.status(Response.Status.OK) 63 | .entity("hello.jsp") 64 | .build(); 65 | } 66 | } 67 | ---- 68 | 69 | Controller methods that return a non-void type may also be decorated with `@View` as a way to specify a _default_ view for the controller. 70 | [tck-testable tck-id-non-null-viewable]#The default view MUST be used only when such a non-void controller method returns a `null` value#. 71 | 72 | Note that, even though controller methods return types are restricted as explained above, Jakarta MVC does not impose any restrictions on parameter types available to controller methods: 73 | i.e., 74 | [tck-testable tck-id-inject-param-types]#all parameter types injectable in Jakarta RESTful Web Services resources are also available in controllers#. 75 | [tck-testable tck-id-inject-field-props]#Likewise, injection of fields and properties is unrestricted and fully compatible with Jakarta RESTful Web Services#. 76 | Note the restrictions explained in Section <>. 77 | 78 | Controller methods handle a HTTP request directly. Sub-resource locators as described in the Jakarta RESTful Web Services Specification [<>] are not supported by Jakarta MVC. 79 | 80 | [[controller_instances]] 81 | Controller Instances 82 | ^^^^^^^^^^^^^^^^^^^^ 83 | 84 | Unlike in Jakarta RESTful Web Services where resource classes can be native (created and managed by Jakarta RESTful Web Services), Jakarta Contexts and Dependency Injection (CDI) beans, managed beans or EJBs, 85 | [tck-testable tck-id-ctrl-cdi]#Jakarta MVC classes are REQUIRED to be CDI-managed beans only#. 86 | [tck-testable tck-id-ctrl-cdi-hybrid]#It follows that a hybrid class that contains a mix of Jakarta RESTful Web Services resource methods and Jakarta MVC controllers must also be CDI managed#. 87 | 88 | [tck-testable tck-id-request-scope-default]#Like in Jakarta RESTful Web Services, the default resource class instance lifecycle is _per-request_#. 89 | Implementations MAY support other lifecycles via CDI; the same caveats that apply to Jakarta RESTful Web Services classes in other lifecycles applied to Jakarta MVC classes. 90 | [tck-testable tck-id-scope-proxy]#In particular, CDI may need to create proxies when, for example, a per-request instance is as a member of a per-application instance#. 91 | See [<>] for more information on lifecycles and their caveats. 92 | 93 | [[response]] 94 | Response 95 | ^^^^^^^^ 96 | 97 | [tck-testable tck-id-response-header]#Returning a `Response` object gives applications full access to all the parts in a response, including the headers#. 98 | For example, an instance of `Response` can modify the HTTP status code upon encountering an error condition; 99 | Jakarta RESTful Web Services provides a fluent API to build responses as shown next. 100 | 101 | [source,java,numbered] 102 | ---- 103 | @GET 104 | @Controller 105 | public Response getById(@PathParam("id") String id) { 106 | if (id.length() == 0) { 107 | return Response.status(Response.Status.BAD_REQUEST) 108 | .entity("error.jsp") 109 | .build(); 110 | } 111 | //... 112 | } 113 | ---- 114 | 115 | Direct access to `Response` enables applications to override content types, set character encodings, set cache control policies, trigger an HTTP redirect, etc. 116 | For more information, the reader is referred to the Javadoc for the `Response` class. 117 | 118 | [[redirect]] 119 | Redirect and @RedirectScoped 120 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 121 | 122 | As stated in the previous section, [tck-testable tck-id-redirect-response]#controllers can redirect clients by returning a `Response` instance using the Jakarta RESTful Web Services API#. 123 | For example, 124 | 125 | [source,java,numbered] 126 | ---- 127 | @GET 128 | @Controller 129 | public Response redirect() { 130 | return Response.seeOther(URI.create("see/here")).build(); 131 | } 132 | ---- 133 | 134 | Given the popularity of the POST-redirect-GET pattern, 135 | [tck-testable tck-id-redirect-prefix]#Jakarta MVC implementations are REQUIRED to support view paths prefixed by `redirect:` as a more concise way to trigger a client redirect#. 136 | Using this prefix, the controller shown above can be re-written as follows: 137 | 138 | [source,java,numbered] 139 | ---- 140 | @GET 141 | @Controller 142 | public String redirect() { 143 | return "redirect:see/here"; 144 | } 145 | ---- 146 | 147 | [tck-testable tck-id-redirect-relative]#In either case, relative paths are resolved relative to the Jakarta RESTful Web Services application path# - for more information please refer to the Javadoc for the `seeOther` method. 148 | It is worth noting that redirects require client cooperation (all browsers support it, but certain CLI clients may not) and result in a completely new request-response cycle in order to access the intended controller. 149 | If a controller returns a `redirect:` view path, [tck-testable tck-id-redirect-303-302]#Jakarta MVC implementations SHOULD use the 303 (See other) status code for the redirect, but MAY prefer 302 (Found) if HTTP 1.0 compatibility is required.# 150 | 151 | Jakarta MVC applications can leverage CDI by defining beans in scopes such as request and session. 152 | [tck-testable tck-id-scope-request]#A bean in request scope is available only during the processing of a single request#, 153 | [tck-testable tck-id-scope-session]#while a bean in session scope is available throughout an entire web session which can potentially span tens or even hundreds of requests#. 154 | 155 | Sometimes it is necessary to share data between the request that returns a redirect instruction and the new request that is triggered as a result. 156 | That is, a scope that spans at most two requests and thus fits between a request and a session scope. 157 | For this purpose, the Jakarta MVC API defines a new CDI scope identified by the annotation `@RedirectScoped`. 158 | [tck-testable tck-id-scope-redirect]#CDI beans in this scope are automatically created and destroyed by correlating a redirect and the request that follows#. 159 | The exact mechanism by which requests are correlated is implementation dependent, but popular techniques include URL rewrites and cookies. 160 | 161 | Let us assume that `MyBean` is annotated by `@RedirectScoped` and given the name `mybean`, and consider the following controller: 162 | 163 | [source,java,numbered] 164 | ---- 165 | @Controller 166 | @Path("submit") 167 | public class MyController { 168 | 169 | @Inject 170 | private MyBean myBean; 171 | 172 | @POST 173 | public String post() { 174 | myBean.setValue("Redirect about to happen"); 175 | return "redirect:/submit"; 176 | } 177 | 178 | @GET 179 | public String get() { 180 | return "mybean.jsp"; // mybean.value accessed in Jakarta Server Page 181 | } 182 | } 183 | ---- 184 | 185 | The bean `myBean` is injected in the controller and available not only during the first `POST`, but also during the subsequent `GET` request, 186 | enabling _communication_ between the two interactions; the creation and destruction of the bean is under control of CDI, 187 | and thus completely transparent to the application just like any other built-in scope. 188 | 189 | [[models]] 190 | Models 191 | ~~~~~~ 192 | 193 | Jakarta MVC controllers are responsible for combining data models and views (templates) to produce web application pages. 194 | This specification supports two kinds of models: the first is based on CDI `@Named` beans, 195 | and the second on the `Models` interface which defines a map between names and objects. 196 | [tck-testable tck-id-builtin-both-models]#Jakarta MVC provides a view engine for Jakarta Server Pages out of the box, which support both types#. 197 | For all other view engines supporting the `Models` interface is mandatory, 198 | support for CDI `@Named` beans is OPTIONAL but highly RECOMMENDED. 199 | 200 | Let us now revisit our hello-world example, this time also showing how to update a model. Since we intend to show the two ways in which models 201 | can be used, we define the model as a CDI `@Named` bean in request scope even though this is only necessary for the CDI case: 202 | 203 | [source,java,numbered] 204 | ---- 205 | @Named("greeting") 206 | @RequestScoped 207 | public class Greeting { 208 | 209 | private String message; 210 | 211 | public String getMessage() { 212 | return message; 213 | } 214 | 215 | public void setMessage(String message) { 216 | this.message = message; 217 | } 218 | //... 219 | } 220 | ---- 221 | 222 | [tck-testable tck-id-cdi-model-inject]#Given that the view engine for Jakarta Server Pages supports `@Named` beans, all the controller needs to do is fill out the model and return the view#. 223 | Access to the model is straightforward using CDI injection: 224 | 225 | [source,java,numbered] 226 | ---- 227 | @Path("hello") 228 | public class HelloController { 229 | 230 | @Inject 231 | private Greeting greeting; 232 | 233 | @GET 234 | @Controller 235 | public String hello() { 236 | greeting.setMessage("Hello there!"); 237 | return "hello.jsp"; 238 | } 239 | } 240 | ---- 241 | 242 | [tck-testable tck-id-cdi-model-el]#This will allow the view to access the greeting using the EL expression# `${hello.greeting}`. 243 | 244 | Instead of using CDI beans annotated with `@Named`, [tck-testable tck-id-models-inject]#controllers can also use the `Models` map to pass data to the view#: 245 | 246 | [source,java,numbered] 247 | ---- 248 | @Path("hello") 249 | public class HelloController { 250 | 251 | @Inject 252 | private Models models; 253 | 254 | @GET 255 | @Controller 256 | public String hello() { 257 | models.put("greeting", new Greeting("Hello there!")); 258 | return "hello.jsp"; 259 | } 260 | } 261 | ---- 262 | 263 | In this example, the model is given the same name as that in the `@Named` annotation above, but using the injectable `Models` map instead. 264 | 265 | For more information about view engines see the <> section. 266 | 267 | [[views]] 268 | Views 269 | ~~~~~ 270 | 271 | A _view_, sometimes also referred to as a template, defines the structure of the output page and can refer to one or more models. 272 | It is the responsibility of a _view engine_ to process (render) a view by extracting the information in the models and producing the output page. 273 | 274 | Here is the Jakarta Server Pages page for the hello-world example: 275 | 276 | [source,html,numbered] 277 | ---- 278 | 279 | 280 | 281 | Hello 282 | 283 | 284 |

${greeting.message}

285 | 286 | 287 | ---- 288 | 289 | [tck-testable tck-id-jsp-el]#In Jakarta Server Pages, model properties are accessible via EL# [<>]. In the example above, the property `message` is read from the `greeting` model 290 | whose name was either specified in a `@Named` annotation or used as a key in the `Models` map, depending on which controller from the <> section triggered this view's processing. 291 | 292 | [[mvc_uri]] 293 | Building URIs in a View 294 | ^^^^^^^^^^^^^^^^^^^^^^^ 295 | 296 | A typical application requires to build URIs for the view, which often refer to controller methods within the same application. 297 | Typical examples for such URIs include HTML links and form actions. 298 | As building URIs manually is difficult and duplicating path patterns between the controller class and the view is error prone, 299 | Jakarta MVC provides a simple way to generate URIs using the `MvcContext` class. 300 | 301 | See the following controller as an example: 302 | 303 | [source,java,numbered] 304 | ---- 305 | @Controller 306 | @Path("books") 307 | public class BookController { 308 | 309 | @GET 310 | public String list() { 311 | // ... 312 | } 313 | 314 | @GET 315 | @Path("{id}") 316 | public String detail( @PathParam("id") long id ) { 317 | // ... 318 | } 319 | 320 | } 321 | ---- 322 | 323 | Assuming the application is deployed with the context path `/myapp` and is using the application path `/mvc`, 324 | [tck-testable tck-id-el-access]#URIs for these controller methods can be created with an EL expression# like this: 325 | 326 | [source,html] 327 | ---- 328 | 329 | ${mvc.uri('BookController#list')} 330 | 331 | 332 | ${mvc.uri('BookController#detail', { 'isbn': 1234 })} 333 | ---- 334 | 335 | [tck-testable tck-id-class-method-name]#The controller method is referenced using the simple name of the controller class and the corresponding method name separated by `pass:[#]`#. 336 | [tck-testable tck-id-param-map]#If the URI contains path, query or matrix parameters, concrete values can be supplied using a map#. 337 | Please note that the keys of this map must match the parameter name used in the `@PathParam`, `@QueryParam` or `@MatrixParam` annotation. 338 | [tck-testable tck-id-uri-encoding]#Jakarta MVC implementations MUST apply the corresponding URI encoding rules depending on whether the value is used in a query, path or matrix parameter#. 339 | 340 | The syntax used above to reference the controller method works well in most cases. 341 | However, because of the simple nature of this reference style, it will require controller class names to be unique. 342 | Also, the references may break if the controller class or method name changes as part of a refactoring. 343 | 344 | [tck-testable tck-id-uri-ref]#Therefore, applications can use the `@UriRef` annotation to define a stable and unique name for a controller method#. 345 | 346 | [source,java,numbered] 347 | ---- 348 | @Controller 349 | @Path("books") 350 | public class BookController { 351 | 352 | @GET 353 | @UriRef("book-list") 354 | public String list() { 355 | // ... 356 | } 357 | 358 | // ... 359 | 360 | } 361 | ---- 362 | 363 | Given such a controller class, the view can generate a matching URI by referencing the controller method using this reference. 364 | 365 | [source,html] 366 | ---- 367 | 368 | ${mvc.uri('book-list')} 369 | ---- 370 | 371 | Please note that this feature will work with Jakarta Server Pages and all view engines which support invoking methods on CDI model objects. 372 | -------------------------------------------------------------------------------- /spec/src/main/asciidoc/chapters/data-binding.asciidoc: -------------------------------------------------------------------------------- 1 | [[data_binding]] 2 | == Data Binding 3 | 4 | This chapter discusses data binding in the Jakarta MVC API. 5 | Data binding is based on the underlying mechanism provided by Jakarta RESTful Web Services, 6 | but with additional support for i18n requirements and for handling data binding errors within the controller. 7 | 8 | [[data_binding_intro]] 9 | === Introduction 10 | 11 | Jakarta RESTful Web Services provides support for binding request parameters (like form/query parameters) to resource fields or resource method parameters. 12 | With Jakarta RESTful Web Services, developers can also specify validation constraints using Bean Validation annotations. 13 | In this case submitted values are automatically validated against the given constraints and rejected if validation fails. 14 | 15 | Let's have a look at the following resource for an example: 16 | 17 | [source,java,numbered] 18 | ---- 19 | @Path("form") 20 | public class FormResource { 21 | 22 | @FormParam("age") 23 | @Min(18) 24 | private int age; 25 | 26 | @POST 27 | public Response handlePost() { 28 | // ... 29 | } 30 | } 31 | ---- 32 | 33 | This resource uses a `@FormParam` annotation to bind the value of the `age` form parameter to a resource field. 34 | It also uses the Bean Validation annotation `@Min` to specify a constraint on the value. 35 | 36 | When Jakarta RESTful Web Services binds the submitted data to the field, two types of errors are possible: 37 | 38 | [horizontal] 39 | Binding Error:: 40 | This type occurs if Jakarta RESTful Web Services is unable to convert the submitted value into the desired target Java type. 41 | For the resource shown above, such an error will be thrown if the user submits some arbitrary string like `foobar` which cannot be converted into an integer. 42 | Validation Error:: 43 | If the submitted value can be converted into the target type, Jakarta RESTful Web Services will validate the data according to the Bean Validation constraints. 44 | In our example submitting the value 16 would be considered invalid and therefore result in a constraint violation. 45 | 46 | Unfortunately the Jakarta RESTful Web Services data binding mechanism doesn't work well for web applications: 47 | 48 | * Both binding and validation errors will cause Jakarta RESTful Web Services to throw an exception which can only be handled by an `ExceptionMapper`. 49 | Especially Jakarta RESTful Web Services won't execute the resource method if errors were detected. 50 | This is problematic, because typically web applications will want to display the submitted form again and include a message explaining why the submission failed. 51 | Implementing such a requirement using an `ExceptionMapper` is not feasible. 52 | * The Jakarta RESTful Web Services data binding is not locale-aware. 53 | This is a problem especially for numeric data types containing fraction digits (like `double`, `float`, `BigDecimal`, etc). 54 | By default, Jakarta RESTful Web Services will always assume the US number format. 55 | 56 | [[mvc_binding_annotation]] 57 | === @MvcBinding annotation 58 | 59 | Jakarta MVC addresses the shortcomings of the standard Jakarta RESTful Web Services data binding by providing a special data binding mode optimized for web applications. 60 | [tck-testable tck-id-mvc-binding]#You can enable the Jakarta MVC specific data binding by adding a `@MvcBinding` annotation to the corresponding controller field or method parameter#. 61 | 62 | The following example shows a controller which uses a Jakarta MVC binding on a controller field. 63 | 64 | [source,java,numbered] 65 | ---- 66 | @Controller 67 | @Path("form") 68 | public class FormController { 69 | 70 | @MvcBinding 71 | @FormParam("age") 72 | @Min(18) 73 | private int age; 74 | 75 | @POST 76 | public String processForm() { 77 | // ... 78 | } 79 | } 80 | ---- 81 | 82 | Please note that usually `@MvcBinding` will be used with `@FormParam` and `@QueryParam` bindings, as they are very common in web application. 83 | However, depending on the specific use case, it may also be useful to use it with other parameter binding types. 84 | [tck-testable tck-id-all-binding-annotations]#Therefore, Jakarta MVC implementations MUST support `@MvcBinding` with all Jakarta RESTful Web Services binding annotations#. 85 | 86 | The following sections will describe the differences from traditional Jakarta RESTful Web Services data binding in detail. 87 | 88 | [[error_handling_bindingresult]] 89 | === Error handling with BindingResult 90 | 91 | As mentioned in the first section, Jakarta RESTful Web Services data binding aborts request processing for any binding or validation error. 92 | This means, that a resource method will only be invoked if all bindings were successful. 93 | 94 | Jakarta MVC bindings handle such errors in a different way. 95 | [tck-testable tck-id-invoke-controller]#A Jakarta MVC implementation is required to invoke the matched controller method even if binding or validation errors occurred#. 96 | [tck-testable tck-id-inject-binding-result]#Controllers can inject a request-scoped instance of `BindingResult` to access details about potential data binding errors#. 97 | This allows controllers to handle such errors themselves, which typically means that human-readable error messages are presented to the user when the next view is rendered. 98 | 99 | The following example shows a controller which uses `BindingResult` to handle data binding errors: 100 | 101 | [source,java,numbered] 102 | ---- 103 | @Controller 104 | @Path("form") 105 | public class FormController { 106 | 107 | @MvcBinding 108 | @FormParam("age") 109 | @Min(18) 110 | private int age; 111 | 112 | @Inject 113 | private BindingResult bindingResult; 114 | 115 | @Inject 116 | private Models models; 117 | 118 | @POST 119 | public String processForm() { 120 | 121 | if( bindingResult.isFailed() ) { 122 | models.put( "errors", bindingResult.getAllMessages() ); 123 | return "form.jsp"; 124 | } 125 | 126 | // process the form request 127 | 128 | } 129 | } 130 | ---- 131 | 132 | Please note that it is very important for a controller to actually check the `BindingResult` for errors if it uses Jakarta MVC bindings. 133 | If a binding failed and the controller processes the value without checking for errors, the bound value may be empty or contain an invalid value. 134 | 135 | Jakarta MVC implementations SHOULD log a warning if a request created data binding errors but the controller didn't invoke any method on `BindingResult`. 136 | 137 | [[converting_parameters]] 138 | === Converting to Java types 139 | 140 | The standard Jakarta RESTful Web Services data binding doesn't work very well for web application, 141 | because it isn't locale-aware and some standard HTML form elements submit data which cannot easily be bound to matching Java types 142 | (e.g. checkboxes are submitting `on` if checked and Jakarta RESTful Web Services is expecting `true` for boolean values). 143 | 144 | Jakarta MVC implementations are required to apply the following data conversion rules if a binding is annotated with `@MvcBinding`. 145 | 146 | [[numeric_types]] 147 | ==== Numeric types 148 | 149 | Implementations MUST support `int`, `long`, `float`, `double`, `BigDecimal`, `BigInteger` and corresponding wrapper types for Jakarta MVC bindings. 150 | Support for other numeric types is optional. 151 | [tck-testable tck-id-convert-numeric]#When converting values to these numeric Java types, Jakarta MVC implementations MUST use the current _request locale_ for parsing non-empty strings#. 152 | Typically, an implementation will use a `NumberFormat` instance initialized with the corresponding locale for converting the data. 153 | [tck-testable tck-id-convert-empty-numeric]#Empty strings are either converted to `null` or to the default value of the corresponding primitive data type#. 154 | Please refer to the <> section for details about the Jakarta MVC request locale. 155 | 156 | [[boolean_type]] 157 | ==== Boolean type 158 | 159 | [tck-testable tck-id-convert-boolean]#When a Jakarta MVC implementation converts a non-empty string to a `boolean` primitive type or the `java.lang.Boolean` wrapper type, it MUST convert both `true` and `on` to the boolean `true` and all others strings to `false`#. 160 | [tck-testable tck-id-convert-empty-boolean]#Empty strings are converted to `false` in case of the primitive `boolean` type and to `null` for the wrapper type#. 161 | 162 | [[other_types]] 163 | ==== Other types 164 | 165 | The conversion rules for all other Java types are implementation-specific. -------------------------------------------------------------------------------- /spec/src/main/asciidoc/chapters/engines.asciidoc: -------------------------------------------------------------------------------- 1 | [[view_engines]] 2 | View Engines 3 | ------------ 4 | 5 | This chapter introduces the notion of a view engine as the mechanism by which views are processed in Jakarta MVC. 6 | The set of available view engines is extensible via Jakarta Contexts and Dependency Injection, enabling applications as well as other frameworks to provide support for additional view languages. 7 | 8 | [[view_engines_introduction]] 9 | Introduction 10 | ~~~~~~~~~~~~ 11 | 12 | A _view engine_ is responsible for processing views. In this context, processing entails (i) locating and loading a view (ii) preparing any 13 | required models and (iii) rendering the view and writing the result back to the client. 14 | 15 | [tck-testable tck-id-jsp]#Implementations MUST provide built-in support for Jakarta Server Pages#. 16 | Additional engines may be supported via an extension mechanism based on Jakarta Contexts and Dependency Injection. 17 | [tck-testable tck-id-cdi-discovery]#Namely, any Jakarta Contexts and Dependency Injection bean that implements the `jakarta.mvc.engine.ViewEngine` interface MUST be considered as a possible target for processing by calling its `supports` method, discarding the engine if this method returns `false`#. 18 | 19 | This is the interface that must be implemented by all Jakarta MVC view engines: 20 | 21 | [source,java,numbered] 22 | ---- 23 | include::{mvc-api-source-dir}jakarta/mvc/engine/ViewEngine.java[lines=19..-1] 24 | ---- 25 | 26 | [[selection_algorithm]] 27 | Selection Algorithm 28 | ~~~~~~~~~~~~~~~~~~~ 29 | 30 | [tck-testable tck-id-selection-algo]#Implementations should perform the following steps while trying to find a suitable view engine for a view#. 31 | 32 | . Lookup all instances of `jakarta.mvc.engine.ViewEngine` available via Jakarta Contexts and Dependency Injection. 33 | . Call `supports` on every view engine found in the previous step, discarding those that return `false`. 34 | . If the resulting set is empty, return `null`. 35 | . Otherwise, sort the resulting set in descending order of priority using the integer value from the `@Priority` annotation decorating the view engine class or the default value `ViewEngine.PRIORITY_APPLICATION` if the annotation is not present. 36 | . Return the first element in the resulting sorted set, that is, the view engine with the highest priority that supports the given view. 37 | 38 | If a view engine that can process a view is not found, implementations SHOULD throw a corresponding exception and stop to process the request. 39 | 40 | The `processView` method has all the information necessary for processing in the `ViewEngineContext`, including the view, a reference to `Models`, as well as the underlying `OutputStream` that can be used to send the result to the client. 41 | 42 | Prior to the view render phase, all entries available in `Models` MUST be bound in such a way that they become available to the view being processed. 43 | The exact mechanism for this depends on the actual view engine implementation. 44 | [tck-testable tck-id-models-binding]#In the case of the built-in view engines for JSPs, entries in `Models` must be bound by calling `HttpServletRequest.setAttribute(String, Object)`#. 45 | Calling this method ensures access to the named models from EL expressions. 46 | 47 | A view returned by a controller method represents a path within an application archive. 48 | [tck-testable tck-id-path-relative]#If the path is relative, does not start with `/`, implementations MUST resolve view paths relative to the view folder, which defaults to `/WEB-INF/views/`#. 49 | [tck-testable tck-id-path-absolute]#If the path is absolute, no further processing is required#. 50 | It is recommended to use relative paths and a location under `WEB-INF` to prevent direct access to views as static resources. 51 | -------------------------------------------------------------------------------- /spec/src/main/asciidoc/chapters/events.asciidoc: -------------------------------------------------------------------------------- 1 | [[events]] 2 | Events 3 | ------ 4 | 5 | This chapter introduces a mechanism by which Jakarta MVC applications can be informed of important events that occur while processing a request. 6 | This mechanism is based on Jakarta Contexts and Dependency Injection events that can be fired by implementations and observed by applications. 7 | 8 | [[observers]] 9 | Observers 10 | ~~~~~~~~~ 11 | 12 | The package `jakarta.mvc.event` defines a number of event types that MUST be fired by implementations during the processing of a request. 13 | Implementations MAY extend this set and also provide additional information on any of the events defined by this specification. 14 | The reader is referred to the implementation’s documentation for more information on event support. 15 | 16 | Observing events can be useful for applications to learn about the lifecycle of a request, perform logging, monitor performance, etc. 17 | [tck-testable tck-id-before-after-controller]#The events `BeforeControllerEvent` and `AfterControllerEvent` are fired around the invocation of a controller#. 18 | [tck-testable tck-id-after-controller-exception]#Please note that `AfterControllerEvent` is always fired, even if the controller fails with an exception#. 19 | 20 | [source,java,numbered] 21 | ---- 22 | include::{mvc-api-source-dir}jakarta/mvc/event/BeforeControllerEvent.java[lines=22..-1] 23 | ---- 24 | 25 | [source,java,numbered] 26 | ---- 27 | include::{mvc-api-source-dir}jakarta/mvc/event/AfterControllerEvent.java[lines=22..-1] 28 | ---- 29 | 30 | Applications can monitor these events using an observer as shown next. 31 | 32 | [source,java,numbered] 33 | ---- 34 | @ApplicationScoped 35 | public class EventObserver { 36 | 37 | public void onBeforeController(@Observes BeforeControllerEvent e) { 38 | System.out.println("URI: " + e.getUriInfo().getRequestUri()); 39 | } 40 | 41 | public void onAfterController(@Observes AfterControllerEvent e) { 42 | System.out.println("Controller: " + 43 | e.getResourceInfo().getResourceMethod()); 44 | } 45 | } 46 | ---- 47 | 48 | Observer methods in Jakarta Contexts and Dependency Injection are defined using the `@Observes` annotation on a parameter position. 49 | The class `EventObserver` is a Jakarta Contexts and Dependency Injection bean in application scope whose methods `onBeforeController` and `onAfterController` are called before and after a controller is called. 50 | 51 | Each event includes additional information that is specific to the event; 52 | for example, the events shown in the example above allow applications to get information about the request URI and the resource (controller) selected. 53 | 54 | The <> section describes the algorithm used by implementations to select a specific view engine for processing; after a view engine is selected, the method `processView` is called. 55 | [tck-testable tck-id-before-after-view]#The events `BeforeProcessViewEvent` and `AfterProcessViewEvent` are fired around this call#. 56 | [tck-testable tck-id-after-view-exception]#Please note that `AfterProcessViewEvent` is always fired, even if the view engine fails with an exception#. 57 | 58 | [source,java,numbered] 59 | ---- 60 | include::{mvc-api-source-dir}jakarta/mvc/event/BeforeProcessViewEvent.java[lines=21..-1] 61 | ---- 62 | 63 | [source,java,numbered] 64 | ---- 65 | include::{mvc-api-source-dir}jakarta/mvc/event/AfterProcessViewEvent.java[lines=21..-1] 66 | ---- 67 | 68 | These events can be observed in a similar manner: 69 | 70 | [source,java,numbered] 71 | ---- 72 | @ApplicationScoped 73 | public class EventObserver { 74 | 75 | public void onBeforeProcessView(@Observes BeforeProcessViewEvent e) { 76 | // ... 77 | } 78 | 79 | public void onAfterProcessView(@Observes AfterProcessViewEvent e) { 80 | // ... 81 | } 82 | } 83 | ---- 84 | 85 | To complete the example, let us assume that the information about the selected view engine needs to be conveyed to the client. 86 | To ensure that this information is available to a view returned to the client, 87 | the `EventObserver` class can inject and update the same request-scope bean accessed by such a view: 88 | 89 | [source,java,numbered] 90 | ---- 91 | @ApplicationScoped 92 | public class EventObserver { 93 | 94 | @Inject 95 | private EventBean eventBean; 96 | 97 | public void onBeforeProcessView(@Observes BeforeProcessViewEvent e) { 98 | eventBean.setView(e.getView()); 99 | eventBean.setEngine(e.getEngine()); 100 | } 101 | // ... 102 | } 103 | ---- 104 | 105 | For more information about the interaction between views and models, the reader is referred to the <> section. 106 | 107 | [tck-testable tck-id-redirect-event]#The last event supported by Jakarta MVC is `ControllerRedirectEvent`, which is fired just before the Jakarta MVC implementation returns a redirect status code#. 108 | [tck-testable tck-id-redirect-after-controller-event]#Please note that this event MUST be fired after `AfterControllerEvent`#. 109 | 110 | [source,java,numbered] 111 | ---- 112 | include::{mvc-api-source-dir}jakarta/mvc/event/ControllerRedirectEvent.java[lines=23..-1] 113 | ---- 114 | 115 | Jakarta Contexts and Dependency Injection events fired by implementations are _synchronous_, so it is recommended that applications carry out only simple tasks in their observer methods, 116 | avoiding long-running computations as well as blocking calls. 117 | For a complete list of events, the reader is referred to the Javadoc for the `jakarta.mvc.event` package. 118 | 119 | Event reporting requires the Jakarta MVC implementations to create event objects before firing. 120 | In high-throughput systems without any observers the number of unnecessary objects created may not be insignificant. 121 | For this reason, it is RECOMMENDED for implementations to consider smart firing strategies when no observers are present. 122 | -------------------------------------------------------------------------------- /spec/src/main/asciidoc/chapters/form-method-overwrite.asciidoc: -------------------------------------------------------------------------------- 1 | [[form_method_overwrite]] 2 | Form method override 3 | -------------------- 4 | 5 | This chapter introduces the notion of _form method overwrite_ and describes how Jakarta MVC supports HTTP methods besides `GET` and `POST` when using HTML forms. 6 | 7 | [[form_method_overwrite_introduction]] 8 | Introduction 9 | ~~~~~~~~~~~~ 10 | 11 | The HTML `
` is per default only capable of handling the HTTP `GET` and `POST` verbs. Anyway, more complex applications maybe want to use Jakarta MVC to support HTML as one type of resource representation and need the power of other HTTP verbs like `PATCH` or `DELETE` too. Therefore Jakarta MVC supports overwriting the HTTP method by providing an easy to use and configurable mechanism. 12 | 13 | Jakarta MVC defines the term _form method overwrite_ as the mechanism being responsible for changing the HTTP request's method to something different than `GET` or `POST`. 14 | 15 | The _form method overwrite_ MUST happen exactly once per request as described in <> before the controller is resolved. 16 | 17 | To have control over the form method handling, Jakarta MVC provides two properties with constants for easier usage in the class `jakarta.mvc.form.FormMethodOverwriter`: 18 | 19 | [source,java,numbered] 20 | ---- 21 | include::{mvc-api-source-dir}jakarta/mvc/form/FormMethodOverwriter.java[lines=26..-1] 22 | ---- 23 | 24 | - `jakarta.mvc.form.FormMethodOverwrite` which can be either `ENABLED` or `DISABLED`. The legal options for this property are defined in `jakarta.mvc.form.FormMethodOverwriter.Options`. Its default value is `ENABLED`. 25 | - `jakarta.mvc.form.HiddenFieldName` which defines the name of the hidden input field containing the HTTP method which shall be used instead of the original one. 26 | The default value `_method` is defined in `jakarta.mvc.form.FormMethodOverwriter#HIDDEN_FIELD_NAME_DEFAULT`. 27 | 28 | The following sections will explain the form method overwrite resolving algorithm provided by the Jakarta MVC implementation. 29 | 30 | [[form_method_overwrite_resolving_algorithm]] 31 | Resolving Algorithm 32 | ~~~~~~~~~~~~~~~~~~~ 33 | 34 | The _form method overwriter_ is responsible to detect if the HTTP method shall be overwritten and perform the overwrite if necessary. The specification won't provide an interface for this task, as there are a lot of possibilities provided by the specifications MVC is based on, like `HttpServletFilter` from Jakarta Servlet or Jakarta RESTful's `ContainerRequestFilter`. 35 | 36 | [tck-testable tck-id-form-overwriter-algorithm]#Implementations MUST use the following algorithm to overwrite the HTTP method for each request#: 37 | 38 | . Check if the following preconditions are `true`: 39 | .. The configuration property `jakarta.mvc.form.FormMethodOverwrite` is set to `FormMethodOverwriter.Options#ENABLED` 40 | .. The request is a `POST` request. 41 | .. A form field with the name like it's configured in `jakarta.mvc.form.HiddenFieldName` is available 42 | 43 | . If all conditions are resolved to true: 44 | .. Overwrite the HTTP method to the value provided by the hidden form field. 45 | 46 | . If any of these preconditions evaluates to `false`: 47 | .. End the procedure without changing the request's HTTP method 48 | 49 | Applications can either rely on the form method overwriter algorithm which is described in this section or provide a custom form method overwriter which implements some other strategy. 50 | -------------------------------------------------------------------------------- /spec/src/main/asciidoc/chapters/i18n.asciidoc: -------------------------------------------------------------------------------- 1 | [[i18n]] 2 | Internationalization 3 | -------------------- 4 | 5 | This chapter introduces the notion of a _request locale_ and describes how Jakarta MVC handles internationalization and localization. 6 | 7 | [[i18n_introduction]] 8 | Introduction 9 | ~~~~~~~~~~~~ 10 | 11 | Internationalization and localization are very important concepts for any web application framework. 12 | Therefore Jakarta MVC has been designed to make supporting multiple languages and regional differences in applications very easy. 13 | 14 | Jakarta MVC defines the term _request locale_ as the locale which is used for any locale-dependent operation within the lifecycle of a request. 15 | The request locale MUST be resolved exactly once for each request using the resolving algorithm described in the <> section. 16 | 17 | These locale-dependent operations include, but are not limited to: 18 | 19 | . Data type conversion as part of the data binding mechanism. 20 | . Formatting of data when rendering it to the view. 21 | . Generating binding and validation error messages in the specific language. 22 | 23 | [tck-testable tck-id-mvc-context-locale]#The request locale is available from `MvcContext` and can be used by controllers, view engines and other components# to perform operations which depend on the current locale. 24 | The example below shows a controller that uses the request locale to create a `NumberFormat` instance. 25 | 26 | 27 | [source,java,numbered] 28 | ---- 29 | @Controller 30 | @Path("/foobar") 31 | public class MyController { 32 | 33 | @Inject 34 | private MvcContext mvc; 35 | 36 | @GET 37 | public String get() { 38 | Locale locale = mvc.getLocale(); 39 | NumberFormat format = NumberFormat.getInstance(locale); 40 | } 41 | } 42 | ---- 43 | 44 | The following sections will explain the locale resolving algorithm and the default resolver provided by the Jakarta MVC implementation. 45 | 46 | [[i18n_resolving_algorithm]] 47 | Resolving Algorithm 48 | ~~~~~~~~~~~~~~~~~~~ 49 | 50 | The _locale resolver_ is responsible to detect the request locale for each request processed by the Jakarta MVC runtime. 51 | A locale resolver MUST implement the `jakarta.mvc.locale.LocaleResolver` interface which is defined like this: 52 | 53 | [source,java,numbered] 54 | ---- 55 | include::{mvc-api-source-dir}jakarta/mvc/locale/LocaleResolver.java[lines=21..-1] 56 | ---- 57 | 58 | There may be more than one locale resolver for a Jakarta MVC application. Locale resolvers are discovered using Jakarta Contexts and Dependency Injection. 59 | [tck-testable tck-id-resolver-discovery]#Every Jakarta Contexts and Dependency Injection bean implementing the `LocaleResolver` interface and visible to the application participates in the locale resolving algorithm#. 60 | 61 | [tck-testable tck-id-resolve-algorithm]#Implementations MUST use the following algorithm to resolve the request locale for each request#: 62 | 63 | . Obtain a list of all Jakarta Contexts and Dependency Injection beans implementing the `LocaleResolver` interface visible to the application’s `BeanManager`. 64 | . Sort the list of locale resolvers in descending order of priority using the integer value from the `@Priority` annotation decorating the resolver class. + 65 | If no `@Priority` annotation is present, assume a default priority of `1000`. 66 | . Call `resolveLocale()` on the first resolver in the list. If the resolver returns `null`, continue with the next resolver in the list. + 67 | If a resolver returns a non-null result, stop the algorithm and use the returned locale as the request locale. 68 | 69 | Applications can either rely on the default locale resolver which is described in the <> section 70 | or provide a custom resolver which implements some other strategy for resolving the request locale. 71 | A custom strategy could for example track the locale using the session, a query parameter or the server’s hostname. 72 | 73 | [[i18n_default_resolver]] 74 | Default Locale Resolver 75 | ~~~~~~~~~~~~~~~~~~~~~~~ 76 | 77 | [tck-testable tck-id-default-locale-resolver]#Every Jakarta MVC implementation MUST provide a default locale resolver with a priority of `0` which resolves the request locale according to the following algorithm#: 78 | 79 | . First check whether the client provided an `Accept-Language` request header. If this is the case, the locale with the highest quality factor is returned as the result. 80 | . If the previous step was not successful, return the system default locale of the server. 81 | 82 | Please note that applications can customize the locale resolving process by providing a custom locale resolver with a priority higher than `0`. 83 | See the <> section for details. 84 | -------------------------------------------------------------------------------- /spec/src/main/asciidoc/chapters/intro.asciidoc: -------------------------------------------------------------------------------- 1 | [[introduction]] 2 | Introduction 3 | ------------ 4 | 5 | Model-View-Controller, or _MVC_ for short, is a common pattern in Web frameworks where it is used predominantly to build HTML applications. 6 | The _model_ refers to the application’s data, the _view_ to the application’s data presentation and the _controller_ to the part of the 7 | system responsible for managing input, updating models and producing output. 8 | 9 | Web UI frameworks can be categorized as _action-based_ or _component-based_. In an action-based framework, HTTP requests are 10 | routed to controllers where they are turned into actions by application code; in a component-based framework, HTTP requests are grouped and 11 | typically handled by framework components with little or no interaction from application code. In other words, in a component-based framework, 12 | the majority of the controller logic is provided by the framework instead of the application. 13 | 14 | The API defined by this specification falls into the action-based category and is, therefore, not intended to be a replacement for 15 | component-based frameworks such as Jakarta Server Faces [<>], but simply a different approach to building Web applications on the Jakarta EE platform. 16 | 17 | [[goals]] 18 | Goals 19 | ~~~~~ 20 | 21 | The following are goals of the API: 22 | 23 | [horizontal] 24 | Goal 1:: Leverage existing Jakarta EE technologies like Jakarta Contexs and Dependency Injecttion [<>] and Jakarta Bean Validation [<>]. 25 | Goal 2:: Define a solid core to build MVC applications without necessarily supporting all the features in its first version. 26 | Goal 3:: Build on top of Jakarta RESTful Web Services for the purpose of re-using its matching and binding layers. 27 | Goal 4:: Provide built-in support for Jakarta Server Pages view languages. 28 | 29 | [[non_goals]] 30 | Non-Goals 31 | ~~~~~~~~~ 32 | 33 | The following are non-goals of the API: 34 | 35 | [horizontal] 36 | Non-Goal 1:: Define a new view (template) language and processor. 37 | Non-Goal 2:: Support standalone implementations of MVC running outside of Jakarta EE. 38 | Non-Goal 3:: Support REST services not based on Jakarta RESTful Web Services. 39 | Non-Goal 4:: Provide built-in support for view languages that are not part of Jakarta EE. 40 | 41 | It is worth noting that, even though a standalone implementation of MVC that runs outside of Jakarta EE is a non-goal, 42 | this specification shall not intentionally prevent implementations to run in other environments, 43 | provided that those environments include support for all the Jakarta EE technologies required by MVC. 44 | 45 | [[additional_information]] 46 | Additional Information 47 | ~~~~~~~~~~~~~~~~~~~~~~ 48 | 49 | The issue tracking system for this specification can be found at: 50 | 51 | https://github.com/eclipse-ee4j/mvc-api/issues 52 | 53 | The corresponding Javadocs can be found online at: 54 | 55 | https://jakarta.ee/specifications/mvc/1.1/apidocs/ 56 | 57 | A compatible implementation can be obtained from: 58 | 59 | https://projects.eclipse.org/projects/ee4j.krazo 60 | 61 | The project team seeks feedback from the community on any aspect of this specification, please send comments to: 62 | 63 | https://accounts.eclipse.org/mailing-list/mvc-dev 64 | 65 | [[terminology]] 66 | Terminology 67 | ~~~~~~~~~~~ 68 | 69 | Most of the terminology used in this specification is borrowed from other specifications such as Jakarta RESTful Web Services and Jakarta Contexts and Dependency Injection. We use the terms _per-request_ 70 | and _request-scoped_ as well as _per-application_ and _application-scoped_ interchangeably. 71 | 72 | [[conventions]] 73 | Conventions 74 | ~~~~~~~~~~~ 75 | 76 | The keywords `MUST', `MUST NOT', `REQUIRED', `SHALL', `SHALL NOT', `SHOULD', `SHOULD NOT', `RECOMMENDED', `MAY', and `OPTIONAL' 77 | in this document are to be interpreted as described in RFC 2119 [<>]. 78 | 79 | Java code and sample data fragments are formatted as shown below: 80 | 81 | [source,java,numbered] 82 | ---- 83 | package com.example.hello; 84 | 85 | public class Hello { 86 | public static void main(String args[]){ 87 | System.out.println("Hello World"); 88 | } 89 | } 90 | ---- 91 | 92 | URIs of the general form http://example.org/[http://example.org/...] and http://example.com/[http://example.com/...] represent application or context-dependent URIs. 93 | 94 | All parts of this specification are normative, with the exception of examples, notes and sections explicitly marked as `Non-Normative'. 95 | Non-normative notes are formatted as shown below. 96 | 97 | .Note 98 | [NOTE] 99 | This is a note. 100 | 101 | [[acks20]] 102 | Acknowledgements for version 2.0 103 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 104 | 105 | The Jakarta MVC 2.0 specification was created by the Jakarta MVC Specification Project with 106 | guidance provided by the Jakarta EE Working Group (https://jakarta.ee/). 107 | 108 | [[acks11]] 109 | Acknowledgements for version 1.1 110 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 111 | 112 | The Jakarta MVC 1.1 specification was created by the Jakarta MVC Specification Project with 113 | guidance provided by the Jakarta EE Working Group (https://jakarta.ee/). 114 | 115 | [[acks10]] 116 | Acknowledgements for version 1.0 117 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 118 | 119 | Version 1.0 was developed as part of https://jcp.org/en/jsr/detail?id=371[JSR 371] under the Java Community Process. 120 | 121 | [[spec_leads]] 122 | Specification Leads 123 | ^^^^^^^^^^^^^^^^^^^ 124 | 125 | The following table lists the specification leads of the JSR: 126 | 127 | [cols="1,1"] 128 | |=== 129 | |Ivar Grimstad (Individual Member)|(Jan 2017 - present) 130 | |Christian Kaltepoth (ingenit GmbH & Co. KG)|(May 2017 - present) 131 | |Santiago Pericas-Geertsen (Oracle)|(Aug 2014 - Jan 2017) 132 | |Manfred Riem (Oracle)|(Aug 2014 - Jan 2017) 133 | |=== 134 | 135 | [[expert_group]] 136 | Expert Group Members 137 | ^^^^^^^^^^^^^^^^^^^^ 138 | 139 | The following were the expert group members: 140 | 141 | [cols="1,1"] 142 | |=== 143 | |Ivar Grimstad (Individual Member) 144 | |Neil Griffin (Liferay, Inc) 145 | |Joshua Wilson (RedHat) 146 | |Rodrigo Turini (Caelum) 147 | |Stefan Tilkov (innoQ Deutschland GmbH) 148 | |Frank Caputo (Individual Member) 149 | |Christian Kaltepoth (ingenit GmbH & Co. KG) 150 | |Woong-ki Lee (TmaxSoft, Inc.) 151 | |Paul Nicolucci (IBM) 152 | |Kito D. Mann (Individual Member) 153 | |Rahman Usta (Individual Member) 154 | |Florian Hirsch (adorsys GmbH & Co KG) 155 | |Santiago Pericas-Geertsen (Oracle) 156 | |Manfred Riem (Oracle) 157 | |=== 158 | 159 | The following were former members of the expert group: 160 | 161 | [cols="1,1"] 162 | |=== 163 | |Guilherme de Azevedo Silveira (Individual Member) 164 | | 165 | |=== 166 | 167 | [[contributors]] 168 | Contributors 169 | ^^^^^^^^^^^^ 170 | 171 | The following were the contributors of the specification: 172 | 173 | [cols="1,1"] 174 | |=== 175 | |Daniel Dias dos Santos 176 | |Phillip Krüger 177 | |Andreas Badelt 178 | | 179 | |=== 180 | 181 | During the course of this JSR we received many excellent suggestions. Special thanks to Marek Potociar, Dhiru Pandey and Ed Burns, all from Oracle. 182 | In addition, to everyone in the user’s alias that followed the expert discussions and provided feedback, including Peter Pilgrim, Ivar Grimstad, Jozef Hartinger, Florian Hirsch, Frans Tamura, Rahman Usta, Romain Manni-Bucau, Alberto Souza, among many others. 183 | -------------------------------------------------------------------------------- /spec/src/main/asciidoc/chapters/license.asciidoc: -------------------------------------------------------------------------------- 1 | [colophon] 2 | == License 3 | 4 | Eclipse Public License 2.0 and GNU General Public License, version 2 with the GNU Classpath Exception. -------------------------------------------------------------------------------- /spec/src/main/asciidoc/chapters/refs.asciidoc: -------------------------------------------------------------------------------- 1 | :numbered!: 2 | ["bibliography",sectnum="0"] 3 | 4 | [[bibliography]] 5 | 6 | == Bibliography 7 | 8 | [[jsf23]] 9 | [1]:: Jakarta Server Faces 2.3, August 2019 + 10 | https://jakarta.ee/specifications/faces/2.3/ 11 | 12 | [[cdi20]] 13 | [2]:: Jakarta Context Dependency Injection 2.0, August 2019 + 14 | https://jakarta.ee/specifications/cdi/2.0/ 15 | 16 | [[bv20]] 17 | [3]:: Jakarta Bean Validation 2.0, August 2019 + 18 | https://jakarta.ee/specifications/bean-validation/2.0/ 19 | 20 | [[rfc2119]] 21 | [4]:: S. Bradner. RFC 2119: Keywords for use in RFCs to Indicate Requirement Levels. RFC, IETF, March 1997 + 22 | http://www.ietf.org/rfc/rfc2119.txt 23 | 24 | [[jaxrs21]] 25 | [5]:: Jakarta RESTful Web Services 2.1, August 2019 + 26 | https://jakarta.ee/specifications/restful-ws/2.1/ 27 | 28 | [[el30]] 29 | [6]:: Jakarta Expression Language 3.0, August 2019 + 30 | https://jakarta.ee/specifications/expression-language/3.0/ -------------------------------------------------------------------------------- /spec/src/main/asciidoc/chapters/revision.asciidoc: -------------------------------------------------------------------------------- 1 | [appendix] 2 | [[revision_history]] 3 | Revision History 4 | ---------------- 5 | 3.0 6 | [[version_three_zero]] 7 | ~~~ 8 | 9 | Remove requirement for Facelets support 10 | 11 | 2.1 12 | [[version_two_one]] 13 | ~~~ 14 | 15 | Specified `FormMethodOverwrite` for extended HTTP method support 16 | 17 | 2.0 18 | [[version_two_zero]] 19 | ~~~ 20 | 21 | Changed namespace from `javax.mvc` to `jakarta.mvc`. 22 | 23 | 1.1 24 | [[version_one_one]] 25 | ~~~ 26 | 27 | No API changes since 1.0. -------------------------------------------------------------------------------- /spec/src/main/asciidoc/chapters/security.asciidoc: -------------------------------------------------------------------------------- 1 | [[security]] 2 | Security 3 | -------- 4 | 5 | [[security_introduction]] 6 | Introduction 7 | ~~~~~~~~~~~~ 8 | 9 | Guarding against malicious attacks is a great concern for web application developers. In particular, Jakarta MVC applications that accept 10 | input from a browser are often targetted by attackers. Two of the most common forms of attacks are cross-site request forgery (CSRF) 11 | and cross-site scripting (XSS). This chapter explores techniques to prevent these type of attacks with the aid of the Jakarta MVC API. 12 | 13 | [[cross-site-request-forgery]] 14 | Cross-site Request Forgery 15 | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 16 | 17 | Cross-site Request Forgery (CSRF) is a type of attack in which a user, who has a trust relationship with a certain site, is mislead into 18 | executing some commands that exploit the existence of such a trust relationship. The canonical example for this attack is that of a user 19 | unintentionally carrying out a bank transfer while visiting another site. 20 | 21 | The attack is based on the inclusion of a link or script in a page that accesses a site to which the user is known or assumed to have been 22 | authenticated (trusted). Trust relationships are often stored in the form of cookies that may be active while the user is visiting other 23 | sites. For example, such a malicious site could include the following HTML snippet: 24 | 25 | [source,html] 26 | ---- 27 | 28 | ---- 29 | 30 | This will result in the browser executing a bank transfer in an attempt to load an image. 31 | 32 | In practice, most sites require the use of form posts to submit requests such as bank transfers. The common way to prevent CSRF attacks is by 33 | embedding additional, difficult-to-guess data fields in requests that contain sensible commands. This additional data, known as a token, is 34 | obtained from the trusted site but unlike cookies it is never stored in the browser. 35 | 36 | Jakarta MVC implementations provide CSRF protection using the `Csrf` object and the `@CsrfProtected` annotation. 37 | [tck-testable tck-id-csrf-obj]#The `Csrf` object is available to applications via the injectable `MvcContext` type or in Jakarta Expression Language as `mvc.csrf`#. 38 | For more information about `MvcContext`, please refer to the <> section. 39 | 40 | [tck-testable tck-id-csrf-hidden-field]#Applications may use the `Csrf` object to inject a hidden field in a form that can be validated upon submission#. 41 | Consider the following JSP: 42 | 43 | [source,html,numbered] 44 | ---- 45 | 46 | 47 | CSRF Protected Form 48 | 49 | 50 | 51 | 52 | 54 | 55 | 56 | 57 | ---- 58 | 59 | The hidden field will be submitted with the form, giving the Jakarta MVC implementation the opportunity to verify the token and ensure the 60 | validity of the post request. 61 | 62 | Another way to convey this information to and from the client is via an HTTP header. 63 | [tck-testable tck-id-csrf-verify]#Jakarta MVC implementations are REQUIRED to support CSRF tokens both as form fields (with the help of the application developer as shown above) and as HTTP headers#. 64 | 65 | The application-level property `jakarta.mvc.security.CsrfProtection` enables CSRF protection when set to one of the possible values defined in `jakarta.mvc.security.Csrf.CsrfOptions`. 66 | [tck-testable tck-id-csrf-opt-default]#The default value of this property is `CsrfOptions.IMPLICIT`#. 67 | [tck-testable tck-id-csrf-inject-header]#Any other value than `CsrfOptions.OFF` will automatically inject a CSRF token as an HTTP header#. 68 | [tck-testable tck-id-csrf-custom-header-name]#The actual name of the header can be configured via the `Csrf.CSRF_HEADER_NAME` configuration property#. 69 | [tck-testable tck-id-csrf-default-header-name]#The default name of the header is `Csrf.DEFAULT_CSRF_HEADER_NAME`#. 70 | 71 | [tck-testable tck-id-csrf-implicit]#Automatic validation is enabled by setting this property to `CsrfOptions.IMPLICIT`, in which case all post requests must include either an HTTP header or a hidden field with the correct token#. 72 | [tck-testable tck-id-csrf-explict]#Finally, if the property is set to `CsrfOptions.EXPLICIT` then application developers must annotate controllers using `@CsrfProtected` to manually enable validation as shown in the following example#. 73 | 74 | [source,java,numbered] 75 | ---- 76 | @Path("csrf") 77 | @Controller 78 | public class CsrfController { 79 | 80 | @GET 81 | public String getForm() { 82 | return "csrf.jsp"; // Injects CSRF token 83 | } 84 | 85 | @POST 86 | @CsrfProtected // Required for CsrfOptions.EXPLICIT 87 | public void postForm(@FormParam("greeting") String greeting) { 88 | // Process greeting 89 | } 90 | } 91 | ---- 92 | 93 | [tck-testable tck-id-csrf-mediatype]#Jakarta MVC implementations are required to support CSRF validation of tokens for controllers annotated with `@POST` and consuming the media type `x-www-form-urlencoded`#; 94 | other media types and scenarios may also be supported but are OPTIONAL. 95 | 96 | If CSRF protection is enabled for a controller method and the CSRF validation fails (because the token is either missing or invalid), 97 | [tck-testable tck-id-csrf-exception]#the Jakarta MVC implementation MUST throw a `jakarta.mvc.security.CsrfValidationException`#. 98 | [tck-testable tck-id-csrf-default-mapper]#The implementation MUST provide a default exception mapper for this exception which handles it by responding with a 403 (Forbidden) status code#. 99 | [tck-testable tck-id-csrf-custom-mapper]#Applications MAY provide a custom exception mapper for `CsrfValidationException` to change this default behavior#. 100 | 101 | [[cross-site-scripting]] 102 | Cross-site Scripting 103 | ~~~~~~~~~~~~~~~~~~~~ 104 | 105 | Cross-site scripting (XSS) is a type of attack in which snippets of scripting code are injected and later executed when returned back from a 106 | server. The typical scenario is that of a website with a search field that does not validate its input, and returns an error message that 107 | includes the value that was submitted. If the value includes a snippet of the form `` then it will be executed by the browser when 108 | the page containing the error is rendered. 109 | 110 | There are lots of different variations of this the XSS attack, but most can be prevented by ensuring that the data submitted by clients is 111 | properly _sanitized_ before it is manipulated, stored in a database, returned to the client, etc. Data escaping/encoding is the recommended 112 | way to deal with untrusted data and prevent XSS attacks. 113 | 114 | [tck-testable tck-id-xss-encoders-obj]#Jakarta MVC applications can gain access to encoders through the `MvcContext` object#; 115 | [tck-testable tck-id-xss-escaping]#the methods defined by `jakarta.mvc.security.Encoders` can be used by applications to contextually encode data in an attempt to prevent XSS attacks#. 116 | The reader is referred to the Javadoc for this type for further information. -------------------------------------------------------------------------------- /spec/src/main/asciidoc/images/jakarta_ee_logo_schooner_color_stacked_default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jakartaee/mvc/ea273f2c2d787898cfe1e56c36fe1d5b1e8aca6a/spec/src/main/asciidoc/images/jakarta_ee_logo_schooner_color_stacked_default.png -------------------------------------------------------------------------------- /spec/src/main/asciidoc/license-efsl.adoc: -------------------------------------------------------------------------------- 1 | [colophon] 2 | == License 3 | [subs="normal"] 4 | .... 5 | Specification: {doctitle} 6 | 7 | Version: {revnumber} 8 | 9 | ifeval::["{revremark}" != ""] 10 | Status: {revremark} 11 | endif::[] 12 | ifeval::["{revremark}" == ""] 13 | Status: Final Release 14 | endif::[] 15 | 16 | Release: {revdate} 17 | .... 18 | [[Copyright]] 19 | == Copyright 20 | 21 | Copyright (c) 2018, 2025 Eclipse Foundation AISBL. 22 | 23 | [[efsl]] 24 | === Eclipse Foundation Specification License - v1.1 25 | 26 | By using and/or copying this document, or the Eclipse Foundation document from which this statement is linked or incorporated by reference, you (the licensee) agree that you have read, understood, and will comply with the following terms and conditions: 27 | 28 | Permission to copy, and distribute the contents of this document, or the Eclipse Foundation document from which this statement is linked, in any medium for any purpose and without fee or royalty is hereby granted, provided that you include the following on ALL copies of the document, or portions thereof, that you use: 29 | 30 | * link or URL to the original Eclipse Foundation document. 31 | * All existing copyright notices, or if one does not exist, a notice (hypertext is preferred, but a textual representation is permitted) of the form: "Copyright (c) [$date-of-document] Eclipse Foundation AISBL \<> " 32 | 33 | Inclusion of the full text of this NOTICE must be provided. We request that authorship attribution be provided in any software, documents, or other items or products that you create pursuant to the implementation of the contents of this document, or any portion thereof. 34 | 35 | No right to create modifications or derivatives of Eclipse Foundation documents is granted pursuant to this license, except anyone may prepare and distribute derivative works and portions of this document in software that implements the specification, in supporting materials accompanying such software, and in documentation of such software, PROVIDED that all such works include the notice below. HOWEVER, the publication of derivative works of this document for use as a technical specification is expressly prohibited. 36 | 37 | The notice is: 38 | 39 | "Copyright (c) [$date-of-document] Eclipse Foundation AISBL. This software or document includes material copied from or derived from [title and URI of the Eclipse Foundation specification document]." 40 | 41 | [[Disclaimers]] 42 | ==== Disclaimers 43 | 44 | THIS DOCUMENT IS PROVIDED "AS IS," AND TO THE EXTENT PERMITTED BY APPLICABLE LAW THE COPYRIGHT HOLDERS AND THE ECLIPSE FOUNDATION AISBL MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, OR TITLE; THAT THE CONTENTS OF THE DOCUMENT ARE SUITABLE FOR ANY PURPOSE; NOR THAT THE IMPLEMENTATION OF SUCH CONTENTS WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. 45 | 46 | TO THE EXTENT PERMITTED BY APPLICABLE LAW THE COPYRIGHT HOLDERS AND THE ECLIPSE FOUNDATION AISBL WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE DOCUMENT OR THE PERFORMANCE OR IMPLEMENTATION OF THE CONTENTS THEREOF. 47 | 48 | The name and trademarks of the copyright holders or the Eclipse Foundation AISBL may NOT be used in advertising or publicity pertaining to this document or its contents without specific, written prior permission. Title to copyright in this document will at all times remain with copyright holders. 49 | -------------------------------------------------------------------------------- /spec/src/main/asciidoc/mvc-spec.asciidoc: -------------------------------------------------------------------------------- 1 | :mvc-api-source-dir: ../../../../../api/src/main/java/ 2 | 3 | include::chapters/intro.asciidoc[] 4 | 5 | include::chapters/controllers.asciidoc[] 6 | 7 | include::chapters/data-binding.asciidoc[] 8 | 9 | include::chapters/security.asciidoc[] 10 | 11 | include::chapters/events.asciidoc[] 12 | 13 | include::chapters/applications.asciidoc[] 14 | 15 | include::chapters/engines.asciidoc[] 16 | 17 | include::chapters/i18n.asciidoc[] 18 | 19 | include::chapters/form-method-overwrite.asciidoc[] 20 | 21 | include::chapters/annotations.asciidoc[] 22 | 23 | include::chapters/revision.asciidoc[] 24 | 25 | include::chapters/refs.asciidoc[] 26 | -------------------------------------------------------------------------------- /spec/src/main/asciidoc/spec.asciidoc: -------------------------------------------------------------------------------- 1 | 2 | // Copyright (c) 2020 Contributors to the Eclipse Foundation 3 | // 4 | 5 | = Jakarta MVC Specification 6 | :authors: Jakarta EE MVC Team, https://projects.eclipse.org/projects/ee4j.mvc 7 | :email: https://dev.eclipse.org/mailman/listinfo/mvc-dev 8 | :version-label!: 9 | :doctype: book 10 | :license: Eclipse Foundation Specification License 11 | :source-highlighter: coderay 12 | :toc: left 13 | :toclevels: 3 14 | :sectnumlevels: 4 15 | :sectanchors: 16 | :experimental: 17 | :reproducible: 18 | :icons: font 19 | :listing-caption: Listing 20 | :sectnums: 21 | :autofit-option: 22 | ifdef::backend-pdf[] 23 | :pagenums: 24 | :numbered: 25 | :title-logo-image: image:images/jakarta_ee_logo_schooner_color_stacked_default.png[pdfwidth=4.25in,align=right] 26 | :compat-mode: 27 | endif::[] 28 | 29 | // == License 30 | :sectnums!: 31 | include::license-efsl.adoc[] 32 | 33 | :sectnums: 34 | include::mvc-spec.asciidoc[] 35 | -------------------------------------------------------------------------------- /spec/src/main/xsl/tck-audit.xsl: -------------------------------------------------------------------------------- 1 | 2 | 19 | 46 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | ' 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | en/ 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | No node found for link id: 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | Copyright (c) 2016-2019 JSR 371 expert group and contributors 139 | 140 | This program and the accompanying materials are made available under the 141 | terms of the Eclipse Public License v. 2.0, which is available at 142 | http://www.eclipse.org/legal/epl-2.0. 143 | 144 | This Source Code may also be made available under the following Secondary 145 | Licenses when the conditions for such availability set forth in the 146 | Eclipse Public License v. 2.0 are satisfied: GNU General Public License, 147 | version 2 with the GNU Classpath Exception, which is available at 148 | https://www.gnu.org/software/classpath/license.html. 149 | 150 | SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 151 | 152 | 153 | 154 | 155 | Generated by tck-audit.xsl at 156 | (revision ) 157 | 158 | 159 | 160 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 |
174 | 175 | 176 | 177 | 178 | - 179 | 180 | 181 | 182 |
183 | 184 | 185 | 186 |
187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | false 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | Needs update 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | Error: section - seems to be automatically generated: it starts with an underscore. 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 |
266 | --------------------------------------------------------------------------------