├── .gitignore ├── LICENSE.txt ├── NOTICE.txt ├── README.txt ├── RELEASE-NOTES.txt ├── pom.xml └── src ├── changes └── changes.xml ├── conf ├── MANIFEST.MF └── joda.tld ├── main ├── assembly │ └── dist.xml └── java │ └── org │ └── joda │ └── time │ └── contrib │ └── jsptag │ ├── DateTimeZoneSupport.java │ ├── DateTimeZoneTag.java │ ├── FormatSupport.java │ ├── FormatTag.java │ ├── JodaTagLibraryValidator.java │ ├── ParseDateTimeSupport.java │ ├── ParseDateTimeTag.java │ ├── Resources.java │ ├── Resources.properties │ ├── Resources_ja.properties │ ├── SetDateTimeZoneSupport.java │ ├── SetDateTimeZoneTag.java │ └── Util.java └── site ├── resources ├── css │ └── site.css └── download.html ├── site.xml └── xdoc ├── index.xml ├── licensecover.xml └── userguide.xml /.gitignore: -------------------------------------------------------------------------------- 1 | /bin/ 2 | /target/ 3 | *.log 4 | /tests/ 5 | .checkstyle 6 | .classpath 7 | .project 8 | /.settings/ 9 | /nbproject/ 10 | .idea 11 | *.iml 12 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. -------------------------------------------------------------------------------- /NOTICE.txt: -------------------------------------------------------------------------------- 1 | ============================================================================= 2 | = NOTICE file corresponding to section 4d of the Apache License Version 2.0 = 3 | ============================================================================= 4 | This product includes software developed by 5 | Joda.org (http://www.joda.org/). 6 | 7 | This product includes software developed by 8 | The Apache Software Foundation (http://www.apache.org/). 9 | -------------------------------------------------------------------------------- /README.txt: -------------------------------------------------------------------------------- 1 | 2 | Joda-Time Contributions area - JSP tags 3 | ======================================= 4 | Joda-Time is a date and time library that vastly improves on the JDK. 5 | This separate project provides JSP tag support. 6 | 7 | See the home page for more details: 8 | http://www.joda.org/joda-time-jsptags/ 9 | 10 | The source code is held at GitHub: 11 | https://github.com/JodaOrg/joda-time-jsptags 12 | -------------------------------------------------------------------------------- /RELEASE-NOTES.txt: -------------------------------------------------------------------------------- 1 | Joda-Time JSP tags contributed project version 1.1.1 2 | ---------------------------------------------------- 3 | 4 | Joda-Time is a date and time handling library that seeks to replace the JDK 5 | Date and Calendar classes. 6 | 7 | This is the 1.1.1 release of the JSP tag library support classes. 8 | These classes were converted from code at Jakarta Taglibs by Jim Newsham. 9 | Please check the NOTICE.txt for the Apache credit. 10 | 11 | 12 | About 13 | ----- 14 | The Joda Time Tag Library is a custom tag library for formatting and parsing 15 | Joda dates in jsp pages. This library works very similarly to the date-related 16 | tags in the jstl fmt library, so please refer to the documentation for that 17 | standard if you still have questions after reading this document or online help. 18 | 19 | Unlike the fmt tags which work with java.util.Date and java.util.TimeZone objects, 20 | the Joda tags work with Joda DateTime, ReadableInstant, ReadablePartial, 21 | and DateTimeZone objects. 22 | 23 | Note that I, Stephen Colebourne, am releasing this because an update needs to reach 24 | the maven repository. However, the code was not provided originally with unit tests. 25 | Therefore, please test the code in your environment before using in production. 26 | Or fork the GitHub project and provide some tests ;-) 27 | 28 | 29 | Changes since 1.1 30 | ----------------- 31 | - Updated OSGI manifest 32 | 33 | 34 | Changes since 1.0.2 35 | ------------------- 36 | - Moved to Java 5 37 | 38 | - Moved source code to GitHub 39 | 40 | - Changed to maven build 41 | 42 | - Mark all maven dependencies as "provided", so they are controlled by users 43 | 44 | 45 | Build 46 | ----- 47 | Build-time dependencies are Joda 1.0 or later, the Servlet 2.4 API, the 48 | JSP 2.0 API, and JSTL 1.1 API. A source build can be achieved from maven. 49 | The library is built with Java 5 and should work with Joda 2.0 or later. 50 | 51 | 52 | Setup 53 | ----- 54 | You'll need a servlet container which supports Servlet 2.4, JSP 2.0, JSTL 1.1. 55 | Copy the joda-time-1.2.jar and joda-time-tags.jar to the WEB-INF/lib directory of 56 | your web application. Declare the library as follows in your jsp pages: 57 | 58 | <%@taglib prefix="joda" uri="http://www.joda.org/joda/time/tags"%> 59 | 60 | 61 | Tags 62 | ---- 63 | FORMAT. 64 | 65 | Example: 66 | <% pageContext.setAttribute("now", new org.joda.time.DateTime()); %> 67 | 68 | 69 | Formats ReadableInstant (including DateTime) and ReadablePartial (including LocalDateTime, LocalDate and LocalTime) objects. 70 | The var and scope attributes can be used to set the value of a variable instead of printing the result. 71 | The time zone may be specified using an attribute, en enclosing tag, 72 | preceding tag, or via the "org.joda.time.dateTimeZone" scoped variable. 73 | 74 | Attributes: 75 | 76 | value (required). Must be a ReadableInstant or ReadablePartial. 77 | var. The scoped variable to set. 78 | scope. The scope of the variable to set. 79 | locale. The locale to use for formatting. 80 | style. The style to use for formatting (see Joda format documentation for recognized style strings) 81 | pattern. The pattern to use for formatting (see Joda format documentation for recognized pattern strings) 82 | dateTimeZone. The time zone to use for formatting. 83 | 84 | 85 | PARSEDATETIME. 86 | 87 | Example: 88 | 89 | 90 | 91 | Parses a string into a DateTime object. 92 | The var and scope attributes can be used to set the value of a variable instead of printing the result. 93 | The time zone may be specified using an attribute, en enclosing tag, 94 | preceding tag, or via the "org.joda.time.dateTimeZone" scoped variable. 95 | 96 | Attributes: 97 | 98 | value (required; unless value is nested within tag). 99 | Must be a string which can be parsed into a DateTime according to the parsing options specified. 100 | var. The scoped variable to set. 101 | scope. The scope of the variable to set. 102 | locale. The locale to use for parsing. 103 | style. The style to use for parsing (see Joda format documentation for recognized style strings) 104 | pattern. The pattern to use for parsing (see Joda format documentation for recognized pattern strings) 105 | dateTimeZone. The time zone to use for formatting. 106 | 107 | 108 | DATETIMEZONE. 109 | 110 | Example: 111 | <% pageContext.setAttribute("now", new DateTime()); %> 112 | <% pageContext.setAttribute("bkk", DateTimeZone.forID("Asia/Bangkok")); %> 113 | 114 | 115 | 116 | 117 | Provides a default time zone to all tags which are nested within it. 118 | The tag may override this value with an explicit dateTimeZone attribute. 119 | 120 | Attributes: 121 | 122 | value (required). The default time zone for nested tags to use. 123 | 124 | 125 | SETDATETIMEZONE. 126 | 127 | Example. 128 | <% pageContext.setAttribute("now", new DateTime()); %> 129 | <% pageContext.setAttribute("bkk", DateTimeZone.forID("Asia/Bangkok")); %> 130 | 131 | 132 | 133 | Sets the time zone object in the given scoped variable. 134 | If var is not specified, it will be stored in a scoped variable called "org.joda.time.dateTimeZone". 135 | The tag will default to using a time zone stored under this name if it does not have 136 | a dateTimeZone attribute and is not nested within a tag. 137 | 138 | Attributes: 139 | 140 | value (required). The time zone to set. 141 | var. The scoped variable to set. 142 | scope. The scope of the variable to set. 143 | 144 | 145 | -------- 146 | Home page: http://www.joda.org/joda-time-jsptags/ 147 | GitHub: https://github.com/JodaOrg/joda-time-jsptags 148 | 149 | The Joda team 150 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 4.0.0 8 | joda-time 9 | joda-time-jsptags 10 | jar 11 | Joda-Time-JSP-tags 12 | 1.2-SNAPSHOT 13 | Contribution to Joda-Time that adds JSP tags support 14 | http://www.joda.org/joda-time-jsptags/ 15 | 16 | 17 | 18 | GitHub 19 | https://github.com/JodaOrg/joda-time-jsptags/issues 20 | 21 | 2005 22 | 23 | 24 | 25 | 26 | jimnewsham 27 | Jim Newsham 28 | 29 | 30 | Lead developer 31 | 32 | 33 | 34 | jodastephen 35 | Stephen Colebourne 36 | 37 | Website and Release manager 38 | 39 | 0 40 | https://github.com/jodastephen 41 | 42 | 43 | 44 | 45 | 46 | 47 | Apache License, Version 2.0 48 | http://www.apache.org/licenses/LICENSE-2.0.txt 49 | repo 50 | 51 | 52 | 53 | scm:git:https://github.com/JodaOrg/joda-time-jsptags.git 54 | scm:git:git@github.com:JodaOrg/joda-time-jsptags.git 55 | https://github.com/JodaOrg/joda-time-jsptags 56 | 57 | 58 | Joda.org 59 | http://www.joda.org 60 | 61 | 62 | 63 | 64 | 65 | 66 | META-INF 67 | ${project.basedir} 68 | 69 | LICENSE.txt 70 | NOTICE.txt 71 | 72 | 73 | 74 | META-INF 75 | src/conf 76 | 77 | joda.tld 78 | 79 | 80 | 81 | org/joda/time/contrib/jsptag 82 | src/main/java/org/joda/time/contrib/jsptag 83 | 84 | *.properties 85 | 86 | 87 | 88 | 89 | 90 | 91 | org.apache.maven.plugins 92 | maven-jar-plugin 93 | 94 | 95 | src/conf/MANIFEST.MF 96 | 97 | true 98 | true 99 | 100 | 101 | 102 | 103 | 104 | org.apache.maven.plugins 105 | maven-surefire-plugin 106 | 107 | 108 | **/Test* 109 | 110 | 111 | 112 | 113 | org.apache.maven.plugins 114 | maven-javadoc-plugin 115 | 116 | 117 | http://www.joda.org/joda-time/apidocs/ 118 | 119 | 120 | 121 | 122 | attach-javadocs 123 | package 124 | 125 | jar 126 | 127 | 128 | 129 | 130 | 131 | org.apache.maven.plugins 132 | maven-source-plugin 133 | 134 | 135 | attach-sources 136 | package 137 | 138 | jar-no-fork 139 | 140 | 141 | 142 | 143 | 144 | org.apache.maven.plugins 145 | maven-assembly-plugin 146 | 147 | false 148 | 149 | src/main/assembly/dist.xml 150 | 151 | gnu 152 | 153 | 154 | 155 | make-assembly 156 | deploy 157 | 158 | single 159 | 160 | 161 | 162 | 163 | 164 | org.apache.maven.plugins 165 | maven-site-plugin 166 | 167 | true 168 | 169 | 170 | 171 | com.github.github 172 | site-maven-plugin 173 | 0.9 174 | 175 | 176 | github-site 177 | 178 | site 179 | 180 | site-deploy 181 | 182 | 183 | 184 | Create website for ${project.artifactId} v${project.version} 185 | ${project.artifactId} 186 | true 187 | github 188 | JodaOrg 189 | jodaorg.github.io 190 | refs/heads/master 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | org.apache.maven.plugins 200 | maven-assembly-plugin 201 | ${maven-assembly-plugin.version} 202 | 203 | 204 | org.apache.maven.plugins 205 | maven-checkstyle-plugin 206 | ${maven-checkstyle-plugin.version} 207 | 208 | 209 | org.apache.maven.plugins 210 | maven-changes-plugin 211 | ${maven-changes-plugin.version} 212 | 213 | 214 | org.apache.maven.plugins 215 | maven-clean-plugin 216 | ${maven-clean-plugin.version} 217 | 218 | 219 | org.apache.maven.plugins 220 | maven-compiler-plugin 221 | ${maven-compiler-plugin.version} 222 | 223 | 224 | org.apache.maven.plugins 225 | maven-deploy-plugin 226 | ${maven-deploy-plugin.version} 227 | 228 | 229 | org.apache.maven.plugins 230 | maven-dependency-plugin 231 | ${maven-dependency-plugin.version} 232 | 233 | 234 | org.apache.maven.plugins 235 | maven-gpg-plugin 236 | ${maven-gpg-plugin.version} 237 | 238 | 239 | org.apache.maven.plugins 240 | maven-install-plugin 241 | ${maven-install-plugin.version} 242 | 243 | 244 | org.apache.maven.plugins 245 | maven-jar-plugin 246 | ${maven-jar-plugin.version} 247 | 248 | 249 | org.apache.maven.plugins 250 | maven-javadoc-plugin 251 | ${maven-javadoc-plugin.version} 252 | 253 | 254 | org.apache.maven.plugins 255 | maven-jxr-plugin 256 | ${maven-jxr-plugin.version} 257 | 258 | 259 | org.apache.maven.plugins 260 | maven-plugin-plugin 261 | ${maven-plugin-plugin.version} 262 | 263 | 264 | org.apache.maven.plugins 265 | maven-pmd-plugin 266 | ${maven-pmd-plugin.version} 267 | 268 | 269 | org.apache.maven.plugins 270 | maven-project-info-reports-plugin 271 | ${maven-project-info-reports-plugin.version} 272 | 273 | 274 | org.apache.maven.plugins 275 | maven-repository-plugin 276 | ${maven-repository-plugin.version} 277 | 278 | 279 | org.apache.maven.plugins 280 | maven-resources-plugin 281 | ${maven-resources-plugin.version} 282 | 283 | 284 | org.apache.maven.plugins 285 | maven-site-plugin 286 | ${maven-site-plugin.version} 287 | 288 | 289 | org.apache.maven.plugins 290 | maven-source-plugin 291 | ${maven-source-plugin.version} 292 | 293 | 294 | org.apache.maven.plugins 295 | maven-surefire-plugin 296 | ${maven-surefire-plugin.version} 297 | 298 | 299 | org.apache.maven.plugins 300 | maven-surefire-report-plugin 301 | ${maven-surefire-report-plugin.version} 302 | 303 | 304 | org.apache.maven.plugins 305 | maven-toolchains-plugin 306 | ${maven-toolchains-plugin.version} 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 3.0.4 315 | 316 | 317 | 318 | joda-time 319 | joda-time 320 | 1.6.2 321 | provided 322 | 323 | 324 | javax.servlet 325 | servlet-api 326 | 2.4 327 | provided 328 | 329 | 330 | javax.servlet 331 | jsp-api 332 | 2.0 333 | provided 334 | 335 | 336 | javax.servlet 337 | jstl 338 | 1.1.2 339 | provided 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | org.apache.maven.plugins 348 | maven-project-info-reports-plugin 349 | ${maven-project-info-plugin.version} 350 | 351 | 352 | 353 | dependencies 354 | dependency-info 355 | issue-tracking 356 | license 357 | project-team 358 | scm 359 | summary 360 | 361 | 362 | 363 | 364 | 365 | org.apache.maven.plugins 366 | maven-javadoc-plugin 367 | ${maven-javadoc-plugin.version} 368 | 369 | 370 | 371 | javadoc 372 | 373 | 374 | 375 | 376 | 377 | http://www.joda.org/joda-time/apidocs/ 378 | 379 | 380 | 381 | 382 | org.apache.maven.plugins 383 | maven-surefire-report-plugin 384 | ${maven-surefire-report-plugin.version} 385 | 386 | true 387 | 388 | 389 | 390 | org.apache.maven.plugins 391 | maven-changes-plugin 392 | ${maven-changes-plugin.version} 393 | 394 | 395 | 396 | changes-report 397 | 398 | 399 | 400 | 401 | 402 | org.apache.maven.plugins 403 | maven-jxr-plugin 404 | ${maven-jxr-plugin.version} 405 | 406 | 407 | 408 | jxr 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | sonatype-joda-staging 420 | Sonatype OSS staging repository 421 | https://oss.sonatype.org/service/local/staging/deploy/maven2/ 422 | default 423 | 424 | 425 | false 426 | sonatype-joda-snapshot 427 | Sonatype OSS snapshot repository 428 | https://oss.sonatype.org/content/repositories/joda-snapshots 429 | default 430 | 431 | http://oss.sonatype.org/content/repositories/joda-releases 432 | 433 | 434 | 435 | 436 | 437 | repo-sign-artifacts 438 | 439 | 440 | oss.repo 441 | true 442 | 443 | 444 | 445 | 446 | 447 | org.apache.maven.plugins 448 | maven-toolchains-plugin 449 | 450 | 451 | validate 452 | 453 | toolchain 454 | 455 | 456 | 457 | 458 | 459 | 460 | 1.5 461 | sun 462 | 463 | 464 | 465 | 466 | 467 | org.apache.maven.plugins 468 | maven-gpg-plugin 469 | 470 | 471 | sign-artifacts 472 | verify 473 | 474 | sign 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 2.4 488 | 2.9 489 | 2.11 490 | 2.5 491 | 3.1 492 | 2.8.1 493 | 2.8 494 | 1.4 495 | 2.5.1 496 | 2.4 497 | 2.9.1 498 | 2.3 499 | 3.2 500 | 3.0.1 501 | 2.7 502 | 2.3.1 503 | 2.6 504 | 3.3 505 | 2.2.1 506 | 2.16 507 | 2.16 508 | 1.0 509 | 510 | 1.5 511 | 1.5 512 | 1.5 513 | true 514 | true 515 | true 516 | true 517 | lines,source 518 | 519 | false 520 | true 521 | 522 | ${project.basedir}/src/main/checkstyle/checkstyle.xml 523 | 524 | UTF-8 525 | UTF-8 526 | 527 | 528 | -------------------------------------------------------------------------------- /src/changes/changes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Java date and time API - JSP tags - Changes 6 | 7 | 8 | 9 | 10 | 11 | 12 | Home page at GitHub. 13 | 14 | 15 | Change to use m2e Maven Eclipse 16 | 17 | 18 | 19 | 20 | 21 | Fix OSGi manifest 22 | 23 | 24 | 25 | 26 | 27 | Release based on Java 5, to setup maven repository correctly. 28 | 29 | 30 | 31 | 32 | 33 | Fix missing properties files in jar. 34 | 35 | 36 | Fix maven definition for servlet-api to be provided. 37 | 38 | 39 | 40 | 41 | 42 | Fix missing directory tag in project.xml. 43 | 44 | 45 | 46 | 47 | 48 | Add documentation about servlet specification needed. 49 | 50 | 51 | 52 | 53 | 54 | Better error message when unknown object type passed in. 55 | 56 | 57 | 58 | 59 | 60 | Initial version. 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /src/conf/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Package: org.joda.time 2 | Extension-Name: joda-time-jsptags 3 | Specification-Title: Joda-Time JSP tags support 4 | Specification-Vendor: Joda.org 5 | Specification-Version: 1.1 6 | Implementation-Vendor: Joda.org 7 | Implementation-Title: org.joda.time.contrib.jsptags 8 | Implementation-Version: 1.1.1 9 | Implementation-Vendor-Id: org.joda 10 | Bundle-ManifestVersion: 2 11 | Bundle-Vendor: Joda.org 12 | Bundle-Name: Joda-Time-JSP-tags 13 | Bundle-SymbolicName: joda-time-jsptags 14 | Bundle-Version: 1.1.1 15 | Import-Package: org.joda.time;version="1.6.2" 16 | Export-Package: org.joda.time.contrib.jsptag;version=1.1.1 17 | Bundle-License: Apache 2.0 18 | Bundle-DocURL: http://www.joda.org/joda-time-jsptags/ 19 | -------------------------------------------------------------------------------- /src/conf/joda.tld: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | Joda Time Tag Library 9 | Joda Time 10 | 1.1 11 | joda 12 | http://www.joda.org/joda/time/tags 13 | 14 | 15 | 16 | Provides core validation features for JSTL tags. 17 | 18 | 19 | org.joda.time.contrib.jsptag.JodaTagLibraryValidator 20 | 21 | 22 | 23 | 24 | 25 | Specifies the time zone for any time formatting or parsing actions 26 | nested in its body 27 | 28 | dateTimeZone 29 | org.joda.time.contrib.jsptag.DateTimeZoneTag 30 | JSP 31 | 32 | 33 | The time zone. A String value is interpreted as 34 | a time zone ID. This may be one of the time zone 35 | IDs supported by the Joda. See 36 | org.joda.time.DateTimeZone for more information on 37 | supported time zone formats. 38 | 39 | value 40 | true 41 | true 42 | 43 | 44 | 45 | 46 | 47 | Stores the given time zone in the time zone configuration variable 48 | 49 | setDateTimeZone 50 | org.joda.time.contrib.jsptag.SetDateTimeZoneTag 51 | empty 52 | 53 | 54 | The time zone. A String value is interpreted as 55 | a time zone ID. This may be one of the time zone 56 | IDs supported by the Joda. See 57 | org.joda.time.DateTimeZone for more information on 58 | supported time zone formats. 59 | 60 | value 61 | true 62 | true 63 | 64 | 65 | 66 | Name of the exported scoped variable which 67 | stores the time zone of type 68 | java.util.DateTimeZone. 69 | 70 | var 71 | false 72 | false 73 | 74 | 75 | 76 | Scope of var or the time zone configuration 77 | variable. 78 | 79 | scope 80 | false 81 | false 82 | 83 | 84 | 85 | 86 | 87 | Formats a Joda instant or partial using the supplied style or pattern 88 | 89 | format 90 | org.joda.time.contrib.jsptag.FormatTag 91 | empty 92 | 93 | 94 | ReadableInstant or ReadablePartial to be formatted. 95 | 96 | value 97 | true 98 | true 99 | 100 | 101 | 102 | Formatting style to apply. See 103 | org.joda.time.format.DateTimeFormat#forStyle() 104 | for more information on supported styles. 105 | 106 | style 107 | false 108 | true 109 | 110 | 111 | 112 | Formatting pattern to apply. See 113 | org.joda.time.format.DateTimeFormat#forPattern() 114 | for more information on supported patterns. 115 | 116 | pattern 117 | false 118 | true 119 | 120 | 121 | 122 | Time zone in which to represent the formatted 123 | time. 124 | 125 | dateTimeZone 126 | false 127 | true 128 | 129 | 130 | 131 | Name of the exported scoped variable which 132 | stores the formatted result as a String. 133 | 134 | var 135 | false 136 | false 137 | 138 | 139 | 140 | Scope of var. 141 | 142 | scope 143 | false 144 | false 145 | 146 | 147 | 148 | Locale whose predefined formatting styles 149 | for dates and times are to be used for 150 | formatting. 151 | 152 | locale 153 | false 154 | true 155 | 156 | 157 | 158 | 159 | 160 | Parses the string representation of a date/time 161 | 162 | parseDateTime 163 | org.joda.time.contrib.jsptag.ParseDateTimeTag 164 | JSP 165 | 166 | 167 | Date/time to be parsed. 168 | 169 | value 170 | true 171 | true 172 | 173 | 174 | 175 | Formatting style to use. See 176 | org.joda.time.format.DateTimeFormat#forStyle() 177 | for more information on supported styles. 178 | 179 | style 180 | false 181 | true 182 | 183 | 184 | 185 | Formatting pattern to use. See 186 | org.joda.time.format.DateTimeFormat#forPattern() 187 | for more information on supported patterns. 188 | 189 | pattern 190 | false 191 | true 192 | 193 | 194 | 195 | Time zone in which to parse the date/time. 196 | 197 | dateTimeZone 198 | false 199 | true 200 | 201 | 202 | 203 | Locale whose predefined formatting styles 204 | for dates and times are to be used to 205 | parse. 206 | 207 | locale 208 | false 209 | true 210 | 211 | 212 | 213 | Name of the exported scoped variable in 214 | which the parsing result (of type 215 | org.joda.time.DateTime) is stored. 216 | 217 | var 218 | false 219 | false 220 | 221 | 222 | 223 | Scope of var. 224 | 225 | scope 226 | false 227 | false 228 | 229 | 230 | 231 | 232 | -------------------------------------------------------------------------------- /src/main/assembly/dist.xml: -------------------------------------------------------------------------------- 1 | 2 | dist 3 | 4 | tar.gz 5 | zip 6 | 7 | ${artifactId}-${version} 8 | 9 | 10 | 11 | checkstyle.xml 12 | LICENSE.txt 13 | NOTICE.txt 14 | pom.xml 15 | RELEASE-NOTES.txt 16 | 17 | 18 | 19 | src 20 | 21 | 22 | target 23 | 24 | 25 | *.jar 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /src/main/java/org/joda/time/contrib/jsptag/DateTimeZoneSupport.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2004 The Apache Software Foundation. 3 | * Modifications, Copyright 2005 Stephen Colebourne 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.joda.time.contrib.jsptag; 18 | 19 | import java.io.IOException; 20 | 21 | import javax.servlet.jsp.JspException; 22 | import javax.servlet.jsp.JspTagException; 23 | import javax.servlet.jsp.PageContext; 24 | import javax.servlet.jsp.jstl.core.Config; 25 | import javax.servlet.jsp.tagext.BodyTagSupport; 26 | import javax.servlet.jsp.tagext.Tag; 27 | 28 | import org.joda.time.DateTimeZone; 29 | 30 | /** 31 | * Support for tag handlers for <timeZone>. 32 | * 33 | * @author Jan Luehe 34 | * @author Jim Newsham 35 | */ 36 | public abstract class DateTimeZoneSupport extends BodyTagSupport { 37 | 38 | /** The config key for the time zone. */ 39 | public static final String FMT_TIME_ZONE = "org.joda.time.dateTimeZone"; 40 | 41 | /** The value attribute. */ 42 | protected Object value; 43 | 44 | /** The zone. */ 45 | private DateTimeZone dateTimeZone; 46 | 47 | /** 48 | * Constructor. 49 | */ 50 | public DateTimeZoneSupport() { 51 | super(); 52 | init(); 53 | } 54 | 55 | private void init() { 56 | value = null; 57 | } 58 | 59 | public DateTimeZone getDateTimeZone() { 60 | return dateTimeZone; 61 | } 62 | 63 | public int doStartTag() throws JspException { 64 | if (value == null) { 65 | dateTimeZone = DateTimeZone.UTC; 66 | } else if (value instanceof String) { 67 | try { 68 | dateTimeZone = DateTimeZone.forID((String) value); 69 | } catch (IllegalArgumentException iae) { 70 | dateTimeZone = DateTimeZone.UTC; 71 | } 72 | } else { 73 | dateTimeZone = (DateTimeZone) value; 74 | } 75 | return EVAL_BODY_BUFFERED; 76 | } 77 | 78 | public int doEndTag() throws JspException { 79 | try { 80 | pageContext.getOut().print(bodyContent.getString()); 81 | } catch (IOException ioe) { 82 | throw new JspTagException(ioe.toString(), ioe); 83 | } 84 | return EVAL_PAGE; 85 | } 86 | 87 | // Releases any resources we may have (or inherit) 88 | public void release() { 89 | init(); 90 | } 91 | 92 | /** 93 | * Determines and returns the time zone to be used by the given action. 94 | *

95 | * If the given action is nested inside a <dateTimeZone> action, 96 | * the time zone is taken from the enclosing <dateTimeZone> action. 97 | *

98 | * Otherwise, the time zone configuration setting 99 | * org.joda.time.FMT_TIME_ZONE is used. 100 | * 101 | * @param pc the page containing the action for which the time zone 102 | * needs to be determined 103 | * @param fromTag the action for which the time zone needs to be determined 104 | * 105 | * @return the time zone, or null if the given action is not 106 | * nested inside a <dateTimeZone> action and no time zone configuration 107 | * setting exists 108 | */ 109 | static DateTimeZone getDateTimeZone(PageContext pc, Tag fromTag) { 110 | DateTimeZone tz = null; 111 | 112 | Tag t = findAncestorWithClass(fromTag, DateTimeZoneSupport.class); 113 | if (t != null) { 114 | // use time zone from parent tag 115 | DateTimeZoneSupport parent = (DateTimeZoneSupport) t; 116 | tz = parent.getDateTimeZone(); 117 | } else { 118 | // get time zone from configuration setting 119 | Object obj = Config.find(pc, FMT_TIME_ZONE); 120 | if (obj != null) { 121 | if (obj instanceof DateTimeZone) { 122 | tz = (DateTimeZone) obj; 123 | } else { 124 | try { 125 | tz = DateTimeZone.forID((String) obj); 126 | } catch (IllegalArgumentException iae) { 127 | tz = DateTimeZone.UTC; 128 | } 129 | } 130 | } 131 | } 132 | 133 | return tz; 134 | } 135 | 136 | } 137 | -------------------------------------------------------------------------------- /src/main/java/org/joda/time/contrib/jsptag/DateTimeZoneTag.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2004 The Apache Software Foundation. 3 | * Modifications, Copyright 2005 Stephen Colebourne 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.joda.time.contrib.jsptag; 18 | 19 | import javax.servlet.jsp.JspTagException; 20 | 21 | /** 22 | * A handler for <dateTimeZone>. 23 | * 24 | * @author Jan Luehe 25 | * @author Jim Newsham 26 | */ 27 | public class DateTimeZoneTag extends DateTimeZoneSupport { 28 | 29 | // for tag attribute 30 | public void setValue(Object value) throws JspTagException { 31 | this.value = value; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/org/joda/time/contrib/jsptag/FormatSupport.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2004 The Apache Software Foundation. 3 | * Modifications, Copyright 2005 Stephen Colebourne 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.joda.time.contrib.jsptag; 18 | 19 | import java.io.IOException; 20 | import java.text.DateFormat; 21 | import java.util.Locale; 22 | 23 | import javax.servlet.jsp.JspException; 24 | import javax.servlet.jsp.JspTagException; 25 | import javax.servlet.jsp.PageContext; 26 | import javax.servlet.jsp.tagext.TagSupport; 27 | 28 | import org.joda.time.DateTimeZone; 29 | import org.joda.time.ReadableInstant; 30 | import org.joda.time.ReadablePartial; 31 | import org.joda.time.format.DateTimeFormat; 32 | import org.joda.time.format.DateTimeFormatter; 33 | 34 | /** 35 | * Support for tag handlers for <formatDate>, the date and time 36 | * formatting tag in JSTL 1.0. 37 | * 38 | * @author Jan Luehe 39 | * @author Jim Newsham 40 | */ 41 | public abstract class FormatSupport extends TagSupport { 42 | 43 | /** The value attribute. */ 44 | protected Object value; 45 | /** The pattern attribute. */ 46 | protected String pattern; 47 | /** The style attribute. */ 48 | protected String style; 49 | /** The dateTimeZone attribute. */ 50 | protected DateTimeZone dateTimeZone; 51 | /** The locale attribute. */ 52 | protected Locale locale; 53 | /** The var attribute. */ 54 | private String var; 55 | /** The scope attribute. */ 56 | private int scope; 57 | 58 | /** 59 | * Constructor. 60 | */ 61 | public FormatSupport() { 62 | super(); 63 | init(); 64 | } 65 | 66 | private void init() { 67 | var = null; 68 | value = null; 69 | pattern = null; 70 | style = null; 71 | dateTimeZone = null; 72 | locale = null; 73 | scope = PageContext.PAGE_SCOPE; 74 | } 75 | 76 | public void setVar(String var) { 77 | this.var = var; 78 | } 79 | 80 | public void setScope(String scope) { 81 | this.scope = Util.getScope(scope); 82 | } 83 | 84 | /* 85 | * Formats the given instant or partial. 86 | */ 87 | public int doEndTag() throws JspException { 88 | if (value == null) { 89 | if (var != null) { 90 | pageContext.removeAttribute(var, scope); 91 | } 92 | return EVAL_PAGE; 93 | } 94 | 95 | // Create formatter 96 | DateTimeFormatter formatter; 97 | if (pattern != null) { 98 | formatter = DateTimeFormat.forPattern(pattern); 99 | } else if (style != null) { 100 | formatter = DateTimeFormat.forStyle(style); 101 | } else { 102 | // use a medium date (no time) style by default; same as jstl 103 | formatter = DateTimeFormat.mediumDate(); 104 | } 105 | 106 | // set formatter locale 107 | Locale locale = this.locale; 108 | if (locale == null) { 109 | locale = Util.getFormattingLocale(pageContext, this, true, 110 | DateFormat.getAvailableLocales()); 111 | } 112 | if (locale != null) { 113 | formatter = formatter.withLocale(locale); 114 | } 115 | 116 | // set formatter timezone 117 | DateTimeZone tz = this.dateTimeZone; 118 | if (tz == null) { 119 | tz = DateTimeZoneSupport.getDateTimeZone(pageContext, this); 120 | } 121 | if (tz != null) { 122 | formatter = formatter.withZone(tz); 123 | } 124 | 125 | // format value 126 | String formatted; 127 | if (value instanceof ReadableInstant) { 128 | formatted = formatter.print((ReadableInstant) value); 129 | } else if (value instanceof ReadablePartial) { 130 | formatted = formatter.print((ReadablePartial) value); 131 | } else { 132 | throw new JspException( 133 | "value attribute of format tag must be a ReadableInstant or ReadablePartial," + 134 | " was: " + value.getClass().getName()); 135 | } 136 | 137 | if (var != null) { 138 | pageContext.setAttribute(var, formatted, scope); 139 | } else { 140 | try { 141 | pageContext.getOut().print(formatted); 142 | } catch (IOException ioe) { 143 | throw new JspTagException(ioe.toString(), ioe); 144 | } 145 | } 146 | 147 | return EVAL_PAGE; 148 | } 149 | 150 | // Releases any resources we may have (or inherit) 151 | public void release() { 152 | init(); 153 | } 154 | 155 | } 156 | -------------------------------------------------------------------------------- /src/main/java/org/joda/time/contrib/jsptag/FormatTag.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2004 The Apache Software Foundation. 3 | * Modifications, Copyright 2005 Stephen Colebourne 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.joda.time.contrib.jsptag; 18 | 19 | import java.util.Locale; 20 | 21 | import javax.servlet.jsp.JspTagException; 22 | 23 | import org.joda.time.DateTimeZone; 24 | 25 | /** 26 | *

27 | * A handler for <format> that supports rtexprvalue-based attributes. 28 | *

29 | * 30 | * @author Jan Luehe 31 | * @author Jim Newsham 32 | */ 33 | public class FormatTag extends FormatSupport { 34 | 35 | /** 36 | * Sets the value attribute. 37 | * 38 | * @param value the value 39 | */ 40 | public void setValue(Object value) throws JspTagException { 41 | this.value = value; 42 | } 43 | 44 | /** 45 | * Sets the style attribute. 46 | * 47 | * @param style the style 48 | */ 49 | public void setStyle(String style) throws JspTagException { 50 | this.style = style; 51 | } 52 | 53 | /** 54 | * Sets the pattern attribute. 55 | * 56 | * @param pattern the pattern 57 | */ 58 | public void setPattern(String pattern) throws JspTagException { 59 | this.pattern = pattern; 60 | } 61 | 62 | /** 63 | * Sets the zone attribute. 64 | * 65 | * @param dtz the zone 66 | */ 67 | public void setDateTimeZone(Object dtz) throws JspTagException { 68 | if (dtz == null || dtz instanceof String 69 | && ((String) dtz).length() == 0) { 70 | this.dateTimeZone = null; 71 | } else if (dtz instanceof DateTimeZone) { 72 | this.dateTimeZone = (DateTimeZone) dtz; 73 | } else { 74 | try { 75 | this.dateTimeZone = DateTimeZone.forID((String) dtz); 76 | } catch (IllegalArgumentException iae) { 77 | this.dateTimeZone = DateTimeZone.UTC; 78 | } 79 | } 80 | } 81 | 82 | /** 83 | * Sets the style attribute. 84 | * 85 | * @param loc the locale 86 | */ 87 | public void setLocale(Object loc) throws JspTagException { 88 | if (loc == null 89 | || (loc instanceof String && ((String) loc).length() == 0)) { 90 | this.locale = null; 91 | } else if (loc instanceof Locale) { 92 | this.locale = (Locale) loc; 93 | } else { 94 | this.locale = Util.parseLocale((String) loc); 95 | } 96 | } 97 | 98 | } 99 | -------------------------------------------------------------------------------- /src/main/java/org/joda/time/contrib/jsptag/JodaTagLibraryValidator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2004 The Apache Software Foundation. 3 | * Modifications, Copyright 2005 Stephen Colebourne 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.joda.time.contrib.jsptag; 18 | 19 | import java.io.IOException; 20 | import java.util.Vector; 21 | 22 | import javax.servlet.jsp.tagext.PageData; 23 | import javax.servlet.jsp.tagext.TagLibraryValidator; 24 | import javax.servlet.jsp.tagext.ValidationMessage; 25 | import javax.xml.parsers.ParserConfigurationException; 26 | import javax.xml.parsers.SAXParser; 27 | import javax.xml.parsers.SAXParserFactory; 28 | 29 | import org.xml.sax.Attributes; 30 | import org.xml.sax.SAXException; 31 | import org.xml.sax.helpers.DefaultHandler; 32 | 33 | /** 34 | *

35 | * A SAX-based TagLibraryValidator for the Joda tags. Currently implements the 36 | * following checks: 37 | *

38 | * 39 | *
    40 | *
  • Tag bodies that must either be empty or non-empty given particular 41 | * attributes.
  • 42 | *
  • Expression syntax validation (NOTE: this has been disabled; per my 43 | * understanding, it shouldn't be needed in JSP 2.0+ containers; see notes in 44 | * source code for more information). 45 | *
46 | * 47 | * @author Shawn Bayern 48 | * @author Jan Luehe 49 | * @author Jim Newsham 50 | */ 51 | public class JodaTagLibraryValidator extends TagLibraryValidator { 52 | 53 | /* 54 | * Expression syntax validation has been disabled since when I ported this 55 | * code over from Jakarta Taglib, I wanted to reduce dependencies. As I 56 | * understand it, JSP 2.0 containers take over the responsibility of 57 | * handling EL code (both in attribute tags, and externally), so this 58 | * shouldn't be a problem unless you're using something old. If you want to 59 | * restore this validation, you must uncomment the various lines in this 60 | * source, include the Jakarta Taglib's standard.jar library at build and 61 | * runtime, and (I believe, but don't know specifically) make a legacy-style 62 | * tld which describes which attributes should be validated. Have a look at 63 | * fmt.tld, fmt-1.0.tld, fmt-1.0-rt.tld in standard.jar for an example of 64 | * this. 65 | */ 66 | 67 | // ********************************************************************* 68 | // Implementation Overview 69 | /* 70 | * We essentially just run the page through a SAX parser, handling the 71 | * callbacks that interest us. We collapse elements into the text 72 | * they contain, since this simplifies processing somewhat. Even a quick 73 | * glance at the implementation shows its necessary, tree-oriented nature: 74 | * multiple Stacks, an understanding of 'depth', and so on all are important 75 | * as we recover necessary state upon each callback. This TLV demonstrates 76 | * various techniques, from the general "how do I use a SAX parser for a 77 | * TLV?" to "how do I read my init parameters and then validate?" But also, 78 | * the specific SAX methodology was kept as general as possible to allow for 79 | * experimentation and flexibility. 80 | */ 81 | 82 | // ********************************************************************* 83 | // Constants 84 | // tag names 85 | private static final String SET_DATETIMEZONE = "setDateTimeZone"; 86 | 87 | private static final String PARSE_DATETIME = "parseDateTime"; 88 | 89 | private static final String JSP_TEXT = "jsp:text"; 90 | 91 | // attribute names 92 | private static final String VALUE = "value"; 93 | 94 | // parameter names 95 | // private final String EXP_ATT_PARAM = "expressionAttributes"; 96 | 97 | // attributes 98 | private static final String VAR = "var"; 99 | 100 | private static final String SCOPE = "scope"; 101 | 102 | // scopes 103 | private static final String PAGE_SCOPE = "page"; 104 | 105 | private static final String REQUEST_SCOPE = "request"; 106 | 107 | private static final String SESSION_SCOPE = "session"; 108 | 109 | private static final String APPLICATION_SCOPE = "application"; 110 | 111 | // Relevant URIs 112 | private final String JSP = "http://java.sun.com/JSP/Page"; 113 | 114 | // ********************************************************************* 115 | // Validation and configuration state (protected) 116 | 117 | private String uri; // our taglib's uri (as passed by JSP container on XML 118 | // View) 119 | 120 | private String prefix; // our taglib's prefix 121 | 122 | private Vector messageVector; // temporary error messages 123 | 124 | // private Map config; // configuration (Map of Sets) 125 | // 126 | // private boolean failed; // have we failed >0 times? 127 | 128 | private String lastElementId; // the last element we've seen 129 | 130 | // ********************************************************************* 131 | // Constructor and lifecycle management 132 | 133 | public JodaTagLibraryValidator() { 134 | init(); 135 | } 136 | 137 | private void init() { 138 | messageVector = null; 139 | prefix = null; 140 | // config = null; 141 | } 142 | 143 | public void release() { 144 | super.release(); 145 | init(); 146 | } 147 | 148 | public synchronized ValidationMessage[] validate(String prefix, String uri, 149 | PageData page) { 150 | try { 151 | this.uri = uri; 152 | // initialize 153 | messageVector = new Vector(); 154 | 155 | // save the prefix 156 | this.prefix = prefix; 157 | 158 | // parse parameters if necessary 159 | /* 160 | * try { if (config == null) { configure((String) 161 | * getInitParameters().get(EXP_ATT_PARAM)); } } catch 162 | * (NoSuchElementException ex) { // parsing error return 163 | * vmFromString(Resources.getMessage("TLV_PARAMETER_ERROR", 164 | * EXP_ATT_PARAM)); } 165 | */ 166 | 167 | DefaultHandler h = new Handler(); 168 | 169 | // parse the page 170 | SAXParserFactory f = SAXParserFactory.newInstance(); 171 | f.setValidating(false); 172 | f.setNamespaceAware(true); 173 | SAXParser p = f.newSAXParser(); 174 | p.parse(page.getInputStream(), h); 175 | 176 | if (messageVector.size() == 0) { 177 | return null; 178 | } else { 179 | return vmFromVector(messageVector); 180 | } 181 | } catch (SAXException ex) { 182 | return vmFromString(ex.toString()); 183 | } catch (ParserConfigurationException ex) { 184 | return vmFromString(ex.toString()); 185 | } catch (IOException ex) { 186 | return vmFromString(ex.toString()); 187 | } 188 | } 189 | 190 | /* 191 | * // delegate validation to the appropriate expression language private 192 | * String validateExpression(String elem, String att, String expr) { // 193 | * let's just use the cache kept by the ExpressionEvaluatorManager 194 | * ExpressionEvaluator current; try { current = 195 | * ExpressionEvaluatorManager.getEvaluatorByName( 196 | * ExpressionEvaluatorManager.EVALUATOR_CLASS); } catch (JspException ex) { // 197 | * (using JspException here feels ugly, but it's what EEM uses) return 198 | * ex.getMessage(); } String response = current.validate(att, expr); return 199 | * (response == null) ? null : "tag = '" + elem + "' / attribute = '" + att + 200 | * "': " + response; } 201 | */ 202 | 203 | // utility methods to help us match elements in our tagset 204 | private boolean isTag(String tagUri, String tagLn, String matchUri, 205 | String matchLn) { 206 | if (tagUri == null || tagLn == null || matchUri == null 207 | || matchLn == null) { 208 | return false; 209 | } 210 | // match beginning of URI since some suffix *_rt tags can 211 | // be nested in EL enabled tags as defined by the spec 212 | if (tagUri.length() > matchUri.length()) { 213 | return (tagUri.startsWith(matchUri) && tagLn.equals(matchLn)); 214 | } else { 215 | return (matchUri.startsWith(tagUri) && tagLn.equals(matchLn)); 216 | } 217 | } 218 | 219 | // private boolean isJspTag(String tagUri, String tagLn, String target) { 220 | // return isTag(tagUri, tagLn, JSP, target); 221 | // } 222 | 223 | private boolean isJodaTag(String tagUri, String tagLn, String target) { 224 | return isTag(tagUri, tagLn, this.uri, target); 225 | } 226 | 227 | // utility method to determine if an attribute exists 228 | private boolean hasAttribute(Attributes a, String att) { 229 | return (a.getValue(att) != null); 230 | } 231 | 232 | /* 233 | * method to assist with failure [ as if it's not easy enough already :-) ] 234 | */ 235 | private void fail(String message) { 236 | // failed = true; 237 | messageVector.add(new ValidationMessage(lastElementId, message)); 238 | } 239 | 240 | // // returns true if the given attribute name is specified, false otherwise 241 | // private boolean isSpecified(TagData data, String attributeName) { 242 | // return (data.getAttribute(attributeName) != null); 243 | // } 244 | 245 | // returns true if the 'scope' attribute is valid 246 | protected boolean hasNoInvalidScope(Attributes a) { 247 | String scope = a.getValue(SCOPE); 248 | if ((scope != null) && !scope.equals(PAGE_SCOPE) 249 | && !scope.equals(REQUEST_SCOPE) && !scope.equals(SESSION_SCOPE) 250 | && !scope.equals(APPLICATION_SCOPE)) { 251 | return false; 252 | } 253 | return true; 254 | } 255 | 256 | // returns true if the 'var' attribute is empty 257 | protected boolean hasEmptyVar(Attributes a) { 258 | return "".equals(a.getValue(VAR)); 259 | } 260 | 261 | // returns true if the 'scope' attribute is present without 'var' 262 | protected boolean hasDanglingScope(Attributes a) { 263 | return (a.getValue(SCOPE) != null && a.getValue(VAR) == null); 264 | } 265 | 266 | // retrieves the local part of a QName 267 | protected String getLocalPart(String qname) { 268 | int colon = qname.indexOf(":"); 269 | return (colon == -1) ? qname : qname.substring(colon + 1); 270 | } 271 | 272 | // parses our configuration parameter for element:attribute pairs 273 | /* 274 | * private void configure(String info) { // construct our configuration map 275 | * config = new HashMap(); 276 | * // leave the map empty if we have nothing to configure if (info == null) { 277 | * return; } 278 | * // separate parameter into space-separated tokens and store them 279 | * StringTokenizer st = new StringTokenizer(info); while 280 | * (st.hasMoreTokens()) { String pair = st.nextToken(); StringTokenizer 281 | * pairTokens = new StringTokenizer(pair, ":"); String element = 282 | * pairTokens.nextToken(); String attribute = pairTokens.nextToken(); Object 283 | * atts = config.get(element); if (atts == null) { atts = new HashSet(); 284 | * config.put(element, atts); } ((Set) atts).add(attribute); } } 285 | */ 286 | 287 | // constructs a ValidationMessage[] from a single String and no ID 288 | private static ValidationMessage[] vmFromString(String message) { 289 | return new ValidationMessage[] { new ValidationMessage(null, message) }; 290 | } 291 | 292 | // constructs a ValidationMessage[] from a ValidationMessage Vector 293 | private static ValidationMessage[] vmFromVector(Vector v) { 294 | ValidationMessage[] vm = new ValidationMessage[v.size()]; 295 | for (int i = 0; i < vm.length; i++) { 296 | vm[i] = (ValidationMessage) v.get(i); 297 | } 298 | return vm; 299 | } 300 | 301 | /** 302 | * SAX event handler. 303 | */ 304 | private class Handler extends DefaultHandler { 305 | // parser state 306 | private int depth = 0; 307 | 308 | private String lastElementName = null; 309 | 310 | private boolean bodyNecessary = false; 311 | 312 | private boolean bodyIllegal = false; 313 | 314 | // process under the existing context (state), then modify it 315 | public void startElement(String ns, String ln, String qn, Attributes a) { 316 | // substitute our own parsed 'ln' if it's not provided 317 | if (ln == null) { 318 | ln = getLocalPart(qn); 319 | } 320 | 321 | // for simplicity, we can ignore for our purposes 322 | // (don't bother distinguishing between it and its characters) 323 | if (qn.equals(JSP_TEXT)) { 324 | return; 325 | } 326 | 327 | // check body-related constraint 328 | if (bodyIllegal) { 329 | fail(Resources.getMessage("TLV_ILLEGAL_BODY", lastElementName)); 330 | } 331 | 332 | // validate expression syntax if we need to 333 | /* 334 | * Set expAtts; if (qn.startsWith(prefix + ":") && (expAtts = (Set) 335 | * config.get(ln)) != null) { for (int i = 0; i < a.getLength(); 336 | * i++) { String attName = a.getLocalName(i); if 337 | * (expAtts.contains(attName)) { String vMsg = 338 | * validateExpression(ln, attName, a.getValue(i)); if (vMsg != null) { 339 | * fail(vMsg); } } } } 340 | */ 341 | 342 | // validate attributes 343 | if (qn.startsWith(prefix + ":") && !hasNoInvalidScope(a)) { 344 | fail(Resources.getMessage("TLV_INVALID_ATTRIBUTE", SCOPE, qn, a 345 | .getValue(SCOPE))); 346 | } 347 | if (qn.startsWith(prefix + ":") && hasEmptyVar(a)) { 348 | fail(Resources.getMessage("TLV_EMPTY_VAR", qn)); 349 | } 350 | if (qn.startsWith(prefix + ":") 351 | && !isJodaTag(ns, ln, SET_DATETIMEZONE) 352 | && hasDanglingScope(a)) { 353 | fail(Resources.getMessage("TLV_DANGLING_SCOPE", qn)); 354 | } 355 | 356 | // now, modify state 357 | 358 | // set up a check against illegal attribute/body combinations 359 | bodyIllegal = false; 360 | bodyNecessary = false; 361 | if (isJodaTag(ns, ln, PARSE_DATETIME)) { 362 | if (hasAttribute(a, VALUE)) { 363 | bodyIllegal = true; 364 | } else { 365 | bodyNecessary = true; 366 | } 367 | } 368 | 369 | // record the most recent tag (for error reporting) 370 | lastElementName = qn; 371 | lastElementId = a.getValue(JSP, "id"); 372 | 373 | // we're a new element, so increase depth 374 | depth++; 375 | } 376 | 377 | public void characters(char[] ch, int start, int length) { 378 | bodyNecessary = false; // body is no longer necessary! 379 | 380 | // ignore strings that are just whitespace 381 | String s = new String(ch, start, length).trim(); 382 | if (s.equals("")) { 383 | return; 384 | } 385 | 386 | // check and update body-related constraints 387 | if (bodyIllegal) { 388 | fail(Resources.getMessage("TLV_ILLEGAL_BODY", lastElementName)); 389 | } 390 | } 391 | 392 | public void endElement(String ns, String ln, String qn) { 393 | // consistently, we ignore JSP_TEXT 394 | if (qn.equals(JSP_TEXT)) { 395 | return; 396 | } 397 | 398 | // handle body-related invariant 399 | if (bodyNecessary) { 400 | fail(Resources.getMessage("TLV_MISSING_BODY", lastElementName)); 401 | } 402 | bodyIllegal = false; // reset: we've left the tag 403 | 404 | // update our depth 405 | depth--; 406 | } 407 | } 408 | 409 | } 410 | -------------------------------------------------------------------------------- /src/main/java/org/joda/time/contrib/jsptag/ParseDateTimeSupport.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2004 The Apache Software Foundation. 3 | * Modifications, Copyright 2005 Stephen Colebourne 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.joda.time.contrib.jsptag; 18 | 19 | import java.io.IOException; 20 | import java.text.DateFormat; 21 | import java.util.Locale; 22 | 23 | import javax.servlet.jsp.JspException; 24 | import javax.servlet.jsp.JspTagException; 25 | import javax.servlet.jsp.PageContext; 26 | import javax.servlet.jsp.tagext.BodyTagSupport; 27 | 28 | import org.joda.time.DateTime; 29 | import org.joda.time.DateTimeZone; 30 | import org.joda.time.format.DateTimeFormat; 31 | import org.joda.time.format.DateTimeFormatter; 32 | 33 | /** 34 | * Support for tag handlers for <parseDate>, the date and time parsing tag 35 | * in JSTL 1.0. 36 | * 37 | * @author Jan Luehe 38 | * @author Jim Newsham 39 | */ 40 | public abstract class ParseDateTimeSupport extends BodyTagSupport { 41 | 42 | /** The value attribute. */ 43 | protected String value; 44 | /** Status of the value. */ 45 | protected boolean valueSpecified; 46 | /** The pattern attribute. */ 47 | protected String pattern; 48 | /** The style attribute. */ 49 | protected String style; 50 | /** The zone attribute. */ 51 | protected DateTimeZone dateTimeZone; 52 | /** The locale attribute. */ 53 | protected Locale locale; 54 | /** The var attribute. */ 55 | private String var; 56 | /** The scope attribute. */ 57 | private int scope; 58 | 59 | /** 60 | * Constructor. 61 | */ 62 | public ParseDateTimeSupport() { 63 | super(); 64 | init(); 65 | } 66 | 67 | private void init() { 68 | value = null; 69 | valueSpecified = false; 70 | pattern = null; 71 | style = null; 72 | dateTimeZone = null; 73 | locale = null; 74 | scope = PageContext.PAGE_SCOPE; 75 | } 76 | 77 | public void setVar(String var) { 78 | this.var = var; 79 | } 80 | 81 | public void setScope(String scope) { 82 | this.scope = Util.getScope(scope); 83 | } 84 | 85 | public int doEndTag() throws JspException { 86 | String input = null; 87 | 88 | // determine the input by... 89 | if (valueSpecified) { 90 | // ... reading 'value' attribute 91 | input = value; 92 | } else { 93 | // ... retrieving and trimming our body 94 | if (bodyContent != null && bodyContent.getString() != null) { 95 | input = bodyContent.getString().trim(); 96 | } 97 | } 98 | 99 | if ((input == null) || input.equals("")) { 100 | if (var != null) { 101 | pageContext.removeAttribute(var, scope); 102 | } 103 | return EVAL_PAGE; 104 | } 105 | 106 | // Create formatter 107 | DateTimeFormatter formatter; 108 | if (pattern != null) { 109 | formatter = DateTimeFormat.forPattern(pattern); 110 | } else if (style != null) { 111 | formatter = DateTimeFormat.forStyle(style); 112 | } else { 113 | formatter = DateTimeFormat.fullDateTime(); 114 | } 115 | 116 | // set formatter locale 117 | Locale locale = this.locale; 118 | if (locale == null) { 119 | locale = Util.getFormattingLocale(pageContext, this, true, 120 | DateFormat.getAvailableLocales()); 121 | } 122 | if (locale != null) { 123 | formatter = formatter.withLocale(locale); 124 | } 125 | 126 | // set formatter timezone 127 | DateTimeZone tz = this.dateTimeZone; 128 | if (tz == null) { 129 | tz = DateTimeZoneSupport.getDateTimeZone(pageContext, this); 130 | } 131 | if (tz != null) { 132 | formatter = formatter.withZone(tz); 133 | } 134 | 135 | // Parse date 136 | DateTime parsed = null; 137 | try { 138 | parsed = formatter.parseDateTime(input); 139 | } catch (IllegalArgumentException iae) { 140 | throw new JspException(Resources.getMessage( 141 | "PARSE_DATE_PARSE_ERROR", input), iae); 142 | } 143 | 144 | if (var != null) { 145 | pageContext.setAttribute(var, parsed, scope); 146 | } else { 147 | try { 148 | pageContext.getOut().print(parsed); 149 | } catch (IOException ioe) { 150 | throw new JspTagException(ioe.toString(), ioe); 151 | } 152 | } 153 | 154 | return EVAL_PAGE; 155 | } 156 | 157 | // Releases any resources we may have (or inherit) 158 | public void release() { 159 | init(); 160 | } 161 | 162 | } 163 | -------------------------------------------------------------------------------- /src/main/java/org/joda/time/contrib/jsptag/ParseDateTimeTag.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2004 The Apache Software Foundation. 3 | * Modifications, Copyright 2005 Stephen Colebourne 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.joda.time.contrib.jsptag; 18 | 19 | import java.util.Locale; 20 | 21 | import javax.servlet.jsp.JspTagException; 22 | 23 | import org.joda.time.DateTimeZone; 24 | 25 | /** 26 | *

27 | * A handler for <parseDate> that supports rtexprvalue-based attributes. 28 | *

29 | * 30 | * @author Jan Luehe 31 | * @author Jim Newsham 32 | */ 33 | 34 | public class ParseDateTimeTag extends ParseDateTimeSupport { 35 | 36 | /** 37 | * Sets the value attribute. 38 | * 39 | * @param value the value 40 | */ 41 | public void setValue(String value) throws JspTagException { 42 | this.value = value; 43 | this.valueSpecified = true; 44 | } 45 | 46 | /** 47 | * Sets the style attribute. 48 | * 49 | * @param style the style 50 | */ 51 | public void setStyle(String style) throws JspTagException { 52 | this.style = style; 53 | } 54 | 55 | /** 56 | * Sets the pattern attribute. 57 | * 58 | * @param pattern the pattern 59 | */ 60 | public void setPattern(String pattern) throws JspTagException { 61 | this.pattern = pattern; 62 | } 63 | 64 | /** 65 | * Sets the zone attribute. 66 | * 67 | * @param dtz the zone 68 | */ 69 | public void setDateTimeZone(Object dtz) throws JspTagException { 70 | if (dtz == null || dtz instanceof String 71 | && ((String) dtz).length() == 0) { 72 | this.dateTimeZone = null; 73 | } else if (dtz instanceof DateTimeZone) { 74 | this.dateTimeZone = (DateTimeZone) dtz; 75 | } else { 76 | try { 77 | this.dateTimeZone = DateTimeZone.forID((String) dtz); 78 | } catch (IllegalArgumentException iae) { 79 | this.dateTimeZone = DateTimeZone.UTC; 80 | } 81 | } 82 | } 83 | 84 | /** 85 | * Sets the style attribute. 86 | * 87 | * @param loc the locale 88 | */ 89 | public void setLocale(Object loc) throws JspTagException { 90 | if (loc == null 91 | || (loc instanceof String && ((String) loc).length() == 0)) { 92 | this.locale = null; 93 | } else if (loc instanceof Locale) { 94 | this.locale = (Locale) loc; 95 | } else { 96 | locale = Util.parseLocale((String) loc); 97 | } 98 | } 99 | 100 | } 101 | -------------------------------------------------------------------------------- /src/main/java/org/joda/time/contrib/jsptag/Resources.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2004 The Apache Software Foundation. 3 | * Modifications, Copyright 2005 Stephen Colebourne 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.joda.time.contrib.jsptag; 18 | 19 | import java.text.MessageFormat; 20 | import java.util.MissingResourceException; 21 | import java.util.ResourceBundle; 22 | 23 | /** 24 | *

Provides locale-neutral access to string resources. Only the 25 | * documentation and code are in English. :-) 26 | * 27 | *

The major goal, aside from globalization, is convenience. 28 | * Access to resources with no parameters is made in the form:

29 | *
 30 |  *     Resources.getMessage(MESSAGE_NAME);
 31 |  * 
32 | * 33 | *

Access to resources with one parameter works like

34 | *
 35 |  *     Resources.getMessage(MESSAGE_NAME, arg1);
 36 |  * 
37 | * 38 | *

... and so on.

39 | * 40 | * @author Shawn Bayern 41 | */ 42 | public class Resources { 43 | 44 | //********************************************************************* 45 | // Static data 46 | 47 | /** The location of our resources. */ 48 | private static final String RESOURCE_LOCATION = "org.joda.time.contrib.jsptag.Resources"; 49 | 50 | /** Our class-wide ResourceBundle. */ 51 | private static ResourceBundle rb = ResourceBundle.getBundle(RESOURCE_LOCATION); 52 | 53 | 54 | //********************************************************************* 55 | // Public static methods 56 | 57 | /** Retrieves a message with no arguments. */ 58 | public static String getMessage(String name) 59 | throws MissingResourceException { 60 | return rb.getString(name); 61 | } 62 | 63 | /** Retrieves a message with arbitrarily many arguments. */ 64 | public static String getMessage(String name, Object[] a) 65 | throws MissingResourceException { 66 | String res = rb.getString(name); 67 | return MessageFormat.format(res, a); 68 | } 69 | 70 | /** Retrieves a message with one argument. */ 71 | public static String getMessage(String name, Object a1) 72 | throws MissingResourceException { 73 | return getMessage(name, new Object[] { a1 }); 74 | } 75 | 76 | /** Retrieves a message with two arguments. */ 77 | public static String getMessage(String name, Object a1, Object a2) 78 | throws MissingResourceException { 79 | return getMessage(name, new Object[] { a1, a2 }); 80 | } 81 | 82 | /** Retrieves a message with three arguments. */ 83 | public static String getMessage(String name, 84 | Object a1, 85 | Object a2, 86 | Object a3) 87 | throws MissingResourceException { 88 | return getMessage(name, new Object[] { a1, a2, a3 }); 89 | } 90 | 91 | /** Retrieves a message with four arguments. */ 92 | public static String getMessage(String name, 93 | Object a1, 94 | Object a2, 95 | Object a3, 96 | Object a4) 97 | throws MissingResourceException { 98 | return getMessage(name, new Object[] { a1, a2, a3, a4 }); 99 | } 100 | 101 | /** Retrieves a message with five arguments. */ 102 | public static String getMessage(String name, 103 | Object a1, 104 | Object a2, 105 | Object a3, 106 | Object a4, 107 | Object a5) 108 | throws MissingResourceException { 109 | return getMessage(name, new Object[] { a1, a2, a3, a4, a5 }); 110 | } 111 | 112 | /** Retrieves a message with six arguments. */ 113 | public static String getMessage(String name, 114 | Object a1, 115 | Object a2, 116 | Object a3, 117 | Object a4, 118 | Object a5, 119 | Object a6) 120 | throws MissingResourceException { 121 | return getMessage(name, new Object[] { a1, a2, a3, a4, a5, a6 }); 122 | } 123 | 124 | } 125 | -------------------------------------------------------------------------------- /src/main/java/org/joda/time/contrib/jsptag/Resources.properties: -------------------------------------------------------------------------------- 1 | ######################################################################### 2 | # Conventions: 3 | # - For error messages from particular tags, the resource should 4 | # - (a) have a name beginning with TAGNAME_ 5 | # - (b) contain the name of the tag within the message 6 | # - Generic tag messages -- i.e., those used in more than one tag -- 7 | # should begin with TAG_ 8 | # - Errors for TagLibraryValidators should begin with TLV_ 9 | ######################################################################### 10 | 11 | 12 | ######################################################################### 13 | # Generic tag error messages 14 | ######################################################################### 15 | 16 | TAG_NULL_ATTRIBUTE=\ 17 | The "{0}" attribute illegally evaluated to "null" or "" in <{1}> 18 | 19 | ######################################################################### 20 | # Specific tag error messages 21 | ######################################################################### 22 | 23 | # CORE 24 | 25 | CHOOSE_EXCLUSIVITY=\ 26 | Only one (or is it two?) <choose> subtag may evaluate its body 27 | 28 | EXPR_BAD_VALUE=\ 29 | In <expr>, attribute value="{0}" didn't evaluate successfully, \ 30 | but there was no "default" attribute and no non-whitespace content \ 31 | for the tag. 32 | 33 | FOREACH_STEP_NO_RESULTSET=\ 34 | Step cannot be > 1 when iterating over a ResultSet with <forEach> 35 | 36 | FOREACH_BAD_ITEMS=\ 37 | Don't know how to iterate over supplied "items" in <forEach> 38 | 39 | IMPORT_BAD_RELATIVE=\ 40 | In URL tags, when the "context" attribute is specified, \ 41 | values of both "context" and "url" must start with "/". 42 | 43 | IMPORT_REL_WITHOUT_HTTP=\ 44 | Relative <import> from non-HTTP request not allowed 45 | 46 | IMPORT_REL_WITHOUT_DISPATCHER=\ 47 | Unable to get RequestDispatcher for Context: "{0}" and URL: "{1}". \ 48 | Verify values and/or enable cross context access. 49 | 50 | IMPORT_IO=\ 51 | I/O error in <import> occurred reading "{0}" 52 | 53 | IMPORT_ILLEGAL_STREAM=\ 54 | Unexpected internal error during <import>: \ 55 | Target servlet called getWriter(), then getOutputStream() 56 | 57 | IMPORT_ILLEGAL_WRITER=\ 58 | Unexpected internal error during <import>: \ 59 | Target servlet called getOutputStream(), then getWriter() 60 | 61 | #IMPORT_ILLEGAL_GETSTRING=\ 62 | # Unexpected internal error during <import>: \ 63 | # Target servlet called neither getOutputStream() nor getWriter() 64 | 65 | PARAM_OUTSIDE_PARENT=\ 66 | <param> outside <import> or <urlEncode> 67 | 68 | PARAM_ENCODE_BOOLEAN=\ 69 | In <param>, "encode" must be "true" or "false". Got "{0}" instead. 70 | 71 | SET_BAD_SCOPE=\ 72 | Invalid "scope" attribute for <set>: "{0}" 73 | 74 | SET_INVALID_PROPERTY=\ 75 | Invalid property in <set>: "{0}" 76 | 77 | SET_INVALID_TARGET=\ 78 | Attempt to set the property of an invalid object in <set>. 79 | 80 | SET_NO_VALUE=\ 81 | Need either non-whitespace body or "value" attribute in <set> 82 | 83 | URLENCODE_NO_VALUE=\ 84 | Need either non-whitespace body or "value" attribute in <urlEncode> 85 | 86 | WHEN_OUTSIDE_CHOOSE=\ 87 | Illegal use of <when>-style tag without <choose> as its \ 88 | direct parent 89 | 90 | # I18N 91 | 92 | LOCALE_NO_LANGUAGE=\ 93 | Missing language component in 'value' attribute in <setLocale> 94 | 95 | LOCALE_EMPTY_COUNTRY=\ 96 | Empty country component in 'value' attribute in <setLocale> 97 | 98 | PARAM_OUTSIDE_MESSAGE=\ 99 | <param> outside <message> 100 | 101 | MESSAGE_NO_KEY=\ 102 | <message> needs 'key' attribute or non-whitespace body 103 | 104 | FORMAT_NUMBER_INVALID_TYPE=\ 105 | In <formatNumber>, invalid 'type' attribute: "{0}" 106 | 107 | FORMAT_NUMBER_NO_VALUE=\ 108 | <formatNumber> needs 'value' attribute or non-whitespace body 109 | 110 | FORMAT_NUMBER_PARSE_ERROR=\ 111 | In <formatNumber>, 'value' attribute can not be parsed into java.lang.Number: "{0}" 112 | 113 | FORMAT_NUMBER_CURRENCY_ERROR=\ 114 | In <formatNumber>, unable to set currency 115 | 116 | PARSE_NUMBER_INVALID_TYPE=\ 117 | In <parseNumber>, invalid 'type' attribute: "{0}" 118 | 119 | PARSE_NUMBER_NO_VALUE=\ 120 | <parseNumber> needs 'value' attribute or non-whitespace body 121 | 122 | PARSE_NUMBER_NO_PARSE_LOCALE=\ 123 | In <parseNumber>, a parse locale can not be established 124 | 125 | PARSE_NUMBER_PARSE_ERROR=\ 126 | In <parseNumber>, 'value' attribute can not be parsed: "{0}" 127 | 128 | FORMAT_DATE_INVALID_TYPE=\ 129 | In <formatDate>, invalid 'type' attribute: "{0}" 130 | 131 | FORMAT_DATE_BAD_TIMEZONE=\ 132 | In <formatDate>, 'timeZone' must be an instance of java.lang.String or java.util.TimeZone 133 | 134 | FORMAT_DATE_INVALID_DATE_STYLE=\ 135 | In <formatDate>, invalid 'dateStyle' attribute: "{0}" 136 | 137 | FORMAT_DATE_INVALID_TIME_STYLE=\ 138 | In <formatDate>, invalid 'timeStyle' attribute: "{0}" 139 | 140 | PARSE_DATE_INVALID_TYPE=\ 141 | In <parseDate>, invalid 'type' attribute: "{0}" 142 | 143 | PARSE_DATE_BAD_TIMEZONE=\ 144 | In <parseDate>, 'timeZone' must be an instance of java.lang.String or java.util.TimeZone 145 | 146 | PARSE_DATE_INVALID_DATE_STYLE=\ 147 | In <parseDate>, invalid 'dateStyle' attribute: "{0}" 148 | 149 | PARSE_DATE_INVALID_TIME_STYLE=\ 150 | In <parseDate>, invalid 'timeStyle' attribute: "{0}" 151 | 152 | PARSE_DATE_NO_VALUE=\ 153 | <parseDate> needs 'value' attribute or non-whitespace body 154 | 155 | PARSE_DATE_PARSE_ERROR=\ 156 | In <parseDate>, 'value' attribute can not be parsed: "{0}" 157 | 158 | PARSE_DATE_NO_PARSE_LOCALE=\ 159 | In <parseDate>, a parse locale can not be established 160 | 161 | # SQL 162 | 163 | DRIVER_INVALID_CLASS=\ 164 | In <driver>, invalid driver class name: "{0}" 165 | 166 | DATASOURCE_INVALID=\ 167 | Unable to get connection, DataSource invalid: "{0}" 168 | 169 | JDBC_PARAM_COUNT=\ 170 | Invalid number of JDBC parameters specified. 171 | 172 | PARAM_BAD_VALUE=\ 173 | Invalid or out of bounds value specified in parameter. 174 | 175 | TRANSACTION_NO_SUPPORT=\ 176 | In <transaction>, datasource does not support transactions 177 | 178 | TRANSACTION_COMMIT_ERROR=\ 179 | In <transaction>, error committing transaction: "{0}" 180 | 181 | TRANSACTION_INVALID_ISOLATION=\ 182 | In <transaction>, invalid transaction isolation 183 | 184 | NOT_SUPPORTED=\ 185 | Not supported 186 | 187 | ERROR_GET_CONNECTION=\ 188 | Error getting connection: "{0}" 189 | 190 | ERROR_NESTED_DATASOURCE=\ 191 | It is illegal to specify a DataSource when nested within a <transaction> 192 | 193 | SQL_PARAM_OUTSIDE_PARENT=\ 194 | <param> or <dateParam> must be subtag of SQLExecutionTag actions like <query> or <update> 195 | 196 | SQL_NO_STATEMENT=\ 197 | No SQL statement specified 198 | 199 | SQL_PROCESS_ERROR=\ 200 | Error processing SQL: "{0}" 201 | 202 | SQL_DATASOURCE_INVALID_TYPE=\ 203 | 'dataSource' is neither a String nor a javax.sql.DataSource 204 | 205 | SQL_DATASOURCE_NULL=\ 206 | 'dataSource' is null 207 | 208 | SQL_MAXROWS_PARSE_ERROR=\ 209 | Error parsing 'javax.servlet.jsp.jstl.sql.maxRows' configuration setting: "{0}" 210 | 211 | SQL_MAXROWS_INVALID=\ 212 | 'javax.servlet.jsp.jstl.sql.maxRows' configuration setting neither an Integer nor a String 213 | 214 | SQL_DATE_PARAM_INVALID_TYPE=\ 215 | In <dateParam>, invalid 'type' attribute: "{0}" 216 | 217 | # XML 218 | 219 | FOREACH_NOT_NODESET=\ 220 | <forEach> can't iterate over XPath expressions that don't return a node-set 221 | 222 | PARAM_NO_VALUE=\ 223 | <param> needs 'value' attribute or non-whitespace body 224 | 225 | PARAM_OUTSIDE_TRANSFORM=\ 226 | <param> outside <transform> 227 | 228 | PARSE_INVALID_SOURCE=\ 229 | Unrecognized object supplied as 'xml' attribute to <parse> 230 | 231 | PARSE_NO_SAXTRANSFORMER=\ 232 | Filter supplied to <parse>, but default TransformerFactory \ 233 | does not support SAX. 234 | 235 | TRANSFORM_NO_TRANSFORMER=\ 236 | <transform> was not passed an XSLT stylesheet 237 | 238 | TRANSFORM_SOURCE_INVALID_LIST=\ 239 | <transform> encountered an invalid java.util.List while processing 'xml' attribute. This error is typically caused if you pass a node-set with more than one node to <transform>'s 'xml' attribute. 240 | 241 | TRANSFORM_SOURCE_UNRECOGNIZED=\ 242 | <transform> encountered an unknown type while processing 'xml' attribute 243 | 244 | TRANSFORM_XSLT_UNRECOGNIZED=\ 245 | <transform> encountered an unknown type while processing 'xslt' attribute 246 | 247 | UNABLE_TO_RESOLVE_ENTITY=\ 248 | Could not resolve entity reference: "{0}" 249 | 250 | ######################################################################### 251 | # JSTL core TLV messages 252 | ######################################################################### 253 | 254 | # Parameters 255 | 256 | TLV_PARAMETER_ERROR=\ 257 | Invalid value for "{0}" validator parameter in TLD 258 | 259 | # Generic errors 260 | 261 | TLV_ILLEGAL_BODY=\ 262 | Encountered illegal body of tag "{0}" tag, given its attributes. 263 | 264 | TLV_MISSING_BODY=\ 265 | A body is necessary inside the "{0}" tag, given its attributes. 266 | 267 | TLV_ILLEGAL_CHILD_TAG=\ 268 | Illegal child tag in "{0}:{1}" tag: "{2}" tag 269 | 270 | TLV_ILLEGAL_TEXT_BODY=\ 271 | Illegal text inside "{0}:{1}" tag: "{2}...". 272 | 273 | TLV_INVALID_ATTRIBUTE=\ 274 | Invalid "{0}" attribute in "{1}" tag: "{2}" 275 | 276 | TLV_ILLEGAL_ORPHAN=\ 277 | Invalid use of "{0}" tag outside legitimate parent tag 278 | 279 | TLV_PARENT_WITHOUT_SUBTAG=\ 280 | Illegal "{0}" without child "{1}" tag 281 | 282 | # Errors customized to particular tags (sort of) :-) 283 | 284 | TLV_ILLEGAL_ORDER=\ 285 | Illegal "{0}" after "{1}:{2}" tag in "{1}:{3}" tag. 286 | 287 | TLV_ILLEGAL_PARAM=\ 288 | Illegal "{0}:{1}" tag within "{0}:{2} {3}='...'" tag 289 | 290 | TLV_DANGLING_SCOPE=\ 291 | Illegal 'scope' attribute without 'var' in "{0}" tag. 292 | 293 | TLV_EMPTY_VAR=\ 294 | Empty 'var' attribute in "{0}" tag. 295 | 296 | SET_NO_SETTER_METHOD=No setter method in <set> for property "{0}" 297 | 298 | IMPORT_ABS_ERROR=Problem accessing the absolute URL "{0}". {1} 299 | 300 | XPATH_ERROR_EVALUATING_EXPR=Error evaluating XPath expression "{0}": {1} 301 | 302 | XPATH_ILLEGAL_ARG_EVALUATING_EXPR=Illegal argument evaluating XPath expression "{0}": {1} 303 | 304 | XPATH_ERROR_XOBJECT=Error accessing data in XObject: {0} 305 | -------------------------------------------------------------------------------- /src/main/java/org/joda/time/contrib/jsptag/Resources_ja.properties: -------------------------------------------------------------------------------- 1 | ######################################################################### 2 | # Conventions: 3 | # - For error messages from particular tags, the resource should 4 | # - (a) have a name beginning with TAGNAME_ 5 | # - (b) contain the name of the tag within the message 6 | # - Generic tag messages -- i.e., those used in more than one tag -- 7 | # should begin with TAG_ 8 | # - Errors for TagLibraryValidators should begin with TLV_ 9 | ######################################################################### 10 | 11 | 12 | ######################################################################### 13 | # Generic tag error messages 14 | ######################################################################### 15 | 16 | TAG_NULL_ATTRIBUTE=\ 17 | <{1}> \u5185\u306b\u3042\u308b "{0}" \u5c5e\u6027\u304c "null" \u3082\u3057\u304f\u306f "" \u3067\u3042\u308b\u3068\u4e0d\u6b63\u306b\u8a55\u4fa1\u3057\u307e\u3057\u305f\u3002 18 | 19 | ######################################################################### 20 | # Specific tag error messages 21 | ######################################################################### 22 | 23 | # CORE 24 | 25 | CHOOSE_EXCLUSIVITY=\ 26 | \uff11\u3064\u3057\u304b\u5b58\u5728\u306a\u3044 <choose> \u306e\u4e0b\u4f4d\u30bf\u30b0\u306f\u30dc\u30c7\u30a3\u306e\u4e2d\u8eab\u3092\u305d\u306e\u307e\u307e\u8a55\u4fa1\u3057\u307e\u3059 27 | 28 | EXPR_BAD_VALUE=\ 29 | <expr> \u5185\u3067\u3001\u5c5e\u6027\u5024="{0}" \u304c\u6b63\u3057\u304f\u8a55\u4fa1\u3055\u308c\u305a\u3001"default" \u5c5e\u6027\u3084\u30db\u30ef\u30a4\u30c8\u30b9\u30da\u30fc\u30b9\u306e\u306a\u3044\u30b3\u30f3\u30c6\u30f3\u30c4\u304c\u30bf\u30b0\u306e\u4e2d\u306b\u5b58\u5728\u3057\u307e\u305b\u3093 30 | 31 | FOREACH_STEP_NO_RESULTSET=\ 32 | <forEach> \u3067 ResultSet \u3092\u53cd\u5fa9\u51e6\u7406\u3057\u3088\u3046\u3068\u3057\u305f\u3068\u3053\u308d\u3001step \u306e\u5024\u3092 1 \u3088\u308a\u5927\u304d\u304f\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u305b\u3093 33 | 34 | FOREACH_BAD_ITEMS=\ 35 | <forEach> \u5185\u3067\u4f9b\u7d66\u3055\u308c\u305f "items" \u3092\u53cd\u5fa9\u51e6\u7406\u3059\u308b\u65b9\u6cd5\u304c\u4e0d\u660e\u3067\u3059 36 | 37 | IMPORT_BAD_RELATIVE=\ 38 | URL \u30bf\u30b0\u3067 "context" \u5c5e\u6027\u3092\u6307\u5b9a\u3059\u308b\u969b\u3001"context" \u304a\u3088\u3073 "url" \u306e\u4e21\u65b9\u306e\u5024\u306f "/" \u3067\u59cb\u307e\u3063\u3066\u3044\u306a\u3044\u3068\u3044\u3051\u307e\u305b\u3093 39 | 40 | IMPORT_REL_WITHOUT_HTTP=\ 41 | \u975e HTTP \u8981\u6c42\u3067\u306f\u3001URL\u3092\u76f8\u5bfe\u6307\u5b9a\u3059\u308b <import> \u3092\u8a31\u53ef\u3057\u3066\u3044\u307e\u305b\u3093 42 | 43 | IMPORT_REL_WITHOUT_DISPATCHER=\ 44 | Context: "{0}" \u304a\u3088\u3073 URL: "{1}" \u306b\u5bfe\u3057\u3066 RequestDispatcher \u3092\u53d6\u5f97\u3067\u304d\u307e\u305b\u3093\u3002\u6307\u5b9a\u3057\u305f\u5024\u3092\u78ba\u8a8d\u3059\u308b\u304b\u3001\u3082\u3057\u304f\u306f\u3001Context \u3092\u76f8\u4e92\u7684\u306b\u30a2\u30af\u30bb\u30b9\u3067\u304d\u308b\u3088\u3046\u306b\u3057\u3066\u304f\u3060\u3055\u3044 45 | 46 | IMPORT_IO=\ 47 | <import> \u3067\u3001"{0}" \u3092\u8aad\u307f\u8fbc\u307f\u4e2d\u306b\u5165\u51fa\u529b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f 48 | 49 | IMPORT_ILLEGAL_STREAM=\ 50 | <import> \u5185\u3067\u4e88\u671f\u305b\u306c\u5185\u90e8\u30a8\u30e9\u30fc: \u5bfe\u8c61\u3068\u306a\u3063\u305f Servlet \u3067 getWriter() \u30e1\u30bd\u30c3\u30c9\u304c\u547c\u3073\u51fa\u3055\u308c\u3066\u3044\u308b\u306e\u306b getOutputStream() \u30e1\u30bd\u30c3\u30c9\u3092\u547c\u3073\u51fa\u305d\u3046\u3068\u3057\u307e\u3057\u305f 51 | 52 | IMPORT_ILLEGAL_WRITER=\ 53 | <import> \u5185\u3067\u4e88\u671f\u305b\u306c\u5185\u90e8\u30a8\u30e9\u30fc: \u5bfe\u8c61\u3068\u306a\u3063\u305f Servlet \u3067 getOutputStream() \u30e1\u30bd\u30c3\u30c9\u304c\u547c\u3073\u51fa\u3055\u308c\u3066\u3044\u308b\u306e\u306b getWriter() \u30e1\u30bd\u30c3\u30c9\u3092\u547c\u3073\u51fa\u305d\u3046\u3068\u3057\u307e\u3057\u305f 54 | 55 | #IMPORT_ILLEGAL_GETSTRING=\ 56 | # Unexpected internal error during <import>: \ 57 | # Target servlet called neither getOutputStream() nor getWriter() 58 | 59 | PARAM_OUTSIDE_PARENT=\ 60 | <import> \u3082\u3057\u304f\u306f <urlEncode> \u306e\u5916\u5074\u306b <param> \u304c\u3042\u308a\u307e\u3059 61 | 62 | PARAM_ENCODE_BOOLEAN=\ 63 | <param> \u3067\u306f\u3001"encode" \u306f "true" \u3082\u3057\u304f\u306f "false" \u3067\u306a\u3044\u3068\u3044\u3051\u307e\u305b\u3093\u3002\u4ee3\u308f\u308a\u306b "{0}" \u3092\u53d6\u5f97\u3057\u307e\u3057\u305f 64 | 65 | SET_BAD_SCOPE=\ 66 | <set> \u306b\u5bfe\u3057\u3001\u7121\u52b9\u306a "scope" \u5c5e\u6027\u3067\u3059: "{0}" 67 | 68 | SET_INVALID_PROPERTY=\ 69 | <set> \u306b\u5bfe\u3057\u3001\u7121\u52b9\u306a\u30d7\u30ed\u30d1\u30c6\u30a3\u3067\u3059: "{0}" 70 | 71 | SET_INVALID_TARGET=\ 72 | <set> \u306b\u5bfe\u3057\u3001\u7121\u52b9\u306a\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u306e\u30d7\u30ed\u30d1\u30c6\u30a3\u3092\u30bb\u30c3\u30c8\u3057\u3088\u3046\u3068\u3057\u3066\u3044\u307e\u3059 73 | 74 | SET_NO_VALUE=\ 75 | <set> \u3067\u306f\u3001\u30db\u30ef\u30a4\u30c8\u30b9\u30da\u30fc\u30b9\u306e\u306a\u3044\u30dc\u30c7\u30a3\u3082\u3057\u304f\u306f "value" \u5c5e\u6027\u304c\u5fc5\u8981\u3067\u3059 76 | 77 | URLENCODE_NO_VALUE=\ 78 | <urlEncode> \u3067\u306f\u3001\u30db\u30ef\u30a4\u30c8\u30b9\u30da\u30fc\u30b9\u306e\u306a\u3044\u30dc\u30c7\u30a3\u3082\u3057\u304f\u306f "value" \u5c5e\u6027\u304c\u5fc5\u8981\u3067\u3059 79 | 80 | WHEN_OUTSIDE_CHOOSE=\ 81 | \u76f4\u8fd1\u306e\u89aa\u30bf\u30b0\u3067\u3042\u308b <choose> \u3092\u30bb\u30c3\u30c8\u305b\u305a\u306b <when> \u30b9\u30bf\u30a4\u30eb\u30fb\u30bf\u30b0\u3092\u4f7f\u3046\u3053\u3068\u306f\u6b63\u3057\u304f\u3042\u308a\u307e\u305b\u3093 82 | 83 | # I18N 84 | 85 | LOCALE_NO_LANGUAGE=\ 86 | <setLocale> \u3067\u3001'value' \u5c5e\u6027\u306b\u6307\u5b9a\u3057\u305f\u8a00\u8a9e\u30b3\u30fc\u30c9\u304c\u307e\u3061\u304c\u3063\u3066\u3044\u307e\u3059 87 | 88 | LOCALE_EMPTY_COUNTRY=\ 89 | <setLocale> \u3067\u3001'value' \u5c5e\u6027\u306b\u6307\u5b9a\u3057\u305f\u56fd\u30b3\u30fc\u30c9\u304c\u5b58\u5728\u3057\u307e\u305b\u3093 90 | 91 | PARAM_OUTSIDE_MESSAGE=\ 92 | <message> \u306e\u5916\u5074\u306b <param> \u304c\u3042\u308a\u307e\u3059 93 | 94 | MESSAGE_NO_KEY=\ 95 | <message> \u3067\u306f 'key' \u5c5e\u6027\u3082\u3057\u304f\u306f\u30db\u30ef\u30a4\u30c8\u30b9\u30da\u30fc\u30b9\u306e\u306a\u3044\u30dc\u30c7\u30a3\u304c\u5fc5\u8981\u3067\u3059 96 | 97 | FORMAT_NUMBER_INVALID_TYPE=\ 98 | <formatNumber> \u3067\u3001\u7121\u52b9\u306a 'type' \u5c5e\u6027\u3067\u3059: "{0}" 99 | 100 | FORMAT_NUMBER_NO_VALUE=\ 101 | <formatNumber> \u3067\u306f 'value' \u5c5e\u6027\u3082\u3057\u304f\u306f\u30db\u30ef\u30a4\u30c8\u30b9\u30da\u30fc\u30b9\u306e\u306a\u3044\u30dc\u30c7\u30a3\u304c\u5fc5\u8981\u3067\u3059 102 | 103 | FORMAT_NUMBER_PARSE_ERROR=\ 104 | <formatNumber> \u5185\u306b\u3042\u308b\u3001'value' \u5c5e\u6027\u3092 java.lang.Number \u578b\u3067\u89e3\u6790\u3067\u304d\u307e\u305b\u3093: "{0}" 105 | 106 | FORMAT_NUMBER_CURRENCY_ERROR=\ 107 | <formatNumber> \u3067\u3001\u901a\u8ca8\u30d5\u30a9\u30fc\u30de\u30c3\u30c8\u3092\u30bb\u30c3\u30c8\u3067\u304d\u307e\u305b\u3093 108 | 109 | PARSE_NUMBER_INVALID_TYPE=\ 110 | <parseNumber> \u3067\u3001\u7121\u52b9\u306a 'type' \u5c5e\u6027\u3067\u3059: "{0}" 111 | 112 | PARSE_NUMBER_NO_VALUE=\ 113 | <parseNumber> \u3067\u306f 'value' \u5c5e\u6027\u3082\u3057\u304f\u306f\u30db\u30ef\u30a4\u30c8\u30b9\u30da\u30fc\u30b9\u306e\u306a\u3044\u30dc\u30c7\u30a3\u304c\u5fc5\u8981\u3067\u3059 114 | 115 | PARSE_NUMBER_NO_PARSE_LOCALE=\ 116 | <parseNumber> \u5185\u3067\u3001\u89e3\u6790\u3055\u308c\u305f\u30ed\u30b1\u30fc\u30eb\u3092\u78ba\u5b9a\u3067\u304d\u307e\u305b\u3093 117 | 118 | PARSE_NUMBER_PARSE_ERROR=\ 119 | <parseNumber> \u5185\u306b\u3042\u308b\u3001'value' \u5c5e\u6027\u3092\u89e3\u6790\u3067\u304d\u307e\u305b\u3093: "{0}" 120 | 121 | FORMAT_DATE_INVALID_TYPE=\ 122 | <formatDate> \u3067\u3001\u7121\u52b9\u306a 'type' \u5c5e\u6027\u3067\u3059: "{0}" 123 | 124 | FORMAT_DATE_BAD_TIMEZONE=\ 125 | <formatDate> \u3067\u306f\u3001'timeZone' \u306f java.lang.String \u578b\u3082\u3057\u304f\u306f java.util.TimeZone \u578b\u306e\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3067\u306a\u3044\u3068\u3044\u3051\u307e\u305b\u3093 126 | 127 | FORMAT_DATE_INVALID_DATE_STYLE=\ 128 | <formatDate> \u3067\u3001\u7121\u52b9\u306a 'dateStyle' \u5c5e\u6027\u3067\u3059: "{0}" 129 | 130 | FORMAT_DATE_INVALID_TIME_STYLE=\ 131 | <formatDate> \u3067\u3001\u7121\u52b9\u306a 'timeStyle' \u5c5e\u6027\u3067\u3059: "{0}" 132 | 133 | PARSE_DATE_INVALID_TYPE=\ 134 | <parseDate> \u3067\u3001\u7121\u52b9\u306a 'type' \u5c5e\u6027\u3067\u3059: "{0}" 135 | 136 | PARSE_DATE_BAD_TIMEZONE=\ 137 | <parseDate> \u5185\u306b\u3042\u308b\u3001'timeZone' \u306f java.lang.String \u578b\u3082\u3057\u304f\u306f java.util.TimeZone \u578b\u306e\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3067\u306a\u3044\u3068\u3044\u3051\u307e\u305b\u3093 138 | 139 | PARSE_DATE_INVALID_DATE_STYLE=\ 140 | <parseDate> \u3067\u3001\u7121\u52b9\u306a 'dateStyle' \u5c5e\u6027\u3067\u3059: "{0}" 141 | 142 | PARSE_DATE_INVALID_TIME_STYLE=\ 143 | <parseDate> \u3067\u3001\u7121\u52b9\u306a 'timeStyle' \u5c5e\u6027\u3067\u3059: "{0}" 144 | 145 | PARSE_DATE_NO_VALUE=\ 146 | <parseDate> \u3067\u306f 'value' \u5c5e\u6027\u3082\u3057\u304f\u306f\u30db\u30ef\u30a4\u30c8\u30b9\u30da\u30fc\u30b9\u306e\u306a\u3044\u30dc\u30c7\u30a3\u304c\u5fc5\u8981\u3067\u3059 147 | 148 | PARSE_DATE_PARSE_ERROR=\ 149 | <parseDate> \u5185\u306b\u3042\u308b\u3001'value' \u5c5e\u6027\u3092\u89e3\u6790\u3067\u304d\u307e\u305b\u3093: "{0}" 150 | 151 | PARSE_DATE_NO_PARSE_LOCALE=\ 152 | <parseDate> \u5185\u3067\u3001\u89e3\u6790\u3055\u308c\u305f\u30ed\u30b1\u30fc\u30eb\u3092\u78ba\u5b9a\u3067\u304d\u307e\u305b\u3093 153 | 154 | # SQL 155 | 156 | DRIVER_INVALID_CLASS=\ 157 | <driver> \u3067\u3001\u7121\u52b9\u306a\u30c9\u30e9\u30a4\u30d0\u30fb\u30af\u30e9\u30b9\u540d\u3092\u6307\u5b9a\u3057\u307e\u3057\u305f: "{0}" 158 | 159 | DATASOURCE_INVALID=\ 160 | DataSource \u304c\u7121\u52b9\u3067\u3042\u308b\u305f\u3081\u3001Connection \u3092\u53d6\u5f97\u3067\u304d\u307e\u305b\u3093: "{0}" 161 | 162 | JDBC_PARAM_COUNT=\ 163 | \u6307\u5b9a\u3057\u305f JDBC \u306e\u30d1\u30e9\u30e1\u30fc\u30bf\u6570\u304c\u7121\u52b9\u3067\u3059 164 | 165 | PARAM_BAD_VALUE=\ 166 | \u30d1\u30e9\u30e1\u30fc\u30bf\u3067\u6307\u5b9a\u3057\u305f\u5024\u304c\u7121\u52b9\u3067\u3042\u308b\u304b\u7bc4\u56f2\u5916\u3067\u3059 167 | 168 | TRANSACTION_NO_SUPPORT=\ 169 | <transaction> \u5185\u306b\u3042\u308b\u3001DataSource \u306f\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u3092\u30b5\u30dd\u30fc\u30c8\u3057\u3066\u3044\u307e\u305b\u3093 170 | 171 | TRANSACTION_COMMIT_ERROR=\ 172 | <transaction> \u306b\u304a\u3044\u3066\u3001\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u306e\u30b3\u30df\u30c3\u30c8\u6642\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f: "{0}" 173 | 174 | TRANSACTION_INVALID_ISOLATION=\ 175 | <transaction> \u306b\u304a\u3044\u3066\u3001\u7121\u52b9\u306a\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u906e\u65ad\u30ec\u30d9\u30eb\u3092\u6307\u5b9a\u3057\u307e\u3057\u305f 176 | 177 | NOT_SUPPORTED=\ 178 | \u30b5\u30dd\u30fc\u30c8\u3057\u3066\u3044\u307e\u305b\u3093 179 | 180 | ERROR_GET_CONNECTION=\ 181 | Connection \u306e\u53d6\u5f97\u6642\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f: "{0}" 182 | 183 | ERROR_NESTED_DATASOURCE=\ 184 | <transaction> \u306e\u4e2d\u3067\u5165\u308c\u5b50\u3068\u306a\u3063\u305f\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3092\u6307\u5b9a\u3059\u308b\u3053\u3068\u306f\u4e0d\u6b63\u3067\u3059 185 | 186 | SQL_PARAM_OUTSIDE_PARENT=\ 187 | <param> \u307e\u305f\u306f <dateParam> \u306f <query> \u3082\u3057\u304f\u306f <update> \u306e\u3088\u3046\u306b SQLExecutionTag \u547d\u4ee4\u306e\u4e0b\u4f4d\u30bf\u30b0\u3067\u306a\u3051\u308c\u3070\u3044\u3051\u307e\u305b\u3093 188 | 189 | SQL_NO_STATEMENT=\ 190 | SQL \u30b9\u30c6\u30fc\u30c8\u30e1\u30f3\u30c8\u304c\u6307\u5b9a\u3055\u308c\u3066\u3044\u307e\u305b\u3093 191 | 192 | SQL_PROCESS_ERROR=\ 193 | SQL \u306e\u51e6\u7406\u6642\u306b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f: "{0}" 194 | 195 | SQL_DATASOURCE_INVALID_TYPE=\ 196 | 'dataSource' \u304c String \u578b \u3067\u3082 javax.sql.DataSource \u578b\u306e\u3069\u3061\u3089\u3067\u3082\u3042\u308a\u307e\u305b\u3093 197 | 198 | SQL_DATASOURCE_NULL=\ 199 | 'dataSource' \u304c null \u3067\u3059 200 | 201 | SQL_MAXROWS_PARSE_ERROR=\ 202 | 'javax.servlet.jsp.jstl.sql.maxRows' \u306e\u74b0\u5883\u8a2d\u5b9a\u3067\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f: "{0}" 203 | 204 | SQL_MAXROWS_INVALID=\ 205 | 'javax.servlet.jsp.jstl.sql.maxRows' \u3067\u74b0\u5883\u8a2d\u5b9a\u3057\u305f\u5024\u306f Integer \u578b \u3067\u3082 String \u578b\u306e\u3069\u3061\u3089\u3067\u3082\u3042\u308a\u307e\u305b\u3093 206 | 207 | SQL_DATE_PARAM_INVALID_TYPE=\ 208 | <dateParam> \u3067\u3001\u7121\u52b9\u306a 'type' \u5c5e\u6027\u3067\u3059: "{0}" 209 | 210 | # XML 211 | 212 | FOREACH_NOT_NODESET=\ 213 | \u30ce\u30fc\u30c9\u30bb\u30c3\u30c8\u306e\u8fd4\u3055\u308c\u306a\u3044 XPath \u8868\u73fe\u306b\u5bfe\u3057 <forEach> \u306f\u53cd\u5fa9\u51e6\u7406\u3059\u308b\u3053\u3068\u306f\u3067\u304d\u307e\u305b\u3093 214 | 215 | PARAM_NO_VALUE=\ 216 | <param> \u3067\u306f 'value' \u5c5e\u6027\u3082\u3057\u304f\u306f\u30db\u30ef\u30a4\u30c8\u30b9\u30da\u30fc\u30b9\u306e\u306a\u3044\u30dc\u30c7\u30a3\u304c\u5fc5\u8981\u3067\u3059 217 | 218 | PARAM_OUTSIDE_TRANSFORM=\ 219 | <transform> \u306e\u5916\u5074\u306b <param> \u304c\u3042\u308a\u307e\u3059 220 | 221 | PARSE_INVALID_SOURCE=\ 222 | <parse> \u306b\u5bfe\u3057 'xml' \u5c5e\u6027\u3068\u3057\u3066\u4f9b\u7d66\u3057\u305f\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u3092\u8a8d\u8b58\u3067\u304d\u307e\u305b\u3093 223 | 224 | PARSE_NO_SAXTRANSFORMER=\ 225 | <parse> \u306b\u5bfe\u3057\u30d5\u30a3\u30eb\u30bf\u30fc\u304c\u4f9b\u7d66\u3055\u308c\u307e\u3057\u305f\u304c\u3001\u30c7\u30d5\u30a9\u30eb\u30c8\u306e TransformerFactory \u304c SAX \u3092\u30b5\u30dd\u30fc\u30c8\u3057\u3066\u3044\u307e\u305b\u3093 226 | 227 | TRANSFORM_NO_TRANSFORMER=\ 228 | <transform> \u306b\u5bfe\u3057 XSLT \u30b9\u30bf\u30a4\u30eb\u30b7\u30fc\u30c8\u304c\u901a\u308a\u307e\u305b\u3093 229 | 230 | TRANSFORM_SOURCE_INVALID_LIST=\ 231 | <transform> \u5185\u3067 'xml' \u5c5e\u6027\u306e\u51e6\u7406\u4e2d\u306b\u7121\u52b9\u306a java.util.List \u3068\u906d\u9047\u3057\u307e\u3057\u305f\u3002\u3053\u308c\u306f\u3001<transform> \u5185\u306e 'xml' \u5c5e\u6027\u306b\u5bfe\u3057\u3066 1 \u4ee5\u4e0a\u306e\u30ce\u30fc\u30c9\u3067\u69cb\u6210\u3055\u308c\u308b\u30ce\u30fc\u30c9\u30bb\u30c3\u30c8\u3092\u901a\u3055\u306a\u3044\u5834\u5408\u306b\u767a\u751f\u3059\u308b\u5178\u578b\u7684\u306a\u30a8\u30e9\u30fc\u3067\u3059 232 | 233 | TRANSFORM_SOURCE_UNRECOGNIZED=\ 234 | <transform> \u5185\u3067 'xml' \u5c5e\u6027\u306e\u51e6\u7406\u4e2d\u306b\u672a\u77e5\u306e\u578b\u3068\u906d\u9047\u3057\u307e\u3057\u305f 235 | 236 | TRANSFORM_XSLT_UNRECOGNIZED=\ 237 | <transform> \u5185\u3067 'xslt' \u5c5e\u6027\u306e\u51e6\u7406\u4e2d\u306b\u672a\u77e5\u306e\u578b\u3068\u906d\u9047\u3057\u307e\u3057\u305f 238 | 239 | UNABLE_TO_RESOLVE_ENTITY=\ 240 | \u30a8\u30f3\u30c6\u30a3\u30c6\u30a3\u53c2\u7167\u3092\u89e3\u6c7a\u3067\u304d\u307e\u305b\u3093: "{0}" 241 | 242 | ######################################################################### 243 | # JSTL core TLV messages 244 | ######################################################################### 245 | 246 | # Parameters 247 | 248 | TLV_PARAMETER_ERROR=\ 249 | TLD \u306b\u3088\u308b\u3068 "{0}" \u6709\u52b9\u30d1\u30e9\u30e1\u30fc\u30bf\u306b\u5bfe\u5fdc\u3059\u308b\u5024\u304c\u7121\u52b9\u3067\u3059 250 | 251 | # Generic errors 252 | 253 | TLV_ILLEGAL_BODY=\ 254 | \u5c5e\u6027\u3092\u6307\u5b9a\u3057\u307e\u3057\u305f\u304c\u3001"{0}" \u30bf\u30b0\u3067\u4e0d\u6b63\u306a\u30dc\u30c7\u30a3\u306b\u906d\u9047\u3057\u307e\u3057\u305f 255 | 256 | TLV_MISSING_BODY=\ 257 | \u5c5e\u6027\u3092\u6307\u5b9a\u3057\u307e\u3057\u305f\u304c\u3001\u30dc\u30c7\u30a3\u306f "{0}" \u30bf\u30b0\u306e\u4e2d\u306b\u5fc5\u8981\u3067\u3059 258 | 259 | TLV_ILLEGAL_CHILD_TAG=\ 260 | "{0}:{1}" \u30bf\u30b0\u306b\u4e0d\u6b63\u306a\u4e0b\u4f4d\u30bf\u30b0\u304c\u3042\u308a\u307e\u3059: "{2}" \u30bf\u30b0 261 | 262 | TLV_ILLEGAL_TEXT_BODY=\ 263 | "{0}:{1}" \u30bf\u30b0\u306e\u4e2d\u306b\u4e0d\u6b63\u306a\u30c6\u30ad\u30b9\u30c8\u304c\u3042\u308a\u307e\u3059: "{2}...". 264 | 265 | TLV_INVALID_ATTRIBUTE=\ 266 | "{1}" \u306b\u7121\u52b9\u306a "{0}" \u5c5e\u6027\u304c\u3042\u308a\u307e\u3059: "{2}" 267 | 268 | TLV_ILLEGAL_ORPHAN=\ 269 | \u9069\u5207\u306a\u89aa\u30bf\u30b0\u306e\u5916\u5074\u306b\u3042\u308b "{0}" \u30bf\u30b0\u306e\u4f7f\u3044\u65b9\u306f\u6b63\u3057\u304f\u3042\u308a\u307e\u305b\u3093 270 | 271 | TLV_PARENT_WITHOUT_SUBTAG=\ 272 | \u4e0b\u4f4d\u3067\u3042\u308b "{1}" \u30bf\u30b0\u306e\u306a\u3044 "{0}" \u306f\u6b63\u3057\u304f\u3042\u308a\u307e\u305b\u3093 273 | 274 | # Errors customized to particular tags (sort of) :-) 275 | 276 | TLV_ILLEGAL_ORDER=\ 277 | "{1}:{3}" \u30bf\u30b0\u3067\u306f\u3001"{1}:{2}" \u30bf\u30b0\u306e\u5f8c\u306b\u3042\u308b "{0}" \u306f\u6b63\u3057\u304f\u3042\u308a\u307e\u305b\u3093 278 | 279 | TLV_ILLEGAL_PARAM=\ 280 | "{0}:{2} {3}='...'" \u30bf\u30b0\u306e\u4e2d\u306b\u3042\u308b "{0}:{1}" \u30bf\u30b0\u306f\u6b63\u3057\u304f\u3042\u308a\u307e\u305b\u3093 281 | 282 | TLV_DANGLING_SCOPE=\ 283 | "{0}" \u30bf\u30b0\u3067 'var' \u304c\u5b58\u5728\u3057\u306a\u3044\u306e\u306b 'scope' \u5c5e\u6027\u3092\u6307\u5b9a\u3059\u308b\u3053\u3068\u306f\u6b63\u3057\u304f\u3042\u308a\u307e\u305b\u3093 284 | 285 | TLV_EMPTY_VAR=\ 286 | "{0}" \u30bf\u30b0\u3067 'var' \u5c5e\u6027\u304c\u7a7a\u3067\u3059 287 | 288 | SET_NO_SETTER_METHOD=\ 289 | <set> \u306b\u304a\u3044\u3066\u3001\u30d7\u30ed\u30d1\u30c6\u30a3 "{0}" \u306b\u5bfe\u5fdc\u3059\u308b setter \u30e1\u30bd\u30c3\u30c9\u304c\u5b58\u5728\u3057\u307e\u305b\u3093 290 | 291 | IMPORT_ABS_ERROR=Problem accessing the absolute URL "{0}". {1} 292 | 293 | XPATH_ERROR_EVALUATING_EXPR=Error evaluating XPath expression "{0}": {1} 294 | 295 | XPATH_ILLEGAL_ARG_EVALUATING_EXPR=Illegal argument evaluating XPath expression "{0}": {1} 296 | 297 | XPATH_ERROR_XOBJECT=Error accessing data in XObject: {0} 298 | -------------------------------------------------------------------------------- /src/main/java/org/joda/time/contrib/jsptag/SetDateTimeZoneSupport.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2004 The Apache Software Foundation. 3 | * Modifications, Copyright 2005 Stephen Colebourne 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.joda.time.contrib.jsptag; 18 | 19 | import javax.servlet.jsp.JspException; 20 | import javax.servlet.jsp.PageContext; 21 | import javax.servlet.jsp.jstl.core.Config; 22 | import javax.servlet.jsp.tagext.TagSupport; 23 | 24 | import org.joda.time.DateTimeZone; 25 | 26 | /** 27 | * Support for tag handlers for <setDateTimeZone>. 28 | * 29 | * @author Jan Luehe 30 | * @author Jim Newsham 31 | */ 32 | public abstract class SetDateTimeZoneSupport extends TagSupport { 33 | 34 | /** The value attribute. */ 35 | protected Object value; 36 | /** The scope attribute. */ 37 | private int scope; 38 | /** The var attribute. */ 39 | private String var; 40 | 41 | /** 42 | * Constructor. 43 | */ 44 | public SetDateTimeZoneSupport() { 45 | super(); 46 | init(); 47 | } 48 | 49 | // resets local state 50 | private void init() { 51 | value = null; 52 | var = null; 53 | scope = PageContext.PAGE_SCOPE; 54 | } 55 | 56 | public void setScope(String scope) { 57 | this.scope = Util.getScope(scope); 58 | } 59 | 60 | public void setVar(String var) { 61 | this.var = var; 62 | } 63 | 64 | public int doEndTag() throws JspException { 65 | DateTimeZone dateTimeZone = null; 66 | if (value == null) { 67 | dateTimeZone = DateTimeZone.UTC; 68 | } else if (value instanceof String) { 69 | try { 70 | dateTimeZone = DateTimeZone.forID((String) value); 71 | } catch (IllegalArgumentException iae) { 72 | dateTimeZone = DateTimeZone.UTC; 73 | } 74 | } else { 75 | dateTimeZone = (DateTimeZone) value; 76 | } 77 | 78 | if (var != null) { 79 | pageContext.setAttribute(var, dateTimeZone, scope); 80 | } else { 81 | Config.set(pageContext, DateTimeZoneSupport.FMT_TIME_ZONE, 82 | dateTimeZone, scope); 83 | } 84 | 85 | return EVAL_PAGE; 86 | } 87 | 88 | // Releases any resources we may have (or inherit) 89 | public void release() { 90 | init(); 91 | } 92 | 93 | } 94 | -------------------------------------------------------------------------------- /src/main/java/org/joda/time/contrib/jsptag/SetDateTimeZoneTag.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2004 The Apache Software Foundation. 3 | * Modifications, Copyright 2005 Stephen Colebourne 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.joda.time.contrib.jsptag; 18 | 19 | import javax.servlet.jsp.JspTagException; 20 | 21 | /** 22 | *

23 | * A handler for <setDateTimeZone> that supports rtexprvalue-based 24 | * attributes. 25 | *

26 | * 27 | * @author Jan Luehe 28 | * @author Jim Newsham 29 | */ 30 | public class SetDateTimeZoneTag extends SetDateTimeZoneSupport { 31 | 32 | /** 33 | * Sets the value attribute. 34 | * 35 | * @param value the value 36 | */ 37 | public void setValue(Object value) throws JspTagException { 38 | this.value = value; 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/org/joda/time/contrib/jsptag/Util.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1999-2004 The Apache Software Foundation. 3 | * Modifications, Copyright 2005 Stephen Colebourne 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.joda.time.contrib.jsptag; 18 | 19 | import java.text.DateFormat; 20 | import java.text.NumberFormat; 21 | import java.util.Enumeration; 22 | import java.util.Locale; 23 | import java.util.MissingResourceException; 24 | import java.util.ResourceBundle; 25 | import java.util.Vector; 26 | 27 | import javax.servlet.ServletResponse; 28 | import javax.servlet.http.HttpServletRequest; 29 | import javax.servlet.jsp.PageContext; 30 | import javax.servlet.jsp.jstl.core.Config; 31 | import javax.servlet.jsp.jstl.fmt.LocalizationContext; 32 | import javax.servlet.jsp.tagext.Tag; 33 | 34 | /** 35 | *

36 | * Utilities in support of tag-handler classes. 37 | *

38 | * 39 | * @author Jan Luehe 40 | * @author Jim Newsham 41 | */ 42 | public class Util { 43 | 44 | private static final String REQUEST = "request"; 45 | 46 | private static final String SESSION = "session"; 47 | 48 | private static final String APPLICATION = "application"; 49 | 50 | private static final char HYPHEN = '-'; 51 | 52 | private static final char UNDERSCORE = '_'; 53 | 54 | private static final Locale EMPTY_LOCALE = new Locale("", ""); 55 | 56 | static final String REQUEST_CHAR_SET = "javax.servlet.jsp.jstl.fmt.request.charset"; 57 | 58 | /** 59 | * Converts the given string description of a scope to the corresponding 60 | * PageContext constant. 61 | * 62 | * The validity of the given scope has already been checked by the 63 | * appropriate TLV. 64 | * 65 | * @param scope String description of scope 66 | * 67 | * @return PageContext constant corresponding to given scope description 68 | */ 69 | public static int getScope(String scope) { 70 | int ret = PageContext.PAGE_SCOPE; // default 71 | 72 | if (REQUEST.equalsIgnoreCase(scope)) { 73 | ret = PageContext.REQUEST_SCOPE; 74 | } else if (SESSION.equalsIgnoreCase(scope)) { 75 | ret = PageContext.SESSION_SCOPE; 76 | } else if (APPLICATION.equalsIgnoreCase(scope)) { 77 | ret = PageContext.APPLICATION_SCOPE; 78 | } 79 | return ret; 80 | } 81 | 82 | /** 83 | * HttpServletRequest.getLocales() returns the server's default locale if 84 | * the request did not specify a preferred language. We do not want this 85 | * behavior, because it prevents us from using the fallback locale. We 86 | * therefore need to return an empty Enumeration if no preferred locale has 87 | * been specified. This way, the logic for the fallback locale will be able 88 | * to kick in. 89 | */ 90 | public static Enumeration getRequestLocales(HttpServletRequest request) { 91 | Enumeration values = request.getHeaders("accept-language"); 92 | if (values.hasMoreElements()) { 93 | // At least one "accept-language". Simply return 94 | // the enumeration returned by request.getLocales(). 95 | // System.out.println("At least one accept-language"); 96 | return request.getLocales(); 97 | } else { 98 | // No header for "accept-language". Simply return 99 | // the empty enumeration. 100 | // System.out.println("No accept-language"); 101 | return values; 102 | } 103 | } 104 | 105 | /** 106 | * See parseLocale(String, String) for details. 107 | */ 108 | public static Locale parseLocale(String locale) { 109 | return parseLocale(locale, null); 110 | } 111 | 112 | /** 113 | * Parses the given locale string into its language and (optionally) country 114 | * components, and returns the corresponding java.util.Locale 115 | * object. 116 | * 117 | * If the given locale string is null or empty, the runtime's default locale 118 | * is returned. 119 | * 120 | * @param locale the locale string to parse 121 | * @param variant the variant 122 | * 123 | * @return java.util.Locale object corresponding to the given 124 | * locale string, or the runtime's default locale if the locale string is 125 | * null or empty 126 | * 127 | * @throws IllegalArgumentException if the given locale does not have a 128 | * language component or has an empty country component 129 | */ 130 | public static Locale parseLocale(String locale, String variant) { 131 | Locale ret = null; 132 | String language = locale; 133 | String country = null; 134 | int index = -1; 135 | 136 | if (((index = locale.indexOf(HYPHEN)) > -1) 137 | || ((index = locale.indexOf(UNDERSCORE)) > -1)) { 138 | language = locale.substring(0, index); 139 | country = locale.substring(index + 1); 140 | } 141 | 142 | if ((language == null) || (language.length() == 0)) { 143 | throw new IllegalArgumentException(Resources 144 | .getMessage("LOCALE_NO_LANGUAGE")); 145 | } 146 | 147 | if (country == null) { 148 | if (variant != null) { 149 | ret = new Locale(language, "", variant); 150 | } else { 151 | ret = new Locale(language, ""); 152 | } 153 | } else if (country.length() > 0) { 154 | if (variant != null) { 155 | ret = new Locale(language, country, variant); 156 | } else { 157 | ret = new Locale(language, country); 158 | } 159 | } else { 160 | throw new IllegalArgumentException(Resources 161 | .getMessage("LOCALE_EMPTY_COUNTRY")); 162 | } 163 | 164 | return ret; 165 | } 166 | 167 | /** 168 | * Stores the given locale in the response object of the given page context, 169 | * and stores the locale's associated charset in the 170 | * javax.servlet.jsp.jstl.fmt.request.charset session attribute, which may 171 | * be used by the action in a page invoked by a form 172 | * included in the response to set the request charset to the same as the 173 | * response charset (this makes it possible for the container to decode the 174 | * form parameter values properly, since browsers typically encode form 175 | * field values using the response's charset). 176 | * 177 | * @param pc the page context whose response object is assigned the 178 | * given locale 179 | * @param locale the response locale 180 | */ 181 | static void setResponseLocale(PageContext pc, Locale locale) { 182 | // set response locale 183 | ServletResponse response = pc.getResponse(); 184 | response.setLocale(locale); 185 | 186 | // get response character encoding and store it in session attribute 187 | if (pc.getSession() != null) { 188 | try { 189 | pc.setAttribute(REQUEST_CHAR_SET, response 190 | .getCharacterEncoding(), PageContext.SESSION_SCOPE); 191 | } catch (IllegalStateException ex) { 192 | // invalidated session ignored 193 | } 194 | } 195 | } 196 | 197 | /** 198 | * Returns the formatting locale to use with the given formatting action in 199 | * the given page. 200 | * 201 | * @param pc The page context containing the formatting action @param 202 | * fromTag The formatting action @param format true if the 203 | * formatting action is of type (as opposed to ), and 204 | * false otherwise (if set to true, the formatting 205 | * locale that is returned by this method is used to set the response 206 | * locale). 207 | * 208 | * @param avail the array of available locales 209 | * 210 | * @return the formatting locale to use 211 | */ 212 | static Locale getFormattingLocale(PageContext pc, Tag fromTag, 213 | boolean format, Locale[] avail) { 214 | 215 | LocalizationContext locCtxt = null; 216 | 217 | /* 218 | * // Get formatting locale from enclosing Tag parent = 219 | * findAncestorWithClass(fromTag, BundleSupport.class); if (parent != 220 | * null) { /* use locale from localization context established by parent 221 | * action, unless that locale is null / locCtxt = 222 | * ((BundleSupport) parent).getLocalizationContext(); if 223 | * (locCtxt.getLocale() != null) { if (format) { setResponseLocale(pc, 224 | * locCtxt.getLocale()); } return locCtxt.getLocale(); } } 225 | */ 226 | 227 | // Use locale from default I18N localization context, unless it is null 228 | if ((locCtxt = getLocalizationContext(pc)) != null) { 229 | if (locCtxt.getLocale() != null) { 230 | if (format) { 231 | setResponseLocale(pc, locCtxt.getLocale()); 232 | } 233 | return locCtxt.getLocale(); 234 | } 235 | } 236 | 237 | /* 238 | * Establish formatting locale by comparing the preferred locales (in 239 | * order of preference) against the available formatting locales, and 240 | * determining the best matching locale. 241 | */ 242 | Locale match = null; 243 | Locale pref = getLocale(pc, Config.FMT_LOCALE); 244 | if (pref != null) { 245 | // Preferred locale is application-based 246 | match = findFormattingMatch(pref, avail); 247 | } else { 248 | // Preferred locales are browser-based 249 | match = findFormattingMatch(pc, avail); 250 | } 251 | if (match == null) { 252 | // Use fallback locale. 253 | pref = getLocale(pc, Config.FMT_FALLBACK_LOCALE); 254 | if (pref != null) { 255 | match = findFormattingMatch(pref, avail); 256 | } 257 | } 258 | if (format && (match != null)) { 259 | setResponseLocale(pc, match); 260 | } 261 | 262 | return match; 263 | } 264 | 265 | /** 266 | * Setup the available formatting locales that will be used by 267 | * getFormattingLocale(PageContext). 268 | */ 269 | static Locale[] availableFormattingLocales; 270 | static { 271 | Locale[] dateLocales = DateFormat.getAvailableLocales(); 272 | Locale[] numberLocales = NumberFormat.getAvailableLocales(); 273 | Vector vec = new Vector(dateLocales.length); 274 | for (int i = 0; i < dateLocales.length; i++) { 275 | for (int j = 0; j < numberLocales.length; j++) { 276 | if (dateLocales[i].equals(numberLocales[j])) { 277 | vec.add(dateLocales[i]); 278 | break; 279 | } 280 | } 281 | } 282 | availableFormattingLocales = new Locale[vec.size()]; 283 | availableFormattingLocales = (Locale[]) vec 284 | .toArray(availableFormattingLocales); 285 | /* 286 | * for (int i=0; i is used with a 294 | * locale-less localization context. 295 | * 296 | * @param pc The page context containing the formatting action @return the 297 | * formatting locale to use 298 | */ 299 | static Locale getFormattingLocale(PageContext pc) { 300 | /* 301 | * Establish formatting locale by comparing the preferred locales (in 302 | * order of preference) against the available formatting locales, and 303 | * determining the best matching locale. 304 | */ 305 | Locale match = null; 306 | Locale pref = getLocale(pc, Config.FMT_LOCALE); 307 | if (pref != null) { 308 | // Preferred locale is application-based 309 | match = findFormattingMatch(pref, availableFormattingLocales); 310 | } else { 311 | // Preferred locales are browser-based 312 | match = findFormattingMatch(pc, availableFormattingLocales); 313 | } 314 | if (match == null) { 315 | // Use fallback locale. 316 | pref = getLocale(pc, Config.FMT_FALLBACK_LOCALE); 317 | if (pref != null) { 318 | match = findFormattingMatch(pref, availableFormattingLocales); 319 | } 320 | } 321 | if (match != null) { 322 | setResponseLocale(pc, match); 323 | } 324 | 325 | return match; 326 | } 327 | 328 | /** 329 | * Returns the locale specified by the named scoped attribute or context 330 | * configuration parameter. 331 | * 332 | *

The named scoped attribute is searched in the page, request, session 333 | * (if valid), and application scope(s) (in this order). If no such 334 | * attribute exists in any of the scopes, the locale is taken from the named 335 | * context configuration parameter. 336 | * 337 | * @param pageContext the page in which to search for the named scoped 338 | * attribute or context configuration parameter @param name the name of the 339 | * scoped attribute or context configuration parameter 340 | * 341 | * @return the locale specified by the named scoped attribute or context 342 | * configuration parameter, or null if no scoped attribute or 343 | * configuration parameter with the given name exists 344 | */ 345 | static Locale getLocale(PageContext pageContext, String name) { 346 | Locale loc = null; 347 | 348 | Object obj = Config.find(pageContext, name); 349 | if (obj != null) { 350 | if (obj instanceof Locale) { 351 | loc = (Locale) obj; 352 | } else { 353 | loc = parseLocale((String) obj); 354 | } 355 | } 356 | 357 | return loc; 358 | } 359 | 360 | // ********************************************************************* 361 | // Private utility methods 362 | 363 | /** 364 | * Determines the client's preferred locales from the request, and compares 365 | * each of the locales (in order of preference) against the available 366 | * locales in order to determine the best matching locale. 367 | * 368 | * @param pageContext Page containing the formatting action @param avail 369 | * Available formatting locales 370 | * 371 | * @return Best matching locale, or null if no match was found 372 | */ 373 | private static Locale findFormattingMatch(PageContext pageContext, 374 | Locale[] avail) { 375 | Locale match = null; 376 | for (Enumeration enum_ = Util 377 | .getRequestLocales((HttpServletRequest) pageContext 378 | .getRequest()); enum_.hasMoreElements();) { 379 | Locale locale = (Locale) enum_.nextElement(); 380 | match = findFormattingMatch(locale, avail); 381 | if (match != null) { 382 | break; 383 | } 384 | } 385 | 386 | return match; 387 | } 388 | 389 | /** 390 | * Returns the best match between the given preferred locale and the given 391 | * available locales. 392 | * 393 | * The best match is given as the first available locale that exactly 394 | * matches the given preferred locale ("exact match"). If no exact match 395 | * exists, the best match is given to an available locale that meets the 396 | * following criteria (in order of priority): - available locale's variant 397 | * is empty and exact match for both language and country - available 398 | * locale's variant and country are empty, and exact match for language. 399 | * 400 | * @param pref the preferred locale @param avail the available formatting 401 | * locales 402 | * 403 | * @return Available locale that best matches the given preferred locale, or 404 | * null if no match exists 405 | */ 406 | private static Locale findFormattingMatch(Locale pref, Locale[] avail) { 407 | Locale match = null; 408 | boolean langAndCountryMatch = false; 409 | for (int i = 0; i < avail.length; i++) { 410 | if (pref.equals(avail[i])) { 411 | // Exact match 412 | match = avail[i]; 413 | break; 414 | } else if (!"".equals(pref.getVariant()) 415 | && "".equals(avail[i].getVariant()) 416 | && pref.getLanguage().equals(avail[i].getLanguage()) 417 | && pref.getCountry().equals(avail[i].getCountry())) { 418 | // Language and country match; different variant 419 | match = avail[i]; 420 | langAndCountryMatch = true; 421 | } else if (!langAndCountryMatch 422 | && pref.getLanguage().equals(avail[i].getLanguage()) 423 | && ("".equals(avail[i].getCountry()))) { 424 | // Language match 425 | if (match == null) { 426 | match = avail[i]; 427 | } 428 | } 429 | } 430 | return match; 431 | } 432 | 433 | /** 434 | * Gets the default I18N localization context. 435 | * 436 | * @param pc Page in which to look up the default I18N localization context 437 | */ 438 | public static LocalizationContext getLocalizationContext(PageContext pc) { 439 | LocalizationContext locCtxt = null; 440 | 441 | Object obj = Config.find(pc, Config.FMT_LOCALIZATION_CONTEXT); 442 | if (obj == null) { 443 | return null; 444 | } 445 | 446 | if (obj instanceof LocalizationContext) { 447 | locCtxt = (LocalizationContext) obj; 448 | } else { 449 | // localization context is a bundle basename 450 | locCtxt = getLocalizationContext(pc, (String) obj); 451 | } 452 | 453 | return locCtxt; 454 | } 455 | 456 | /** 457 | * Gets the resource bundle with the given base name, whose locale is 458 | * determined as follows: 459 | * 460 | * Check if a match exists between the ordered set of preferred locales and 461 | * the available locales, for the given base name. The set of preferred 462 | * locales consists of a single locale (if the 463 | * javax.servlet.jsp.jstl.fmt.locale configuration setting is 464 | * present) or is equal to the client's preferred locales determined from 465 | * the client's browser settings. 466 | * 467 | *

468 | * If no match was found in the previous step, check if a match exists 469 | * between the fallback locale (given by the 470 | * javax.servlet.jsp.jstl.fmt.fallbackLocale configuration 471 | * setting) and the available locales, for the given base name. 472 | * 473 | * @param pc Page in which the resource bundle with the given base 474 | * name is requested 475 | * @param basename Resource bundle base name 476 | * 477 | * @return Localization context containing the resource bundle with the 478 | * given base name and the locale that led to the resource bundle match, or 479 | * the empty localization context if no resource bundle match was found 480 | */ 481 | public static LocalizationContext getLocalizationContext(PageContext pc, 482 | String basename) { 483 | LocalizationContext locCtxt = null; 484 | ResourceBundle bundle = null; 485 | 486 | if ((basename == null) || basename.equals("")) { 487 | return new LocalizationContext(); 488 | } 489 | 490 | // Try preferred locales 491 | Locale pref = getLocale(pc, Config.FMT_LOCALE); 492 | if (pref != null) { 493 | // Preferred locale is application-based 494 | bundle = findMatch(basename, pref); 495 | if (bundle != null) { 496 | locCtxt = new LocalizationContext(bundle, pref); 497 | } 498 | } else { 499 | // Preferred locales are browser-based 500 | locCtxt = findMatch(pc, basename); 501 | } 502 | 503 | if (locCtxt == null) { 504 | // No match found with preferred locales, try using fallback locale 505 | pref = getLocale(pc, Config.FMT_FALLBACK_LOCALE); 506 | if (pref != null) { 507 | bundle = findMatch(basename, pref); 508 | if (bundle != null) { 509 | locCtxt = new LocalizationContext(bundle, pref); 510 | } 511 | } 512 | } 513 | 514 | if (locCtxt == null) { 515 | // try using the root resource bundle with the given basename 516 | try { 517 | bundle = ResourceBundle.getBundle(basename, EMPTY_LOCALE, 518 | Thread.currentThread().getContextClassLoader()); 519 | if (bundle != null) { 520 | locCtxt = new LocalizationContext(bundle, null); 521 | } 522 | } catch (MissingResourceException mre) { 523 | // do nothing 524 | } 525 | } 526 | 527 | if (locCtxt != null) { 528 | // set response locale 529 | if (locCtxt.getLocale() != null) { 530 | setResponseLocale(pc, locCtxt.getLocale()); 531 | } 532 | } else { 533 | // create empty localization context 534 | locCtxt = new LocalizationContext(); 535 | } 536 | 537 | return locCtxt; 538 | } 539 | 540 | /** 541 | * Determines the client's preferred locales from the request, and compares 542 | * each of the locales (in order of preference) against the available 543 | * locales in order to determine the best matching locale. 544 | * 545 | * @param pageContext the page in which the resource bundle with the given 546 | * base name is requested @param basename the resource bundle's base name 547 | * 548 | * @return the localization context containing the resource bundle with the 549 | * given base name and best matching locale, or null if no 550 | * resource bundle match was found 551 | */ 552 | private static LocalizationContext findMatch(PageContext pageContext, 553 | String basename) { 554 | LocalizationContext locCtxt = null; 555 | 556 | // Determine locale from client's browser settings. 557 | for (Enumeration enum_ = Util 558 | .getRequestLocales((HttpServletRequest) pageContext 559 | .getRequest()); enum_.hasMoreElements();) { 560 | Locale pref = (Locale) enum_.nextElement(); 561 | ResourceBundle match = findMatch(basename, pref); 562 | if (match != null) { 563 | locCtxt = new LocalizationContext(match, pref); 564 | break; 565 | } 566 | } 567 | 568 | return locCtxt; 569 | } 570 | 571 | /** 572 | * Gets the resource bundle with the given base name and preferred locale. 573 | * 574 | * This method calls java.util.ResourceBundle.getBundle(), but ignores its 575 | * return value unless its locale represents an exact or language match with 576 | * the given preferred locale. 577 | * 578 | * @param basename the resource bundle base name @param pref the preferred 579 | * locale 580 | * 581 | * @return the requested resource bundle, or null if no resource 582 | * bundle with the given base name exists or if there is no exact- or 583 | * language-match between the preferred locale and the locale of the bundle 584 | * returned by java.util.ResourceBundle.getBundle(). 585 | */ 586 | private static ResourceBundle findMatch(String basename, Locale pref) { 587 | ResourceBundle match = null; 588 | 589 | try { 590 | ResourceBundle bundle = ResourceBundle.getBundle(basename, pref, 591 | Thread.currentThread().getContextClassLoader()); 592 | Locale avail = bundle.getLocale(); 593 | if (pref.equals(avail)) { 594 | // Exact match 595 | match = bundle; 596 | } else { 597 | /* 598 | * We have to make sure that the match we got is for the 599 | * specified locale. The way ResourceBundle.getBundle() works, 600 | * if a match is not found with (1) the specified locale, it 601 | * tries to match with (2) the current default locale as 602 | * returned by Locale.getDefault() or (3) the root resource 603 | * bundle (basename). We must ignore any match that could have 604 | * worked with (2) or (3). So if an exact match is not found, we 605 | * make the following extra tests: - avail locale must be equal 606 | * to preferred locale - avail country must be empty or equal to 607 | * preferred country (the equality match might have failed on 608 | * the variant) 609 | */ 610 | if (pref.getLanguage().equals(avail.getLanguage()) 611 | && ("".equals(avail.getCountry()) || pref.getCountry() 612 | .equals(avail.getCountry()))) { 613 | /* 614 | * Language match. By making sure the available locale does 615 | * not have a country and matches the preferred locale's 616 | * language, we rule out "matches" based on the container's 617 | * default locale. For example, if the preferred locale is 618 | * "en-US", the container's default locale is "en-UK", and 619 | * there is a resource bundle (with the requested base name) 620 | * available for "en-UK", ResourceBundle.getBundle() will 621 | * return it, but even though its language matches that of 622 | * the preferred locale, we must ignore it, because matches 623 | * based on the container's default locale are not portable 624 | * across different containers with different default 625 | * locales. 626 | */ 627 | match = bundle; 628 | } 629 | } 630 | } catch (MissingResourceException mre) { 631 | } 632 | 633 | return match; 634 | } 635 | 636 | } 637 | -------------------------------------------------------------------------------- /src/site/resources/css/site.css: -------------------------------------------------------------------------------- 1 | body, td, select, input, li{ 2 | font-family: Helvetica, Arial, sans-serif; 3 | font-size: 13px; 4 | background-color: #fff; 5 | } 6 | a { 7 | text-decoration: none; 8 | } 9 | a:link { 10 | color:#009; 11 | } 12 | a:visited { 13 | color:#009; 14 | } 15 | a:active, a:hover { 16 | text-decoration: underline; 17 | } 18 | a.externalLink, a.externalLink:link, a.externalLink:visited, a.externalLink:active, a.externalLink:hover { 19 | background: url(../images/external.png) right center no-repeat; 20 | padding-right: 15px; 21 | } 22 | a.newWindow, a.newWindow:link, a.newWindow:visited, a.newWindow:active, a.newWindow:hover { 23 | background: url(../images/newwindow.png) right center no-repeat; 24 | padding-right: 18px; 25 | } 26 | h2 { 27 | font-family: Verdana, Helvetica, Arial, sans-serif; 28 | padding: 4px 4px 4px 6px; 29 | border: 1px solid #999; 30 | color: #006; 31 | background-color: #eef; 32 | font-weight:bold; 33 | font-size: 16px; 34 | margin-top: 4px; 35 | margin-bottom: 6px; 36 | } 37 | h3 { 38 | padding: 4px 4px 4px 6px; 39 | border: 1px solid #aaa; 40 | color: #006; 41 | background-color: #eee; 42 | font-weight: normal; 43 | font-size: 14px; 44 | margin-top: 4px; 45 | margin-bottom: 6px; 46 | } 47 | p, ul { 48 | font-size: 13px; 49 | margin-top: 4px; 50 | margin-bottom: 6px; 51 | } 52 | #banner { 53 | background-color: #eef; 54 | border-bottom: 1px solid #aaa; 55 | padding: 8px; 56 | } 57 | #bannerLeft, #bannerRight { 58 | font-size: 30px; 59 | color:black; 60 | padding: 0px 5px; 61 | } 62 | #banner a:hover { 63 | text-decoration:none; 64 | } 65 | #breadcrumbs { 66 | padding-top: 1px; 67 | padding-bottom: 2px; 68 | border-bottom: 1px solid #aaa; 69 | background-color: #ddf; 70 | } 71 | #leftColumn { 72 | margin: 8px 0 8px 4px; 73 | border: 1px solid #999; 74 | background-color: #eef; 75 | } 76 | #navcolumn { 77 | padding: 6px 4px 0 6px; 78 | } 79 | #navcolumn h5 { 80 | font-size: 12px; 81 | border-bottom: 1px solid #aaaaaa; 82 | padding-top: 2px; 83 | font-weight: normal; 84 | } 85 | #navcolumn li { 86 | font-size: 12px; 87 | padding-left: 12px; 88 | background-color: #eef; 89 | } 90 | #navcolumn a:active, #navcolumn a:hover { 91 | text-decoration: none; 92 | } 93 | #lastPublished { 94 | font-size: 10px; 95 | } 96 | table.bodyTable th { 97 | color: white; 98 | background-color: #bbb; 99 | text-align: left; 100 | font-weight: bold; 101 | font-size: 13px; 102 | } 103 | 104 | table.bodyTable th, table.bodyTable td { 105 | font-size: 13px; 106 | } 107 | 108 | table.bodyTable tr.a { 109 | background-color: #ddd; 110 | } 111 | 112 | table.bodyTable tr.b { 113 | background-color: #eee; 114 | } 115 | 116 | .source { 117 | border: 1px solid #999; 118 | padding: 8px; 119 | margin: 6px; 120 | } 121 | #footer { 122 | background-color: #eef; 123 | border-top: 1px solid #999; 124 | } 125 | body { 126 | padding-bottom: 0px; 127 | } 128 | -------------------------------------------------------------------------------- /src/site/resources/download.html: -------------------------------------------------------------------------------- 1 | 2 | OpenGamma 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/site/site.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Joda.org 6 | http://www.joda.org/ 7 | 8 | 9 | Joda-Time-JspTags 10 | http://www.joda.org/joda-time-jsptags/ 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 |

22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 52 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /src/site/xdoc/index.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Java date and time API - JSP tags - Home 7 | Stephen Colebourne 8 | 9 | 10 | 11 | 12 |
13 |

14 | Joda-Time provides a complete quality alternative 15 | to the JDK date and time classes. 16 | However, this causes issues when working with other libraries that expect 17 | a JDK object, such as the JSTL JSP tag library. 18 |

19 |

20 | To solve this problem, the Joda-Time JSP tags contributed project provides 21 | a JSTL-like set of tags that format and parse Joda-Time based date and time 22 | objects instead of JDK based objects. 23 |

24 |

25 | As a flavour of the tags, here's how to format a Joda-Time object in JSP: 26 | 27 | <%@taglib prefix="joda" uri="http://www.joda.org/joda/time/tags" %> 28 | <% pageContext.setAttribute("now", new org.joda.time.DateTime()); %> 29 | <joda:format value="${now}" style="SM" /> 30 | 31 | Version 1.1.1 was released on 2011-11-24 - 32 | Download now 33 |

34 |
35 | 36 | 37 |
38 |

39 | Various documentation is available: 40 |

45 |

46 |
47 | 48 | 49 |
50 |

51 | Release 1.1.1 52 | is the current latest release. 53 | This release is basically the same as v1.1, but with altered OSGI info. 54 |

55 |

56 | The dependencies are Joda-Time 1.0 or later (including v2.0 or later), 57 | the Servlet 2.4 API, the JSP 2.0 API, JSTL 1.1 API and JDK 1.5 or later. 58 | All maven dependencies are provided, 59 | thus there is no automatic dependency resolution. 60 |

61 |

62 | Available in Maven Central. 63 |

64 |
65 | 66 | 67 |
68 |

69 | The Joda-Time JSP tags library was contributed to Joda-Time by Jim Newsham. 70 | It is based on the code from Jakarta Taglibs, now Tomcat Taglibs. 71 |

72 |

73 | Support on bugs, library usage or enhancement requests is available on a best efforts basis. 74 |

75 |

76 | To suggest enhancements or contribute, please fork the source code on GitHub. 77 | Alternatively, use GitHub issues. 78 |

79 |

80 |
81 |

82 |

83 |
84 |

85 |

86 |
87 |

88 |
89 | 90 |
91 | -------------------------------------------------------------------------------- /src/site/xdoc/licensecover.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Java date and time API - JSP tags - License 6 | Stephen Colebourne 7 | 8 | 9 | 10 | 11 |
12 |

13 | Joda-Time source code is released under the business-friendly 14 | Apache 2.0 license. 15 | This is the same license as Ant, 16 | Spring, 17 | Tomcat and 18 | Jakarta. 19 |

20 |

21 | The JSP tags contributed library is an edited version of code originally 22 | from Jakarta Taglibs, now Tomcat Taglibs. 23 | As a result, the NOTICE file contains the Apache information clause 24 | as well as the Joda-Time information clause as follows: 25 | 26 | ============================================================================= 27 | = NOTICE file corresponding to section 4d of the Apache License Version 2.0 = 28 | ============================================================================= 29 | This product includes software developed by 30 | Joda.org (http://www.joda.org/). 31 | 32 | This product includes software developed by 33 | The Apache Software Foundation (http://www.apache.org/). 34 | 35 |

36 |
37 | 38 | 39 |
40 | -------------------------------------------------------------------------------- /src/site/xdoc/userguide.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Java date and time API - JSP tags - User Guide 6 | Jim Newsham 7 | Stephen Colebourne 8 | 9 | 10 | 11 | 12 | 13 |
14 |

15 | Joda-Time JSP tags provide a JSTL-like set of tags to format and parse 16 | Joda-Time based date and time objects. 17 |

18 |

19 | The JSTL fmt tags work with java.util.Date and java.util.TimeZone objects. 20 | The tags in this library work with Joda-Time DateTime, ReadableInstant, 21 | ReadablePartial, and DateTimeZone objects. 22 | Otherwise, the two libraries are very similar, thus you can refer to standard 23 | JSTL books and documentation to supplement this document. 24 |

25 | 26 | 27 | 28 | 29 |

30 | You will need a servlet container which supports Servlet 2.4, JSP 2.0, JSTL 1.1. 31 | One such container is Tomcat 5. 32 |

33 |

34 | The simplest setup is to copy the joda-time and joda-time-jsptags jar files 35 | to the WEB-INF/lib directory of your web application. 36 |

37 |

38 | You then need to declare the library as follows at the top of your jsp pages: 39 | 40 | <%@taglib prefix="joda" uri="http://www.joda.org/joda/time/tags" %> 41 | 42 |

43 |

44 | In addition to these steps you should ensure that your application is using 45 | servlet specification 2.4. This is usually controlled by the web.xml file. 46 | If you do not do this then EL expressions will not work as expected. 47 |

48 |
49 |
50 | 51 | 52 | 53 |
54 |

55 | This tag formats ReadableInstant (including DateTime) and ReadablePartial 56 | (including LocalDateTime, LocalDate and LocalTime) objects. 57 | The time zone may be specified using an attribute, an enclosing <joda:dateTimeZone/> tag, 58 | preceding <joda:timeZone/> tag, or via the "org.joda.time.dateTimeZone" scoped variable. 59 |

60 |

61 | The tag may be used in one of two ways. 62 | The simplest way is to output directly to the HTTP response. 63 | The second way is to set the var and scope attributes and set the value of a variable. 64 |

65 |

66 | Example: 67 | 68 | <% pageContext.setAttribute("now", new org.joda.time.DateTime()); %> 69 | <joda:format value="${now}" style="SM" /> 70 | 71 |

72 |

73 | 74 | 75 | 76 | 77 | 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 |
Attributes
value (required)Must be a ReadableInstant or ReadablePartial
varThe scoped variable to set
scopeThe scope of the variable to set
localeThe locale to use for formatting
styleThe style to use for formatting (two characters, one for date, one for time, from S=Short, M=Medium, L=Long, F=Full, -=None)
patternThe pattern to use for formatting (see Joda format documentation for recognized pattern strings)
dateTimeZoneThe time zone to use for formatting
106 |

107 |
108 | 109 | 110 | 111 |
112 |

113 | This tag parses a String into a DateTime object. 114 | The time zone may be specified using an attribute, an enclosing <joda:dateTimeZone/> tag, 115 | preceding <joda:timeZone/> tag, or via the "org.joda.time.dateTimeZone" scoped variable. 116 |

117 |

118 | The tag may be used in one of two ways. 119 | The simplest way is to parse the input and then directly format the output to the HTTP response. 120 | The second way, and more usual way, is to set the var and scope attributes and 121 | set the value of a variable with the results of the parse. 122 |

123 |

124 | Example: 125 | 126 | <joda:parseDateTime var="parsed" pattern="yy/M/d" value="05/11/19" /> 127 | <joda:format value="${parsed}" style="L-" /> 128 | 129 |

130 |

131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 |
Attributes
value (required; unless value is nested within tag)Must be a string which can be parsed into a DateTime according to the parsing options specified
varThe scoped variable to set
scopeThe scope of the variable to set
localeThe locale to use for parsing
styleThe style to use for parsing (two characters, one for date, one for time, from S=Short, M=Medium, L=Long, F=Full, -=None)
patternThe pattern to use for parsing (see Joda format documentation for recognized pattern strings)
dateTimeZoneThe time zone to use for parsing
164 |

165 |
166 | 167 | 168 | 169 |
170 |

171 | This tag sets the default time zone to use for all nested tags. 172 | The <joda:format /> tag may override this value with an explicit dateTimeZone attribute. 173 |

174 |

175 | Example: 176 | 177 | <% pageContext.setAttribute("now", new DateTime()); %> 178 | <% pageContext.setAttribute("bkk", DateTimeZone.forID("Asia/Bangkok")); %> 179 | <joda:dateTimeZone value="${bkk}"> 180 | <joda:format value="${datetime}" /> 181 | </joda:dateTimeZone> 182 | 183 |

184 |

185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 |
Attributes
value (required)Must be a DateTimeZone object, or an id of a zone
194 |

195 |
196 | 197 | 198 | 199 |
200 |

201 | This tag sets the default time zone, either for the remainder of the page, or to a variable. 202 | If var is not specified, the zone will be stored in a scoped variable called "org.joda.time.dateTimeZone". 203 | This acts as a default for all the other tags. 204 | It will be overridden by a <joda:datetimezone /> tag, or by 205 | an explicit dateTimeZone attribute on <joda:format />. 206 |

207 |

208 | Example: 209 | 210 | <% pageContext.setAttribute("now", new DateTime()); %> 211 | <% pageContext.setAttribute("bkk", DateTimeZone.forID("Asia/Bangkok")); %> 212 | <joda:dateTimeZone value="${bkk}" /> 213 | <joda:format value="${datetime}" /> 214 | 215 |

216 |

217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 |
Attributes
value (required)Must be a DateTimeZone object, or an id of a zone
varThe scoped variable to set
scopeThe scope of the variable to set
234 |

235 |
236 | 237 | 238 | 239 | 240 |
241 | --------------------------------------------------------------------------------