velocity-tools-2.0-src/dist/ 40755 0 0 0 11365341753 13141 5ustar 0 0 velocity-tools-2.0-src/examples/ 40755 0 0 0 11365341752 14013 5ustar 0 0 velocity-tools-2.0-src/examples/showcase/ 40755 0 0 0 11360645211 15617 5ustar 0 0 velocity-tools-2.0-src/examples/showcase/WEB-INF/ 40755 0 0 0 11365341752 16656 5ustar 0 0 velocity-tools-2.0-src/examples/showcase/WEB-INF/src/ 40755 0 0 0 11202122667 17435 5ustar 0 0 velocity-tools-2.0-src/examples/showcase/layout/ 40755 0 0 0 11202122667 17134 5ustar 0 0 velocity-tools-2.0-src/examples/simple/ 40755 0 0 0 11115263033 15270 5ustar 0 0 velocity-tools-2.0-src/examples/simple/META-INF/ 40755 0 0 0 10747440004 16435 5ustar 0 0 velocity-tools-2.0-src/examples/simple/WEB-INF/ 40755 0 0 0 11365341751 16332 5ustar 0 0 velocity-tools-2.0-src/examples/simple/WEB-INF/src/ 40755 0 0 0 10747440005 17114 5ustar 0 0 velocity-tools-2.0-src/examples/struts/ 40755 0 0 0 11110347753 15352 5ustar 0 0 velocity-tools-2.0-src/examples/struts/META-INF/ 40755 0 0 0 10747440007 16513 5ustar 0 0 velocity-tools-2.0-src/examples/struts/WEB-INF/ 40755 0 0 0 11365341752 16406 5ustar 0 0 velocity-tools-2.0-src/examples/struts/WEB-INF/src/ 40755 0 0 0 11115263033 17161 5ustar 0 0 velocity-tools-2.0-src/examples/struts/WEB-INF/src/examples/ 40755 0 0 0 10747440010 21001 5ustar 0 0 velocity-tools-2.0-src/examples/struts/WEB-INF/src/examples/app1/ 40755 0 0 0 10747440010 21642 5ustar 0 0 velocity-tools-2.0-src/examples/struts/WEB-INF/src/examples/app2/ 40755 0 0 0 10747440010 21643 5ustar 0 0 velocity-tools-2.0-src/examples/struts/WEB-INF/src/examples/app3/ 40755 0 0 0 10747440010 21644 5ustar 0 0 velocity-tools-2.0-src/examples/struts/WEB-INF/src/examples/app4/ 40755 0 0 0 10747440010 21645 5ustar 0 0 velocity-tools-2.0-src/examples/struts/WEB-INF/src/examples/app5/ 40755 0 0 0 10747440010 21646 5ustar 0 0 velocity-tools-2.0-src/examples/struts/WEB-INF/tld/ 40755 0 0 0 11115263033 17155 5ustar 0 0 velocity-tools-2.0-src/examples/struts/app1/ 40755 0 0 0 10747440005 16212 5ustar 0 0 velocity-tools-2.0-src/examples/struts/app2/ 40755 0 0 0 11110347753 16214 5ustar 0 0 velocity-tools-2.0-src/examples/struts/app3/ 40755 0 0 0 10747440005 16214 5ustar 0 0 velocity-tools-2.0-src/examples/struts/app4/ 40755 0 0 0 10747440006 16216 5ustar 0 0 velocity-tools-2.0-src/examples/struts/app4/layout/ 40755 0 0 0 10747440006 17533 5ustar 0 0 velocity-tools-2.0-src/examples/struts/app5/ 40755 0 0 0 10747440006 16217 5ustar 0 0 velocity-tools-2.0-src/examples/struts/app6/ 40755 0 0 0 10747440006 16220 5ustar 0 0 velocity-tools-2.0-src/examples/struts/app7/ 40755 0 0 0 10747440006 16221 5ustar 0 0 velocity-tools-2.0-src/lib/ 40755 0 0 0 11202122726 12727 5ustar 0 0 velocity-tools-2.0-src/src/ 40755 0 0 0 10747440015 12757 5ustar 0 0 velocity-tools-2.0-src/src/main/ 40755 0 0 0 10747440011 13677 5ustar 0 0 velocity-tools-2.0-src/src/main/java/ 40755 0 0 0 10747440012 14621 5ustar 0 0 velocity-tools-2.0-src/src/main/java/META-INF/ 40755 0 0 0 11360645210 15760 5ustar 0 0 velocity-tools-2.0-src/src/main/java/org/ 40755 0 0 0 10747440012 15410 5ustar 0 0 velocity-tools-2.0-src/src/main/java/org/apache/ 40755 0 0 0 10747440012 16631 5ustar 0 0 velocity-tools-2.0-src/src/main/java/org/apache/velocity/ 40755 0 0 0 10747440012 20467 5ustar 0 0 velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/ 40755 0 0 0 11360645211 21627 5ustar 0 0 velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/config/ 40755 0 0 0 11110347747 23102 5ustar 0 0 velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/generic/ 40755 0 0 0 11361115526 23245 5ustar 0 0 velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/generic/log/ 40755 0 0 0 11115263032 24017 5ustar 0 0 velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/struts/ 40755 0 0 0 11110347747 23201 5ustar 0 0 velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/view/ 40755 0 0 0 11360645210 22600 5ustar 0 0 velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/view/context/ 40755 0 0 0 11030275247 24267 5ustar 0 0 velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/view/i18n/ 40755 0 0 0 11202122665 23356 5ustar 0 0 velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/view/jsp/ 40755 0 0 0 11202554465 23402 5ustar 0 0 velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/view/servlet/ 40755 0 0 0 11110347752 24267 5ustar 0 0 velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/view/tools/ 40755 0 0 0 11202122665 23737 5ustar 0 0 velocity-tools-2.0-src/src/test/ 40755 0 0 0 10747440015 13736 5ustar 0 0 velocity-tools-2.0-src/src/test/java/ 40755 0 0 0 11115263031 14646 5ustar 0 0 velocity-tools-2.0-src/src/test/java/org/ 40755 0 0 0 10747440015 15446 5ustar 0 0 velocity-tools-2.0-src/src/test/java/org/apache/ 40755 0 0 0 10747440016 16670 5ustar 0 0 velocity-tools-2.0-src/src/test/java/org/apache/velocity/ 40755 0 0 0 10747440016 20526 5ustar 0 0 velocity-tools-2.0-src/src/test/java/org/apache/velocity/tools/ 40755 0 0 0 11202122663 21656 5ustar 0 0 velocity-tools-2.0-src/src/test/java/org/apache/velocity/tools/generic/ 40755 0 0 0 11202122664 23273 5ustar 0 0 velocity-tools-2.0-src/src/test/java/org/apache/velocity/tools/test/ 40755 0 0 0 10747440016 22645 5ustar 0 0 velocity-tools-2.0-src/src/test/java/org/apache/velocity/tools/test/blackbox/ 40755 0 0 0 11360645207 24433 5ustar 0 0 velocity-tools-2.0-src/src/test/java/org/apache/velocity/tools/test/whitebox/ 40755 0 0 0 11115263031 24464 5ustar 0 0 velocity-tools-2.0-src/test/ 40755 0 0 0 11114542310 13135 5ustar 0 0 velocity-tools-2.0-src/test/conf/ 40755 0 0 0 11115263026 14067 5ustar 0 0 velocity-tools-2.0-src/test/etc/ 40755 0 0 0 11365341752 13727 5ustar 0 0 velocity-tools-2.0-src/xdocs/ 40755 0 0 0 11360645207 13312 5ustar 0 0 velocity-tools-2.0-src/xdocs/css/ 40755 0 0 0 11360645207 14102 5ustar 0 0 velocity-tools-2.0-src/xdocs/documentation/ 40755 0 0 0 10747440020 16155 5ustar 0 0 velocity-tools-2.0-src/xdocs/generic/ 40755 0 0 0 10747440020 14720 5ustar 0 0 velocity-tools-2.0-src/xdocs/images/ 40755 0 0 0 11030275235 14551 5ustar 0 0 velocity-tools-2.0-src/xdocs/struts/ 40755 0 0 0 10747440020 14650 5ustar 0 0 velocity-tools-2.0-src/xdocs/view/ 40755 0 0 0 10747440020 14256 5ustar 0 0 velocity-tools-2.0-src/CONTRIBUTORS100644 0 0 1152 10730012262 14133 0ustar 0 0 This project is an effort by many people. If you feel that your name should be in here and has been omitted in error, please open an issue with the Velocity Tools Issue tracker at issues.apache.org/jira/browse/VELTOOLS Christopher Schultz Chris Townsen Claude Brisson Craig R. McClanahan Daniel Rall Dave Bryson David Graham David Winterfeldt Denis Bredelet Dmitri Colebatch Gabriel Sidler Geir Magnusson Jr. Henning P. Schmiedehausen Jon S. Stevens Kent Johnson Leon Messerschmidt Marinó A. Jónsson Mike Kienenberger Nathan Bubna Oliver O'Halloran S. Brett Sutton Shinobu Kawai Spencer Davis Ted Husted Tim Colson velocity-tools-2.0-src/LICENSE100644 0 0 26446 10730012262 13315 0ustar 0 0 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. velocity-tools-2.0-src/NOTICE100644 0 0 721 10730012262 13140 0ustar 0 0 Apache Velocity Tools Copyright (C) 2000-2007 The Apache Software Foundation This product includes software developed at The Apache Software Foundation (http://www.apache.org/). Support for using SSL with Struts is provided using the sslext library package, which is open source software under the Apache Software License 1.1 with copyright attributed to The Apache Software Foundation. This software is available from http://sslext.sourceforge.net/ velocity-tools-2.0-src/README.txt100644 0 0 5202 11035250473 13760 0ustar 0 0 R E A D M E =========== Welcome to the VelocityTools projects. This is a subproject of the Apache Velocity project hosted at http://velocity.apache.org/ The VelocityTools project contains three subprojects: VelocityStruts Includes tools specific to integrating Velocity and Struts. This package sits on top of (requires) the VelocityView package. VelocityView Package containing the VelocityViewServlet for rendering Velocity templates. There is no controller functionality - it's akin to the JspServlet. It includes toolbox support. (Also contains a VelocityLayoutServlet to support more advanced template rendering as an alternative to Tiles.) Generic tools A collection of general purpose tools that may be used independently of the VelocityView or VelocityStruts package (but is included with both). Build Instructions ------------------ Building the project requires JDK 1.5 or higher and ant 1.7 or higher. There is an ant script included that builds the entire project, including all three subprojects, documentation, application examples, etc. To build the project, start ant in the root directory of the project: > ant To return the project to the original virgin state, execute: > ant clean By default, the project will build the VelocityStruts jar, javadoc and project documentation. To build only the VelocityStruts jar (which includes both VelocityView classes and the generic tools), execute: > ant jar.struts To build only the VelocityView jar (which includes the generic tools), execute: > ant jar.view To build only the generic tools jar, execute: > ant jar.generic To build only the simple example for VelocityView, execute: > ant simple To build only the VelocityStruts example, execute: > ant struts To build only the Showcase example, execute: > ant showcase Please note: - Due to new compile-time dependencies, VelocityTools can only be compiled on JDK 1.5 or higher The build process has been tested with JDK 1.5. The included example applications have been tested with Tomcat, but should work with any web container. If you observe any problems with the build process, please report this to the Velocity users mailing list, user@velocity.apache.org, and put [veltools] in the subject line. Documentation ------------- The project includes brief overview documentation and more detailed documentation for each subproject. Follow the 'Build Instructions' to build then project, then, point your browser at docs/index.html Feedback -------- We welcome your feedback to user@velocity.apache.org. $Revision: 672844 $ $Date: 2008-06-30 10:53:20 -0700 (Mon, 30 Jun 2008) $ velocity-tools-2.0-src/STATUS100644 0 0 2610 11031054626 13226 0ustar 0 0 S T A T U S =========== $Id: STATUS 672102 2008-06-27 03:08:02Z nbubna $ Known Issues/Bugs: - see http://issues.apache.org/jira/browse/VELTOOLS Documentation Wishlist: - Complete user guide. - Improve documention of the view tools (either xml/dvsl or javadoc) - Create a developer's guide (how to write tools, tips on extending VVS, etc.) Proposed Features/Upgrades: General: - finish/fix/improve Maven2 build support - add more automated testing of tools Generic tools: - TableTool (VELTOOLS-102) - Template debugging tool(s)/support - Add support for ValueParser to use a properties file as a source VelocityView: - Tool pooling/cleanup support (use commons-pool probably) - look into supporting arbitrary layout depth (sort of a "tiles lite") for the VelocityLayoutServlet (cf. Niall's work with Simple) - support for JSP tags - develop Tiles2 compatible TilesTool VelocityStruts: - add a library of velocimacros for use with struts tools (ideally these would be roughly parallel to struts tags to ease transition) - move dynamic javascript generation from java (ValidatorTool) to templates (this would probably work in concert with the velocimacro libraries) Example Ideas: - a FooShop-type demo app (i.e. something closer to real-world use) velocity-tools-2.0-src/WHY_THREE_JARS.txt100644 0 0 1404 10730012262 15231 0ustar 0 0 WHY ARE THERE THREE VELOCITY-TOOLS JARS? WHAT'S THE DIFFERENCE? velocity-tools-.jar ---------------- This jar contains the classes for all three velocity-tools subprojects--VelocityStruts, VelocityView, and the Generic Tools. velocity-tools-view-.jar ---------------- This jar contains only the classes that are part of the VelocityView and Generic Tools subprojects. Alls Struts-related classes are excluded for those not interested in using Struts. velocity-tools-generic-.jar -------------------- This jar contains only the classes that are part of the Generic Tools subproject. It has no dependencies on the Servlet API or Struts. Please see the project documentation for more information. velocity-tools-2.0-src/build.properties100644 0 0 14266 11360645661 15541 0ustar 0 0 # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # local build.properties # # $Id: build.properties 933312 2010-04-12 16:35:03Z nbubna $ # # compile switches compile.debug= true compile.optimize= false compile.deprecation= true compile.encoding= utf-8 compile.source=1.5 compile.target=1.5 # project identification project.name=VelocityTools project.version=2.0 project.libname=velocity-tools project.id=${project.libname}-${project.version} struts.name=VelocityTools struts.libname=${project.libname} struts.description=a set of utilities for use with the Velocity template engine and Struts web framework struts.id=${struts.libname}-${project.version} view.name=VelocityView view.libname=${project.libname}-view view.description=a set of utilities for use with the Velocity template engine view.id=${view.libname}-${project.version} generic.name=Velocity GenericTools generic.libname=${project.libname}-generic generic.description=a set of non-J2EE utilities for use with the Velocity template engine generic.id=${generic.libname}-${project.version} # source directories source.home=${basedir}/src examples.home=${basedir}/examples conf.home=${source.home}/conf classes.src=${source.home}/main/java macros.src=${source.home}/velocity docs.src=${basedir}/xdocs # build directories build.dir=${basedir}/build mvn.build.dir=${basedir}/target classes.dir=${build.dir}/classes lib.dir=${basedir}/lib dist.dir=${basedir}/dist docs.dir=${basedir}/docs release.dir=${dist.dir}/release/${project.id} # distribution properties publish.server=people.apache.org publish.dir=~/public_html/velocity/tools/${project.version} publish.docs.dir=/www/velocity.apache.org/tools/ # javadoc properties javadoc.dir=${docs.dir}/javadoc javadoc.title=${project.name} ${project.version} Documentation javadoc.year=2003-2007 javadocs.ref.jsdk= http://java.sun.com/j2se/1.5.0/docs/api/ # test directories test.dir=${basedir}/test test.conf.dir=${test.dir}/conf test.lib.dir=${test.dir}/lib test.src.dir=${source.home}/test/java test.build.dir=${build.dir}/test test.build.src.dir=${test.build.dir}/src test.classes.dir=${test.build.dir}/classes test.rst.dir=${test.build.dir}/rst test.log.dir=${test.build.dir}/log # Needs to be configured with system location of findbugs for findbugs task findbugs.home=*unset* # Needs to be configured with system location of PMD for pmd task pmd.home=*unset* #test switches test.haltonerror=true test.haltonfailure=true test.compile.source=1.5 test.compile.target=1.5 #test webcontainer parameters test.webcontainer.port=8081 test.webcontainer.control.port=8082 # ####################################################################### # # Downloading jars from ibiblio repository # # ####################################################################### # Settings for the proxy to use for download. Change this if you must # use a proxy from your host. If the proxy.host property is unset, no # proxy is used. # proxy.host= proxy.port= 80 # We download directly from the ibiblio maven repository # #repo.m1.url=http://www.ibiblio.org/maven repo.m1.url=http://mirrors.ibiblio.org/pub/mirrors/maven2 repo.m2.url=http://www.ibiblio.org/maven2 # Skip or force downloading of dependencies skip.jar.loading= false force.jar.loading= false # Jars to be downloaded for compilation # jar.antlr.version= 2.7.2 jar.commons-beanutils.version= 1.7.0 jar.commons-chain.version= 1.1 jar.commons-collections.version= 3.2 jar.commons-digester.version= 1.8 jar.commons-lang.version= 2.2 jar.commons-logging.version= 1.1 jar.commons-validator.version= 1.3.1 jar.dom4j.version= 1.1 jar.oro.version= 2.0.8 jar.servletapi.version= 2.3 jar.sslext.version = 1.2-0 jar.struts-core.version = 1.3.8 jar.struts-taglib.version = 1.3.8 jar.struts-tiles.version = 1.3.8 jar.velocity.version= 1.6.2 # Jars to be downloaded for building documentation # jar.velocity-dvsl.version= 1.0 # Jars needed for testing # jar.httpunit.version=1.6.1 jar.jetty.version=6.0.1 jar.js.version = 1.6R5 jar.nekohtml.version=0.9.5 jar.xercesimpl.version=2.8.1 jar.xmlparserapis.version=2.6.2 jar.junit.version=4.1 jar.maven.ant.version=2.0.9 ######################################################################## # Maven Ant Task settings maven.pom=${basedir}/pom.xml maven.build.dir= ${mvn.build.dir} wagon-ssh.version=1.0-beta-2 # POM distributionManagement is used if this is not set #maven.remote.repository= # Full paths to the jars for building the examples antlr.jar=${lib.dir}/antlr-${jar.antlr.version}.jar commons-beanutils.jar=${lib.dir}/commons-beanutils-${jar.commons-beanutils.version}.jar commons-chain.jar=${lib.dir}/commons-chain-${jar.commons-chain.version}.jar commons-collections.jar=${lib.dir}/commons-collections-${jar.commons-collections.version}.jar commons-digester.jar=${lib.dir}/commons-digester-${jar.commons-digester.version}.jar commons-lang.jar=${lib.dir}/commons-lang-${jar.commons-lang.version}.jar commons-logging.jar=${lib.dir}/commons-logging-${jar.commons-logging.version}.jar commons-validator.jar=${lib.dir}/commons-validator-${jar.commons-validator.version}.jar dom4j.jar=${lib.dir}/dom4j-${jar.dom4j.version}.jar servlet.jar=${lib.dir}/servletapi-${jar.servletapi.version}.jar struts-core.jar=${lib.dir}/struts-core-${jar.struts-core.version}.jar struts-taglib.jar=${lib.dir}/struts-taglib-${jar.struts-taglib.version}.jar struts-tiles.jar=${lib.dir}/struts-tiles-${jar.struts-tiles.version}.jar sslext.jar=${lib.dir}/sslext-${jar.sslext.version}.jar oro.jar=${lib.dir}/oro-${jar.oro.version}.jar velocity.jar=${lib.dir}/velocity-${jar.velocity.version}.jar velocity-tools-2.0-src/build.xml100644 0 0 107154 11365323674 14166 0ustar 0 0 Global settings: java.home = ${java.home} user.home = ${user.home} java.class.path = ${java.class.path} Project settings: Version: ${project.id} Debug: ${compile.debug} Optimize: ${compile.optimize} Deprecation: ${compile.deprecation} Encoding: ${compile.encoding} Build settings: Source Files: ${source.home} Build Files: ${build.dir} Distribution Files: ${dist.dir} ***** RELEASE INSTRUCTIONS ***** * Be sure you can answer "yes" to the following: * Was your local code up to date and free of modifications or extra files? * Was the version number correct in both build.properties and pom.xml? * For a final release, the distributionManagement.site.url value in the pom.xml should be: scpexe://people.apache.org/www/velocity.apache.org/tools/releases/velocity-tools-${project.version} and for alpha or beta releases it should be: scpexe://people.apache.org/www/velocity.apache.org/engine/devel/ * Do all new files have the Apache License? (use "ant rat" to double-check) * Is ${basedir}/xdocs/changes.xml up to date? Feel free to set an estimated release date for this version in that file; it can be corrected later if the release is delayed. * Is the ${basedir}/README.txt up to date for this release? * Check that you have no uncommitted changes with 'svn status' * Run 'ant clean compile' and 'ant clean test' with all supported JDKs * Check that at least 'maven clean install' works. * Check that all version numbers are in sync: build.properties, changes.xml, and pom.xml * Check that the README.txt and other documentation are up to date. * Write down the current svn revision so you don't have to look it up later when you make the tag for this release (post-vote). * Go to ${build.dir} and sign all the jar, zip, tar.gz and pom files with your personal PGP key. If using gpg, you'll probably do this: gpg --armor --output ${final.name}.zip.asc --detach-sig ${final.name}.zip * Now that the distribution files have been created, you will need to sign all of the jar, zip, pom, and tar.gz files with your private key. You can simplify this process with a script along the lines of: #! /bin/bash for i in *.tar.gz *.zip *jar; do gpg --armor --output $i.asc --detach-sig $i done * SSH into people.apache.org and make sure that this directory exists: ${publish.dir} * Login to people.apache.org and create an empty folder at: ~/public_html/velocity/tools/${project.version} * If you haven't done it before, ensure that your PGP key is appended to /www/www.apache.org/dist/velocity/KEYS Some instructions for that are at the top of that file. * Use 'ant publish' to upload the distribution files to that folder. * Review http://wiki.apache.org/velocity/ReleaseProcess for more details. You must first execute "release" target, then sign the distribution files with your pgp key (creating the needed '.asc'signature files). You may also need to add the Jsch jar to Ant's classpath to enable the optional 'scp' task. Uploading distribution files from ${dist.dir} to ${username}:${password}@${publish.server}:${publish.dir} ***** RELEASE INSTRUCTIONS ***** * SSH to ${publish.server} and verify the checksums and signatures of the uploaded files with a script like: #!/bin/csh foreach fn ( *.tar.gz *.zip *.jar *.pom ) echo Verifying $fn... echo GPG signature should be "Good" gpg --verify $fn.asc echo MD5s should be identical cat $fn.md5 md5 -q $fn echo SHA1s should be identical cat $fn.sha1 sha1 -q $fn echo end * Announce the availability of the test build on the dev@velocity.apache.org list. * Allow a couple days for people to test the test build. * Call for a release vote on private@velocity.apache.org and dev@velocity.apache.org * Once the release vote has passed, these files should all be copied to /www/www.apache.org/dist/velocity/tools/${project.version} and the full jar, pom and their md5 and sha1 files should be copied into /www/people.apache.org/repo/m2-ibiblio-rsync-repository/org/apache/velocity/velocity-tools/${project.version}/ * Remove older releases of the same grade as this one (alpha, beta, final) from /www/www.apache.org/dist/velocity/tools * Tag the release in SVN with a command such as: svn copy -m "Release Tools ${project.version}" -r [revision #] \ https://svn.apache.org/repos/asf/velocity/tools/trunk \ https://svn.apache.org/repos/asf/velocity/tools/tags/${project.version} * Publish the documentation for this release on the website using 'ant publish.docs' * Update the download and news pages on the website * Send an announcement email to all Velocity lists and announce@apache.org once most of the mirrors have been updated with the distribution files. * Review http://wiki.apache.org/velocity/ReleaseProcess for more details. Zips documentation files from ${docs.dir} and uploads them to ${username}:${password}@${publish.server}:${publish.docs.dir} ***** PUBLISH INSTRUCTIONS ***** * SSH into people.apache.org * Unzip ${publish.docs.dir}docs.zip into either ${publish.docs.dir}releases/${project.version} or ${publish.docs.dir}devel/ as appropriate. NOTE: At this time, you must add Apache RAT, Apache RAT AntTasks Commons-Lang, Commons-Collections and Commons-CLI to Ant's lib directory to use this. Your RAT report is here: ${build.dir}/rat-report.txt Deploying to ${maven.remote.repository} Deploying to Apache Maven repository velocity-tools-2.0-src/download.xml100644 0 0 41404 11114542172 14635 0ustar 0 0 velocity-tools-2.0-src/examples.xml100644 0 0 14261 11110347753 14651 0ustar 0 0 A WAR file (Web ARchive) was created for you at ${examples.home}/${name}.war To use it with Tomcat, copy the ${name}.war file to the webapps directory in the Tomcat tree (assuming a standard Tomcat installation) and then restart Tomcat. To access the page point your browser to http://localhost:8080/${name}/index.vm If you have any questions, don't hesitate to ask on the Velocity user list. velocity-tools-2.0-src/examples/showcase/Error.vm100644 0 0 2711 10730012262 17344 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. ## Force use of default layout (so req params don't override it) #set( $layout = "Default.vm" ) #title( "Error - $!cause.class.name" )

$text.error.header


#if( $invocation_exception ) $!invocation_exception.message #else $!cause.message #end
#if( $invocation_exception )
oh joy! it's a MethodInvocationException!

Reference name: $invocation_exception.referenceName
Method name: $invocation_exception.methodName
#end

Alright, here's the stack.  Good luck.

$stack_trace

$text.error.sorry

velocity-tools-2.0-src/examples/showcase/VM_global_library.vm100644 0 0 21303 11202122670 21657 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. #** * Sets the $page_title key, so if it ever changes, * it need only be changed here. *# #macro( title $string ) #set( $page_title = $string )#end #** * Creates a link to the javadoc for the specified tool. *# #macro( doclink $toolname $generic ) #set( $doclink = "http://velocity.apache.org/tools/devel/javadoc/org/apache/velocity/tools/## #if( $generic )generic/#else#**#view/#end## ${toolname}.html" )## $toolname#end #** * Creates a list item for the toolmenu. *# #macro( toolMenuItem $menulink $tool )
  • $text.tools.get($tool)
  • #end #** * Creates a smart default value for a demo field. *# #macro( demoDefault $valuetype ) #if( $valuetype.simpleName ) #set( $valuetype = $valuetype.simpleName ) #end #if( $valuetype eq 'String' ) 'test'## #elseif( $valuetype eq 'int' or $valuetype eq 'Integer' or $valuetype eq 'long' or $valuetype eq 'Long' ) 1## #elseif( $valuetype eq 'double' or $valuetype eq 'Double' or $valuetype eq 'float' or $valuetype eq 'Float' ) 1.1## #elseif( $valuetype eq 'boolean' or $valuetype eq 'Boolean' ) true## #elseif( $valuetype eq 'Class' ) ${esc.d}class.class## #end## #end #** * Creates the start tag and header row for a function demonstration table. *# #macro( demoTableStart ) #set( $demo = $text.demo ) #if( $params.layout ) #end #end #** * Creates a demonstration row of a tool method that takes no parameters. *# #macro( demo $toolname $method $description ) #end #** * Creates a faux demonstration row of a tool method that takes no parameters. *# #macro( demoAlt $toolname $method $result $description ) #end #** * Creates an interactive demonstration row for a tool method that takes one parameter. *# #macro( demo1 $toolname $method $size $description ) #if( !$quote ) #set( $quote = $esc.q ) #end ## HttpUnit doesn't like anchor-only links #end #** * Creates an interactive demonstration row for a tool method that takes two parameters. *# #macro( demo2 $toolname $method $size $description ) #if( !$quote ) #set( $quote = $esc.q ) #end #set( $method1 = "${method}1" ) #set( $method2 = "${method}2" ) ## HttpUnit doesn't like anchor-only links #end #** * Creates an interactive demonstration row for a tool method that takes three parameters. *# #macro( demo3 $toolname $method $size $description ) #if( !$quote ) #set( $quote = $esc.q ) #end #set( $method1 = "${method}A" ) #set( $method2 = "${method}B" ) #set( $method3 = "${method}C" ) ## HttpUnit doesn't like anchor-only links #end #** * Creates a free-form interactive demonstration row. *# #macro( demoCustom $toolname ) #end velocity-tools-2.0-src/examples/showcase/WEB-INF/src/LayoutLinkTool.java100644 0 0 3275 11202122667 23335 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import org.apache.velocity.tools.view.LinkTool; import org.apache.velocity.tools.view.VelocityLayoutServlet; /** * This is meant to demonstrate how to extend the LinkTool to * avoid the manual use of "magic" or common query parameters. * So instead of doing $link.param('layout', 'Table.vm') in your * template, you would just do $link.layout('Table'). * * @author Nathan Bubna * @version $Id: LayoutLinkTool.java 479724 2006-11-27 18:49:37Z nbubna $ */ public class LayoutLinkTool extends LinkTool { public LayoutLinkTool layout(Object obj) { if (obj == null) { return null; } return layout(obj.toString()); } public LayoutLinkTool layout(String layout) { if (layout != null && !layout.endsWith(".vm")) { layout += ".vm"; } return (LayoutLinkTool)param(VelocityLayoutServlet.KEY_LAYOUT, layout); } } velocity-tools-2.0-src/examples/showcase/WEB-INF/src/MySearchTool.java100644 0 0 7757 10730012262 22760 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.velocity.tools.view.AbstractSearchTool; /** * This is meant to demonstrate how to extend the AbstractSearchTool. * A typical implementation would have no static Set as a database, * , not have store() methods, and have a real * executeQuery(criteria) implementation. But this works for the * purposes of this demo. * * @author Nathan Bubna * @version $Id: MySearchTool.java 479724 2006-11-27 18:49:37Z nbubna $ */ public class MySearchTool extends AbstractSearchTool { private static Set DATABASE = new HashSet(); static { // some random data to get things started DATABASE.add("foo"); DATABASE.add("bar"); DATABASE.add("baz"); DATABASE.add("woogie"); DATABASE.add("pizza"); DATABASE.add("cheese"); DATABASE.add("wine"); DATABASE.add("avocado"); DATABASE.add("peanut butter"); DATABASE.add("salami"); DATABASE.add("hobbits"); DATABASE.add("basketball"); DATABASE.add("four score and seven years"); DATABASE.add("whatever"); DATABASE.add("you"); DATABASE.add("want"); } /** * Adds the specified item to our static "database". * You would not do this in a normal application! */ public void store(Object item) { DATABASE.add(item); } /** * Adds the entries of the specified map to our static "database". * You would not do this in a normal application! */ public void store(Map items) { DATABASE.addAll(items.entrySet()); } /** * Adds the specified items to our static "database". * You would not do this in a normal application! */ public void store(Collection items) { DATABASE.addAll(items); } /** * Override to create a session in which to store search results. * This is done to make the demo work well. In a normal app, it * would probably not be the search tool's responsibility to ensure * that there is a session. */ public boolean getCreateSession() { return true; } /** * This is a very simplistic implementation that looks for the * string value of the criteria in the string value of every item * in our stupid static database. If the criteria string is in * the item string, it is added to the result list. */ protected List executeQuery(Object crit) { String findme = String.valueOf(crit); List results = new ArrayList(); synchronized (DATABASE) { for (Iterator i = DATABASE.iterator(); i.hasNext(); ) { String item = String.valueOf(i.next()); if (item.indexOf(findme) >= 0) { results.add(item); } } } Collections.sort(results); return results; } } velocity-tools-2.0-src/examples/showcase/WEB-INF/src/file.xml100644 0 0 1607 11115263034 21174 0ustar 0 0 woogie wiggie velocity-tools-2.0-src/examples/showcase/WEB-INF/src/otherStuff.properties100644 0 0 1475 11115263034 24005 0ustar 0 0 # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. foo= woogie baz= The args are {0} and {1}. velocity-tools-2.0-src/examples/showcase/WEB-INF/src/resources.properties100644 0 0 67670 11202122667 23722 0ustar 0 0 # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. ## text.vm demo foo = bar hello.whoever = Hello {0}! world = World appname = Showcase ## Error.vm error.header = There has been an error! error.sorry = There has been an error! ## Default.vm css.name = CSS Layout css.issuesHeader = Known Issues css.issues = This layout fails in IE4.5/Mac. That browser has poor support for CSS absolute positioning, yet it recognizes and executes the CSS @import statement used to hide CSS from broken browsers. Currently, there is no known solution. css.niftyHeader = Nifty Layout Techniques css.nifty = All sorts of nifty layout can be accomplished using cascading style sheets (CSS). Check out bluerobot.com and the Layout Reservoir ## Print.vm print.name = Print Layout ## Simple.vm simple.name = Simple Layout ## Table.vm table.name = Table Layout ## index.vm index.greeting = Hi index.explanation = This is a demo application meant to showcase the abilities of \ the various tools provided by the VelocityTools library, as well \ as some best practices for using them with the VelocityView servlets. index.start = To begin, choose a tool from the menu. index.asterisk = With the exception of the way we abuse the RenderTool and \ Velocimacros. They''ve been stretched pretty far in order to allow the content \ to be very rapidly developed and more user-interactive than is usually needed. \ This has entailed the loss of some performance and much clarity. As such, the \ way we use these two facilities should probably not be considered a best practice. :) ## layoutmenu.vm layouts.header = Choose a layout layouts.css = CSS Layout layouts.simple = Simple Layout layouts.table = Table Layout layouts.print = Print Layout ## toolmenu.vm tools.header = Choose a tool tools.alternator = AlternatorTool tools.browser = BrowserTool tools.class = ClassTool tools.context = ContextTool tools.convert = ConversionTool tools.cookies = CookieTool tools.date = DateTool tools.display = DisplayTool tools.esc = EscapeTool tools.field = FieldTool tools.include = IncludeTool tools.import = ImportTool tools.link = LinkTool tools.lists = ListTool tools.math = MathTool tools.loop = LoopTool tools.number = NumberTool tools.pager = PagerTool tools.params = ParameterTool tools.render = RenderTool tools.text = ResourceTool tools.search = SearchTool tools.sorter = SortTool tools.xml = XmlTool ## demo common resources demo.function = Function demo.result = Demo Result demo.nullResult = null demo.clear = Clear All demo.description = Description demo.descriptionMissing = TODO: add {0} = [description] to resources.properties demo.try = Go demo.tryAgain = Go demo.tryAnything = Try any code out here. demo.thisPage = This page demonstrates functions of the {0} demo.mainExampleHeader = Example Display demo.mainResultsIntro = Your code returned the following results demo.toString = Returns a customized string representation of the tool. # alternator.vm resources alternator.intro = The example at the bottom is a good \ demonstration of the difference between an automatic {0} and a manual one. \

    Please see the javadoc for {0} to understand how they work and the methods \ you can call on them. \

    Also note that the varargs methods here only work fully with Velocity 1.6 \ (which supports vararg method calls). The old non-vararg versions are still \ available (as seen in the demo below). But they are \ deprecated (and thus not listed below) to discourage those extending this \ tool or using it outside Velocity templates from depending on those methods. alternator.getAutoAlternateDefault = Returns true if Alternators created by this tool will auto-alternate by default. alternator.make = Returns a new, default Alternator that alternates over the specified values. alternator.make_booleanObjectVarArgs = Returns a new Alternater that alternates of the specified values using the specified auto-alternate setting. alternator.auto = Returns a new, automatically alternating Alternator that alternates over the specified values. alternator.auto_ObjectVarArgs.param1 = [''b'',''c'',''a''] alternator.manual = Returns a new, manually alternating Alternator that alternates over the specified values. alternator.manual_ObjectVarArgs.param1 = [''red'',''green''] alternator.custom = $alternator.make([''b'',''c'',''a'']) # class.vm resources class.intro = By default, the ClassTool is set to inspect \ java.lang.Object, though you may set the "inspect" \ property in your ClassTool configuration to point to any class on the classpath. \ Also, a new ClassTool instance can be created for any class you wish \ by a call to one of the inspect() methods. \ By default, the safeMode property is set to true unless you \ configure it to be false. \ When true, safeMode will restrict ClassTool (or any instances it creates) to \ only inspecting classes, methods, fields and constructors that were declared public. class.getAnnotations = Returns a list of the Annotations of the class being inspected. class.getConstructors = Returns a list of ConstructorSubs for each constructor declared in the inspected class. class.getFields = Returns a list of FieldSubs for each field declared in the inspected class. class.getFullName = Returns the fully qualified name of the class being inspected. class.getMethods = Returns a list of MethodSubs for each method declared in the inspected class. class.getName = Returns the simple name of the class being inspected. class.getPackage = Returns the package name of the class being inspected. class.getShowDeprecated = Returns the current showDeprecated setting. class.getSafeMode = Returns the current safeMode setting. class.getType = Returns the actual Class being inspected. class.getTypes = Returns a Set of all Classes that are part of the signatures (i.e. parameters or return types) of the inspected Class''s methods, constructors and fields. class.getSuper = Returns a new ClassTool instance that inspects the immediate superclass of the class being inspected. class.inspect_Class = Returns a new ClassTool instance that inspects the specified Class. class.inspect_Class.param1 = $class.class class.inspect_Object = Returns a new ClassTool instance that inspects the Class of the specified object. class.inspect_Object.param1 = $class class.inspect_String = Returns a new ClassTool instance that inspects the Class for the specified class name \ or null if no class can be found for the specified name. class.inspect_String.param1 = ''org.apache.velocity.tools.generic.ClassTool'' class.isAbstract = Returns true if the class being inspected is abstract. class.isFinal = Returns true if the class being inspected is final. class.isInterface = Returns true if the class being inspected is an interface. class.isPrivate = Returns true if the class being inspected is private. class.isProtected = Returns true if the class being inspected is protected. class.isPublic = Returns true if the class being inspected is public. class.isStatic = Returns true if the class being inspected is static. class.isStrict = Returns true if the class being inspected is declared strict. class.supportsNewInstance = Returns true if a new instance of the class being inspected can be created via $class.type.newInstance(). class.toString = Returns the result of $class.type.toString(). # context.vm resources context.intro = This tool exists to provide access to the current context and various attributes of it. context.getThis = Returns the ViewContext currently being analyzed by this tool. context.contains = Returns true if there is a value available in the current request context for the specified key. context.get = Returns the value for the specified key in the current request context. context.getKeys = Returns a java.util.Set of the keys available in the current request context context.getToolbox = Returns a java.util.Map of the tools available in the current request context and their context keys. context.getValues = Returns a java.util.Set of the values available in the current request context. # convert.vm resources convert.intro = This tool aids in converting Strings (or other objects) to more useful types. convert.getDateFormat = The default configured Date format string. convert.getNumberFormat = The default configured Number format string. convert.getStringsDelimiter = The delimiter used to identify separate values in any of the pluralized methods below. convert.getStringsTrim = Whether or not whitespace is trimmed off of Strings passed in before they are used. convert.toString = Converts an object to an instance of String if the object is not already an instance of String. convert.toString.param1 = $convert convert.toStrings = Converts an array, Collection, delimited String, or object to an array of Strings. convert.toStrings.Object = [true,false] convert.toBoolean = Converts an object to an instance of Boolean if the object is not already an instance of Boolean. convert.toBoolean.Object = ''true'' convert.toBooleans = Converts an array, Collection, delimited String, or object to an array of Booleans. convert.toBooleans.Object = ''false,true'' convert.toLocale = Converts an object to an instance of Locale if the object is not already an instance of Locale. convert.toLocale.Object = ''en_US'' convert.toLocales = Converts an array, Collection, delimited String, or object to an array of Locales. convert.toLocales.Object = ''en_US,fr'' convert.toInteger = Converts an object to an instance of Integer using the format returned by $convert.numberFormat and the Locale returned by $convert.locale if the object is not already an instance of Integer. convert.toInteger.Object = 1.2 convert.toInts = Converts an array, Collection, delimited String, or object to an array of Ints. convert.toInts.Object = ''1.2,2.3,3.4'' convert.toDouble = Converts an object to an instance of Double using the format returned by $convert.numberFormat and the Locale returned by $convert.locale if the object is not already an instance of Double. convert.toDouble.Object = 1 convert.toDoubles = Converts an array, Collection, delimited String, or object to an array of Doubles. convert.toDoubles.Object = ''1,2.3'' convert.toNumber = Converts an object to an instance of Number using the format returned by $convert.numberFormat and the Locale returned by $convert.locale if the object is not already an instance of Number. convert.toNumber.Object = $date.date convert.toNumbers = Converts an array, Collection, delimited String, or object to an array of Numbers. convert.toNumbers.Object = ''1,2.3'' convert.parseNumber_String = Parses the specified String to an instance of Number using the default Locale (as returned by $convert.locale). convert.parseNumber_String.param1 = ''10.2'' convert.parseNumber_StringObject = Parses a String to an instance of Number using the specified format and the Locale returned by $convert.locale. convert.parseNumber.String = convert.parseNumber_StringStringObject = Parses a String to an instance of Number using the specified format and Locale. convert.toDate = Converts an object to an instance of Date using the format returned by $convert.dateFormat and the Locale returned by $convert.locale. convert.toDate.Object = ''2009-01-31'' convert.toDates = Converts an array, Collection, delimited String, or object to an array of Dates. convert.toDates.Object = ''2009-01-31,2006-07-17'' convert.parseDate_String = Parses the specified String to an instance of Date using the default format and Locale. convert.parseDate_String.param1 = ''2006-07-17'' convert.parseDate_StringObject = Parses a String to an instance of Date using the specified format and the Locale returned by $convert.locale. convert.parseDate_StringObject.param1 = ''8-1-79'' convert.parseDate_StringObject.param2 = ''M-d-yy'' convert.parseDate_StringStringObject = Parses a String to an instance of Date using the specified format and Locale convert.parseDate.String = convert.parseDate_StringStringObjectTimeZone = Parses a String to an instance of Date using the specified format, Locale and TimeZone convert.toCalendar = Converts an object to an instance of Calendar using the format returned by $convert.dateFormat and the Locale returned by $convert.locale. convert.toCalendar.Object = $date convert.toCalendars = Converts an array, Collection, delimited String, or object to an array of Calendars. convert.toCalendars.Object = ''2009-01-31,2006-07-17'' # cookies.vm resources cookies.intro = Remember, when adding a cookie, it is not added \ to the same request which does the adding. This means to see a cookie \ you''ve added, you must add it, and then refresh the page again. cookies.getAll = Returns a list of Cookies for this request. cookies.get = Returns the Cookie with the specified name, if it exists. cookies.add_Cookie = Adds the cookie to the HttpServletResponse. This does NOT add it to the current request. cookies.add_Cookie.param1 = $cookies.create(''test'',''test'') cookies.add_StringString = Adds a new Cookie with the specified name and value to the HttpServletResponse. This does not add a Cookie to the current request. cookies.add_StringStringObject = Convenience method to add a new Cookie to the response and set an expiry time for it. cookies.create_StringString = Creates a new Cookie with the specified name and value. This does not add the Cookie to the response, so the created Cookie will not be set unless you do $cookies.add($myCookie) cookies.create_StringStringObject = Convenience method to create a new Cookie and set an expiry time for it. The created cookie must then be manually added. cookies.delete_String = Instructs the browser to remove the specified cookie by setting it with a Max-Age of 0. cookies.toString = If there are no Cookies in the request, this returns the standard Object.toString output; otherwise, it returns a pretty printed list of cookie names and values. cookies.custom = $cookies.JSESSIONID cookies.Object = 10 # display.vm resources display.intro = This tool provides a variety of methods for controlling the output \ displayed by various references in your templates. display.list = Formats a collection or array into the form "A, B and C". display.list_Object.param1 = [''A'',''B'',''C''] display.list_ObjectString = Formats a collection or array into a string delimited by the second argument display.list_ObjectStringString = Formats a collection or array into a string delimited by the second argument, except the last two arguments are delimited by the third argument display.truncate = Limits the string output of the specified value to the configured max length in characters (default is 30 characters). If the string gets curtailed, the configured suffix (default is "...") is used as the ending of the truncated string. display.truncate_Objectint = Limits the string output of the second argument to the specified number of characters. If the string gets curtailed, the configured suffix (default is "...") is used as the ending of the truncated string. display.truncate_ObjectString = Limits the string output of the first argument to the configured max length in characters (default is 30 characters). If the string gets curtailed, the specified suffix is used as the ending of the truncated string. display.truncate_ObjectintString = Limits the string output of the second argument to the specified number of characters. If the string gets curtailed, the specified suffix is used as the ending of the truncated string. display.alt = Returns the configured default value ("null" by default) if the specified value is null. display.alt_ObjectObject = Returns the second argument if first argument specified is null. display.br_Object = Inserts HTML line break tag (<br />) in front of all newline characters of the string value of the specified object and returns the resulting string. display.cell = Truncates or pads the string value of the specified object as necessary to ensure that the returned string''s length equals the default cell size. display.cell_Objectint = Truncates or pads the string value of the specified object as necessary to ensure that the returned string''s length equals the specified cell size. display.cell_ObjectString = Truncates or pads the string value of the specified object as necessary to ensure that the returned string''s length equals the default cell size. If truncation is necessary, the specified suffix will replace the end of the string value to indicate that. display.cell_ObjectintString = Truncates or pads the string value of the specified object as necessary to ensure that the returned string''s length equals the specified cell size. If truncation is necessary, the specified suffix will replace the end of the string value to indicate that. display.message = Uses java.text.MessageFormat to format the specified String with the specified arguments. If there are no arguments, then the String is returned directly. display.message_StringObjectVarArgs.param1 = ''foo {1} {0}'' display.message_StringObjectVarArgs.param2 = [''bar'', 2] display.plural_intString = Builds plural form of a passed word if ''value'' is plural, otherwise returns ''singular''. Plural form is built using some basic English language rules for nouns which does not guarantee correct syntax of a result in all cases. display.plural_intStringString = Returns ''plural'' parameter if passed 'value' is plural, otherwise ''singular'' is returned. display.printf_StringObjectVarArgs = Uses String.format(Locale,String,Object...) to format the specified String with the specified arguments. Please note that the format required here is quite different from that of message(String,Object...). display.space = Returns a string of spaces of the specified length. display.space_int.param1 = 4 display.stripTags_Object = Removes HTML tags from the string value of the specified object and returns the resulting string. display.stripTags_ObjectStringVarArgs = Removes all not allowed HTML tags from the string value of the specified object and returns the resulting string. display.capitalize = Changes the first character of the string value of the specified object to upper case and returns the resulting string. display.uncapitalize = Changes the first character of the string value of the specified object to lower case and returns the resulting string. display.measure = Returns the measurements of the string value of the specified object. display.getAllowedTags = Returns the configured tags allowed to remain by stripTags(Object). display.getCellLength = Returns the configured default cell size. display.getCellSuffix = Returns the configured default suffix used when cell contents need truncating. display.getDefaultAlternate = Returns the configured default alternate used by alt(Object). display.getListDelimiter = Returns the configured default delimiter used between items by the list formatting methods. display.getListFinalDelimiter = Returns the configured default delimiter used between the last two items by the list formatting methods. display.getTruncateLength = Returns the configured default length used by truncate(Object). display.getTruncateSuffix = Returns the configured default suffix used by the truncate methods. display.getTruncateAtWord = Returns the configured default setting for whether to truncate at a precise character or the last fitting word. display.Object = ''string'' # field.vm resources field.intro = This tool allows easy access to public static fields in classes, such as string constants. field.get_String = Returns the value of the field with the specified name, if found. field.get_String.param1 = ''java.lang.Boolean.FALSE'' field.in_Class = Loads all public static fields in the specified class. field.in_Class.param1 = $date.class field.in_Object = Loads all public static fields in the Class of the specified object. field.in_Object.param1 = 1 field.in_String = Looks for a class with the specified name; if found, loads all public static fields. field.in_String.param1 = ''java.lang.Float'' field.custom = $field.in($field).INCLUDE_KEY # include.vm resources include.intro = Allows for transparent content negotiation in a manner mimicking Apache httpd''s \ MultiViews. \ Reads the default language out of the ViewToolContext as \ org.apache.velocity.tools.view.i18n.defaultLanguage. \ This is the successor to the MultiViewsTool in VelocityTools 1.x. \ Please note that it does NOT do the actual #include or #parse for you, \ but is merely to aid in include content negotiation. include.exists_String = Checks whether or not a resource with the specified name is available. include.exists_String.param1 = ''include.vm'' include.exists_StringString = Checks whether or not a resource is available with the specified name and language suffix. include.exists_StringString.param1 = ''include.vm'' include.exists_StringString.param2 = ''de'' include.find_String = Returns the localized name for the specified resource. include.find_String.param1 = ''demo.vm'' include.find_StringLocale = Returns the localized name for the specified resource, \ with the specified Locale's language suffix. If one for that language is unavailable, \ then it will "widen" the langauge until one is found. If none is found at all, \ the name parameter is returned. include.find_StringLocale.param1 = ''demo.vm'' include.find_StringLocale.param2 = $text.locale include.find_StringString = Returns the localized name for the specified resource, \ with the requested language suffix. If one for that language is unavailable, \ then it will "widen" the langauge until one is found. If none is found at all, \ the name parameter is returned. include.find_StringString.param1 = ''demo.vm'' include.find_StringString.param2 = ''fr'' # loop.vm resources loop.intro = This tool is a convenience tool to use with #foreach loops. It wraps a \ list to let you prematurely stop iterating, skip iterations, sync iteration over \ multiple lists in the same loop, easily \ determine if you are on the first or last iteration, get the number of iterations \ completed, automatically stop before or exclude particular elements and easily \ do all the above even with complex, nested loops. # xml.vm resources xml.intro = Tool for reading/navigating XML files. This uses dom4j under the \ covers to provide complete XPath support for traversing XML files. \ Most of the methods below will do nothing, as the default tool does not \ have any XML content to work with. For demo''s sake, there is a file.xml \ in the classpath that is automatically loaded for you to work with, \ and we have turned off safe mode, so you can do things like \ $xml.read(''tools.xml''). \ Still, the full demo at the bottom will likely be the most useful for you. xml.read_Object.param1 = ''file.xml'' xml.read_Object = Returns null if safe mode is on; otherwise \ this will accept url pointing to an XML document. It will then parse that document \ and return a new instance with that document''s root element as its node. xml.parse_Object.param1 = ''that'' xml.parse_Object = Accepts XML strings. If the XML is valid, it will return a \ new XmlTool instance with the XML''s root as its internal node. xml.get_Object.param1 = ''bar[2]'' xml.get_Object = This will first attempt to find an attribute with the \ specified name and return its value. If no such attribute \ exists or its value is null, this will attempt to convert \ the given value to a Number and get the result of get(Number). If the number conversion fails, \ then this will convert the object to a string. If that string \ does not start contain a ''/'', it appends the result of getPath() and a ''/'' to the front of it. \ Finally, it delegates the string to the find(String) method and returns the result of that. xml.getName = Asks get(Object) for "name". If none, this will return the result of getNodeName(). xml.getNodeName = Returns the name of the root node. If the internal Node \ list has more than one Node, it will only return the name of the first node in the list. xml.attr_Object.param1 = ''x'' xml.attr_Object = Returns the value of the specified attribute for the first/sole \ Node in the internal Node list for this instance, if that Node is an Element. If it is a non-Element node type or \ there is no value for that attribute in this element, then this will return null. xml.attributes = Returns a Map of all attributes for the first/sole \ Node held internally by this instance. If that Node is not an Element, this will return null. xml.isEmpty = Returns true if there are no Nodes internally held by this instance. xml.size = Returns the number of Nodes internally held by this instance. xml.iterator = Returns an Iterator that returns new XmlTool instances for each Node held internally by this instance. xml.getFirst = Returns a new instance that wraps only the first Node from this instance''s internal Node list. xml.getLast = Returns a new instance that wraps only the last Node from this instance''s internal Node list. xml.get_Number.param1 = 0 xml.get_Number = Returns a new instance that wraps the specified Node from this instance''s internal Node list. xml.node = Returns the first/sole Node from this instance''s internal Node list, if any. xml.find_Object.param1 = ''/*/a[@*]'' xml.find_Object = Converts the specified object to a String and calls find(String) with that. xml.find_String.param1 = ''@baz'' xml.find_String = Performs an XPath selection on the current set of \ Nodes held by this instance and returns a new instance that wraps those results. \ If the specified value is null or this instance does not currently hold any nodes, then this will return \ null. If the specified value, when converted to a string, does not contain a ''/'' character, then \ it has "//" prepended to it. This means that a call to $xml.find("a") is equivalent to calling \ $xml.find("//a"). The full range of XPath selectors is supported here. xml.getParent = Returns a new XmlTool instance that wraps the parent Element of the first/sole Node \ being wrapped by this instance. xml.getPath = Returns the XPath that identifies the first/sole Node represented by this instance. xml.parents = Returns a new XmlTool instance that wraps the parent Elements of each of the Nodes \ being wrapped by this instance. This does not return all ancestors, just the immediate parents. xml.children = Returns a new XmlTool instance that wraps all the \ child Elements of all the current internally held nodes that are Elements themselves. xml.getText = Returns the concatenated text content of all the internally held \ nodes. Obviously, this is most useful when only one node is held. xml.toString = If this instance has no XML Nodes, then this returns the result of super.toString(). Otherwise, \ it returns the XML (as a string) of all the internally held nodes \ that are not Attributes. For attributes, only the value is used. xml.custom = $xml.find(''*[@name]'').attributes() velocity-tools-2.0-src/examples/showcase/WEB-INF/src/resources_de.properties100644 0 0 1505 11115263034 24330 0ustar 0 0 # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. foo = Stab hello.whoever = Hallo {0}! world = Welt velocity-tools-2.0-src/examples/showcase/WEB-INF/src/resources_fr.properties100644 0 0 1511 11115263034 24344 0ustar 0 0 # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. foo = barre hello.whoever = Bonjour {0}! world = Monde velocity-tools-2.0-src/examples/showcase/WEB-INF/tools.xml100644 0 0 2745 11360645211 20635 0ustar 0 0 Nathan Bubna velocity-tools-2.0-src/examples/showcase/WEB-INF/velocity.properties100644 0 0 2575 10730012262 22722 0ustar 0 0 # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # # These are the default properties. So, this file is essentially # unnecessary here, but is included just to demonstrate that these # can be changed. # # Filepath for error template, relative to web application root directory tools.view.servlet.error.template = Error.vm # Directory for layout templates, relative to web application root directory tools.view.servlet.layout.directory = layout/ # Filepath of the default layout template # relative to the layout directory # NOT relative to the root directory of the webapp! tools.view.servlet.layout.default.template = Default.vm velocity-tools-2.0-src/examples/showcase/WEB-INF/web.xml100644 0 0 3374 11202122667 20251 0ustar 0 0 velocity org.apache.velocity.tools.view.VelocityLayoutServlet org.apache.velocity.tools.deprecationSupportMode false org.apache.velocity.tools.cleanConfiguration true org.apache.velocity.tools.userCanOverwriteTools false velocity *.vm index.vm velocity-tools-2.0-src/examples/showcase/alternator.vm100644 0 0 2746 11030275256 20446 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. #title( 'AlternatorTool' )

    $text.demo.thisPage.insert("#doclink( 'AlternatorTool' true )"). #set( $toollink = $doclink ) $text.alternator.intro.insert("#doclink( 'Alternator' true )")

    ## The demo.vm template expects the following values to be set #set( $toolname = 'alternator' ) #set( $toolclass = $alternator.class ) #set( $toolDemo = "${esc.h}set( ${esc.d}color = ${esc.d}alternator.auto('red', 'blue') ) ${esc.h}${esc.h} use manual alternation for this one ${esc.h}set( ${esc.d}style = ${esc.d}alternator.manual(['hip','fly','groovy']) ) ${esc.h}foreach( ${esc.d}i in [1..5] ) Number ${esc.d}i is ${esc.d}color and ${esc.d}style. I dig $style.next numbers. ${esc.h}end" ) #parse( 'demo.vm' ) velocity-tools-2.0-src/examples/showcase/browser.vm100644 0 0 14432 11360645211 17767 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. #title( 'BrowserTool' )

    #set( $demo = $text.demo ) $demo.thisPage.insert("#doclink( 'BrowserTool' false )").

    #demoTableStart() #set( $desc = 'Returns true if the specified value is found in the user-agent string' ) #demo1( 'browser' 'get' 6 $desc ) #set( $desc = 'Finds and returns the specified version information' ) #demo( 'browser' 'Version' $desc ) #demo( 'browser' 'MajorVersion' $desc ) #demo( 'browser' 'MinorVersion' $desc ) #demo( 'browser' 'GeckoVersion' $desc ) #demo( 'browser' 'GeckoMajorVersion' $desc ) #demo( 'browser' 'GeckoMinorVersion' $desc ) #set( $desc = 'Returns true if the user-agent string indicates this browser made the request' ) #demo( 'browser' 'Gecko' $desc ) #demo( 'browser' 'Firefox' $desc ) #demo( 'browser' 'Safari' $desc ) #demo( 'browser' 'Chrome' $desc ) #demo( 'browser' 'Netscape' $desc ) #demo( 'browser' 'Nav2' $desc ) #demo( 'browser' 'Nav3' $desc ) #demo( 'browser' 'Nav4' $desc ) #demo( 'browser' 'Nav4up' $desc ) #demo( 'browser' 'Nav45' $desc ) #demo( 'browser' 'Nav45up' $desc ) #demo( 'browser' 'Navgold' $desc ) #demo( 'browser' 'Nav6' $desc ) #demo( 'browser' 'Nav6up' $desc ) #demo( 'browser' 'Mozilla' $desc ) #demo( 'browser' 'Ie' $desc ) #demo( 'browser' 'Ie3' $desc ) #demo( 'browser' 'Ie4' $desc ) #demo( 'browser' 'Ie4up' $desc ) #demo( 'browser' 'Ie5' $desc ) #demo( 'browser' 'Ie5up' $desc ) #demo( 'browser' 'Ie55' $desc ) #demo( 'browser' 'Ie55up' $desc ) #demo( 'browser' 'Ie6' $desc ) #demo( 'browser' 'Ie6up' $desc ) #demo( 'browser' 'Neoplanet' $desc ) #demo( 'browser' 'Neoplanet2' $desc ) #demo( 'browser' 'Aol' $desc ) #demo( 'browser' 'Aol3' $desc ) #demo( 'browser' 'Aol4' $desc ) #demo( 'browser' 'Aol5' $desc ) #demo( 'browser' 'Aol6' $desc ) #demo( 'browser' 'AolTV' $desc ) #demo( 'browser' 'Opera' $desc ) #demo( 'browser' 'Opera3' $desc ) #demo( 'browser' 'Opera4' $desc ) #demo( 'browser' 'Opera5' $desc ) #demo( 'browser' 'Opera6' $desc ) #demo( 'browser' 'Opera7' $desc ) #demo( 'browser' 'Hotjava' $desc ) #demo( 'browser' 'Hotjava3' $desc ) #demo( 'browser' 'Hotjava3up' $desc ) #demo( 'browser' 'Amaya' $desc ) #demo( 'browser' 'Curl' $desc ) #demo( 'browser' 'Staroffice' $desc ) #demo( 'browser' 'Icab' $desc ) #demo( 'browser' 'Lotusnotes' $desc ) #demo( 'browser' 'Konqueror' $desc ) #demo( 'browser' 'Lynx' $desc ) #demo( 'browser' 'Links' $desc ) #demo( 'browser' 'WebTV' $desc ) #demo( 'browser' 'Mosaic' $desc ) #demo( 'browser' 'Wget' $desc ) #demo( 'browser' 'Getright' $desc ) #demo( 'browser' 'Lwp' $desc ) #demo( 'browser' 'Yahoo' $desc ) #demo( 'browser' 'Google' $desc ) #demo( 'browser' 'Java' $desc ) #demo( 'browser' 'Altavista' $desc ) #demo( 'browser' 'Scooter' $desc ) #demo( 'browser' 'Lycos' $desc ) #demo( 'browser' 'Infoseek' $desc ) #demo( 'browser' 'Webcrawler' $desc ) #demo( 'browser' 'Linkexchange' $desc ) #demo( 'browser' 'Slurp' $desc ) #demo( 'browser' 'Robot' $desc ) #set( $desc = 'Returns true if the user-agent string indicates the request was made by this device' ) #demo( 'browser' 'Blackberry' $desc ) #demo( 'browser' 'Audrey' $desc ) #demo( 'browser' 'Iopener' $desc ) #demo( 'browser' 'Avantgo' $desc ) #demo( 'browser' 'Palm' $desc ) #demo( 'browser' 'Wap' $desc ) #set( $desc = 'Returns true if the user-agent string indicates the request was made using this operating system' ) #demo( 'browser' 'Win16' $desc ) #demo( 'browser' 'Win3x' $desc ) #demo( 'browser' 'Win31' $desc ) #demo( 'browser' 'Win95' $desc ) #demo( 'browser' 'Win98' $desc ) #demo( 'browser' 'Winnt' $desc ) #demo( 'browser' 'Win2k' $desc ) #demo( 'browser' 'Winxp' $desc ) #demo( 'browser' 'Dotnet' $desc ) #demo( 'browser' 'Winme' $desc ) #demo( 'browser' 'Win32' $desc ) #demo( 'browser' 'Windows' $desc ) #demo( 'browser' 'Mac' $desc ) #demo( 'browser' 'Macosx' $desc ) #demo( 'browser' 'Mac68k' $desc ) #demo( 'browser' 'Macppc' $desc ) #demo( 'browser' 'Amiga' $desc ) #demo( 'browser' 'Emacs' $desc ) #demo( 'browser' 'Os2' $desc ) #demo( 'browser' 'Sun' $desc ) #demo( 'browser' 'Sun4' $desc ) #demo( 'browser' 'Sun5' $desc ) #demo( 'browser' 'Suni86' $desc ) #demo( 'browser' 'Irix' $desc ) #demo( 'browser' 'Irix5' $desc ) #demo( 'browser' 'Irix6' $desc ) #demo( 'browser' 'Hpux' $desc ) #demo( 'browser' 'Hpux9' $desc ) #demo( 'browser' 'Hpux10' $desc ) #demo( 'browser' 'Aix' $desc ) #demo( 'browser' 'Aix1' $desc ) #demo( 'browser' 'Aix2' $desc ) #demo( 'browser' 'Aix3' $desc ) #demo( 'browser' 'Aix4' $desc ) #demo( 'browser' 'Linux' $desc ) #demo( 'browser' 'Sco' $desc ) #demo( 'browser' 'Unixware' $desc ) #demo( 'browser' 'Mpras' $desc ) #demo( 'browser' 'Reliant' $desc ) #demo( 'browser' 'Dec' $desc ) #demo( 'browser' 'Sinix' $desc ) #demo( 'browser' 'Freebsd' $desc ) #demo( 'browser' 'Bsd' $desc ) #demo( 'browser' 'X11' $desc ) #demo( 'browser' 'Unix' $desc ) #demo( 'browser' 'VMS' $desc ) #set( $desc = 'Returns true if this feature is supported. Since support of those features is often partial, the sniffer returns true when a consequent subset is supported. ' ) #demo( 'browser' 'Css' $desc ) #demo( 'browser' 'Css1' $desc ) #demo( 'browser' 'Css2' $desc ) #demo( 'browser' 'Dom0' $desc ) #demo( 'browser' 'Dom1' $desc ) #demo( 'browser' 'Dom2' $desc ) #demo( 'browser' 'Javascript' $desc ) #demo1('browser' 'setLanguagesFilter' 6 'setter for a coma-separated list of weapp languages filter') #demo( 'browser' 'languagesFilter' 'coma-separated list of weapp languages filter') #set( $desc = 'Returns the preferred language tag from Accept-Header, filtered by values given to the LanguageFilter param' ) #demo( 'browser' 'preferredLanguage' $desc) #demoCustom( 'browser' )
    $demo.function
    $demo.result
    $demo.description
    ${esc.d}${toolname}.${method} $render.eval("${esc.d}${toolname}.${method}") $description
    ${esc.d}${toolname}.${method} $!result $description
    ${esc.d}${toolname}.$method(${quote}${quote}) #if( $params.get($method) ) ${esc.d}${toolname}.${method}(${quote}$params.get($method)${quote}) =
    $render.eval("${esc.d}${toolname}.${method}(${quote}$params.get($method)${quote})")
    #else #end #foreach( $param in $request.parameterMap.keySet() ) #foreach( $value in $params.getStrings($param) ) #if( $param != $method ) #end #end #end
    $description
    ${esc.d}${toolname}.$method(${quote}${quote}, ${quote}${quote}) #if( $params.get(${method1}) ) ${esc.d}${toolname}.${method}(${quote}$!params.get(${method1})${quote}, ${quote}$!params.get(${method2})${quote}) =
    $render.eval("${esc.d}${toolname}.${method}(${quote}$!params.get(${method1})${quote}, ${quote}$!params.get(${method2})${quote})")
    #else #end #foreach( $param in $request.parameterMap.keySet() ) #foreach( $value in $params.getStrings($param) ) #if( $param != $method1 && $param != $method2 ) #end #end #end
    $description
    ${esc.d}${toolname}.$method(${quote}${quote}, ${quote}${quote}, ${quote}${quote}) #if( $params.get(${method1}) ) ${esc.d}${toolname}.${method}(${quote}$!params.get(${method1})${quote}, ${quote}$!params.get(${method2})${quote}, ${quote}$!params.get(${method3})${quote}) =
    $render.eval("${esc.d}${toolname}.${method}(${quote}$!params.get(${method1})${quote}, ${quote}$!params.get(${method2})${quote}, ${quote}$!params.get(${method3})${quote})")
    #else #end #foreach( $param in $request.parameterMap.keySet() ) #foreach( $value in $params.getStrings($param) ) #if( $param != $method1 && $param != $method2 && $param != $method3 ) #end #end #end
    $description
    #if( $params.custom ) $params.custom = $render.eval($params.custom) #else #end #foreach( $param in $request.parameterMap.keySet() ) #foreach( $value in $params.getStrings($param) ) #if( $param != 'custom' ) #end #end #end $text.demo.tryAnything
    velocity-tools-2.0-src/examples/showcase/class.vm100644 0 0 2323 11030275256 17367 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. #title( 'ClassTool' )

    $text.demo.thisPage.insert("#doclink( 'ClassTool' true )").

    $text.get('class.intro')

    #set( $toolname = 'class' ) #set( $toolclass = $class.class ) #set( $toollink = $doclink ) #set( $toolDemo = "${esc.h}set( ${esc.d}classTool = ${esc.d}class.inspect(${esc.d}class) ) ${esc.h}foreach( ${esc.d}method in ${esc.d}classTool.methods ) ${esc.d}method.javadocRef ${esc.h}end" ) #parse( 'demo.vm' ) velocity-tools-2.0-src/examples/showcase/context.vm100644 0 0 2526 11030275256 17753 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. #title( 'ContextTool' )

    $text.demo.thisPage.insert("#doclink( 'ViewContextTool' false )").

    $text.get('context.intro')

    #set( $toolname = 'context' ) ## all the interesting methods are actually in the superclass ## since ViewContextTool only adds request/session/app attributes ## and not any additional methods #set( $toolclass = $context.class.superclass ) #set( $toollink = $doclink ) #set( $toolDemo = "${esc.h}foreach( ${esc.d}key in ${esc.d}context.keys ) ${esc.d}key = ${esc.d}context.get(${esc.d}key) ${esc.h}end" ) #parse( 'demo.vm' ) velocity-tools-2.0-src/examples/showcase/convert.vm100644 0 0 2537 11202122667 17747 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. #title( 'ConversionTool' )

    $text.demo.thisPage.insert("#doclink( 'ConversionTool' true )"). $text.convert.intro

    ## The demo.vm template expects the following values to be set #set( $toollink = $doclink ) #set( $toolname = 'convert' ) #set( $toolclass = $convert.class ) #set( $toolDemo = "" ) #set( $skip = [ 'parseDate_StringString', 'parseNumber_StringString', 'toBooleans_Collection', 'toNumbers_Collection', 'toCalendars_Collection', 'toDates_Collection', 'toLocales_Collection', 'toString_Collection' ] ) #parse( 'demo.vm' ) velocity-tools-2.0-src/examples/showcase/cookies.vm100644 0 0 2655 11202122670 17716 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. #title( 'CookieTool' )

    $text.demo.thisPage.insert("#doclink( 'CookieTool' false )"). $text.cookies.intro

    ## The demo.vm template expects the following values to be set #set( $toollink = $doclink ) #set( $toolname = 'cookies' ) #set( $toolclass = $cookies.class ) #set( $toolDemo = "${esc.h}foreach( ${esc.d}cookie in ${esc.d}cookies.all ) ${esc.d}cookie.name = ${esc.d}cookie.value Expiry ${esc.d}cookie.maxAge Domain ${esc.d}cookie.domain Comment ${esc.d}cookie.comment Version ${esc.d}cookie.version Secure ${esc.d}cookie.secure ${esc.h}end" ) #set( $skipAll = [ 'setRequest', 'setResponse', 'setLog' ] ) #parse( 'demo.vm' ) velocity-tools-2.0-src/examples/showcase/date.vm100644 0 0 14747 10730012262 17224 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. #title( 'DateTool' )

    #set( $demo = $text.demo ) $demo.thisPage.insert("#doclink( 'DateTool' true )") and its subclass, the #doclink( 'ComparisonDateTool' true ). As the DateTool is quite full-featured and provides many similar functions with varying and strongly-typed options, not all functions are demonstrated below. See the javadoc for a full listing of available functions.

    #demoTableStart() #set( $quote = '' ) #set( $desc = 'Converts the specified object to a date and formats it according to the pattern or style returned by $date.format.' ) #demo1( 'date' 'format' 4 $desc) #set( $desc = 'Converts the specified object to a date and formats it according to the specified date format.' ) #demo2( 'date' 'format' 4 $desc ) #set( $desc = 'Returns the value of $date.date as a string formatted according to the specified date format.' ) #demo1( 'date' 'get' 4 $desc ) #set( $desc = 'Returns a formatted string representing the date and/or time given by $date.date in the specified date and time styles.' ) #demo2( 'date' 'get' 4 $desc ) #set( $desc = 'Returns the day (of the month) value of the date returned by $date.calendar' ) #demo( 'date' 'day' $desc ) #set( $desc = 'Returns the day (of the month) value for the specified date.' ) #demo1( 'date' 'getDay' 4 $desc ) #set( $desc = 'Returns the month value of the date returned by $date.calendar.' ) #demo( 'date' 'month' $desc ) #set( $desc = 'Returns the month value of the specified date.' ) #demo1( 'date' 'getMonth' 4 $desc ) #set( $desc = 'Returns the year value of the date returned by $date.calendar.' ) #demo( 'date' 'year' $desc ) #set( $desc = 'Returns the year value of the specified date.' ) #demo1( 'date' 'getYear' 4 $desc ) #set( $desc = 'Return the specified value of the date returned by $date.calendar or null if the field is invalid.' ) #demo1( 'date' 'getValue' 4 $desc ) #set( $desc = 'Returns the specified value of the specified date, or null if the field or date is invalid.' ) #demo2( 'date' 'getValue' 4 $desc ) #set( $desc = 'Returns a Date derived from the result of $date.calendar' ) #demo( 'date' 'date' $desc ) #set( $desc = 'Return the pattern or style to be used for formatting dates when none is specified.' ) #demo( 'date' 'format' $desc ) #set( $desc = 'This returns the default Locale configured for this instance.' ) #demo( 'date' 'locale' $desc ) #set( $desc = 'This returns the id of the default TimeZone configured for this instance.' ) #demo( 'date' 'timeZone.ID' $desc ) #set( $desc = 'Gets the Date at the time this page was rendered for the system running this application.' ) #demo( 'date' 'systemDate' $desc ) #set( $desc = 'Converts an object to an instance of Calendar using the locale returned by $date.locale if necessary.' ) #demo1( 'date' 'toCalendar' 4 $desc ) #set( $desc = 'Converts an object to an instance of Date using the format returned by $date.format,the Locale returned by $date.locale, and the TimeZone returned by $date.timeZone if the object is not already an instance of Date, Calendar, or Long.' ) #demo1( 'date' 'toDate' 4 $desc ) #set( $desc = 'Converts an object to an instance of Date using the specified format,the Locale returned by $date.locale, and the TimeZone returned by $date.timeZone if the object is not already an instance of Date, Calendar, or Long.' ) #demo2( 'date' 'toDate' 4 $desc ) #demoCustom( 'date' )

    Here are a few demos of the functions provided by the #doclink( 'ComparisonDateTool' true ) class that are not in the standard DateTool.

    #demoTableStart() #set( $desc = "This returns a #doclink( 'ComparisonDateTool.Comparison' true ) between the result of ${esc.d}date.calendar and the specified date. The default rendering of that Comparison will be the largest unit difference between the dates followed by a description of their relative position." ) #demo1( 'date' 'whenIs' 6 $desc ) #set( $desc = "This returns a #doclink( 'ComparisonDateTool.Comparison' true ) between the second specified date and the first specified date. The default rendering of that Comparison will be the largest unit difference between the dates followed by a description of their relative position." ) #demo2( 'date' 'whenIs' 6 $desc ) #set( $desc = "This returns a #doclink( 'ComparisonDateTool.Comparison' true ) between the second specified date and the first specified date. The default rendering of that Comparison will be the largest unit difference between the dates." ) #demo2( 'date' 'difference' 6 $desc ) #demoCustom( "date.whenIs('2005-07-04').depth(3)" )

    $demo.mainExampleHeader


    #if( $params.layout ) #end
    #if( $params.demo ) $demo.mainResultsIntro:
      $render.eval($params.demo)
    
    #end
    velocity-tools-2.0-src/examples/showcase/demo.vm100644 0 0 17306 11202122670 17225 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. #* * This template exists to automatically generate demos for a tool. * It expects the following values to be set before it is parsed: * $toolname -> should be the context key of the tool * $toolclass -> should be the actual Class of the tool * $toollink -> a URL for the javadoc of the tool Class on velocity.apache.org * This is usually set by copying the $doclink reference that is set * whenever the #doclink() macro is used. * Optionally, you can also set: * $toolDemo -> to specify the default text for the full demo at the bottom * * If you're wondering why this is a template, instead of a macro; * it is because it takes less memory in the cache this way. *# #set( $demo = $text.demo ) #set( $tool = $class.inspect($toolclass) ) ## be sure not to lose the current layout when clearing other params #if( $params.layout ) #end ## generate a demo for each method (except the configure(Map) method) #foreach( $method in $loop.watch($tool.methods).exclude('method configure(java.util.Map)') ) #if( (!$skip or !$skip.contains($method.uniqueName)) and (!$skipAll or !$skipAll.contains($method.name)) ) ## create a fake call of the method to use as the name/signature #set( $call = "${esc.d}${toolname}.#if( !$method.takesParameters() && $method.propertyName )$method.propertyName#else$method.signature#end" ) #if( !$method.takesParameters() ) ## simply call the method #set( $result = $call ) #set( $result = $render.eval($call) ) #else ## create a form to allow the user to input values and call the method ## HttpUnit doesn't like anchor-only links #end ## look for a description of the specific method #set( $desc = $text.get("${toolname}.${method.uniqueName}") ) #if( !$desc.exists ) ## look for a description of all methods with that name #set( $desc = $text.get("${toolname}.${method.name}") ) #if( !$desc.exists ) #if( $method.propertyName ) ## look for a tool-specific generic property description #set( $desc = $text.get("${toolname}.propertyDescription").insert($method.propertyName) ) #else ## look for a generic method description for the tool #set( $desc = $text.get("${toolname}.methodDescription") ) #end #if( !$desc.exists ) #if( $method.uniqueName eq 'toString' ) ## use the generic toString description #set( $desc = $demo.toString ) #else ## use the generic description missing message #set( $desc = $demo.descriptionMissing.insert("${toolname}.${method.uniqueName}") ) #end #end #end #end #end #end ## create a space for an extended, custom, one line demo
    $demo.function
    $demo.result
    $demo.description
    $call#if( $result == $call )$text.demo.nullResult#else$esc.xml($result)#end
    ## create a text field for each parameter ## whose size is inversely proportional to the number of fields #set( $fieldsize = $math.sub($math.idiv(24, $method.parameterCount), $method.parameterCount) ) #foreach( $param in $method.parameters ) #set( $fieldname = "$method.uniqueName$velocityCount" ) ## look for a default value #set( $fielddefault = $text.get("${toolname}.${method.uniqueName}.param$velocityCount") ) #if( !$fielddefault.exists ) ## look for a default for this type for this method #set( $fielddefault = $text.get("${toolname}.${method.name}.$param.simpleName") ) #if( !$fielddefault.exists ) ## look for a default for this type for this tool #set( $fielddefault = $text.get("${toolname}.$param.simpleName") ) #if( !$fielddefault.exists ) ## generate a reasonable default for the param type #set( $fielddefault = "#demoDefault( $param )" ) #end #end #end ## look for a value in the params, use the default if none is found #set( $fieldvalue = $display.alt($params.get($fieldname), $fielddefault) ) #if( $velocityCount > 1 ),#end #end ## if we have at least one param value #if( $params.get("${method.uniqueName}1") ) ## do the actual call using the provided param values #set( $call = "${esc.d}${toolname}.${method.name}(#foreach( $param in $method.parameters )#if( $velocityCount > 1 ), #end$!params.get($render.eval('$method.uniqueName$velocityCount'))#end)" ) #set( $result = $call ) #set( $result = $render.eval($call) )
    $call =
    #if( $result == $call )$demo.nullResult#else$esc.xml($result)#end
    #end ## maintain all params for other method demos #foreach( $param in $params.all.keySet() ) #if( !$param.startsWith($method.uniqueName) && $param != 'fullDemo' ) #foreach( $value in $params.getStrings($param) ) #end #end #end
    $desc
    ## first check the params for a custom demo #set( $custom = $params.getValue('custom', false) ) ## then look for a default in the resources #set( $default = $text.get("${toolname}.custom") ) #if( !$default.exists ) ## ok, just have a dumb little custom demo #set( $default = "$esc.d$toolname" ) #end #if( $params.custom ) #set( $result = $call ) #set( $result = $render.eval($params.custom) )
    $params.custom =
    #if( $result == $call )$demo.nullResult#else$esc.xml($result)#end
    #end ## maintain params for all the other demos #foreach( $param in $params.all.keySet() ) #if( $param != 'custom' && $param != 'fullDemo' ) #foreach( $value in $params.getStrings($param) ) #end #end #end
    $text.demo.tryAnything
    #parse( 'fullDemo.vm' ) velocity-tools-2.0-src/examples/showcase/display.vm100644 0 0 2776 11030275256 17743 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. #title( 'DisplayTool' )

    $text.demo.thisPage.insert("#doclink( 'DisplayTool' true )"). $text.get('display.intro')

    #set( $toolname = 'display' ) #set( $toolclass = $display.class ) #set( $toollink = $doclink ) #set( $toolDemo = "${esc.h}set( ${esc.d}primes = [1, 2, 3, 5, 7, 11] ) ${esc.d}display.list(${esc.d}primes) ${esc.d}display.truncate('This sentence should be truncated at 30 characters.') ${esc.d}display.truncate('This will be cut at 15.', 15) ${esc.d}display.alt(${esc.d}primes) ${esc.d}display.alt(${esc.d}null, '--') ${esc.h}set( ${esc.d}demoSize = ${esc.d}display.measure(${esc.d}toolDemo) ) This demo is ${esc.d}demoSize.height lines with a max length of ${esc.d}demoSize.width chars." ) #parse( 'demo.vm' ) velocity-tools-2.0-src/examples/showcase/esc.vm100644 0 0 10560 10730012262 17046 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. #title( 'EscapeTool' )

    #set( $demo = $text.demo ) $demo.thisPage.insert("#doclink( 'EscapeTool' true )").

    #demoTableStart() #set( $desc = 'Renders a backslash (\)' ) #demo( 'esc' 'b' $desc ) #set( $desc = 'Renders a backslash (\)' ) #demo( 'esc' 'backslash' $desc ) #set( $desc = 'Renders a dollar sign ($)' ) #demo( 'esc' 'd' $desc ) #set( $desc = 'Renders a dollar sign ($)' ) #demo( 'esc' 'dollar' $desc ) #set( $desc = 'Renders an exclamation mark (!)' ) #demo( 'esc' 'e' $desc ) #set( $desc = 'Renders an exclamation mark (!)' ) #demo( 'esc' 'exclamation' $desc ) #set( $desc = 'Renders a hash (#)' ) #demo( 'esc' 'h' $desc ) #set( $desc = 'Renders a hash (#)' ) #demo( 'esc' 'hash' $desc ) #set( $desc = 'Renders a double quotation mark (")' ) #demo( 'esc' 'q' $desc ) #set( $desc = 'Renders a double quotation mark (")' ) #demo( 'esc' 'quote' $desc ) #set( $desc = "Renders a single quotation mark (')" ) #demo( 'esc' 's' $desc ) #set( $desc = "Renders a single quotation mark (')" ) #demo( 'esc' 'singleQuote' $desc ) #set( $desc = 'Escapes the characters in a String using HTML entities.' ) #demo1( 'esc' 'html' 8 $desc ) #set( $desc = 'Escapes the characters in a String using UTF-8 URL character encoding.' ) #demo1( 'esc' 'url' 8 $desc ) #set( $desc = 'Escapes the characters in a String using Java String rules.' ) #demo1( 'esc' 'java' 8 $desc ) #set( $desc = 'Escapes the characters in a String using JavaScript String rules.' ) #demo1( 'esc' 'javascript' 8 $desc ) #set( $desc = 'Escapes the characters in a String to be suitable to pass to an SQL query.' ) #demo1( 'esc' 'sql' 8 $desc ) #set( $desc = 'Escapes the characters in a String using XML entities.' ) #demo1( 'esc' 'xml' 8 $desc ) #set( $desc = 'Escapes the characters in a String using java.util.Properties rules for escaping keys.' ) #demo1( 'esc' 'propertyKey' 8 $desc ) #set( $desc = 'Escapes the characters in a String using java.util.Properties rules for escaping values.' ) #demo1( 'esc' 'propertyValue' 8 $desc ) #demoCustom( 'esc' ) #set( $java = "He didn't say, ${esc.q}Stop!${esc.q}" ) #set( $javascript = $java ) #set( $html = ' & ' ) #set( $url = 'food/dinner?appetizer=bread & butter' ) #set( $xml = $html ) #set( $sql = "McHale's Navy" ) #set( $propKey = ' C:\Program Files' ) #set( $propValue = ' C:\Program Files' )

    $demo.mainExampleHeader


    #if( $params.layout ) #end
    #if( $params.demo ) $demo.mainResultsIntro:
      $render.eval($params.demo)
    
    #end
    velocity-tools-2.0-src/examples/showcase/field.vm100644 0 0 2410 10730012262 17332 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. #title( 'FieldTool' )

    $text.demo.thisPage.insert("#doclink( 'FieldTool' true )").

    $text.field.intro

    ## The demo.vm template expects the following values to be set #set( $toolname = 'field' ) #set( $toolclass = $field.class ) #set( $toollink = $doclink ) #set( $toolDemo = "${esc.d}field.in(0).MIN_VALUE ${esc.h}${esc.h} once a class's fields have been searched, they remain available ${esc.d}field.MAX_VALUE" ) #parse( 'demo.vm' ) velocity-tools-2.0-src/examples/showcase/footer.vm100644 0 0 1503 10730012262 17547 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. velocity-tools-2.0-src/examples/showcase/fullDemo.vm100644 0 0 4335 11115263034 20031 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. ## make sure we have access to demo resources #if( !$demo ) #set( $demo = $text.demo ) #end ## look for a full demo in the params #set( $fullDemo = $params.fullDemo ) #if( !$fullDemo ) ## see if one was set in the parent template #if( $toolDemo ) #set( $fullDemo = $toolDemo ) #else ## ok, try looking for one in the resources #set( $fullDemo = $text.get("${toolname}.fullDemo") ) #if( !$fullDemo.exists ) ## give up and hide the full demo #set( $fullDemo = false ) #end #end #end #if( $fullDemo ) #set( $dims = $display.measure($fullDemo) )

    $demo.mainExampleHeader


    ## maintain params for all the other demos #foreach( $param in $params.all.keySet() ) #if( $param != 'fullDemo' ) #foreach( $value in $params.getStrings($param) ) #end #end #end
    ## evaluate and display results if they hit submit #if( $params.fullDemo ) $demo.mainResultsIntro:
            $render.eval($params.fullDemo)
          
    #end
    #end velocity-tools-2.0-src/examples/showcase/header.vm100644 0 0 2073 10730012262 17504 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. VelocityTools - $text.appname#if( $page_title ) - $page_title#end #if( $stylesheet ) #end velocity-tools-2.0-src/examples/showcase/import.vm100644 0 0 2763 10730012262 17574 0ustar 0 0 ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. #title( 'ImportTool' )

    #set( $demo = $text.demo ) $demo.thisPage.insert("#doclink( 'ImportTool' false )").

    #demoCustom( 'import' )
    $demo.function $demo.result $demo.description
    ${esc.d}import.read('') #if( $params.read ) $esc.html($import.read($params.read)) #else
    Please note that the results will be html-escaped by the EscapeTool for the purposes of this demo. #end
    Returns the content read from the specified URL
    velocity-tools-2.0-src/examples/showcase/include.vm100644 0 0 2300 11202122670 17670 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. #title( 'IncludeTool' )

    $text.demo.thisPage.insert("#doclink( 'IncludeTool' false )"). $text.get('include.intro')

    #set( $toolname = 'include' ) #set( $toolclass = $include.class ) #set( $toollink = $doclink ) #set( $toolDemo = "${esc.d}include.exists('include.vm') ${esc.d}include.exists('foo.vm') ${esc.h}${esc.h}this demo is currently poor because we don't have i18n templates!" ) #parse( 'demo.vm' ) velocity-tools-2.0-src/examples/showcase/index.vm100644 0 0 1764 10730012262 17371 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. #set( $index = $text.index )

    $index.greeting!

    $index.explanation*

    $index.start

    *$index.asterisk
    velocity-tools-2.0-src/examples/showcase/layout/Default.vm100644 0 0 2625 10730012262 21160 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. #set( $stylesheet = '/layout/layout.css' ) #set( $css = $text.css ) #parse( 'header.vm' )

    $text.appname: $css.name

    $screen_content

    #parse( 'footer.vm' ) velocity-tools-2.0-src/examples/showcase/layout/Print.vm100644 0 0 1651 10730012262 20666 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. #parse( 'header.vm' )

    $text.appname: $text.print.name

    $screen_content

    #parse( 'footer.vm' ) velocity-tools-2.0-src/examples/showcase/layout/Simple.vm100644 0 0 2037 10730012262 21022 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. #parse( 'header.vm' )
    $text.appname: $text.simple.name
    $screen_content
    #parse( 'footer.vm' ) velocity-tools-2.0-src/examples/showcase/layout/Table.vm100644 0 0 2472 10730012262 20623 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. #parse( 'header.vm' )
    $text.appname: $text.table.name
    #parse( 'toolmenu.vm' ) $screen_content #parse( 'layoutmenu.vm' )
    #parse( 'footer.vm' ) velocity-tools-2.0-src/examples/showcase/layout/layout.css100644 0 0 11152 11202122667 21300 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ body { color:#333; background-color:white; margin:10px; padding:0px; font:11px verdana, arial, helvetica, sans-serif; } h1 { margin:0px 0px 15px 0px; padding:0px; font-size:28px; font-weight:900; color:#ccc; } h2 { font:bold 12px/14px verdana, arial, helvetica, sans-serif; margin:0px 0px 5px 0px; padding:0px; } p { font:11px/20px verdana, arial, helvetica, sans-serif; margin:0px 0px 10px 0px; padding:0px; } .Content>p {margin:0px;} .Content>p+p {text-indent:30px;} a { color:#09c; font-size:11px; font-family:verdana, arial, helvetica, sans-serif; font-weight:600; text-decoration:none; } a:link {color:#09c;} a:visited {color:#07a;} a:hover {background-color:#eee;} td.method a { font-weight: 400; } td.demo, td.demo input { font-size: 10px; } td.desc { font-size: 10px; } /* All the content boxes belong to the content class. */ .content { position:relative; /* Position is declared "relative" to gain control of stacking order (z-index). */ width:auto; min-width:120px; margin:0px 157px 10px 157px; border:1px solid black; background-color:white; padding:5px; z-index:3; /* This allows the content to overlap the right menu in narrow windows in good browsers. */ } .content #footnote { margin: 40px 0px 0px 0px; padding: 5px; border:1px dotted gray; font: 9px verdana, arial, helvetica, sans-serif; } #navAlpha { position:absolute; width:150px; top:10px; left:10px; border:1px dashed black; background-color:#eee; padding:5px; z-index:2; /* Here is the ugly brilliant hack that protects IE5/Win from its own stupidity. Thanks to Tantek Celik for the hack and to Eric Costello for publicizing it. IE5/Win incorrectly parses the "\"}"" value, prematurely closing the style declaration. The incorrect IE5/Win value is above, while the correct value is below. See http://glish.com/css/hacks.asp for details. */ voice-family: "\"}\""; voice-family:inherit; width:135px; } /* I've heard this called the "be nice to Opera 5" rule. Basically, it feeds correct length values to user agents that exhibit the parsing error exploited above yet get the CSS box model right and understand the CSS2 parent-child selector. ALWAYS include a "be nice to Opera 5" rule every time you use the Tantek Celik hack (above). */ body>#navAlpha {width:135px;} #navBeta { position:absolute; width:190px; top:10px; right:10px; border:1px dashed black; background-color:#eee; padding:5px; z-index:1; /* Again, the ugly brilliant hack. */ voice-family: "\"}\""; voice-family:inherit; width:135px; } /* Again, "be nice to Opera 5". */ body>#navBeta {width:135px;} /* Rollover Menu CSS from http://www.alistapart.com/stories/taminglists/ */ .menu { width: 12.3em; border-right: 0px solid #000; padding: 0 0 0 0; margin-bottom: 1em; font-family: 'Trebuchet MS', 'Lucida Grande', Verdana, Lucida, Geneva, Helvetica, Arial, sans-serif; background-color: #90bade; color: #333; } .menu ul { list-style: none; margin: 0; padding: 0; border: none; } .menu li { border-bottom: 1px solid #90bade; margin: 0; } .menu li a { display: block; padding: 4px 4px 4px 0.2em; border-left: 4px solid #1958b7; border-right: 4px solid #508fc4; background-color: #2175bc; color: #fff; text-decoration: none; width: 100%; } html>body .menu li a { width: auto; } .menu li a:hover { border-left: 4px solid #1c64d1; border-right: 4px solid #5ba3e0; background-color: #2586d7; color: #fff; } velocity-tools-2.0-src/examples/showcase/layoutmenu.vm100644 0 0 2210 10730012262 20447 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. #set( $slink = $link.self ) #set( $layouts = $text.layouts )

    $layouts.header:

    velocity-tools-2.0-src/examples/showcase/link.vm100644 0 0 10562 11360645211 17241 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. #title( 'LinkTool' )

    #set( $demo = $text.demo ) $demo.thisPage.insert("#doclink( 'LinkTool' false )"). This tool is somewhat unusual in that every method that takes parameters will return a new instance of the tool that is a copy of the one the method was called upon, with the additional change specified by the method call.

    #demoTableStart() #set( $desc = "Returns a new ${esc.d}link with the addition of the specified anchor value." ) #demo1( 'link' 'anchor' 6 $desc ) #set( $desc = "Returns the anchor set for the ${esc.d}link" ) #if( $params.anchor ) #set( $result = $link.anchor($params.anchor) ) #else #set( $result = $!link.anchor ) #end #demoAlt( 'link' 'anchor' $result $desc ) #set( $desc = "Returns a new ${esc.d}link with the addition of the specified path value." ) #demo1( 'link' 'path' 6 $desc ) #set( $desc = "Returns a new ${esc.d}link with the addition of the specified relative value." ) #demo1( 'link' 'relative' 6 $desc ) #set( $desc = "Returns a new ${esc.d}link with the addition of the specified absolute value." ) #demo1( 'link' 'absolute' 6 $desc ) #set( $desc = "Returns the path currently set for this ${esc.d}link." ) #demoAlt( 'link' 'path' $link.path $desc ) #set( $desc = "Returns a new ${esc.d}link with the addition of the specified parameter." ) #demo2( 'link' 'param' 6 $desc ) #set( $desc = "Returns the query data set for this ${esc.d}link" ) #if( $params.param ) #set( $result = $link.param($params.param).params ) #else #set( $result = $link.params ) #end #demoAlt( 'link' 'params' $result $desc ) #set( $desc = "Returns the URI that addresses this web application. E.g. http://myserver.net/myapp. This string may not end with a ${esc.q}/${esc.q}." ) #demo( 'link' 'contextURL' $desc ) #set( $desc = "Returns the context path that addresses this web application, e.g. /myapp. This string starts with a ${esc.q}/${esc.q} but does not end with a ${esc.q}/${esc.q}." ) #demo( 'link' 'contextPath' $desc ) #set( $desc = "Retrieves the path for the current request regardless of whether this is a direct request or an include by the RequestDispatcher." ) #demo( 'link' 'requestPath' $desc ) #set( $desc = "Returns the full URI of this template without any query data. e.g. http://myserver.net/myapp/stuff/View.vm" ) #demo( 'link' 'baseRef' $desc ) #set( $desc = "This method returns a new self-referencing ${esc.d}link for the current request (e.g. /myapp/stuff/View.vm). However, the behavior can be changed via toolbox configuration to use absolute URIs and/or add the current request parameters." ) #demo( 'link' 'self' $desc ) #set( $desc = "Performs URL encoding on the specified text." ) #demo1( 'link' 'encode' 6 $desc ) #demoCustom( 'link' ) #set( $base = $link.self.anchor('fullDemo') )

    $demo.mainExampleHeader


    #if( $params.layout ) #end
    #if( $params.fullDemo ) $demo.mainResultsIntro:
      $render.eval($params.fullDemo)
    
    #end
    velocity-tools-2.0-src/examples/showcase/lists.vm100644 0 0 5111 11030275256 17416 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. #title( 'ListTool' )

    #set( $demo = $text.demo ) $demo.thisPage.insert("#doclink( 'ListTool' true )"). Once Velocity 1.6 is released, this tool will be obsolete since Velocity 1.6 now allows all List methods to be called directly on arrays within templates.

    #demoTableStart() ## set quote character to empty string so values are not treated as strings #set( $quote = '' ) #set( $desc = 'Checks if a List/array contains a certain element.' ) #demo2( 'lists' 'contains' 5 $desc ) #set( $desc = 'Gets the specified element of a List/array.' ) #demo2( 'lists' 'get' 5 $desc ) #set( $desc = 'Checks if an object is an array.' ) #demo1( 'lists' 'isArray' 3 $desc) #set( $desc = 'Checks if a List/array is empty.' ) #demo1( 'lists' 'isEmpty' 3 $desc) #set( $desc = 'Checks if an object is a List.' ) #demo1( 'lists' 'isList' 3 $desc) #set( $desc = 'Sets the specified element of a List/array.' ) #demo3( 'lists' 'set' 5 $desc ) #set( $desc = 'Gets the size of a List/array.' ) #demo1( 'lists' 'size' 3 $desc) #demoCustom( 'lists' ) #set( $primes = [1, 2, 3, 5, 7, 11] )

    $demo.mainExampleHeader


    #if( $params.layout ) #end
    #if( $params.demo ) $demo.mainResultsIntro:
      $render.eval($params.demo)
    
    #end
    velocity-tools-2.0-src/examples/showcase/loop.vm100644 0 0 2454 11030275256 17240 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. #title( 'LoopTool' )

    $text.demo.thisPage.insert("#doclink( 'LoopTool' true )").

    $text.loop.intro

    #set( $fullDemo = '#set( $numbers = [1..5] ) #set( $letters = ["A","B","C"] ) #set( $symbols = ["!", "@"] ) #foreach( $l in $loop.watch($letters, "l").sync($symbols, "s") ) #foreach( $n in $loop.watch($numbers).exclude(3) ) #if( $loop.first )$l$loop.s[#end## $n## #if( $loop.last )] #else, #end## #if( $l == "B" )$loop.stop("l")#end## stop the letter loop after B #end #end' ) #parse( 'fullDemo.vm' ) velocity-tools-2.0-src/examples/showcase/math.vm100644 0 0 7737 11360645211 17227 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. #title( 'MathTool' )

    #set( $demo = $text.demo ) $demo.thisPage.insert("#doclink( 'MathTool' true )").

    #demoTableStart() #set( $desc = 'Returns the sum of the numbers or null if they are invalid.' ) #demo2( 'math' 'add' 3 $desc) #set( $desc = 'Returns the difference of the numbers or null if they are invalid.' ) #demo2( 'math' 'sub' 3 $desc) #set( $desc = 'Returns the product of the numbers or null if they are invalid.' ) #demo2( 'math' 'mul' 3 $desc) #set( $desc = 'Returns the quotient of the numbers or null if they are invalid.' ) #demo2( 'math' 'div' 3 $desc) #set( $desc = 'Returns the first number raised to the power of the second or null if they are invalid.' ) #demo2( 'math' 'pow' 3 $desc) #set( $desc = 'Returns the result of performing integer division on the operands or null if they are invalid.' ) #demo2( 'math' 'idiv' 3 $desc) #set( $desc = 'Returns the result of performing integer modulus on the operands or null if they are invalid.' ) #demo2( 'math' 'mod' 3 $desc) #set( $desc = 'Returns the largest of the numbers or null if they are invalid.' ) #demo2( 'math' 'max' 3 $desc) #set( $desc = 'Returns the smallest of the numbers or null if they are invalid.' ) #demo2( 'math' 'min' 3 $desc) #set( $desc = 'Returns the absolute value of the number or null if it is invalid.' ) #demo1( 'math' 'abs' 3 $desc) #set( $desc = 'Returns the smallest integer that is not less than the given number or null if it is invalid.' ) #demo1( 'math' 'ceil' 3 $desc) #set( $desc = 'Returns the integer portion of the given number or null if it is invalid.' ) #demo1( 'math' 'floor' 3 $desc) #set( $desc = 'Returns the given number rounded to the nearest whole Integer or null if it is invalid.' ) #demo1( 'math' 'round' 3 $desc) #set( $desc = "Rounds a number to the specified number of decimal places. This is particulary useful for simple display formatting. If you want to round an number to the nearest integer, it is better to use ${esc.d}math.round(), as that will return an Integer rather than a Double." ) #demo2( 'math' 'roundTo' 2 $desc ) #set( $desc = 'Returns a pseudo-random Double greater than or equal to 0.0 and less than 1.0' ) #demo( 'math' 'random' $desc ) #set( $desc = 'This returns a random Number within the specified range. The returned value will be greater than or equal to the first number and less than the second number. If both arguments are whole numbers then the returned number will also be, otherwise a Double will be returned.' ) #demo2( 'math' 'random' 3 $desc ) #set( $desc = 'Converts an object with a numeric value into an Integer. Valid formats are Number or a string representation of a number.' ) #demo1( 'math' 'toInteger' 3 $desc ) #set( $desc = 'Converts an object with a numeric value into a Double. Valid formats are Number or a string representation of a number.' ) #demo1( 'math' 'toDouble' 3 $desc ) #set( $desc = 'Converts an object with a numeric value into a Number. Valid formats are Number or a string representation of a number.' ) #demo1( 'math' 'toNumber' 3 $desc ) #demoCustom( 'math' ) velocity-tools-2.0-src/examples/showcase/mill.vm100644 0 0 3426 10730012262 17214 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. #title( 'IteratorTool' )

    #set( $demo = $text.demo ) $demo.thisPage.insert("#doclink( 'IteratorTool' true )"). This tool is a convenience tool to use with ${esc.h}foreach loops. It wraps a list to let the designer specify a condition to terminate the loop, and reuse the same list in different loops.

    #if( $params.layout ) #end
    #if( $params.demo ) $demo.mainResultsIntro:
      $render.eval($params.demo)
    
    #end velocity-tools-2.0-src/examples/showcase/number.vm100644 0 0 6176 10730012262 17554 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. #title( 'NumberTool' )

    #set( $demo = $text.demo ) $demo.thisPage.insert("#doclink( 'NumberTool' true )").

    #demoTableStart() #set( $desc = 'Convenience method equivalent to $number.format("currency", $foo).' ) #demo1( 'number' 'currency' 4 $desc ) #set( $desc = 'Converts the specified object to a number and formats it according to the pattern or style returned by $number.format.' ) #demo1( 'number' 'format' 4 $desc ) #set( $desc = 'Converts the specified object to a number and returns a formatted string representing that number in the locale returned by $number.locale.' ) #demo2( 'number' 'format' 4 $desc ) #set( $quote = '' ) #set( $desc = 'Converts the specified object to a number and returns a formatted string representing that number in the specified Locale.' ) #demo3( 'number' 'format' 4 $desc ) #set( $quote = '"' ) #set( $desc = 'Return the pattern or style to be used for formatting numbers when none is specified.' ) #demo( 'number' 'format' $desc ) #set( $desc = 'This implementation returns the default locale.' ) #demo( 'number' 'locale' $desc ) #set( $quote = '' ) #set( $desc = 'Returns a NumberFormat instance for the specified format and Locale.' ) #demo2( 'number' 'getNumberFormat' 4 $desc ) #set( $quote = '"' ) #set( $desc = 'Convenience method equivalent to $number.format("integer", $foo).' ) #demo1( 'number' 'integer' 4 $desc ) #set( $desc = 'Convenience method equivalent to $number.format("number", $foo).' ) #demo1( 'number' 'number' 4 $desc ) #set( $desc = 'Convenience method equivalent to $number.format("percent", $foo).' ) #demo1( 'number' 'percent' 4 $desc ) #set( $desc = 'Converts an object to an instance of Number using the format returned by $number.format and the Locale returned by $number.locale if the object is not already an instance of Number.' ) #demo1( 'number' 'toNumber' 4 $desc ) #set( $desc = 'Converts an object to an instance of Number using the specified format and the Locale returned by $number.locale if the object is not already an instance of Number.' ) #demo2( 'number' 'toNumber' 4 $desc ) #set( $quote = '' ) #set( $desc = 'Converts an object to an instance of Number using the specified format and Localeif the object is not already an instance of Number.' ) #demo3( 'number' 'toNumber' 4 $desc ) #demoCustom( 'number' ) velocity-tools-2.0-src/examples/showcase/pager.vm100644 0 0 12406 10730012262 17373 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. #title( 'PagerTool' )

    #set( $demo = $text.demo ) $demo.thisPage.insert("#doclink( 'PagerTool' false )"). In this case, we provide a control to set the item list from a template. Typically, your "action" class would place the list in the request attributes under the "new.items" key.

    If you set a list of items using the "Try it!" form at the top of the table below, then that will activate a full demonstration of this tool's abilities below the function list. An easy list to begin is a list of numbers by entering something like [111..2222] in the "${esc.d}pager.setItems" field.

    #demoTableStart() ## set quote character to empty string so values are not treated as strings #set( $quote = '' ) #set( $desc = 'Sets the List to page through.' ) #demo1( 'pager' 'setItems' 10 $desc ) #set( $desc = 'Sets the index of the first result in the current page' ) #demo1( 'pager' 'setIndex' 4 $desc ) #set( $desc = 'Sets the number of items returned in a page of items' ) #demo1( 'pager' 'setItemsPerPage' 4 $desc ) #set( $desc = 'Sets the number of result page indices for $pager.slip to list.' ) #demo1( 'pager' 'setSlipSize' 4 $desc ) #set( $desc = 'Checks whether or not the result list is empty.' ) #demo( 'pager' 'hasItems()' $desc ) #set( $desc = 'Returns the current search result index.' ) #demo( 'pager' 'index' $desc ) #set( $desc = 'Returns the index of the first item on the current page of results (as determined by the current index, items per page, and the number of items).' ) #demo( 'pager' 'firstIndex' $desc ) #set( $desc = 'Returns the index of the last item on the current page of results (as determined by the current index, items per page, and the number of items).' ) #demo( 'pager' 'lastIndex' $desc ) #set( $desc = 'Return the index for the previous page of items (as determined by the current index, items per page, and the number of items).' ) #demo( 'pager' 'prevIndex' $desc ) #set( $desc = 'Returns the index for the next page of items (as determined by the current index, items per page, and the number of items).' ) #demo( 'pager' 'nextIndex' $desc ) #set( $desc = 'Returns the item list.' ) #demo( 'pager' 'items' $desc ) #set( $desc = 'Returns the current "page" of search items.' ) #demo( 'pager' 'page' $desc ) #set( $desc = 'Returns a description of the current page.' ) #demo( 'pager' 'pageDescription' $desc ) #set( $desc = 'Returns the "page number" for the current index.' ) #demo( 'pager' 'pageNumber' $desc ) #set( $desc = 'Returns the "page number" for the specified index.' ) #demo1( 'pager' 'getPageNumber' 4 $desc ) #set( $desc = 'Returns the set number of items to be displayed per page of items' ) #demo( 'pager' 'itemsPerPage' $desc ) #set( $desc = 'Returns the number of pages that can be made from this list given the set number of items per page.' ) #demo( 'pager' 'pagesAvailable' $desc ) #set( $desc = 'Returns the total number of items available.' ) #demo( 'pager' 'total' $desc ) #set( $desc = 'Returns a Sliding List of Indices for Pages of items.' ) #demo( 'pager' 'slip' $desc ) #set( $desc = 'Returns the number of result page indices $pager.slip will return per request (if available).' ) #demo( 'pager' 'slipSize' $desc ) #demoCustom( 'pager' )

    $demo.mainExampleHeader

    #if( $pager.hasItems() )
    Showing $!pager.pageDescription
    #set( $i = $pager.index + 1 ) #foreach( $item in $pager.page ) ${i}. $!item
    #set( $i = $i + 1 ) #end
    #if ( $pager.pagesAvailable > 1 ) #set( $pagelink = $link.self.anchor('fullDemo').param("layout",$!params.layout).param("show",$!pager.itemsPerPage) ) #if( $pager.prevIndex ) Prev #end #foreach( $index in $pager.slip ) #if( $index == $pager.index ) $pager.pageNumber #else $!pager.getPageNumber($index) #end #end #if( $pager.nextIndex ) Next #end #end
    #else

    There are no items to display. To activate this example, follow the directions at the top of this page.

    #end
    velocity-tools-2.0-src/examples/showcase/params.vm100644 0 0 12475 10730012262 17566 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. #title( 'ParameterTool' )

    #set( $demo = $text.demo ) $demo.thisPage.insert("#doclink( 'ParameterTool' false )").

    #demoTableStart() #set( $quote = '"' ) #set( $desc = 'Convenience method for checking whether a certain parameter exists.' ) #demo1( 'params' 'exists' 6 $desc ) #set( $desc = 'Convenience method for use in Velocity templates. This is the same as $params.getString("foo"), but simplifies the syntax to $params.foo' ) #demo1( 'params' 'get' 6 $desc ) #set( $desc = 'Returns the parameter with the specified key, if it exists; otherwise, returns null.' ) #demo1( 'params' 'getString' 6 $desc ) #set( $desc = 'Returns the parameter with the specified key as a java.lang.Boolean, if it exists and can be converted to that type; otherwise, returns null.' ) #demo1( 'params' 'getBoolean' 6 $desc ) #set( $desc = 'Returns the parameter with the specified key as a java.lang.Number, if it exists and can be converted to that type; otherwise, returns null.' ) #demo1( 'params' 'getNumber' 6 $desc ) #set( $desc = 'Returns the parameter with the specified key as a java.lang.Double, if it exists and can be converted to that type; otherwise, returns null.' ) #demo1( 'params' 'getDouble' 6 $desc ) #set( $desc = 'Returns the parameter with the specified key as a java.lang.Integer, if it exists and can be converted to that type; otherwise, returns null.' ) #demo1( 'params' 'getInteger' 6 $desc ) #set( $desc = 'Returns the parameter with the specified key as a java.util.Locale, if it exists and can be converted to that type; otherwise, returns null.' ) #demo1( 'params' 'getLocale' 6 $desc ) #set( $desc = 'Returns the parameter(s) with the specified key in an array of the type requested, if any exist; otherwise, returns null..' ) #demo1( 'params' 'getStrings' 6 $desc ) #set( $desc = 'Returns the parameter(s) with the specified key in an array of java.lang.Boolean objects, if any exist and can be converted to that type; otherwise, returns null..' ) #demo1( 'params' 'getBooleans' 6 $desc ) #set( $desc = 'Returns the parameter(s) with the specified key in an array of java.lang.Number objects, if any exist and can be converted to that type; otherwise, returns null..' ) #demo1( 'params' 'getNumbers' 6 $desc ) #set( $desc = 'Returns the parameter(s) with the specified key in an array of java.lang.Double objects, if any exist and can be converted to that type; otherwise, returns null..' ) #demo1( 'params' 'getDoubles' 6 $desc ) #set( $desc = 'Returns the parameter(s) with the specified key in an array of int primitives, if any exist and can be converted to that type; otherwise, returns null..' ) #demo1( 'params' 'getInts' 6 $desc ) #set( $desc = 'Returns the parameter(s) with the specified key in an array of java.util.Locale, if any exists and can be converted to that type; otherwise, returns null.' ) #demo1( 'params' 'getLocales' 6 $desc ) #set( $quote = '' ) #set( $desc = 'Returns the parameter with the specified key, if it exists; otherwise, returns the specified alternate value.' ) #demo2( 'params' 'getString' 6 $desc ) #set( $desc = 'Returns the parameter with the specified key as a java.lang., if it exists; otherwise, returns the specified alternate Boolean.' ) #demo2( 'params' 'getBoolean' 6 $desc ) #set( $desc = 'Returns the parameter with the specified key as a java.lang.Number, if it exists; otherwise, returns the specified alternate Number.' ) #demo2( 'params' 'getNumber' 6 $desc ) #set( $desc = 'Returns the parameter with the specified key as a java.lang.Double, if it exists; otherwise, returns the specified alternate Double.' ) #demo2( 'params' 'getDouble' 6 $desc ) #set( $desc = 'Returns the parameter with the specified key as a java.lang.Integer, if it exists; otherwise, returns the specified alternate Integer.' ) #demo2( 'params' 'getInteger' 6 $desc ) #set( $desc = 'Returns the parameter with the specified key as an int, if it exists; otherwise, returns the specified alternate int.' ) #demo2( 'params' 'getInt' 6 $desc ) #set( $desc = 'Returns the parameter with the specified key as a java.util.Locale, if it exists; otherwise, returns the specified alternate Locale.' ) #demo2( 'params' 'getLocale' 6 $desc ) #set( $desc = 'Returns the map of all parameters available for the current request.' ) #demo( 'params' 'all' $desc ) #set( $quote = '"' ) #demoCustom( 'params.layout' ) velocity-tools-2.0-src/examples/showcase/render.vm100644 0 0 4277 11030275256 17553 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. #title( 'ViewRenderTool' )

    #set( $demo = $text.demo ) $demo.thisPage.insert("#doclink( 'RenderTool' true )").

    #demoTableStart() #set( $quote = "'" ) #set( $desc = 'Evaluates a String containing VTL using the current context, and returns the result as a String.' ) #demo1( 'render' 'eval' 15 $desc) #set( $desc = 'Recursively evaluates a String containing VTL using the current context, and returns the result as a String.' ) #demo1( 'render' 'recurse' 15 $desc ) #demoCustom( 'render' )

    $demo.mainExampleHeader


    #if( $params.layout ) #end
    #if( $params.demo ) $demo.mainResultsIntro:
      $render.eval($params.demo)
    
    #end
    velocity-tools-2.0-src/examples/showcase/search.vm100644 0 0 14254 10730012262 17545 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. #title( 'AbstractSearchTool' )

    #set( $demo = $text.demo ) $demo.thisPage.insert("#doclink( 'AbstractSearchTool' false )"). In this case, we are working with a simplistic, demonstration implementation called "MySearchTool".

    If you submit a list of items using the store() function at the bottom> of the table below, that will add those items to a static database of strings which we can use to search for the purposes of the function demonstrations and the example below the function list. Please note that, ${esc.d}search.store() is not a part of the AbstractSearchTool API and exists only for the implementation used in this demo.

    #demoTableStart() #set( $quote = '"' ) #set( $desc = 'Sets the criteria for finding results (i.e. the search terms).' ) #demo1( 'search' 'setCriteria' 8 $desc ) #set( $quote = '' ) #set( $desc = 'Sets the index of the first result in the current page' ) #demo1( 'search' 'setIndex' 4 $desc ) #set( $desc = 'Sets the number of results returned in a page of results' ) #demo1( 'search' 'setItemsPerPage' 4 $desc ) #set( $desc = 'Sets the number of result page indices for $search.slip to list.' ) #demo1( 'search' 'setSlipSize' 4 $desc ) #set( $desc = 'Checks whether or not the result list is empty.' ) #demo( 'search' 'hasItems()' $desc ) #set( $desc = 'Returns the current search criteria.' ) #demo( 'search' 'criteria' $desc ) #set( $desc = 'Returns the current search result index.' ) #demo( 'search' 'index' $desc ) #set( $desc = 'Returns the index of the first result on the current page of results (as determined by the current index, results per page, and the number of results).' ) #demo( 'search' 'firstIndex' $desc ) #set( $desc = 'Returns the index of the last result on the current page of results (as determined by the current index, results per page, and the number of results).' ) #demo( 'search' 'lastIndex' $desc ) #set( $desc = 'Return the index for the previous page of results (as determined by the current index, results per page, and the number of results).' ) #demo( 'search' 'prevIndex' $desc ) #set( $desc = 'Returns the index for the next page of results (as determined by the current index, results per page, and the number of results).' ) #demo( 'search' 'nextIndex' $desc ) #set( $desc = 'Returns the search result list.' ) #demo( 'search' 'items' $desc ) #set( $desc = 'Returns the current "page" of search results.' ) #demo( 'search' 'page' $desc ) #set( $desc = 'Returns a description of the current page.' ) #demo( 'search' 'pageDescription' $desc ) #set( $desc = 'Returns the "page number" for the current index.' ) #demo( 'search' 'pageNumber' $desc ) #set( $desc = 'Returns the "page number" for the specified index.' ) #demo1( 'search' 'getPageNumber' 4 $desc ) #set( $desc = 'Returns the set number of results to be displayed per page of results' ) #demo( 'search' 'itemsPerPage' $desc ) #set( $desc = 'Returns the number of pages that can be made from this list given the set number of results per page.' ) #demo( 'search' 'pagesAvailable' $desc ) #set( $desc = 'Returns the total number of results available.' ) #demo( 'search' 'total' $desc ) #set( $desc = 'Returns a Sliding List of Indices for Pages of results.' ) #demo( 'search' 'slip' $desc ) #set( $desc = 'Returns the number of result page indices $search.slip will return per request (if available).' ) #demo( 'search' 'slipSize' $desc ) #demoCustom( 'search.store($context.toolbox)' ) #set( $desc = 'Adds an item or list of items to the faux "database" that is being "searched" by this example. This method is not part of the AbstractSearchTool API.' ) #demo1( 'search' 'store' 12 $desc )

    $demo.mainExampleHeader

    #foreach( $param in $request.parameterMap.keySet() ) #if( !$param.equals('setCriteria') ) #foreach( $value in $params.getStrings($param) ) #end #end #end
    #if( $search.hasItems() )
    Showing $!search.pageDescription
    #set( $i = $search.index + 1 ) #foreach( $item in $search.page ) ${i}. $!item
    #set( $i = $i + 1 ) #end
    #if ( $search.pagesAvailable > 1 ) #set( $pagelink = $link.self.anchor('fullDemo').param('find',$search.criteria).param('layout',$!params.layout).param('show',$!search.itemsPerPage) ) #if( $search.prevIndex ) Prev #end #foreach( $index in $search.slip ) #if( $index == $search.index ) $search.pageNumber #else $!search.getPageNumber($index) #end #end #if( $search.nextIndex ) Next #end #end
    #else

    There are no items to display. To activate this example, follow the directions at the top of this page.

    #end
    velocity-tools-2.0-src/examples/showcase/sorter.vm100644 0 0 2574 10730012262 17600 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. #title( 'SortTool' )

    #set( $demo = $text.demo ) $demo.thisPage.insert("#doclink( 'SortTool' true )").

    #demoTableStart() #set( $quote = '' ) #set( $desc = 'Sorts the values of the specified Collection, Map, or array of Objects according to their natural ordering' ) #demo1( 'sorter' 'sort' 3 $desc) #set( $desc = "Sorts the values of the specified Collection, Map, or array of Objects according to the values returned by the specified property or list of properties" ) #demo2( 'sorter' 'sort' 5 $desc ) #demoCustom( "sorter.sort(['b','c','a'])" ) velocity-tools-2.0-src/examples/showcase/template.txt100644 0 0 3316 10730012262 20265 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License.

    #set( $demo = $text.demo ) $demo.thisPage.insert("#doclink( 'FooTool' true )").

    #demoTableStart() #set( $quote = '' ) #set( $desc = "" ) #demo( 'foo' '' $desc ) #set( $desc = '' ) #demo1( 'foo' '' 3 $desc) #set( $desc = "" ) #demo2( 'foo' '' 5 $desc ) #demoCustom( 'foo' )

    $demo.mainExampleHeader


    #if( $params.layout ) #end
    #if( $params.demo ) $demo.mainResultsIntro:
      $render.eval($params.demo)
    
    #end
    velocity-tools-2.0-src/examples/showcase/text.vm100644 0 0 6064 11115263034 17247 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. #title( 'ResourceTool' )

    #set( $demo = $text.demo ) $demo.thisPage.insert("#doclink( 'ResourceTool' true )"). This tool is similar to the LinkTool in that most methods return a new object that has mostly the same methods as the original, allowing you to build up parameters elegantly and simply, rather than try to remember how to use methods with many parameters that must be in a specific order. So, you can access a resource with the key 'hello.whoever' in the 'otherStuff' bundle with one message argument like this:

      ${esc.d}text.hello.whoever.bundle('otherStuff').insert('World')
    
    instead of like this:
      ${esc.d}text.get('hello.whoever','otherStuff', $null, 'World')
    
    While the former is somewhat longer, it is much more understandable and flexible.

    #demoTableStart() #set( $desc = 'Returns the resource with the specified name, if it exists.' ) #demo1( 'text' 'get' 9 $desc ) #set( $desc = 'Returns a list of the available keys.' ) #demo( 'text' 'hello.keys' $desc ) #set( $desc = 'Returns a new $text that will search only the specified bundle (if it exists) for the resource "foo".' ) #demo1( 'text.foo' 'bundle' 9 $desc ) #set( $quote = '' ) #set( $desc = 'Returns a new $text that will try to find the resource "foo" for the specified Locale.' ) #demo1( 'text.foo' 'locale' 9 $desc ) #set( $quote = '"' ) #set( $desc = 'Returns the resource "hello.whoever" with the specified value inserted.' ) #demo1( 'text.hello.whoever' 'insert' 9 $desc ) #set( $desc = 'Returns the resource "baz" with the specified values inserted.' ) #demo2( 'text.baz' 'insert' 9 $desc ) #demoCustom( 'text' )

    $demo.mainExampleHeader


    #if( $params.layout ) #end
    #if( $params.demo ) $demo.mainResultsIntro:
      $render.eval($params.demo)
    
    #end
    velocity-tools-2.0-src/examples/showcase/toolmenu.vm100644 0 0 3270 11202122670 20116 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. #if( $params.layout ) #set( $llink = $link.layout($params.layout) ) #else #set( $llink = $link) #end #set( $tools = $text.tools )

    $tools.header:

      #toolMenuItem( $llink 'alternator' ) #toolMenuItem( $llink 'browser' ) #toolMenuItem( $llink 'class' ) #toolMenuItem( $llink 'context' ) #toolMenuItem( $llink 'convert' ) #toolMenuItem( $llink 'cookies' ) #toolMenuItem( $llink 'date' ) #toolMenuItem( $llink 'display' ) #toolMenuItem( $llink 'esc' ) #toolMenuItem( $llink 'field' ) #toolMenuItem( $llink 'import' ) #toolMenuItem( $llink 'include' ) #toolMenuItem( $llink 'link' ) #toolMenuItem( $llink 'loop' ) #toolMenuItem( $llink 'math' ) #toolMenuItem( $llink 'number' ) #toolMenuItem( $llink 'pager' ) #toolMenuItem( $llink 'params' ) #toolMenuItem( $llink 'render' ) #toolMenuItem( $llink 'text' ) #toolMenuItem( $llink 'search' ) #toolMenuItem( $llink 'sorter' ) #toolMenuItem( $llink 'xml' )
    velocity-tools-2.0-src/examples/showcase/xml.vm100644 0 0 2262 11035250472 17062 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. #title( 'XmlTool' )

    $text.demo.thisPage.insert("#doclink( 'XmlTool' true )"). $text.get('xml.intro')

    #set( $toolname = 'xml' ) #set( $toolclass = $xml.class ) #set( $toollink = $doclink ) #set( $toolDemo = "Document: ${esc.d}esc.xml(${esc.d}xml) bar text: ${esc.d}xml.bar.text baz attr value: ${esc.d}xml.a.baz last bar xml: ${esc.d}esc.xml(${esc.d}xml.bar.last)" ) #parse( 'demo.vm' ) velocity-tools-2.0-src/examples/simple/META-INF/MANIFEST.MF100644 0 0 60 10730012260 20107 0ustar 0 0 Manifest-Version: 1.0 Created-By: Ant 1.4.1 velocity-tools-2.0-src/examples/simple/WEB-INF/src/ToyTool.java100644 0 0 2246 10730012260 21457 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ public class ToyTool { private String message = "Hello from ToyTool!"; public String getMessage() { return message; } public void setMessage(String m) { message = m; } /** To test exception handling in templates. */ public boolean whine() { throw new IllegalArgumentException(); } } velocity-tools-2.0-src/examples/simple/WEB-INF/tools.xml100644 0 0 2423 10730012260 20273 0ustar 0 0 this is foo this is bar. velocity-tools-2.0-src/examples/simple/WEB-INF/web.xml100644 0 0 2525 10730012260 17713 0ustar 0 0 velocity org.apache.velocity.tools.view.VelocityViewServlet velocity *.vm index.vm velocity-tools-2.0-src/examples/simple/index.jsp100644 0 0 3010 11115263033 17204 0ustar 0 0 <%@taglib prefix="velocity" uri="http://velocity.apache.org/velocity-view" %> <%-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --%> I'm a JSP file that uses the VelocityViewTag. #if( $XHTML ) #set( $br = "
    " ) #else #set( $br = "
    " ) #end $br $br Here we use a custom tool: $toytool.message $br $br Lets count : #foreach($i in [1..5])$i #end $br $br Let's play with a hashmap:$br first add foo: $map.put("foo",$foo)$br then add bar: $map.put("bar",$bar)$br $br and that gives us $map $br $br Here we get the date from the DateTool: $date.medium $br $br #if( $isSimple ) This is simple#if( $XHTML ) xhtml#end app version ${version}. #end $br $br Click here to see this VTL markup as a normal template.
    velocity-tools-2.0-src/examples/simple/index.vm100644 0 0 3014 10730012260 17032 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. I'm a velocity template processed using the VelocityViewServlet. #if( $XHTML ) #set( $br = "
    " ) #else #set( $br = "
    " ) #end $br $br Here we use a custom tool: $toytool.message $br $br Lets count : #foreach($i in [1..5])$i #end $br $br Let's play with a hashmap:$br first add foo: $map.put("foo",$foo)$br then add bar: $map.put("bar",$bar)$br $br and that gives us $map $br $br Here we get the date from the DateTool: $date.medium $br $br #if( $isSimple ) This is simple#if( $XHTML ) xhtml#end app version ${version}. #end $br $br Click here to see the VelocityViewTag handle the same VTL markup. velocity-tools-2.0-src/examples/struts/META-INF/MANIFEST.MF100644 0 0 56 10730012252 20170 0ustar 0 0 Manifest-Version: 1.0 Created-By: Ant 1.3 velocity-tools-2.0-src/examples/struts/WEB-INF/VM_global_library.vm100644 0 0 3370 10730012256 22425 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. ## Display all queued Struts errors #macro (errorMarkup) #if ($errors.exist() )
      #foreach ($e in $errors.all ) $e #end
    #end #end ## Display all queued Struts errors for a particular property #macro (errorMarkupForProperty $property) #if ($errors.exist($property) )
      #foreach ($er in $errors.get($property)) $er #end
    #end #end ## Display all queued Struts errors #macro (messageMarkup) #if ($messages.exist() )
      #foreach ($m in $messages.all ) $m #end
    #end #end ## Display all queued Struts action messages for a particular property #macro (messageMarkupForProperty $property) #if ($messages.exist($property) )
      #foreach ($m in $messages.get($property)) $m #end
    #end #end velocity-tools-2.0-src/examples/struts/WEB-INF/chain-config.xml100644 0 0 21322 10730012256 21557 0ustar 0 0 velocity-tools-2.0-src/examples/struts/WEB-INF/src/commons-logging.properties100644 0 0 127 11115263033 24453 0ustar 0 0 org.apache.commons.logging.Log=org.apache.velocity.tools.generic.log.LogChuteCommonsLogvelocity-tools-2.0-src/examples/struts/WEB-INF/src/examples/app1/AddressAction.java100644 0 0 12523 10730012256 25347 0ustar 0 0 package examples.app1; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.io.IOException; import java.util.Locale; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import javax.servlet.http.HttpServletResponse; import org.apache.struts.Globals; import org.apache.struts.action.Action; import org.apache.struts.action.ActionErrors; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; /** *

    A simple action that handles the display and editing of an * addres record. This action works with both JSP and Velocity templates. * The type of template to be used is defined in the Struts configuration * file.

    * *

    The action support an action URL parameter. This URL parameter * controls what this action class does. The following values are supported:

    *
      *
    • list - list address record, this is the default if no action parameter is specified *
    • edit - edit address record *
    • save - save address record *
    * * * @author Gabe Sidler * @version $Id: AddressAction.java 477914 2006-11-21 21:52:11Z henning $ */ public class AddressAction extends Action { // --------------------------------------------------------- Public Methods /** * Handle server requests. * * @param mapping The ActionMapping used to select this instance * @param actionForm The optional ActionForm bean for this request (if any) * @param request The HTTP request we are processing * @param response The HTTP response we are creating * * @exception IOException if an input/output error occurs * @exception ServletException if a servlet exception occurs */ public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { String action; HttpSession session; ActionErrors errors = new ActionErrors(); try { session = request.getSession(); // fetch action from form action = ((AddressForm)form).getAction(); servlet.log("[DEBUG] AddressAction at perform(): Action ist " + action); // Determine what to do if ( action.equals("edit") ) { // forward to edit formular return (mapping.findForward("editAddress")); } else if (action.equals("save")) { // check if an address bean exits already AddressBean bean = (AddressBean)session.getAttribute("address"); if (bean == null) { bean = new AddressBean(); session.setAttribute("address", bean); } // update bean with the new values submitted bean.setFirstname( ((AddressForm)form).getFirstname() ); bean.setLastname( ((AddressForm)form).getLastname() ); bean.setStreet( ((AddressForm)form).getStreet() ); bean.setZip( ((AddressForm)form).getZip() ); bean.setCity( ((AddressForm)form).getCity() ); bean.setCountry( ((AddressForm)form).getCountry() ); bean.setLanguages( ((AddressForm)form).getLanguages() ); // forward to list return (mapping.findForward("showAddress")); } else { String locale = ((AddressForm)form).getLocale(); if (locale.equals("Deutsch")) session.setAttribute(Globals.LOCALE_KEY, new Locale("de", "")); else session.setAttribute(Globals.LOCALE_KEY, new Locale("en", "")); // forward to edit formular return (mapping.findForward("showAddress")); } } catch (Exception e) { //errors.add(ActionErrors.GLOBAL_ERROR, new ActionError("lo053")); servlet.log("[ERROR] TskAction at final catch: " + e.getMessage()); e.printStackTrace(); } // Default if everthing else fails return (mapping.findForward("showAddress")); } } velocity-tools-2.0-src/examples/struts/WEB-INF/src/examples/app1/AddressBean.java100644 0 0 5635 10730012256 24765 0ustar 0 0 package examples.app1; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.util.Properties; /** *

    A simple bean that represent an address record.

    * * @author Gabe Sidler * @version $Id: AddressBean.java 477914 2006-11-21 21:52:11Z henning $ */ public class AddressBean extends Object { // ---- Fields ------------------------------------------------------ private String firstname; private String lastname; private String street; private String zip; private String city; private String country; private String[] languages; // ---- Accessor Methods -------------------------------------------- public String getFirstname() { return firstname; } public void setFirstname(String s) { firstname = s; } public String getLastname() { return lastname; } public void setLastname(String s) { lastname = s; } public String getStreet() { return street; } public void setStreet(String s) { street = s; } public String getZip() { return zip; } public void setZip(String s) { zip = s; } public String getCity() { return city; } public void setCity(String s) { city = s; } public String getCountry() { return country; } public void setCountry(String s) { country = s; } public String[] getLanguages() { return languages; } public void setLanguages(String[] languages) { this.languages = languages; } // Convenience method to simplify repopulation of select lists public Properties getLanguagesAsMap() { Properties p = new Properties(); if (languages != null) { for (int i = 0; i < languages.length; i++) p.setProperty((String)languages[i], "SELECTED"); } return p; } } velocity-tools-2.0-src/examples/struts/WEB-INF/src/examples/app1/AddressForm.java100644 0 0 6753 10730012256 25025 0ustar 0 0 package examples.app1; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import javax.servlet.http.HttpServletRequest; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionMapping; /** *

    A simple form that allows a user to enter and modify an address.

    * * @author Gabe Sidler * @version $Id: AddressForm.java 477914 2006-11-21 21:52:11Z henning $ */ public final class AddressForm extends ActionForm { // ---- Form fields ------------------------------------------------- private String action = ""; private String firstname = ""; private String lastname = ""; private String street = ""; private String zip = ""; private String city = ""; private String country = ""; private String locale = ""; private String[] languages; // ---- Accessor Methods -------------------------------------------- public String getAction() { return action; } public void setAction(String s) { action = s; } public String getFirstname() { return firstname; } public void setFirstname(String s) { firstname = s; } public String getLastname() { return lastname; } public void setLastname(String s) { lastname = s; } public String getStreet() { return street; } public void setStreet(String s) { street = s; } public String getZip() { return zip; } public void setZip(String s) { zip = s; } public String getCity() { return city; } public void setCity(String s) { city = s; } public String getCountry() { return country; } public void setCountry(String s) { country = s; } public String getLocale() { return locale; } public void setLocale(String s) { locale = s; } public String[] getLanguages() { return languages; } public void setLanguages(String[] s) { languages = s; } /** * Reset all properties to their default values. * * @param mapping The mapping used to select this instance * @param request The servlet request we are processing */ public void reset(ActionMapping mapping, HttpServletRequest request) { action = ""; locale = ""; firstname = ""; lastname = ""; street = ""; zip = ""; city = ""; country = ""; } } velocity-tools-2.0-src/examples/struts/WEB-INF/src/examples/app1/ApplicationResources.properties100644 0 0 2530 10730012256 30212 0ustar 0 0 # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # Tags for Struts demo application 1 title=Struts Example Application 1 intro=A simple Struts application to demonstrate the use of mixed Velocity and JSP templates. header=The currently registered address is: language=Select language: firstname=First Name lastname=Last Name street=Street zip=ZIP Code city=City country=Country edit=Edit Address version=Version save=Save cancel=cancel languages=Languages chinese=Chinese english=English french=French russian=Russian spanish=Spanish german=German multiple=Shift+click selects more than one velocity-tools-2.0-src/examples/struts/WEB-INF/src/examples/app1/ApplicationResources_de.properties100644 0 0 2555 10730012256 30671 0ustar 0 0 # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # Tags for Struts demo application 1 title=Struts Anwendungsbeispiel 1 intro=Eine einfache Struts Anwendung, die die gemischte Verwendung von Velocity und JSP Templates demonstriert. header=Die registrierte Adresse lautet: language=Sprache auswählen: firstname=Vorname lastname=Nachname street=Strasse zip=PLZ city=Stadt country=Land edit=Adresse mutieren version=Version save=Speichern cancel=Abbrechen Languages=Sprachen languages=Languages chinese=Chinesisch english=Englisch french=Franzsisch russian=Russisch spanish=Spanisch german=Deutsch multiple= velocity-tools-2.0-src/examples/struts/WEB-INF/src/examples/app2/ApplicationResources.properties100644 0 0 2605 10730012256 30216 0ustar 0 0 # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # Tags for Struts demo app 2 title=Struts Example Application 2 test=This string has 5 replacement parameters: {0}, {1}, {2}, {3}, {4} error01=
  • Error 01: A global error message
  • error02=
  • Error 02: Another global error message
  • error10=
  • Error 10: An error specific to "language"
  • error11=
  • Error 11: Another error specific to "language"
  • message01=
  • Message 01: A global message
  • message02=
  • Message 02: Another global message
  • message10=
  • Message 10: An message specific to "foobar"
  • message11=
  • Message 11: Another message specific to "foobar"
  • velocity-tools-2.0-src/examples/struts/WEB-INF/src/examples/app2/DemoAction.java100644 0 0 7301 10730012256 24625 0ustar 0 0 package examples.app2; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import javax.servlet.http.HttpServletResponse; import org.apache.struts.action.Action; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; import org.apache.struts.action.ActionMessage; import org.apache.struts.action.ActionMessages; /** *

    A simple action used to demonstrate the view tools.

    * * @author Gabe Sidler * @version $Id: DemoAction.java 477914 2006-11-21 21:52:11Z henning $ */ public class DemoAction extends Action { /** * Handle server requests. * * @param mapping The ActionMapping used to select this instance * @param actionForm The optional ActionForm bean for this request (if any) * @param request The HTTP request we are processing * @param response The HTTP response we are creating * * @exception IOException if an input/output error occurs * @exception ServletException if a servlet exception occurs */ public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { String action; HttpSession session; // Create serveral error messages to demontrate the output in a template ActionMessages errors = new ActionMessages(); // Add some global errors errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("error01")); errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("error02")); // Add some specific errors errors.add("language", new ActionMessage("error10")); errors.add("language", new ActionMessage("error11")); // Save error messages to request attributes saveErrors(request, errors); // Create serveral error messages to demontrate the output in a template ActionMessages messages = new ActionMessages(); // Add some global messages messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("message01")); messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("message02")); // Add some specific messages messages.add("foobar", new ActionMessage("message10")); messages.add("foobar", new ActionMessage("message11")); // Save messages to request attributes saveMessages(request, messages); // Create and save a new transaction token saveToken(request); return (mapping.findForward("home")); } } velocity-tools-2.0-src/examples/struts/WEB-INF/src/examples/app2/DemoForm.java100644 0 0 3607 10730012256 24320 0ustar 0 0 package examples.app2; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import javax.servlet.http.HttpServletRequest; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionMapping; /** *

    A simple form for demo purposes.

    * * @author Gabe Sidler * @version $Id: DemoForm.java 477914 2006-11-21 21:52:11Z henning $ */ public final class DemoForm extends ActionForm { // ---- Form fields ------------------------------------------------- private String language = ""; // ---- Accessor Methods -------------------------------------------- public String getLanguage() { return language; } public void setLanguage(String s) { language = s; } /** * Reset all properties to their default values. * * @param mapping The mapping used to select this instance * @param request The servlet request we are processing */ public void reset(ActionMapping mapping, HttpServletRequest request) { language = ""; } } velocity-tools-2.0-src/examples/struts/WEB-INF/src/examples/app3/ApplicationResources.properties100644 0 0 2022 10730012256 30210 0ustar 0 0 # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # Tags for Struts demo app 3 errors.footer= errors.header=You must correct the following error(s) before proceeding:
      error.username.required=
    • Username is required
    • error.password.required=
    • Password is required
    • velocity-tools-2.0-src/examples/struts/WEB-INF/src/examples/app3/Constants.java100644 0 0 3355 10730012256 24565 0ustar 0 0 package examples.app3; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ /** * Manifest constants for this application. * * @author Craig R. McClanahan * @author Ted Husted * @version $Revision: 477914 $ $Date: 2006-11-21 13:52:11 -0800 (Tue, 21 Nov 2006) $ */ public final class Constants { /** * The package name for this application. */ public static final String Package = "app"; /** * The session scope attribute under which the Username * for the currently logged in user is stored. */ public static final String USER_KEY = "user"; /** * The token that represents a nominal outcome * in an ActionForward. */ public static final String CONTINUE = "continue"; /** * The value to indicate debug logging. */ public static final int DEBUG = 1; /** * The value to indicate normal logging. */ public static final int NORMAL = 0; } velocity-tools-2.0-src/examples/struts/WEB-INF/src/examples/app3/LogoffAction.java100644 0 0 7075 10730012256 25166 0ustar 0 0 package examples.app3; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.io.IOException; import java.util.Hashtable; import java.util.Locale; import java.util.Vector; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import javax.servlet.http.HttpServletResponse; import org.apache.struts.action.Action; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; import org.apache.struts.action.ActionServlet; import org.apache.struts.util.MessageResources; /** * Implementation of Action that processes a * user logoff. * * @author Craig R. McClanahan * @author Ted Husted * @version $Revision: 477914 $ $Date: 2006-11-21 13:52:11 -0800 (Tue, 21 Nov 2006) $ */ public final class LogoffAction extends Action { // ---------------------------------------------------- Public Methods /** * Logoff the user. * The event is logged if the debug level is >= Constants.DEBUG. * * @param mapping The ActionMapping used to select this instance * @param actionForm The ActionForm bean for this request (if any) * @param request The HTTP request we are processing * @param response The HTTP response we are creating * * @exception IOException if an input/output error occurs * @exception ServletException if a servlet exception occurs */ public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { // Extract attributes we will need HttpSession session = request.getSession(); LogonForm user = (LogonForm) session.getAttribute(Constants.USER_KEY); // Log this user logoff if (user != null) { StringBuffer message = new StringBuffer("LogoffAction: User '"); message.append(user.getUsername()); message.append("' logged off in session "); message.append(session.getId()); servlet.log(message.toString()); } else { StringBuffer message = new StringBuffer("LogoffAction: User '"); message.append(session.getId()); servlet.log(message.toString()); } // Remove user login; invalidate session session.removeAttribute(Constants.USER_KEY); session.invalidate(); // Forward control to the specified success URI return (mapping.findForward(Constants.CONTINUE)); } } // End LogoffAction velocity-tools-2.0-src/examples/struts/WEB-INF/src/examples/app3/LogonAction.java100644 0 0 6137 10730012256 25026 0ustar 0 0 package examples.app3; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import javax.servlet.http.HttpServletResponse; import org.apache.struts.action.Action; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; /** * Implementation of Action that validates a user logon. * * @author Craig R. McClanahan * @author Ted Husted * @version $Revision: 477914 $ $Date: 2006-11-21 13:52:11 -0800 (Tue, 21 Nov 2006) $ */ public final class LogonAction extends Action { // ---------------------------------------------------- Public Methods /** * Login the user. * The event is logged if the debug level is >= Constants.DEBUG. * * @param mapping The ActionMapping used to select this instance * @param actionForm The ActionForm bean for this request (if any) * @param request The HTTP request we are processing * @param response The HTTP response we are creating * * @exception IOException if an input/output error occurs * @exception ServletException if a servlet exception occurs */ public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { String username = ((LogonForm) form).getUsername(); String password = ((LogonForm) form).getPassword(); // Save our logged-in user in the session, // because we use it again later. HttpSession session = request.getSession(); session.setAttribute(Constants.USER_KEY, form); // Log this event StringBuffer message = new StringBuffer("LogonAction: User '"); message.append(username); message.append("' logged on in session "); message.append(session.getId()); servlet.log(message.toString()); // Forward control to the success URI // specified in struts-config.xml return (mapping.findForward(Constants.CONTINUE)); } } velocity-tools-2.0-src/examples/struts/WEB-INF/src/examples/app3/LogonForm.java100644 0 0 7127 10730012256 24514 0ustar 0 0 package examples.app3; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import javax.servlet.http.HttpServletRequest; import org.apache.struts.action.ActionMessage; import org.apache.struts.action.ActionErrors; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionMapping; /** * Form bean for the user profile page. * This form has the following fields, * with default values in square brackets: *
        *
      • password - Entered password value *
      • username - Entered username value *
      * * @author Ted Husted * @version $Revision: 477914 $ $Date: 2006-11-21 13:52:11 -0800 (Tue, 21 Nov 2006) $ */ public final class LogonForm extends ActionForm { // ------------------------------------------------ Instance Variables /** * The password. */ private String password = null; /** * The username. */ private String username = null; // ------------------------------------------------------ Properties /** * Return the password. */ public String getPassword() { return (this.password); } /** * Set the password. * * @param password The new password */ public void setPassword(String password) { this.password = password; } /** * Return the username. */ public String getUsername() { return (this.username); } /** * Set the username. * * @param username The new username */ public void setUsername(String username) { this.username = username; } // -------------------------------------------------- Public Methods /** * Reset all properties to their default values. * * @param mapping The mapping used to select this instance * @param request The servlet request we are processing */ public void reset(ActionMapping mapping, HttpServletRequest request) { setPassword(null); setUsername(null); } /** * Ensure that both fields have been input. * * @param mapping The mapping used to select this instance * @param request The servlet request we are processing */ public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) { ActionErrors errors = new ActionErrors(); if ((username == null) || (username.length() < 1)) errors.add("username", new ActionMessage("error.username.required")); if ((password == null) || (password.length() < 1)) errors.add("password", new ActionMessage("error.password.required")); return errors; } } // End LogonForm velocity-tools-2.0-src/examples/struts/WEB-INF/src/examples/app4/ApplicationResources.properties100644 0 0 2046 10730012256 30217 0ustar 0 0 # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # Tags for Struts demo app 3 errors.footer=
    errors.header=You must correct the following error(s) before proceeding:
      error.username.required=
    • Username is required
    • error.password.required=
    • Password is required
    • some.value=yeah! velocity-tools-2.0-src/examples/struts/WEB-INF/src/examples/app4/MyTileController.java100644 0 0 4242 10730012256 26055 0ustar 0 0 package examples.app4; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import org.apache.struts.tiles.ControllerSupport; import org.apache.struts.tiles.ComponentContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.ServletContext; import javax.servlet.ServletException; import java.io.IOException; /** *

      A simple tile-controller that puts a string into the request scope. * Check out the tiles-defs to see the definition that uses the controller

      * * @author Marinó A. Jónsson * @version $Id: MyTileController.java 477914 2006-11-21 21:52:11Z henning $ */ public class MyTileController extends ControllerSupport { public MyTileController() { } /** * Method associated to a tile and called immediately before the tile * is included. * @param tileContext Current tile context. * @param request Current request * @param response Current response * @param servletContext Current servlet context */ public void execute(ComponentContext tileContext, HttpServletRequest request, HttpServletResponse response, ServletContext servletContext) throws ServletException, IOException { request.setAttribute("foo", "bar"); } } velocity-tools-2.0-src/examples/struts/WEB-INF/src/examples/app5/ApplicationResources.properties100644 0 0 2022 10730012256 30212 0ustar 0 0 # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # Tags for Struts demo app 5 errors.footer=
    errors.header=You must correct the following error(s) before proceeding:
      errors.required = {0} is required. errors.invalid = {0} is invalid. emailForm.label.email = E-mail velocity-tools-2.0-src/examples/struts/WEB-INF/struts-app1-config.xml100644 0 0 3770 10730012256 22667 0ustar 0 0 velocity-tools-2.0-src/examples/struts/WEB-INF/struts-app2-config.xml100644 0 0 3035 10730012256 22662 0ustar 0 0 velocity-tools-2.0-src/examples/struts/WEB-INF/struts-app3-config.xml100644 0 0 5451 10730012256 22667 0ustar 0 0 velocity-tools-2.0-src/examples/struts/WEB-INF/struts-app4-config.xml100644 0 0 3324 10730012256 22665 0ustar 0 0 velocity-tools-2.0-src/examples/struts/WEB-INF/struts-app5-config.xml100644 0 0 3643 10730012256 22672 0ustar 0 0 velocity-tools-2.0-src/examples/struts/WEB-INF/struts-app6-config.xml100644 0 0 6366 10730012256 22700 0ustar 0 0 velocity-tools-2.0-src/examples/struts/WEB-INF/struts-app7-config.xml100644 0 0 7114 10730012256 22671 0ustar 0 0 velocity-tools-2.0-src/examples/struts/WEB-INF/struts-config.xml100644 0 0 5154 10730012256 22026 0ustar 0 0 velocity-tools-2.0-src/examples/struts/WEB-INF/tiles-app4-defs.xml100644 0 0 6410 10730012256 22114 0ustar 0 0 velocity-tools-2.0-src/examples/struts/WEB-INF/tiles-app7-defs.xml100644 0 0 3416 10730012256 22122 0ustar 0 0 velocity-tools-2.0-src/examples/struts/WEB-INF/tld/sslext.tld100644 0 0 20733 10730012254 21325 0ustar 0 0 1.0 1.1 eblt http://www.ebuilt.com/taglib form org.apache.struts.taglib.html.SecureFormTag JSP action true true enctype false true focus false true focusIndex false true method false true name false true onreset false true onsubmit false true scope false true style false true styleClass false true styleId false true target false true type false true link org.apache.struts.taglib.html.SecureLinkTag accesskey false true action false true anchor false true forward false true href false true indexed false true indexId false true linkName false true name false true onblur false true onclick false true ondblclick false true onfocus false true onkeydown false true onkeypress false true onkeyup false true onmousedown false true onmousemove false true onmouseout false true onmouseover false true onmouseup false true page false true paramId false true paramName false true paramProperty false true paramScope false true property false true scope false true style false true styleClass false true styleId false true tabindex false true target false true title false true titleKey false true transaction false true pageScheme org.apache.struts.taglib.html.PageSchemeTag empty secure true true rewrite org.apache.struts.taglib.html.SecureRewriteTag empty anchor false true forward false true href false true name false true page false true paramId false true paramName false true paramProperty false true paramScope false true property false true scope false true transaction false true velocity-tools-2.0-src/examples/struts/WEB-INF/tld/struts-bean.tld100644 0 0 130335 11115263033 22273 0ustar 0 0 1.3 1.2 bean http://struts.apache.org/tags-bean Note: Some of the features in this taglib are also available in the JavaServer Pages Standard Tag Library (JSTL). The Struts team encourages the use of the standard tags over the Struts specific tags when possible.

      This tag library contains tags useful in accessing beans and their properties, as well as defining new beans (based on these accesses) that are accessible to the remainder of the page via scripting variables and page scope attributes. Convenient mechanisms to create new beans based on the value of request cookies, headers, and parameters are also provided.

      Many of the tags in this tag library will throw a JspException at runtime when they are utilized incorrectly (such as when you specify an invalid combination of tag attributes). JSP allows you to declare an "error page" in the <%@ page %> directive. If you wish to process the actual exception that caused the problem, it is passed to the error page as a request attribute under key org.apache.struts.action.EXCEPTION.

      ]]>
      cookie org.apache.struts.taglib.bean.CookieTag org.apache.struts.taglib.bean.CookieTei empty Define a scripting variable based on the value(s) of the specified request cookie.

      Retrieve the value of the specified request cookie (as a single value or multiple values, depending on the multiple attribute), and define the result as a page scope attribute of type Cookie (if multiple is not specified) or Cookie[] (if multiple is specified).

      If no cookie with the specified name can be located, and no default value is specified, a request time exception will be thrown.

      ]]>
      id true false Specifies the name of the scripting variable (and associated page scope attribute) that will be made available with the value of the specified request cookie.

      ]]>
      multiple false true If any arbitrary value for this attribute is specified, causes all matching cookies to be accumulated and stored into a bean of type Cookie[]. If not specified, the first value for the specified cookie will be retrieved as a value of type Cookie.

      ]]>
      name true true Specifies the name of the request cookie whose value, or values, is to be retrieved.

      ]]>
      value false true The default cookie value to return if no cookie with the specified name was included in this request.

      ]]>
      define org.apache.struts.taglib.bean.DefineTag org.apache.struts.taglib.bean.DefineTei JSP Define a scripting variable based on the value(s) of the specified bean property.

      Create a new attribute (in the scope specified by the toScope property, if any), and a corresponding scripting variable, both of which are named by the value of the id attribute. The corresponding value to which this new attribute (and scripting variable) is set are specified via use of exactly one of the following approaches (trying to use more than one will result in a JspException being thrown):

      • Specify a name attribute (plus optional property and scope attributes) - The created attribute and scripting variable will be of the type of the retrieved JavaBean property, unless it is a Java primitive type, in which case it will be wrapped in the appropriate wrapper class (i.e. int is wrapped by java.lang.Integer).
      • Specify a value attribute - The created attribute and scripting variable will be of type java.lang.String, set to the value of this attribute.
      • Specify nested body content - The created attribute and scripting variable will be of type java.lang.String, set to the value of the nested body content.

      If a problem occurs while retrieving the specified bean property, a request time exception will be thrown.

      The <bean:define> tag differs from <jsp:useBean> in several ways, including:

      • Unconditionally creates (or replaces) a bean under the specified identifier.
      • Can create a bean with the value returned by a property getter of a different bean (including properties referenced with a nested and/or indexed property name).
      • Can create a bean whose contents is a literal string (or the result of a runtime expression) specified by the value attribute.
      • Does not support nested content (such as <jsp:setProperty> tags) that are only executed if a bean was actually created.

      USAGE NOTE - There is a restriction in the JSP 1.1 Specification that disallows using the same value for an id attribute more than once in a single JSP page. Therefore, you will not be able to use <bean:define> for the same bean name more than once in a single page.

      USAGE NOTE - If you use another tag to create the body content (e.g. bean:write), that tag must return a non-empty String. An empty String equates to an empty body or a null String, and a new scripting variable cannot be defined as null. Your bean must return a non-empty String, or the define tag must be wrapped within a logic tag to test for an empty or null value.

      USAGE NOTE - You cannot use bean:define to instantiate a DynaActionForm (type="org.apache.struts.action.DynaActionForm") with the properties specified in the struts-config. The mechanics of creating the dyna-properties is complex and cannot be handled by a no-argument constructor. If you need to create an ActionForm this way, you must use a conventional ActionForm.

      See the Bean Developer's Guide section on bean creation for more information about these differences, as well as alternative approaches to introducing beans into a JSP page.

      ]]>
      id true false Specifies the name of the scripting variable (and associated page scope attribute) that will be made available with the value of the specified property.

      ]]>
      name false true Specifies the attribute name of the bean whose property is accessed to define a new page scope attribute (if property is also specified) or the attribute name of the bean that is duplicated with the new reference created by this tag (if property is not also specified). This attribute is required unless you specify a value attribute or nested body content.

      ]]>
      property false true Specifies the name of the property to be accessed on the bean specified by name. This value may be a simple, indexed, or nested property reference expression. If not specified, the bean identified by name is given a new reference identified by id.

      ]]>
      scope false true Specifies the variable scope searched to retrieve the bean specified by name. If not specified, the default rules applied by PageContext.findAttribute() are applied.

      ]]>
      toScope false true Specifies the variable scope into which the newly defined bean will be created. If not specified, the bean will be created in page scope.

      ]]>
      type false true Specifies the fully qualified class name of the value to be exposed as the id attribute.

      ]]>
      value false true The java.lang.String value to which the exposed bean should be set. This attribute is required unless you specify the name attribute or nested body content.

      ]]>
      header org.apache.struts.taglib.bean.HeaderTag org.apache.struts.taglib.bean.HeaderTei empty Define a scripting variable based on the value(s) of the specified request header.

      Retrieve the value of the specified request header (as a single value or multiple values, depending on the multiple attribute), and define the result as a page scope attribute of type String (if multiple is not specified) or String[] (if multiple is specified).

      If no header with the specified name can be located, and no default value is specified, a request time exception will be thrown.

      ]]>
      id true false Specifies the name of the scripting variable (and associated page scope attribute) that will be made available with the value of the specified request header.

      ]]>
      multiple false true If any arbitrary value for this attribute is specified, causes a call to HttpServletRequest.getHeaders() and a definition of the result as a bean of type String[]. Otherwise, HttpServletRequest.getHeader() will be called, and a definition of the result as a bean of type String will be performed.

      ]]>
      name true true Specifies the name of the request header whose value, or values, is to be retrieved.

      ]]>
      value false true The default header value to return if no header with the specified name was included in this request.

      ]]>
      include org.apache.struts.taglib.bean.IncludeTag org.apache.struts.taglib.bean.IncludeTei empty Load the response from a dynamic application request and make it available as a bean.

      Perform an internal dispatch to the specified application component (or external URL) and make the response data from that request available as a bean of type String. This tag has a function similar to that of the standard <jsp:include> tag, except that the response data is stored in a page scope attribute instead of being written to the output stream. If the current request is part of a session, the generated request for the include will also include the session identifier (and thus be part of the same session).

      The URL used to access the specified application component is calculated based on which of the following attributes you specify (you must specify exactly one of them):

      • forward - Use the value of this attribute as the name of a global ActionForward to be looked up, and use the module-relative or context-relative URI found there.
      • href - Use the value of this attribute unchanged (since this might link to a resource external to the application, the session identifier is not included.
      • page - Use the value of this attribute as an module-relative URI to the desired resource.
      ]]>
      anchor false true Optional anchor tag ("#xxx") to be added to the generated hyperlink. Specify this value without any "#" character.

      ]]>
      forward false true Logical name of a global ActionForward that contains the actual content-relative URI of the resource to be included.

      ]]>
      href false true Absolute URL (including the appropriate protocol prefix such as "http:") of the resource to be included. Because this URL could be external to the current web application, the session identifier will not be included in the request.

      ]]>
      id true false Specifies the name of the scripting variable (and associated page scope attribute) that will be made available with the value of the specified web application resource.

      ]]>
      page false true Module-relative URI (starting with a '/') of the web application resource to be included.

      ]]>
      transaction false true boolean Set to true if you want the current transaction control token included in the generated URL for this include.

      ]]>
      message org.apache.struts.taglib.bean.MessageTag empty Render an internationalized message string to the response.

      Retrieves an internationalized message for the specified locale, using the specified message key, and write it to the output stream. Up to five parametric replacements (such as "{0}") may be specified.

      The message key may be specified directly, using the key attribute, or indirectly, using the name and property attributes to obtain it from a bean.

      JSTL: The equivalent JSTL tag is <fmt:message>. For example,
      <fmt:message key="my.msg.key"> <fmt:param value="replacement text"/> </fmt:message>

      ]]>
      arg0 false true First parametric replacement value, if any.

      ]]>
      arg1 false true Second parametric replacement value, if any.

      ]]>
      arg2 false true Third parametric replacement value, if any.

      ]]>
      arg3 false true Fourth parametric replacement value, if any.

      ]]>
      arg4 false true Fifth parametric replacement value, if any.

      ]]>
      bundle false true The name of the application scope bean under which the MessageResources object containing our messages is stored.

      ]]>
      key false true The message key of the requested message, which must have a corresponding value in the message resources. If not specified, the key is obtained from the name and property attributes.

      ]]>
      locale false true The name of the session scope bean under which our currently selected Locale object is stored.

      ]]>
      name false true Specifies the attribute name of the bean whose property is accessed to retrieve the value specified by property (if specified). If property is not specified, the value of this bean itself will be used as the message resource key.

      ]]>
      property false true Specifies the name of the property to be accessed on the bean specified by name. This value may be a simple, indexed, or nested property reference expression. If not specified, the value of the bean identified by name will itself be used as the message resource key.

      ]]>
      scope false true Specifies the variable scope searched to retrieve the bean specified by name. If not specified, the default rules applied by PageContext.findAttribute() are applied.

      ]]>
      page org.apache.struts.taglib.bean.PageTag org.apache.struts.taglib.bean.PageTei empty Expose a specified item from the page context as a bean.

      Retrieve the value of the specified item from the page context for this page, and define it as a scripting variable, and a page scope attribute accessible to the remainder of the current page.

      If a problem occurs while retrieving the specified configuration object, a request time exception will be thrown.

      ]]>
      id true false Specifies the name of the scripting variable (and associated page scope attribute) that will be made available with the value of the specified page context property.

      ]]>
      property true true Name of the property from our page context to be retrieved and exposed. Must be one of application, config, request, response, or session.

      ]]>
      parameter org.apache.struts.taglib.bean.ParameterTag org.apache.struts.taglib.bean.ParameterTei empty Define a scripting variable based on the value(s) of the specified request parameter.

      Retrieve the value of the specified request parameter (as a single value or multiple values, depending on the multiple attribute), and define the result as a page scope attribute of type String (if multiple is not specified) or String[] (if multiple is specified).

      If no request parameter with the specified name can be located, and no default value is specified, a request time exception will be thrown.

      ]]>
      id true false Specifies the name of the scripting variable (and associated page scope attribute) that will be made available with the value of the specified request parameter.

      ]]>
      multiple false true If any arbitrary value for this attribute is specified, causes a call to ServletRequest.getParameterValues() and a definition of the result as a bean of type String[]. Otherwise, ServletRequest.getParameter() will be called, and a definition of the result as a bean of type String will be performed.

      ]]>
      name true true Specifies the name of the request parameter whose value, or values, is to be retrieved.

      ]]>
      value false true The default parameter value to return if no parameter with the specified name was included in this request.

      ]]>
      resource org.apache.struts.taglib.bean.ResourceTag org.apache.struts.taglib.bean.ResourceTei empty Load a web application resource and make it available as a bean.

      Retrieve the value of the specified web application resource, and make it available as either a InputStream or a String, depending on the value of the input attribute.

      If a problem occurs while retrieving the specified resource, a request time exception will be thrown.

      ]]>
      id true false Specifies the name of the scripting variable (and associated page scope attribute) that will be made available with the value of the specified web application resource.

      ]]>
      input false true If any arbitrary value for this attribute is specified, the resource will be made available as an InputStream. If this attribute is not specified, the resource will be made available as a String.

      ]]>
      name true true Module-relative name (starting with a '/') of the web application resource to be loaded and made available.

      ]]>
      size org.apache.struts.taglib.bean.SizeTag org.apache.struts.taglib.bean.SizeTei empty Define a bean containing the number of elements in a Collection or Map.

      Given a reference to an array, Collection or Map, creates a new bean, of type java.lang.Integer, whose value is the number of elements in that collection. You can specify the collection to be counted in any one of the following ways:

      • As a runtime expression specified as the value of the collection attribute.
      • As a JSP bean specified by the name attribute.
      • As the property, specified by the property attribute, of the JSP bean specified by the name attribute.
      ]]>
      collection false true java.lang.Object A runtime expression that evaluates to an array, a Collection, or a Map.

      ]]>
      id true false The name of a page scope JSP bean, of type java.lang.Integer, that will be created to contain the size of the underlying collection being counted.

      ]]>
      name false true The name of the JSP bean (optionally constrained to the scope specified by the scope attribute) that contains the collection to be counted (if property is not specified), or whose property getter is called to return the collection to be counted (if property is specified.

      ]]>
      property false true The name of the property, of the bean specified by the name attribute, whose getter method will return the collection to be counted.

      ]]>
      scope false true The bean scope within which to search for the JSP bean specified by the name attribute. If not specified, the available scopes are searched in ascending sequence.

      ]]>
      struts org.apache.struts.taglib.bean.StrutsTag org.apache.struts.taglib.bean.StrutsTei empty Expose a named Struts internal configuration object as a bean.

      Retrieve the value of the specified Struts internal configuration object, and define it as a scripting variable and as a page scope attribute accessible to the remainder of the current page. You must specify exactly one of the formBean, forward, and mapping attributes to select the configuration object to be exposed.

      If a problem occurs while retrieving the specified configuration object, a request time exception will be thrown.

      ]]>
      id true false Specifies the name of the scripting variable (and associated page scope attribute) that will be made available with the value of the specified Struts internal configuration object.

      ]]>
      formBean false true Specifies the name of the Struts ActionFormBean definition object to be exposed.

      ]]>
      forward false true Specifies the name of the global Struts ActionForward definition object to be exposed.

      ]]>
      mapping false true Specifies the matching path of the Struts ActionMapping definition object to be exposed.

      ]]>
      write org.apache.struts.taglib.bean.WriteTag empty Render the value of the specified bean property to the current JspWriter.

      Retrieve the value of the specified bean property, and render it to the current JspWriter as a String by the ways:

      • If format attribute exists then value will be formatted on base of format string from format attribute and default system locale.
      • If in resources exists format string for value data type (view format attribute description) then value will be formatted on base of format string from resources. Resources bundle and target locale can be specified with bundle and locale attributes. If nothing specified then default resource bundle and current user locale will be used.
      • If there is a PropertyEditor configured for the property value's class, the getAsText() method will be called.
      • Otherwise, the usual toString() conversions will be applied.

      When a format string is provided, numeric values are formatted using the java.text.DecimalFormat class; if the format string came from a resource, the applyLocalisedPattern() method is used, and applyPattern() is used otherwise. Dates are formatted using the SimpleDateFormat class. For details of the specific format patterns, please see the Javadocs for those classes.

      If a problem occurs while retrieving the specified bean property, a request time exception will be thrown.

      ]]>
      bundle false true The name of the application scope bean under which the MessageResources object containing our messages is stored.

      ]]>
      filter false true boolean If this attribute is set to true, the rendered property value will be filtered for characters that are sensitive in HTML, and any such characters will be replaced by their entity equivalents.

      ]]>
      format false true Specifies the format string to use to convert bean or property value to the String. If nothing specified, then default format string for value data type will be searched in message resources by according key.

      ]]>
      formatKey false true Specifies the key to search format string in application resources.

      ]]>
      ignore false true boolean If this attribute is set to true, and the bean specified by the name and scope attributes does not exist, simply return without writing anything. If this attribute is set to false, a runtime exception to be thrown, consistent with the other tags in this tag library.

      ]]>
      locale false true The name of the session scope bean under which our currently selected Locale object is stored.

      ]]>
      name true true Specifies the attribute name of the bean whose property is accessed to retrieve the value specified by property (if specified). If property is not specified, the value of this bean itself will be rendered.

      ]]>
      property false true Specifies the name of the property to be accessed on the bean specified by name. This value may be a simple, indexed, or nested property reference expression. If not specified, the bean identified by name will itself be rendered. If the specified property returns null, no output will be rendered.

      ]]>
      scope false true Specifies the variable scope searched to retrieve the bean specified by name. If not specified, the default rules applied by PageContext.findAttribute() are applied.

      ]]>
      velocity-tools-2.0-src/examples/struts/WEB-INF/tld/struts-html.tld100644 0 0 1215446 11115263033 22362 0ustar 0 0 1.3 1.2 html http://struts.apache.org/tags-html This taglib contains tags used to create struts input forms, as well as other tags generally useful in the creation of HTML-based user interfaces.

      Many of the tags in this tag library will throw a JspException at runtime when they are utilized incorrectly (such as when you specify an invalid combination of tag attributes). JSP allows you to declare an "error page" in the <%@ page %> directive. If you wish to process the actual exception that caused the problem, it is passed to the error page as a request attribute under key org.apache.struts.action.EXCEPTION.

      ]]>
      base org.apache.struts.taglib.html.BaseTag empty Render an HTML <base> Element

      Renders an HTML <base> element with an href attribute pointing to the absolute location of the enclosing JSP page. This tag is valid only when nested inside an HTML <head> element.

      This tag is useful because it allows you to use relative URL references in the page that are calculated based on the URL of the page itself, rather than the URL to which the most recent submit took place (which is where the browser would normally resolve relative references against).

      ]]>
      target false true The window target for this base reference.

      ]]>
      server false true The server name to use instead of request.getServerName().

      ]]>
      ref false true The reference from which the base uri will created. Possible values are:

      • page - The base uri will be the jsp page location. (default)
      • site - The base uri will be the application context path.
      Since:
      Struts 1.3
      ]]>
      button org.apache.struts.taglib.html.ButtonTag Render A Button Input Field

      Renders an HTML <input> element of type button, populated from the specified value or the content of this tag body. This tag is only valid when nested inside a form tag body.

      If a graphical button is needed (a button with an image), then the image tag is more appropriate.

      ]]>
      accesskey false true The keyboard character used to move focus immediately to this element.

      ]]>
      alt false true The alternate text for this element.

      ]]>
      altKey false true The message resources key of the alternate text for this element.

      ]]>
      bundle false true The servlet context attributes key for the MessageResources instance to use. If not specified, defaults to the application resources configured for our action servlet.

      Since:
      Struts 1.2.5
      ]]>
      disabled false true boolean Set to true if this input field should be disabled.

      ]]>
      indexed false true boolean Valid only inside of logic:iterate tag. If true then name of the html tag will be rendered as "propertyName[34]". Number in brackets will be generated for every iteration and taken from ancestor logic:iterate tag.

      ]]>
      onblur false true onchange false true onclick false true ondblclick false true onfocus false true onkeydown false true onkeypress false true onkeyup false true onmousedown false true onmousemove false true onmouseout false true onmouseover false true onmouseup false true property true true style false true styleClass false true styleId false true tabindex false true title false true The advisory title for this element.

      ]]>
      titleKey false true The message resources key for the advisory title for this element.

      ]]>
      value false true
      cancel org.apache.struts.taglib.html.CancelTag Render a Cancel Button

      Renders an HTML <input> element of type submit. This tag is only valid when nested inside a form tag body. Pressing of this submit button causes the action servlet to bypass calling the associated form bean validate() method. The action is called normally.

      ]]>
      accesskey false true alt false true The alternate text for this element.

      ]]>
      altKey false true The message resources key of the alternate text for this element.

      ]]>
      bundle false true
      Since:
      Struts 1.2.5
      ]]>
      disabled false true boolean true if this input field should be disabled. ]]> onblur false true onchange false true onclick false true ondblclick false true onfocus false true onkeydown false true onkeypress false true onkeyup false true onmousedown false true onmousemove false true onmouseout false true onmouseover false true onmouseup false true property false true WARNING - If you set this attribute to a value other than the default, this will NOT be recognized as the cancel key by the Struts controller servlet or the Action.isCancelled() method. You will need to do your own cancel detection. ]]> style false true styleClass false true styleId false true tabindex false true title false true The advisory title for this element.

      ]]>
      titleKey false true The message resources key for the advisory title for this element.

      ]]>
      value false true
      checkbox org.apache.struts.taglib.html.CheckboxTag Render A Checkbox Input Field

      Renders an HTML <input> element of type checkbox, populated from the specified value or the specified property of the bean associated with our current form. This tag is only valid when nested inside a form tag body.

      NOTE: The underlying property value associated with this field should be of type boolean, and any value you specify should correspond to one of the Strings that indicate a true value ("true", "yes", or "on"). If you wish to utilize a set of related String values, consider using the multibox tag.

      WARNING: In order to correctly recognize unchecked checkboxes, the ActionForm bean associated with this form must include a statement setting the corresponding boolean property to false in the reset() method.

      ]]>
      accesskey false true alt false true The alternate text for this element.

      ]]>
      altKey false true The message resources key of the alternate text for this element.

      ]]>
      bundle false true
      Since:
      Struts 1.2.5
      ]]>
      disabled false true boolean true if this input field should be disabled. ]]> errorKey false true Name of the bean (in any scope) under which our error messages have been stored. If not present, the name specified by the Globals.ERROR_KEY constant string will be used.

      N.B. This is used in conjunction with the errorStyle, errorStyleClass and errorStyleId attributes and should be set to the same value as the name attribute on the <html:errors/> tag.

      Since:
      Struts 1.2.5
      ]]>
      errorStyle false true CSS styles to be applied to this HTML element if an error exists for it.

      N.B. If present, this overrides the style attribute in the event of an error.

      Since:
      Struts 1.2.5
      ]]>
      errorStyleClass false true CSS stylesheet class to be applied to this HTML element if an error exists for it (renders a "class" attribute).

      N.B. If present, this overrides the styleClass attribute in the event of an error.

      Since:
      Struts 1.2.5
      ]]>
      errorStyleId false true Identifier to be assigned to this HTML element if an error exists for it (renders an "id" attribute).

      N.B. If present, this overrides the styleId attribute in the event of an error.

      Since:
      Struts 1.2.5
      ]]>
      indexed false true boolean logic:iterate tag. If true then name of the html tag will be rendered as "id[34].propertyName". Number in brackets will be generated for every iteration and taken from ancestor logic:iterate tag. ]]> name false true onblur false true onchange false true onclick false true ondblclick false true onfocus false true onkeydown false true onkeypress false true onkeyup false true onmousedown false true onmousemove false true onmouseout false true onmouseover false true onmouseup false true property true true style false true CSS styles to be applied to this HTML element.

      N.B. If present, the errorStyle overrides this attribute in the event of an error for the element.

      ]]>
      styleClass false true CSS stylesheet class to be applied to this HTML element (renders a "class" attribute).

      N.B. If present, the errorStyleClass overrides this attribute in the event of an error for the element.

      ]]>
      styleId false true Identifier to be assigned to this HTML element (renders an "id" attribute).

      N.B. If present, the errorStyleId overrides this attribute in the event of an error for the element.

      ]]>
      tabindex false true title false true The advisory title for this element.

      ]]>
      titleKey false true The message resources key for the advisory title for this element.

      ]]>
      value false true
      errors org.apache.struts.taglib.html.ErrorsTag empty Conditionally display a set of accumulated error messages.

      Displays a set of error messages prepared by a business logic component and stored as an ActionMessages object, an ActionErrors object, a String, or a String array in any scope. If such a bean is not found, nothing will be rendered.

      In order to use this tag successfully, you must have defined an application scope MessageResources bean under the default attribute name, with optional definitions of message keys specified in the following attributes:

      • header - Text that will be rendered before the error messages list. Typically, this message text will end with <ul> to start the error messages list (default "errors.header").
      • footer - Text that will be rendered after the error messages list. Typically, this message text will begin with </ul> to end the error messages list (default "errors.footer").
      • prefix - Text that will be rendered before each individual error in the list (default "errors.prefix").
      • suffix - Text that will be rendered after each individual error in the list (default "errors.suffix").

      See the messages tag for an alternative to this tag that does not rely on HTML in your MessageResources.

      ]]>
      bundle false true footer false true
      Since:
      Struts 1.2.5
      ]]>
      header false true
      Since:
      Struts 1.2.5
      ]]>
      locale false true name false true Globals.ERROR_KEY constant string will be used. ]]> prefix false true
      Since:
      Struts 1.2.5
      ]]>
      property false true suffix false true
      Since:
      Struts 1.2.5
      ]]>
      file org.apache.struts.taglib.html.FileTag Render A File Select Input Field

      Renders an HTML <input> element of type file, defaulting to the specified value or the specified property of the bean associated with our current form. This tag is only valid when nested inside a form tag body.

      As with the corresponding HTML <input> element, the enclosing form element must specify "POST" for the method attribute, and "multipart/form-data" for the enctype attribute. For example:

          <html:form method="POST" enctype="multipart/form-data">
              <html:file property="theFile" />
          </html:form>

      WARNING: In order to correctly recognize uploaded files, the ActionForm bean associated with this form must include a statement setting the corresponding org.apache.struts.upload.FormFile property to null in the reset() method.

      ]]>
      accesskey false true accept false true alt false true The alternate text for this element.

      ]]>
      altKey false true The message resources key of the alternate text for this element.

      ]]>
      bundle false true
      Since:
      Struts 1.2.5
      ]]>
      disabled false true boolean true if this input field should be disabled. ]]> errorKey false true Name of the bean (in any scope) under which our error messages have been stored. If not present, the name specified by the Globals.ERROR_KEY constant string will be used.

      N.B. This is used in conjunction with the errorStyle, errorStyleClass and errorStyleId attributes and should be set to the same value as the name attribute on the <html:errors/> tag.

      Since:
      Struts 1.2.5
      ]]>
      errorStyle false true CSS styles to be applied to this HTML element if an error exists for it.

      N.B. If present, this overrides the style attribute in the event of an error.

      Since:
      Struts 1.2.5
      ]]>
      errorStyleClass false true CSS stylesheet class to be applied to this HTML element if an error exists for it (renders a "class" attribute).

      N.B. If present, this overrides the styleClass attribute in the event of an error.

      Since:
      Struts 1.2.5
      ]]>
      errorStyleId false true Identifier to be assigned to this HTML element if an error exists for it (renders an "id" attribute).

      N.B. If present, this overrides the styleId attribute in the event of an error.

      Since:
      Struts 1.2.5
      ]]>
      indexed false true boolean logic:iterate tag. If true then name of the html tag will be rendered as "id[34].propertyName". Number in brackets will be generated for every iteration and taken from ancestor logic:iterate tag. ]]> maxlength false true name false true onblur false true onchange false true onclick false true ondblclick false true onfocus false true onkeydown false true onkeypress false true onkeyup false true onmousedown false true onmousemove false true onmouseout false true onmouseover false true onmouseup false true property true true size false true style false true CSS styles to be applied to this HTML element.

      N.B. If present, the errorStyle overrides this attribute in the event of an error for the element.

      ]]>
      styleClass false true CSS stylesheet class to be applied to this HTML element (renders a "class" attribute).

      N.B. If present, the errorStyleClass overrides this attribute in the event of an error for the element.

      ]]>
      styleId false true Identifier to be assigned to this HTML element (renders an "id" attribute).

      N.B. If present, the errorStyleId overrides this attribute in the event of an error for the element.

      ]]>
      tabindex false true title false true The advisory title for this element.

      ]]>
      titleKey false true The message resources key for the advisory title for this element.

      ]]>
      value false true NOTE: When setting this to some value, whether intentional or as the result (for example) of validation errors forcing the user back to the original jsp, this value is ignored by most browsers (for security reasons). This means that your users will have to re-select any previously selected files when submitting the form. Opera web browser will prompt the user so they have a chance to abort the submit.

      Value to which this field should be initialized. [Use the corresponding bean property value or body content (if any) if property is not specified] ]]>
      form org.apache.struts.taglib.html.FormTag JSP Define An Input Form

      Renders an HTML <form> element whose contents are described by the body content of this tag. The form implicitly interacts with the specified request scope or session scope bean to populate the input fields with the current property values from the bean.

      The form bean is located, and created if necessary, based on the form bean specification for the associated ActionMapping.

      ]]>
      action false true The URL to which this form will be submitted. This value is also used to select the ActionMapping we are assumed to be processing, from which we can identify the appropriate form bean and scope. If a value is not provided, the original URI (servletPath) for the request is used.

      If you are using extension mapping for selecting the controller servlet, this value should be equal to the path attribute of the corresponding <action> element, optionally followed by the correct extension suffix.

      If you are using path mapping to select the controller servlet, this value should be exactly equal to the path attribute of the corresponding <action> element.

      ]]>
      acceptCharset false true
      Since:
      Struts 1.2.2
      ]]>
      disabled false true boolean true if the Form's input fields should be disabled.
      Since:
      Struts 1.2.7
      ]]>
      enctype false true focus false true focusIndex false true
      Since:
      Struts 1.1
      ]]>
      method false true onreset false true onsubmit false true readonly false true boolean true if the Form's input fields should be read only.
      Since:
      Struts 1.2.7
      ]]>
      scriptLanguage false true boolean
      Since:
      Struts 1.2
      ]]>
      style false true styleClass false true styleId false true target false true
      frame org.apache.struts.taglib.html.FrameTag Render an HTML frame element

      Renders an HTML <frame> element with processing for the src attribute that is identical to that performed by the <html:link> tag for the href attribute. URL rewriting will be applied automatically, to maintain session state in the absence of cookies.

      The base URL for this frame is calculated based on which of the following attributes you specify (you must specify exactly one of them):

      • forward - Use the value of this attribute as the name of a global ActionForward to be looked up, and use the module-relative or context-relative URI found there.
      • href - Use the value of this attribute unchanged.
      • page - Use the value of this attribute as a module-relative URI, and generate a server-relative URI by including the context path and application prefix.
      • action - Use the value of this attribute as the logical name of a global Action that contains the actual content-relative URI of the destination of this transfer.

      Normally, the hyperlink you specify with one of the attributes described in the previous paragraph will be left unchanged (other than URL rewriting if necessary). However, there are two ways you can append one or more dynamically defined query parameters to the hyperlink -- specify a single parameter with the paramId attribute (and its associated attributes to select the value), or specify the name (and optional property) attributes to select a java.util.Map bean that contains one or more parameter ids and corresponding values.

      To specify a single parameter, use the paramId attribute to define the name of the request parameter to be submitted. To specify the corresponding value, use one of the following approaches:

      • Specify only the paramName attribute - The named JSP bean (optionally scoped by the value of the paramScope attribute) must identify a value that can be converted to a String.
      • Specify both the paramName and paramProperty attributes - The specified property getter method will be called on the JSP bean identified by the paramName (and optional paramScope) attributes, in order to select a value that can be converted to a String.

      If you prefer to specify a java.util.Map that contains all of the request parameters to be added to the hyperlink, use one of the following techniques:

      • Specify only the name attribute - The named JSP bean (optionally scoped by the value of the scope attribute) must identify a java.util.Map containing the parameters.
      • Specify both name and property attributes - The specified property getter method will be called on the bean identified by the name (and optional scope) attributes, in order to return the java.util.Map containing the parameters.

      As the Map is processed, the keys are assumed to be the names of query parameters to be appended to the hyperlink. The value associated with each key must be either a String or a String array representing the parameter value(s), or an object whose toString() method will be called. If a String array is specified, more than one value for the same query parameter name will be created.

      Additionally, you can request that the current transaction control token, if any, be included in the generated hyperlink by setting the transaction attribute to true. You can also request that an anchor ("#xxx") be added to the end of the URL that is created by any of the above mechanisms, by using the anchor attribute.

      ]]>
      bundle false true
      Since:
      Struts 1.2.5
      ]]>
      action false true Logical name of a global Action that contains the actual content-relative URI of the destination of this transfer. This hyperlink may be dynamically modified by the inclusion of query parameters, as described in the tag description. You must specify exactly one of the action attribute, the forward attribute, the href attribute, or the page attribute.

      Additionally, you can specify a module prefix for linking to other modules.

      ]]>
      module false true Prefix name of a Module that contains the action mapping for the Action that is specified by the action attribute. You must specify an action attribute for this to have an effect.

      Note: Use "" to map to the default module.

      ]]>
      anchor false true Optional anchor tag ("#xxx") to be added to the generated hyperlink. Specify this value without any "#" character.

      ]]>
      forward false true Logical name of a global ActionForward that contains the actual content-relative URI of the destination of this transfer. This hyperlink may be dynamically modified by the inclusion of query parameters, as described in the tag description. You must specify exactly one of the action attribute, the forward attribute, the href attribute, or the page attribute.

      ]]>
      frameborder false true Should a frame border be generated around this frame (1) or not (0)?

      ]]>
      frameName false true Value for the name attribute of the rendered <frame> element.

      ]]>
      href false true The URL to which this hyperlink will transfer control if activated. This hyperlink may be dynamically modified by the inclusion of query parameters, as described in the tag description. You must specify exactly one of the action attribute, the forward attribute, the href attribute, or the page attribute.

      ]]>
      longdesc false true URI of a long description of the frame. This description should supplement the short description provided by the title attribute, and may be particularly useful for non-visual user agents.

      ]]>
      marginheight false true java.lang.Integer The amount of space (in pixels) to be left between the frame's contents and its top and bottom margins.

      ]]>
      marginwidth false true java.lang.Integer The amount of space (in pixels) to be left between the frame's contents and its left and right margins.

      ]]>
      name false true The name of a JSP bean that contains a Map representing the query parameters (if property is not specified), or a JSP bean whose property getter is called to return a Map (if property is specified).

      ]]>
      noresize false true boolean Should users be disallowed from resizing the frame? (true, false).

      ]]>
      page false true The module-relative path (beginning with a "/" character) to which this hyperlink will transfer control if activated. This hyperlink may be dynamically modified by the inclusion of query parameters, as described in the tag description. You must specify exactly one of the action attribute, the forward attribute, the href attribute, or the page attribute.

      ]]>
      paramId false true The name of the request parameter that will be dynamically added to the generated hyperlink. The corresponding value is defined by the paramName and (optional) paramProperty attributes, optionally scoped by the paramScope attribute

      ]]>
      paramName false true The name of a JSP bean that is a String containing the value for the request parameter named by paramId (if paramProperty is not specified), or a JSP bean whose property getter is called to return a String (if paramProperty is specified). The JSP bean is constrained to the bean scope specified by the paramScope property, if it is specified.

      ]]>
      paramProperty false true The name of a property of the bean specified by the paramName attribute, whose return value must be a String containing the value of the request parameter (named by the paramId attribute) that will be dynamically added to this hyperlink.

      ]]>
      paramScope false true The scope within which to search for the bean specified by the paramName attribute. If not specified, all scopes are searched.

      ]]>
      property false true The name of a property of the bean specified by the name attribute, whose return value must be a java.util.Map containing the query parameters to be added to the hyperlink. You must specify the name attribute if you specify this attribute.

      ]]>
      scope false true The scope within which to search for the bean specified by the name attribute. If not specified, all scopes are searched.

      ]]>
      scrolling false true Should scroll bars be created unconditionally (yes), never (no), or only when needed (auto)?

      ]]>
      style false true CSS styles to be applied to this element.

      ]]>
      styleClass false true styleId false true title false true The advisory title for this element.

      ]]>
      titleKey false true The message resources key for the advisory title for this element.

      ]]>
      transaction false true boolean If set to true, any current transaction control token will be included in the generated hyperlink, so that it will pass an isTokenValid() test in the receiving Action.

      ]]>
      hidden org.apache.struts.taglib.html.HiddenTag empty Render A Hidden Field

      Renders an HTML <input> element of type hidden, populated from the specified value or the specified property of the bean associated with our current form. This tag is only valid when nested inside a form tag body.

      ]]>
      accesskey false true alt false true The alternate text for this element.

      ]]>
      altKey false true The message resources key of the alternate text for this element.

      ]]>
      bundle false true
      Since:
      Struts 1.2.5
      ]]>
      disabled false true boolean true if this input field should be disabled. ]]> indexed false true boolean logic:iterate tag. If true then name of the html tag will be rendered as "id[34].propertyName". Number in brackets will be generated for every iteration and taken from ancestor logic:iterate tag. ]]> name false true onblur false true onchange false true onclick false true ondblclick false true onfocus false true onkeydown false true onkeypress false true onkeyup false true onmousedown false true onmousemove false true onmouseout false true onmouseover false true onmouseup false true property true true style false true styleClass false true styleId false true title false true The advisory title for this element.

      ]]>
      titleKey false true The message resources key for the advisory title for this element.

      ]]>
      value false true write false true boolean
      html org.apache.struts.taglib.html.HtmlTag JSP Render an HTML <html> Element

      Renders an HTML <html> element with language attributes extracted from the user's current Locale object, if there is one.

      ]]>
      lang false true boolean Accept-Language HTTP header is used. If still not found, the default language for the server is used.
      Since:
      Struts 1.2
      ]]>
      xhtml false true boolean Set to true in order to render xml:lang and xmlns attributes on the generated html element. This also causes all other html tags to render as XHTML 1.0 (the <html:xhtml/> tag has a similar purpose).

      Since:
      Struts 1.1
      ]]>
      image org.apache.struts.taglib.html.ImageTag Render an input tag of type "image"

      Renders an HTML <input> tag of type "image". The base URL for this image is calculated directly based on the value specified in the src or page attributes, or indirectly by looking up a message resource string based on the srcKey or pageKey attributes. You must specify exactly one of these attributes.

      If you would like to obtain the coordinates of the mouse click that submitted this request, see the information below on the property attribute.

      This tag is only valid when nested inside a form tag body.

      ]]>
      accesskey false true The keyboard character used to move focus immediately to this element.

      ]]>
      align false true The alignment option for this image.

      ]]>
      alt false true The alternate text for this image.

      ]]>
      altKey false true The message resources key of the alternate text for this image.

      ]]>
      border false true The width (in pixels) of the border around this image.

      ]]>
      bundle false true The servlet context attribute key for the MessageResources instance to use. If not specified, defaults to the application resources configured for our action servlet.

      ]]>
      disabled false true boolean true if this input field should be disabled. ]]> indexed false true boolean true then name of the html tag will be rendered as "propertyName[34]". Number in brackets will be generated for every iteration and taken from ancestor logic:iterate tag. ]]> locale false true The session attribute key for the Locale used to select internationalized messages. If not specified, defaults to the Struts standard value.

      ]]>
      onblur false true onchange false true onclick false true ondblclick false true onfocus false true onkeydown false true onkeypress false true onkeyup false true onmousedown false true onmousemove false true onmouseout false true onmouseover false true onmouseup false true page false true The module-relative path of the image for this input tag.

      ]]>
      pageKey false true The key of the message resources string specifying the module-relative path of the image for this input tag.

      ]]>
      property false true The property name of this image tag. The parameter names for the request will appear as "property.x" and "property.y", the x and y representing the coordinates of the mouse click for the image. A way of retrieving these values through a form bean is to define getX(), getY(), setX(), and setY() methods, and specify your property as a blank string (property="").

      ]]>
      src false true The source URL of the image for this input tag.

      ]]>
      srcKey false true The key of the message resources string specifying the source URL of the image for this input tag.

      ]]>
      style false true styleClass false true styleId false true tabindex false true title false true The advisory title for this element.

      ]]>
      titleKey false true The message resources key for the advisory title for this element.

      ]]>
      value false true The value that will be submitted if this image button is pressed.

      ]]>
      img org.apache.struts.taglib.html.ImgTag empty Render an HTML img tag

      Renders an HTML <img> element with the image at the specified URL. Like the link tag, URL rewriting will be applied automatically to the value specified in src, page, or action to maintain session state in the absence of cookies. This will allow dynamic generation of an image where the content displayed for this image will be taken from the attributes of this tag.

      The base URL for this image is calculated directly based on the value specified in src, page, or action or page, or indirectly by looking up a message resource string based on the srcKey or pageKey attributes. You must specify exactly one of these attributes.

      Normally, the src, page, or action that you specify will be left unchanged (other than URL rewriting if necessary). However, there are two ways you can append one or more dynamically defined query parameters to the src URL -- specify a single parameter with the paramId attribute (at its associated attributes to select the value), or specify the name (and optional property) attributes to select a java.util.Map bean that contains one or more parameter ids and corresponding values.

      To specify a single parameter, use the paramId attribute to define the name of the request parameter to be submitted. To specify the corresponding value, use one of the following approaches:

      • Specify only the paramName attribute - The named JSP bean (optionally scoped by the value of the paramScope attribute) must identify a value that can be converted to a String.
      • Specify both the paramName and paramProperty attributes - The specified property getter will be called on the JSP bean identified by the paramName (and optional paramScope) attributes, in order to select a value that can be converted to a String.

      If you prefer to specify a java.util.Map that contains all of the request parameters to be added to the hyperlink, use one of the following techniques:

      • Specify only the name attribute - The named JSP bean (optionally scoped by the value of the scope attribute) must identify a java.util.Map containing the parameters.
      • Specify both name and property attributes - The specified property getter method will be called on the bean identified by the name (and optional scope) attributes, in order to return the java.util.Map containing the parameters.

      As the Map is processed, the keys are assumed to be the names of query parameters to be appended to the src URL. The value associated with each key must be either a String or a String array representing the parameter value(s), or an object whose toString() method will be called. If a String array is specified, more than one value for the same query parameter name will be created.

      You can specify the alternate text for this image (which most browsers display as pop-up text block when the user hovers the mouse over this image) either directly, through the alt attribute, or indirectly from a message resources bundle, using the bundle and altKey attributes.

      ]]>
      align false true Where the image is aligned to. Can be one of the following attributes:

      • left - left justify, wrapping text on right
      • right -right justify, wrapping test on left
      • top - aligns the image with the top of the text on the same row
      • middle - aligns the image's vertical center with the text base line
      • bottom - aligns the image with the bottom of the text's base line
      • texttop - aligns the image's top with that of the text font on the same line
      • absmiddle - aligns the image's vertical center with the absolute center of the text
      • absbottom - aligns the image with the absolute bottom of the text font on the same row
      ]]>
      alt false true And alternative text to be displayed in browsers that don't support graphics. Also used often as type of context help over images.

      ]]>
      altKey false true The message resources key of the alternate text for this element.

      ]]>
      border false true The width of the border surrounding the image.

      ]]>
      bundle false true The servlet context attribute key for the MessageResources instance to use. If not specified, defaults to the application resources configured for our action servlet.

      ]]>
      height false true The height of the image being displayed. This parameter is very nice to specify (along with width) to help the browser render the page faster.

      ]]>
      hspace false true The amount of horizontal spacing between the icon and the text. The text may be in the same paragraph, or be wrapped around the image.

      ]]>
      imageName false true The scriptable name to be defined within this page, so that you can reference it with intra-page scripts. In other words, the value specified here will render a "name" element in the generated image tag.

      ]]>
      ismap false true The name of the server-side map that this image belongs to.

      ]]>
      locale false true The name of the request or session Locale attribute used to look up internationalized messages.

      ]]>
      name false true The name of a JSP bean that contains a Map representing the query parameters (if property is not specified), or a JSP bean whose property getter is called to return a Map (if property is specified).

      ]]>
      onclick false true ondblclick false true onkeydown false true JavaScript event handler that is executed when this element receives a key down event.

      ]]>
      onkeypress false true JavaScript event handler that is executed when this element receives a key press event.

      ]]>
      onkeyup false true JavaScript event handler that is executed when this element receives a key up event.

      ]]>
      onmousedown false true onmousemove false true onmouseout false true onmouseover false true onmouseup false true paramId false true The name of the request parameter that will be dynamically added to the generated src URL. The corresponding value is defined by the paramName and (optional) paramProperty attributes, optionally scoped by the paramScope attribute

      ]]>
      page false true The module-relative path, starting with a slash, of the image to be displayed by this tag. The rendered URL for this image will automatically prepend the context path of this web application (in the same manner as the page attribute on the link tag works), in addition to any necessary URL rewriting. You must specify either the page attribute or the src attribute.

      ]]>
      pageKey false true The message key, in the message resources bundle named by the bundle attribute, of the String to be used as the module-relative path for this image.

      ]]>
      action false true The action, starting with a slash, that will render the image to be displayed by this tag. The rendered URL for this image will automatically prepend the context path of this web application (in the same manner as the action attribute on the link tag works), in addition to any necessary URL rewriting. You must specify the action, page attribute or the src attribute.

      Additionally, you can specify a module prefix for linking to other modules.

      ]]>
      module false true Prefix name of a Module that contains the action mapping for the Action that is specified by the action attribute. You must specify an action attribute for this to have an effect.

      Note: Use "" to map to the default module.

      ]]>
      paramName false true The name of a JSP bean that is a String containing the value for the request parameter named by paramId (if paramProperty is not specified), or a JSP bean whose property getter is called to return a String (if paramProperty is specified). The JSP bean is constrained to the bean scope specified by the paramScope property, if it is specified.

      ]]>
      paramProperty false true The name of a property of the bean specified by the paramName attribute, whose return value must be a String containing the value of the request parameter (named by the paramId attribute) that will be dynamically added to this src URL.

      ]]>
      paramScope false true The scope within which to search for the bean specified by the paramName attribute. If not specified, all scopes are searched.

      ]]>
      property false true The name of a property of the bean specified by the name attribute, whose return value must be a java.util.Map containing the query parameters to be added to the src URL. You must specify the name attribute if you specify this attribute.

      ]]>
      scope false true The scope within which to search for the bean specified by the name attribute. If not specified, all scopes are searched.

      ]]>
      src false true The URL to which this image will be transferred from This image may be dynamically modified by the inclusion of query parameters, as described in the tag description. This value will be used unmodified (other than potential URL rewriting) as the value of the "src" attribute in the rendered tag. You must specify either the page attribute or the src attribute.

      ]]>
      srcKey false true The message key, in the message resources bundle named by the bundle attribute, of the String to be used as the URL of this image.

      ]]>
      style false true CSS styles to be applied to this element.

      ]]>
      styleClass false true styleId false true title false true The advisory title for this element.

      ]]>
      titleKey false true The message resources key for the advisory title for this element.

      ]]>
      useLocalEncoding false true boolean If set to true, LocalCharacterEncoding will be used, that is, the characterEncoding set to the HttpServletResponse, as prefered character encoding rather than UTF-8, when URLEncoding is done on parameters of the URL.

      ]]>
      usemap false true The name of the map as defined within this page for mapping hot-spot areas of this image.

      ]]>
      vspace false true The amount of vertical spacing between the icon and the text, above and below.

      ]]>
      width false true The width of the image being displayed. This parameter is very nice to specify (along with height) to help the browser render the page faster.

      ]]>
      javascript org.apache.struts.taglib.html.JavascriptValidatorTag empty Render JavaScript validation based on the validation rules loaded by the ValidatorPlugIn.

      Render JavaScript validation based on the validation rules loaded by the ValidatorPlugIn. The set of validation rules that should be generated is based on the formName attribute passed in, which should match the name attribute of the form element in the xml file.

      The dynamicJavascript and staticJavascript attributes default to true, but if dynamicJavascript is set to true and staticJavascript is set to false then only the dynamic JavaScript will be rendered. If dynamicJavascript is set to false and staticJavascript is set to true then only the static JavaScript will be rendered which can then be put in separate JSP page so the browser can cache the static JavaScript.

      ]]>
      cdata false true If set to "true" and XHTML has been enabled, the JavaScript will be wrapped in a CDATA section to prevent XML parsing. The default is "true" to comply with the W3C's recommendation.

      Since:
      Struts 1.1
      ]]>
      dynamicJavascript false true Whether or not to render the dynamic JavaScript. Defaults to true.

      ]]>
      formName false true The key (form name) to retrieve a specific set of validation rules. If "dynamicJavascript" is set to true and formName is missing or is not recognized by the ValidatorPlugIn, a JspException will be thrown.

      ]]>
      method false true The alternate JavaScript method name to be used instead of the of the default. The default is 'validate' concatenated in front of the key (form name) passed in (ex: validateRegistrationForm).

      ]]>
      page false true int The current page of a set of validation rules if the page attribute for the field element in the xml file is in use.

      ]]>
      scriptLanguage false true boolean
      Since:
      Struts 1.2
      ]]>
      src false true The src attribute's value when defining the html script element.

      ]]>
      staticJavascript false true Whether or not to render the static JavaScript. Defaults to true.

      ]]>
      htmlComment false true Whether or not to enclose the javascript with HTML comments. This attribute is ignored in XHTML mode because the script would be deleted by the XML parser. See the cdata attribute for details on hiding scripts from XML parsers. Defaults to true.

      ]]>
      bundle false true
      Since:
      Struts 1.2.7
      ]]>
      link org.apache.struts.taglib.html.LinkTag Render an HTML anchor or hyperlink

      Renders an HTML <a> element as an anchor definition (if "linkName" is specified) or as a hyperlink to the specified URL. URL rewriting will be applied automatically, to maintain session state in the absence of cookies. The content displayed for this hyperlink will be taken from the body of this tag.

      The base URL for this hyperlink is calculated based on which of the following attributes you specify (you must specify exactly one of them):

      • forward - Use the value of this attribute as the name of a global ActionForward to be looked up, and use the module-relative or context-relative URI found there. If the forward is module-relative then it must point to an action and NOT to a page.
      • action - Use the value of this attribute as the name of a Action to be looked up, and use the module-relative or context-relative URI found there.
      • href - Use the value of this attribute unchanged.
      • page - Use the value of this attribute as a module-relative URI, and generate a server-relative URI by including the context path and module prefix.

      Normally, the hyperlink you specify with one of the attributes described in the previous paragraph will be left unchanged (other than URL rewriting if necessary). However, there are two ways you can append one or more dynamically defined query parameters to the hyperlink -- specify a single parameter with the paramId attribute (and its associated attributes to select the value), or specify the name (and optional property) attributes to select a java.util.Map bean that contains one or more parameter ids and corresponding values.

      To specify a single parameter, use the paramId attribute to define the name of the request parameter to be submitted. To specify the corresponding value, use one of the following approaches:

      • Specify only the paramName attribute - The named JSP bean (optionally scoped by the value of the paramScope attribute) must identify a value that can be converted to a String.
      • Specify both the paramName and paramProperty attributes - The specified property getter method will be called on the JSP bean identified by the paramName (and optional paramScope) attributes, in order to select a value that can be converted to a String.

      If you prefer to specify a java.util.Map that contains all of the request parameters to be added to the hyperlink, use one of the following techniques:

      • Specify only the name attribute - The named JSP bean (optionally scoped by the value of the scope attribute) must identify a java.util.Map containing the parameters.
      • Specify both name and property attributes - The specified property getter method will be called on the bean identified by the name (and optional scope) attributes, in order to return the java.util.Map containing the parameters.

      As the Map is processed, the keys are assumed to be the names of query parameters to be appended to the hyperlink. The value associated with each key must be either a String or a String array representing the parameter value(s), or an object whose toString() method will be called. If a String array is specified, more than one value for the same query parameter name will be created.

      Additionally, you can request that the current transaction control token, if any, be included in the generated hyperlink by setting the transaction attribute to true. You can also request that an anchor ("#xxx") be added to the end of the URL that is created by any of the above mechanisms, by using the anchor attribute.

      ]]>
      accesskey false true The keyboard character used to move focus immediately to this element.

      ]]>
      action false true Logical name of a Action that contains the actual content-relative URI of the destination of this transfer. This hyperlink may be dynamically modified by the inclusion of query parameters, as described in the tag description. You must specify exactly one of the action attribute, the forward attribute, the href attribute, the linkName attribute, or the page attribute.

      Additionally, you can specify a module prefix for linking to other modules.

      ]]>
      module false true Prefix name of a Module that contains the action mapping for the Action that is specified by the action attribute. You must specify an action attribute for this to have an effect.

      Note: Use "" to map to the default module.

      ]]>
      anchor false true Optional anchor tag ("#xxx") to be added to the generated hyperlink. Specify this value without any "#" character.

      ]]>
      forward false true Logical name of a global ActionForward that contains the actual content-relative URI of the destination of this transfer. This hyperlink may be dynamically modified by the inclusion of query parameters, as described in the tag description. You must specify exactly one of the action attribute, the forward attribute, the href attribute, the linkName attribute, or the page attribute.

      ]]>
      href false true The URL to which this hyperlink will transfer control if activated. This hyperlink may be dynamically modified by the inclusion of query parameters, as described in the tag description. You must specify exactly one of the action attribute, the forward attribute, the href attribute, the linkName attribute, or the page attribute.

      ]]>
      indexed false true boolean true then indexed parameter with name from indexId attribute will be added to the query string. Indexed parameter looks like "index[32]". Number in brackets will be generated for every iteration and taken from ancestor logic:iterate tag. ]]> indexId false true bundle false true
      Since:
      Struts 1.2.5
      ]]>
      linkName false true The anchor name to be defined within this page, so that you can reference it with intra-page hyperlinks. In other words, the value specified here will render a "name" element in the generated anchor tag.

      ]]>
      name false true The name of a JSP bean that contains a Map representing the query parameters (if property is not specified), or a JSP bean whose property getter is called to return a Map (if property is specified).

      ]]>
      onblur false true JavaScript event handler that is executed when this element loses input focus.

      ]]>
      onclick false true JavaScript event handler that is executed when this element receives a mouse click.

      ]]>
      ondblclick false true JavaScript event handler that is executed when this element receives a mouse double click.

      ]]>
      onfocus false true JavaScript event handler that is executed when this element receives input focus.

      ]]>
      onkeydown false true JavaScript event handler that is executed when this element receives a key down event.

      ]]>
      onkeypress false true JavaScript event handler that is executed when this element receives a key press event.

      ]]>
      onkeyup false true JavaScript event handler that is executed when this element receives a key up event.

      ]]>
      onmousedown false true JavaScript event handler that is executed when this element receives a mouse down event.

      ]]>
      onmousemove false true JavaScript event handler that is executed when this element receives a mouse move event.

      ]]>
      onmouseout false true JavaScript event handler that is executed when this element receives a mouse out event.

      ]]>
      onmouseover false true JavaScript event handler that is executed when this element receives a mouse over event.

      ]]>
      onmouseup false true JavaScript event handler that is executed when this element receives a mouse up event.

      ]]>
      page false true The module-relative path (beginning with a "/" character) to which this hyperlink will transfer control if activated. This hyperlink may be dynamically modified by the inclusion of query parameters, as described in the tag description. You must specify exactly one of the action attribute, forward attribute, the href attribute, the linkName attribute, or the page attribute.

      ]]>
      paramId false true The name of the request parameter that will be dynamically added to the generated hyperlink. The corresponding value is defined by the paramName and (optional) paramProperty attributes, optionally scoped by the paramScope attribute

      ]]>
      paramName false true The name of a JSP bean that is a String containing the value for the request parameter named by paramId (if paramProperty is not specified), or a JSP bean whose property getter is called to return a String (if paramProperty is specified). The JSP bean is constrained to the bean scope specified by the paramScope property, if it is specified.

      ]]>
      paramProperty false true The name of a property of the bean specified by the paramName attribute, whose return value must be a String containing the value of the request parameter (named by the paramId attribute) that will be dynamically added to this hyperlink.

      ]]>
      paramScope false true The scope within which to search for the bean specified by the paramName attribute. If not specified, all scopes are searched.

      ]]>
      property false true The name of a property of the bean specified by the name attribute, whose return value must be a java.util.Map containing the query parameters to be added to the hyperlink. You must specify the name attribute if you specify this attribute.

      ]]>
      scope false true The scope within which to search for the bean specified by the name attribute. If not specified, all scopes are searched.

      ]]>
      style false true CSS styles to be applied to this element.

      ]]>
      styleClass false true styleId false true tabindex false true The tab order (ascending positive integers) for this element.

      ]]>
      target false true The window target in which the resource requested by this hyperlink will be displayed, for example in a framed presentation.

      ]]>
      title false true The advisory title for this hyperlink.

      ]]>
      titleKey false true The message resources key for the advisory title for this element.

      ]]>
      transaction false true boolean If set to true, any current transaction control token will be included in the generated hyperlink, so that it will pass an isTokenValid() test in the receiving Action.

      ]]>
      useLocalEncoding false true boolean If set to true, LocalCharacterEncoding will be used, that is, the characterEncoding set to the HttpServletResponse, as prefered character encoding rather than UTF-8, when URLEncoding is done on parameters of the URL.

      ]]>
      messages org.apache.struts.taglib.html.MessagesTag org.apache.struts.taglib.html.MessagesTei JSP Conditionally display a set of accumulated messages.

      Displays a set of messages prepared by a business logic component and stored as an ActionMessages object, ActionErrors object, a String, or a String array in any scope. If such a bean is not found, nothing will be rendered. The messages are placed into the page scope in the body of this tag where they can be displayed by standard JSP methods. (For example: <bean:write>,<c:out>)

      In order to use this tag successfully, you must have defined an application scope MessageResources bean under the default attribute name.

      ]]>
      id true false null. ]]> bundle false true locale false true name false true Globals.ERROR_KEY constant string will be used. ]]> property false true header false true footer false true message false true Globals.ERROR_KEY constant string, but if this attribute is set to 'true' the bean will be retrieved from the Globals.MESSAGE_KEY constant string. Also if this is set to 'true', any value assigned to the name attribute will be ignored. ]]>
      multibox org.apache.struts.taglib.html.MultiboxTag Render A Checkbox Input Field

      Renders an HTML <input> element of type checkbox, whose "checked" status is initialized based on whether the specified value matches one of the elements of the underlying property's array of current values. This element is useful when you have large numbers of checkboxes, and prefer to combine the values into a single array-valued property instead of multiple boolean properties. This tag is only valid when nested inside a form tag body.

      WARNING: In order to correctly recognize cases where none of the associated checkboxes are selected, the ActionForm bean associated with this form must include a statement setting the corresponding array to zero length in the reset() method.

      The value to be returned to the server, if this checkbox is selected, must be defined by one of the following methods:

      • Specify a value attribute, whose contents will be used literally as the value to be returned.
      • Specify no value attribute, and the nested body content of this tag will be used as the value to be returned.

      Also note that a map backed attribute cannot be used to hold a the String[] for a group of multibox tags.

      ]]>
      accesskey false true alt false true The alternate text for this element.

      ]]>
      altKey false true The message resources key of the alternate text for this element.

      ]]>
      bundle false true
      Since:
      Struts 1.2.5
      ]]>
      disabled false true boolean true if this input field should be disabled. ]]> errorKey false true Name of the bean (in any scope) under which our error messages have been stored. If not present, the name specified by the Globals.ERROR_KEY constant string will be used.

      N.B. This is used in conjunction with the errorStyle, errorStyleClass and errorStyleId attributes and should be set to the same value as the name attribute on the <html:errors/> tag.

      Since:
      Struts 1.2.5
      ]]>
      errorStyle false true CSS styles to be applied to this HTML element if an error exists for it.

      N.B. If present, this overrides the style attribute in the event of an error.

      Since:
      Struts 1.2.5
      ]]>
      errorStyleClass false true CSS stylesheet class to be applied to this HTML element if an error exists for it (renders a "class" attribute).

      N.B. If present, this overrides the styleClass attribute in the event of an error.

      Since:
      Struts 1.2.5
      ]]>
      errorStyleId false true Identifier to be assigned to this HTML element if an error exists for it (renders an "id" attribute).

      N.B. If present, this overrides the styleId attribute in the event of an error.

      Since:
      Struts 1.2.5
      ]]>
      name false true onblur false true onchange false true onclick false true ondblclick false true onfocus false true onkeydown false true onkeypress false true onkeyup false true onmousedown false true onmousemove false true onmouseout false true onmouseover false true onmouseup false true property true true style false true CSS styles to be applied to this HTML element.

      N.B. If present, the errorStyle overrides this attribute in the event of an error for the element.

      ]]>
      styleClass false true CSS stylesheet class to be applied to this HTML element (renders a "class" attribute).

      N.B. If present, the errorStyleClass overrides this attribute in the event of an error for the element.

      ]]>
      styleId false true Identifier to be assigned to this HTML element (renders an "id" attribute).

      N.B. If present, the errorStyleId overrides this attribute in the event of an error for the element.

      ]]>
      tabindex false true title false true The advisory title for this element.

      ]]>
      titleKey false true The message resources key for the advisory title for this element.

      ]]>
      value false true
      option org.apache.struts.taglib.html.OptionTag Render A Select Option

      Render an HTML <option> element, representing one of the choices for an enclosing <select> element. The text displayed to the user comes from either the body of this tag, or from a message string looked up based on the bundle, locale, and key attributes.

      If the value of the corresponding bean property matches the specified value, this option will be marked selected. This tag is only valid when nested inside a <html:select> tag body.

      ]]>
      bundle false true disabled false true boolean true if this option should be disabled. ]]> key false true bundle for the text displayed to the user for this option. If not specified, the text to be displayed is taken from the body content of this tag. ]]> locale false true key attribute. If not specified, uses the standard Struts session attribute name. ]]> style false true styleId false true styleClass false true value true true
      options org.apache.struts.taglib.html.OptionsTag empty Render a Collection of Select Options

      Renders a set of HTML <option> elements, representing possible choices for a <select> element. This tag can be used multiple times within a single <html:select> element, either in conjunction with or instead of one or more <html:option> or <html:optionsCollection> elements.

      This tag operates in one of two major modes, depending on whether or not the collection attribute is specified. If the collection attribute is included, the following rules apply:

      • The collection attribute is interpreted as the name of a JSP bean, in some scope, that itself represents a collection of individual beans, one per option value to be rendered.
      • The property attribute is interpreted as the name of a property of the individual beans included in the collection, and is used to retrieve the value that will be returned to the server if this option is selected.
      • The labelProperty attribute is interpreted as the name of a property of the individual beans included in the collection, and is used to retrieve the label that will be displayed to the user for this option. If the labelProperty attribute is not specified, the property named by the property attribute will be used to select both the value returned to the server and the label displayed to the user for this option.

      If the collection attribute is not specified, the rules described in the remainder of this section apply.

      The collection of values actually selected depends on the presence or absence of the name and property attributes. The following combinations are allowed:

      • Only name is specified - The value of this attribute is the name of a JSP bean in some scope that is the collection.
      • Only property is specified - The value of this attribute is the name of a property of the ActionForm bean associated with our form, which will return the collection.
      • Both name and property are specified - The value of the name attribute identifies a JSP bean in some scope. The value of the property attribute is the name of some property of that bean which will return the collection.

      The collection of labels displayed to the user can be the same as the option values themselves, or can be different, depending on the presence or absence of the labelName and labelProperty attributes. If this feature is used, the collection of labels must contain the same number of elements as the corresponding collection of values. The following combinations are allowed:

      • Neither labelName nor labelProperty is specified - The labels will be the same as the option values themselves.
      • Only labelName is specified - The value of this attribute is the name of a JSP bean in some scope that is the collection.
      • Only labelProperty is specified - The value of this attribute is the name of a property of the ActionForm bean associated with our form, which will return the collection.
      • Both labelName and labelProperty are specified - The value of the labelName attribute identifies a JSP bean in some scope. The value of the labelProperty attribute is the name of some property of that bean which will return the collection.

      Note that this tag does not support a styleId attribute, as it would have to apply the value to all the option elements created by this element, which would mean that more than one id element might have the same value, which the HTML specification says is illegal.

      ]]>
      collection false true filter false true boolean false if you do NOT want the option labels filtered for sensitive characters in HTML. By default, such values are filtered. ]]> labelName false true labelProperty false true name false true property false true style false true styleClass false true
      optionsCollection org.apache.struts.taglib.html.OptionsCollectionTag empty Render a Collection of Select Options

      Renders a set of HTML <option> elements, representing possible choices for a <select> element. This tag can be used multiple times within a single <html:select> element, either in conjunction with or instead of one or more <html:option> or <html:options> elements.

      This tag operates on a collection of beans, where each bean has a label property and a value property. The actual names of these properties can be configured using the label and value attributes of this tag.

      This tag differs from the <html:options> tag in that it makes more consistent use of the name and property attributes, and allows the collection to be more easily obtained from the enclosing form bean.

      Note that this tag does not support a styleId attribute, as it would have to apply the value to all the option elements created by this element, which would mean that more than one id element might have the same value, which the HTML specification says is illegal.

      ]]>
      filter false true boolean false if you do NOT want the option labels filtered for sensitive characters in HTML. By default, such values are filtered. ]]> label false true name false true property false true style false true styleClass false true value false true
      password org.apache.struts.taglib.html.PasswordTag Render A Password Input Field

      Renders an HTML <input> element of type password, populated from the specified value or the specified property of the bean associated with our current form. This tag is only valid when nested inside a form tag body. ]]>
      accesskey false true alt false true The alternate text for this element.

      ]]>
      altKey false true The message resources key of the alternate text for this element.

      ]]>
      bundle false true
      Since:
      Struts 1.2.5
      ]]>
      disabled false true boolean true if this input field should be disabled. ]]> errorKey false true Name of the bean (in any scope) under which our error messages have been stored. If not present, the name specified by the Globals.ERROR_KEY constant string will be used.

      N.B. This is used in conjunction with the errorStyle, errorStyleClass and errorStyleId attributes and should be set to the same value as the name attribute on the <html:errors/> tag.

      Since:
      Struts 1.2.5
      ]]>
      errorStyle false true CSS styles to be applied to this HTML element if an error exists for it.

      N.B. If present, this overrides the style attribute in the event of an error.

      Since:
      Struts 1.2.5
      ]]>
      errorStyleClass false true CSS stylesheet class to be applied to this HTML element if an error exists for it (renders a "class" attribute).

      N.B. If present, this overrides the styleClass attribute in the event of an error.

      Since:
      Struts 1.2.5
      ]]>
      errorStyleId false true Identifier to be assigned to this HTML element if an error exists for it (renders an "id" attribute).

      N.B. If present, this overrides the styleId attribute in the event of an error.

      Since:
      Struts 1.2.5
      ]]>
      indexed false true boolean true then name of the html tag will be rendered as "id[34].propertyName". Number in brackets will be generated for every iteration and taken from ancestor logic:iterate tag. ]]> maxlength false true name false true onblur false true onchange false true onclick false true ondblclick false true onfocus false true onkeydown false true onkeypress false true onkeyup false true onmousedown false true onmousemove false true onmouseout false true onmouseover false true onmouseup false true property true true readonly false true boolean true if this input field should be read only. ]]> redisplay false true boolean false on login pages. Defaults to true for consistency with all other form tags that redisplay their contents. ]]> style false true CSS styles to be applied to this HTML element.

      N.B. If present, the errorStyle overrides this attribute in the event of an error for the element.

      ]]>
      styleClass false true CSS stylesheet class to be applied to this HTML element (renders a "class" attribute).

      N.B. If present, the errorStyleClass overrides this attribute in the event of an error for the element.

      ]]>
      styleId false true Identifier to be assigned to this HTML element (renders an "id" attribute).

      N.B. If present, the errorStyleId overrides this attribute in the event of an error for the element.

      ]]>
      size false true tabindex false true title false true The advisory title for this element.

      ]]>
      titleKey false true The message resources key for the advisory title for this element.

      ]]>
      value false true
      radio org.apache.struts.taglib.html.RadioTag Render A Radio Button Input Field

      Renders an HTML <input> element of type radio, populated from the specified property of the bean associated with our current form. This tag is only valid when nested inside a form tag body.

      If an iterator is used to render a series of radio tags, the idName attribute may be used to specify the name of the bean exposed by the iterator. In this case, the value attribute is used as the name of a property on the idName bean that returns the value of the radio tag in this iteration.

      ]]>
      accesskey false true alt false true The alternate text for this element.

      ]]>
      altKey false true The message resources key of the alternate text for this element.

      ]]>
      bundle false true
      Since:
      Struts 1.2.5
      ]]>
      disabled false true boolean true if this input field should be disabled. ]]> errorKey false true Name of the bean (in any scope) under which our error messages have been stored. If not present, the name specified by the Globals.ERROR_KEY constant string will be used.

      N.B. This is used in conjunction with the errorStyle, errorStyleClass and errorStyleId attributes and should be set to the same value as the name attribute on the <html:errors/> tag.

      Since:
      Struts 1.2.5
      ]]>
      errorStyle false true CSS styles to be applied to this HTML element if an error exists for it.

      N.B. If present, this overrides the style attribute in the event of an error.

      Since:
      Struts 1.2.5
      ]]>
      errorStyleClass false true CSS stylesheet class to be applied to this HTML element if an error exists for it (renders a "class" attribute).

      N.B. If present, this overrides the styleClass attribute in the event of an error.

      Since:
      Struts 1.2.5
      ]]>
      errorStyleId false true Identifier to be assigned to this HTML element if an error exists for it (renders an "id" attribute).

      N.B. If present, this overrides the styleId attribute in the event of an error.

      Since:
      Struts 1.2.5
      ]]>
      indexed false true boolean true then name of the html tag will be rendered as "id[34].propertyName". Number in brackets will be generated for every iteration and taken from ancestor logic:iterate tag. ]]> name false true onblur false true onchange false true onclick false true ondblclick false true onfocus false true onkeydown false true onkeypress false true onkeyup false true property true true onmousedown false true onmousemove false true onmouseout false true onmouseover false true onmouseup false true style false true CSS styles to be applied to this HTML element.

      N.B. If present, the errorStyle overrides this attribute in the event of an error for the element.

      ]]>
      styleClass false true CSS stylesheet class to be applied to this HTML element (renders a "class" attribute).

      N.B. If present, the errorStyleClass overrides this attribute in the event of an error for the element.

      ]]>
      styleId false true Identifier to be assigned to this HTML element (renders an "id" attribute).

      N.B. If present, the errorStyleId overrides this attribute in the event of an error for the element.

      ]]>
      tabindex false true title false true The advisory title for this element.

      ]]>
      titleKey false true The message resources key for the advisory title for this element.

      ]]>
      value true true idName false true Name of the bean (in some scope) that will return the value of the radio tag. Usually exposed by an iterator. When the idName attribute is present, the value attribute is used as the name of the property on the idName bean that will return the value of the radio tag for this iteration.

      Since:
      Struts 1.1
      ]]>
      reset org.apache.struts.taglib.html.ResetTag Render A Reset Button Input Field

      Renders an HTML <input> element of type reset. ]]>
      accesskey false true alt false true The alternate text for this element.

      ]]>
      altKey false true The message resources key of the alternate text for this element.

      ]]>
      bundle false true
      Since:
      Struts 1.2.5
      ]]>
      disabled false true boolean true if this input field should be disabled. ]]> onblur false true onchange false true onclick false true ondblclick false true onfocus false true onkeydown false true onkeypress false true onkeyup false true onmousedown false true onmousemove false true onmouseout false true onmouseover false true onmouseup false true property false true style false true styleClass false true styleId false true tabindex false true title false true The advisory title for this element.

      ]]>
      titleKey false true The message resources key for the advisory title for this element.

      ]]>
      value false true
      rewrite org.apache.struts.taglib.html.RewriteTag empty Render an URI

      Renders a request URI based on exactly the same rules as the link tag does, but without creating the <a> hyperlink. This value is useful when you want to generate a string constant for use by a JavaScript procedure.

      ]]>
      action false true Logical name of a Action that contains the actual content-relative URI of the destination of this transfer. This hyperlink may be dynamically modified by the inclusion of query parameters, as described in the tag description. You must specify exactly one of the action attribute, the forward attribute, the href attribute, or the page attribute.

      Additionally, you can specify a module prefix for linking to other modules.

      Since:
      Struts 1.2.0
      ]]>
      module false true Prefix name of a Module that contains the action mapping for the Action that is specified by the action attribute. You must specify an action attribute for this to have an effect.

      Note: Use "" to map to the default module.

      ]]>
      anchor false true Optional anchor tag ("#xxx") to be added to the generated hyperlink. Specify this value without any "#" character.

      ]]>
      forward false true Logical name of a global ActionForward that contains the actual content-relative URI of the destination of this transfer. This hyperlink may be dynamically modified by the inclusion of query parameters, as described in the tag description. You must specify exactly one of the action attribute, the forward attribute, the href attribute, or the page attribute.

      ]]>
      href false true The URL to which this hyperlink will transfer control if activated. This hyperlink may be dynamically modified by the inclusion of query parameters, as described in the tag description. You must specify exactly one of the action attribute, the forward attribute, the href attribute, or the page attribute.

      ]]>
      name false true The name of a JSP bean that contains a Map representing the query parameters (if property is not specified), or a JSP bean whose property getter is called to return a Map (if property is specified).

      ]]>
      page false true The module-relative path (beginning with a "/" character) to which this hyperlink will transfer control if activated. This hyperlink may be dynamically modified by the inclusion of query parameters, as described in the tag description. You must specify exactly one of the action attribute, the forward attribute, the href attribute, or the page attribute.

      ]]>
      paramId false true The name of the request parameter that will be dynamically added to the generated hyperlink. The corresponding value is defined by the paramName and (optional) paramProperty attributes, optionally scoped by the paramScope attribute

      ]]>
      paramName false true The name of a JSP bean that is a String containing the value for the request parameter named by paramId (if paramProperty is not specified), or a JSP bean whose property getter is called to return a String (if paramProperty is specified). The JSP bean is constrained to the bean scope specified by the paramScope property, if it is specified.

      ]]>
      paramProperty false true The name of a property of the bean specified by the paramName attribute, whose return value must be a String containing the value of the request parameter (named by the paramId attribute) that will be dynamically added to this hyperlink.

      ]]>
      paramScope false true The scope within which to search for the bean specified by the paramName attribute. If not specified, all scopes are searched.

      ]]>
      property false true The name of a property of the bean specified by the name attribute, whose return value must be a java.util.Map containing the query parameters to be added to the hyperlink. You must specify the name attribute if you specify this attribute.

      ]]>
      scope false true The scope within which to search for the bean specified by the name attribute. If not specified, all scopes are searched.

      ]]>
      transaction false true boolean If set to true, any current transaction control token will be included in the generated hyperlink, so that it will pass an isTokenValid() test in the receiving Action.

      ]]>
      useLocalEncoding false true boolean If set to true, LocalCharacterEncoding will be used, that is, the characterEncoding set to the HttpServletResponse, as prefered character encoding rather than UTF-8, when URLEncoding is done on parameters of the URL.

      ]]>
      select org.apache.struts.taglib.html.SelectTag JSP Render A Select Element

      Renders an HTML <select> element, associated with a bean property specified by our attributes. This tag is only valid when nested inside a form tag body.

      This tag operates in two modes, depending upon the state of the multiple attribute, which affects the data type of the associated property you should use:

      • multiple="true" IS NOT selected - The corresponding property should be a scalar value of any supported data type.
      • multiple="true" IS selected - The corresponding property should be an array of any supported data type.

      WARNING: In order to correctly recognize cases where no selection at all is made, the ActionForm bean associated with this form must include a statement resetting the scalar property to a default value (if multiple is not set), or the array property to zero length (if multiple is set) in the reset() method.

      ]]>
      alt false true The alternate text for this element.

      ]]>
      altKey false true The message resources key of the alternate text for this element.

      ]]>
      bundle false true
      Since:
      Struts 1.2.5
      ]]>
      disabled false true boolean true if this input field should be disabled. ]]> errorKey false true Name of the bean (in any scope) under which our error messages have been stored. If not present, the name specified by the Globals.ERROR_KEY constant string will be used.

      N.B. This is used in conjunction with the errorStyle, errorStyleClass and errorStyleId attributes and should be set to the same value as the name attribute on the <html:errors/> tag.

      Since:
      Struts 1.2.5
      ]]>
      errorStyle false true CSS styles to be applied to this HTML element if an error exists for it.

      N.B. If present, this overrides the style attribute in the event of an error.

      Since:
      Struts 1.2.5
      ]]>
      errorStyleClass false true CSS stylesheet class to be applied to this HTML element if an error exists for it (renders a "class" attribute).

      N.B. If present, this overrides the styleClass attribute in the event of an error.

      Since:
      Struts 1.2.5
      ]]>
      errorStyleId false true Identifier to be assigned to this HTML element if an error exists for it (renders an "id" attribute).

      N.B. If present, this overrides the styleId attribute in the event of an error.

      Since:
      Struts 1.2.5
      ]]>
      indexed false true boolean true then name of the html tag will be rendered as "id[34].propertyName". Number in brackets will be generated for every iteration and taken from ancestor logic:iterate tag. ]]> multiple false true name false true <html:form> tag is utilized. ]]> onblur false true onchange false true onclick false true ondblclick false true onfocus false true onkeydown false true onkeypress false true onkeyup false true onmousedown false true onmousemove false true onmouseout false true onmouseover false true onmouseup false true property true true style false true CSS styles to be applied to this HTML element.

      N.B. If present, the errorStyle overrides this attribute in the event of an error for the element.

      ]]>
      styleClass false true CSS stylesheet class to be applied to this HTML element (renders a "class" attribute).

      N.B. If present, the errorStyleClass overrides this attribute in the event of an error for the element.

      ]]>
      styleId false true Identifier to be assigned to this HTML element (renders an "id" attribute).

      N.B. If present, the errorStyleId overrides this attribute in the event of an error for the element.

      ]]>
      tabindex false true size false true title false true The advisory title for this element.

      ]]>
      titleKey false true The message resources key for the advisory title for this element.

      ]]>
      value false true
      submit org.apache.struts.taglib.html.SubmitTag Render A Submit Button

      Renders an HTML <input> element of type submit.

      If a graphical button is needed (a button with an image), then the image tag is more appropriate.

      ]]>
      accesskey false true alt false true The alternate text for this element.

      ]]>
      altKey false true The message resources key of the alternate text for this element.

      ]]>
      bundle false true
      Since:
      Struts 1.2.5
      ]]>
      disabled false true boolean true if this input field should be disabled. ]]> indexed false true boolean true then name of the html tag will be rendered as "propertyName[34]". Number in brackets will be generated for every iteration and taken from ancestor logic:iterate tag. ]]> onblur false true onchange false true onclick false true ondblclick false true onfocus false true onkeydown false true onkeypress false true onkeyup false true onmousedown false true onmousemove false true onmouseout false true onmouseover false true onmouseup false true property false true style false true styleClass false true styleId false true tabindex false true title false true The advisory title for this element.

      ]]>
      titleKey false true The message resources key for the advisory title for this element.

      ]]>
      value false true
      text org.apache.struts.taglib.html.TextTag Render An Input Field of Type text

      Render an input field of type text. This tag is only valid when nested inside a form tag body.

      ]]>
      accesskey false true The keyboard character used to move focus immediately to this element.

      ]]>
      alt false true The alternate text for this element.

      ]]>
      altKey false true The message resources key of the alternate text for this element.

      ]]>
      bundle false true
      Since:
      Struts 1.2.5
      ]]>
      disabled false true boolean true if this input field should be disabled. ]]> errorKey false true Name of the bean (in any scope) under which our error messages have been stored. If not present, the name specified by the Globals.ERROR_KEY constant string will be used.

      N.B. This is used in conjunction with the errorStyle, errorStyleClass and errorStyleId attributes and should be set to the same value as the name attribute on the <html:errors/> tag.

      Since:
      Struts 1.2.5
      ]]>
      errorStyle false true CSS styles to be applied to this HTML element if an error exists for it.

      N.B. If present, this overrides the style attribute in the event of an error.

      Since:
      Struts 1.2.5
      ]]>
      errorStyleClass false true CSS stylesheet class to be applied to this HTML element if an error exists for it (renders a "class" attribute).

      N.B. If present, this overrides the styleClass attribute in the event of an error.

      Since:
      Struts 1.2.5
      ]]>
      errorStyleId false true Identifier to be assigned to this HTML element if an error exists for it (renders an "id" attribute).

      N.B. If present, this overrides the styleId attribute in the event of an error.

      Since:
      Struts 1.2.5
      ]]>
      indexed false true boolean true then name of the html tag will be rendered as "id[34].propertyName". Number in brackets will be generated for every iteration and taken from ancestor logic:iterate tag. ]]> maxlength false true name false true onblur false true onchange false true onclick false true ondblclick false true onfocus false true onkeydown false true onkeypress false true onkeyup false true onmousedown false true onmousemove false true onmouseout false true onmouseover false true onmouseup false true onselect false true property true true readonly false true boolean true if this input field should be read only. ]]> size false true style false true CSS styles to be applied to this HTML element.

      N.B. If present, the errorStyle overrides this attribute in the event of an error for the element.

      ]]>
      styleClass false true CSS stylesheet class to be applied to this HTML element (renders a "class" attribute).

      N.B. If present, the errorStyleClass overrides this attribute in the event of an error for the element.

      ]]>
      styleId false true Identifier to be assigned to this HTML element (renders an "id" attribute).

      N.B. If present, the errorStyleId overrides this attribute in the event of an error for the element.

      ]]>
      tabindex false true title false true The advisory title for this element.

      ]]>
      titleKey false true The message resources key for the advisory title for this element.

      ]]>
      value false true
      textarea org.apache.struts.taglib.html.TextareaTag Render A Textarea

      Render a textarea element. This tag is only valid when nested inside a form tag body. ]]>
      accesskey false true alt false true The alternate text for this element.

      ]]>
      altKey false true The message resources key of the alternate text for this element.

      ]]>
      bundle false true
      Since:
      Struts 1.2.5
      ]]>
      cols false true disabled false true boolean true if this input field should be disabled. ]]> errorKey false true Name of the bean (in any scope) under which our error messages have been stored. If not present, the name specified by the Globals.ERROR_KEY constant string will be used.

      N.B. This is used in conjunction with the errorStyle, errorStyleClass and errorStyleId attributes and should be set to the same value as the name attribute on the <html:errors/> tag.

      Since:
      Struts 1.2.5
      ]]>
      errorStyle false true CSS styles to be applied to this HTML element if an error exists for it.

      N.B. If present, this overrides the style attribute in the event of an error.

      Since:
      Struts 1.2.5
      ]]>
      errorStyleClass false true CSS stylesheet class to be applied to this HTML element if an error exists for it (renders a "class" attribute).

      N.B. If present, this overrides the styleClass attribute in the event of an error.

      Since:
      Struts 1.2.5
      ]]>
      errorStyleId false true Identifier to be assigned to this HTML element if an error exists for it (renders an "id" attribute).

      N.B. If present, this overrides the styleId attribute in the event of an error.

      Since:
      Struts 1.2.5
      ]]>
      indexed false true boolean true then name of the html tag will be rendered as "id[34].propertyName". Number in brackets will be generated for every iteration and taken from ancestor logic:iterate tag. ]]> name false true onblur false true onchange false true onclick false true ondblclick false true onfocus false true onkeydown false true onkeypress false true onkeyup false true onmousedown false true onmousemove false true onmouseout false true onmouseover false true onmouseup false true onselect false true property true true readonly false true boolean true if this input field should be read only. ]]> rows false true style false true CSS styles to be applied to this HTML element.

      N.B. If present, the errorStyle overrides this attribute in the event of an error for the element.

      ]]>
      styleClass false true CSS stylesheet class to be applied to this HTML element (renders a "class" attribute).

      N.B. If present, the errorStyleClass overrides this attribute in the event of an error for the element.

      ]]>
      styleId false true Identifier to be assigned to this HTML element (renders an "id" attribute).

      N.B. If present, the errorStyleId overrides this attribute in the event of an error for the element.

      ]]>
      tabindex false true title false true The advisory title for this element.

      ]]>
      titleKey false true The message resources key for the advisory title for this element.

      ]]>
      value false true
      xhtml org.apache.struts.taglib.html.XhtmlTag empty Render HTML tags as XHTML

      Using this tag in a page tells all other html taglib tags to render themselves as XHTML 1.0. This is useful when composing pages with JSP includes or Tiles. <html:html xhtml="true"> has a similar effect. This tag has no attributes; you use it like this: <html:xhtml/>.

      Note: Included pages do not inherit the rendering style of the including page. Each JSP fragment or Tile must use this tag to render as XHTML.

      ]]>
      velocity-tools-2.0-src/examples/struts/WEB-INF/tld/struts-logic.tld100644 0 0 217561 11115263033 22472 0ustar 0 0 1.3 1.2 logic http://struts.apache.org/tags-logic Note: Some of the features in this taglib are also available in the JavaServer Pages Standard Tag Library (JSTL). The Struts team encourages the use of the standard tags over the Struts specific tags when possible.

      This tag library contains tags that are useful in managing conditional generation of output text, looping over object collections for repetitive generation of output text, and application flow management.

      For tags that do value comparisons (equal, greaterEqual, greaterThan, lessEqual, lessThan, notEqual), the following rules apply:

      • The specified value is examined. If it can be converted successfully to a double or a long, it is assumed that the ultimate comparison will be numeric (either floating point or integer). Otherwise, a String comparison will be performed.
      • The variable to be compared to is retrieved, based on the selector attribute(s) (cookie, header, name, parameter, property) present on this tag. It will be converted to the appropriate type for the comparison, as determined above.
      • If the specified variable or property returns null, it will be coerced to a zero-length string before the comparison occurs.
      • The specific comparison for this tag will be performed, and the nested body content of this tag will be evaluated if the comparison returns a true result.

      For tags that do substring matching (match, notMatch), the following rules apply:

      • The specified variable is retrieved, based on the selector attribute(s) (cookie, header, name, parameter, property) present on this tag. The variable is converted to a String, if necessary.
      • A request time exception will be thrown if the specified variable cannot be retrieved, or has a null value.
      • The specified value is checked for existence as a substring of the variable, in the position specified by the location attribute, as follows: at the beginning (if location is set to start), at the end (if location is set to end), or anywhere (if location is not specified).

      Many of the tags in this tag library will throw a JspException at runtime when they are utilized incorrectly (such as when you specify an invalid combination of tag attributes). JSP allows you to declare an "error page" in the <%@ page %> directive. If you wish to process the actual exception that caused the problem, it is passed to the error page as a request attribute under key org.apache.struts.action.EXCEPTION.

      ]]>
      empty org.apache.struts.taglib.logic.EmptyTag JSP Evaluate the nested body content of this tag if the requested variable is either null or an empty string.

      This tag evaluates its nested body content only if the specified value is either absent (i.e. null), an empty string (i.e. a java.lang.String with a length of zero), or an empty java.util.Collection or java.util.Map (tested by the .isEmpty() method on the respective interface).

      JSTL: The equivalent JSTL tag is <c:if> using the empty operator. For example,
      <c:if test="${empty sessionScope.myBean.myProperty}"> do something </c:if>

      Since:
      Struts 1.1
      ]]>
      name false true The variable to be compared is the JSP bean specified by this attribute, if property is not specified, or the value of the specified property of this bean, if property is specified.

      ]]>
      property false true The variable to be compared is the property (of the bean specified by the name attribute) specified by this attribute. The property reference can be simple, nested, and/or indexed.

      ]]>
      scope false true The bean scope within which to search for the bean named by the name property, or "any scope" if not specified.

      ]]>
      equal org.apache.struts.taglib.logic.EqualTag JSP Evaluate the nested body content of this tag if the requested variable is equal to the specified value.

      Compares the variable specified by one of the selector attributes against the specified constant value. The nested body content of this tag is evaluated if the variable and value are equal.

      ]]>
      cookie false true The variable to be compared is the value of the cookie whose name is specified by this attribute.

      ]]>
      header false true The variable to be compared is the value of the header whose name is specified by this attribute. The name match is performed in a case insensitive manner.

      ]]>
      name false true The variable to be compared is the JSP bean specified by this attribute, if property is not specified, or the value of the specified property of this bean, if property is specified.

      ]]>
      parameter false true The variable to be compared is the first, or only, value of the request parameter specified by this attribute.

      ]]>
      property false true The variable to be compared is the property (of the bean specified by the name attribute) specified by this attribute. The property reference can be simple, nested, and/or indexed.

      ]]>
      scope false true The bean scope within which to search for the bean named by the name property, or "any scope" if not specified.

      ]]>
      value true true The constant value to which the variable, specified by other attribute(s) of this tag, will be compared.

      ]]>
      forward org.apache.struts.taglib.logic.ForwardTag empty Forward control to the page specified by the specified ActionForward entry.

      Performs a PageContext.forward() or HttpServletResponse.sendRedirect() call for the global ActionForward entry for the specified name. URL rewriting will occur automatically if a redirect is performed.

      ]]>
      name true true The logical name of the global ActionForward entry that identifies the destination, and forwarding approach, to be used. Note: forwarding to Tiles definitions is not supported from this tag. You should forward to them from an Action subclass.

      ]]>
      greaterEqual org.apache.struts.taglib.logic.GreaterEqualTag JSP Evaluate the nested body content of this tag if the requested variable is greater than or equal to the specified value.

      Compares the variable specified by one of the selector attributes against the specified constant value. The nested body content of this tag is evaluated if the variable is greater than or equal to the value.

      ]]>
      cookie false true The variable to be compared is the value of the cookie whose name is specified by this attribute.

      ]]>
      header false true The variable to be compared is the value of the header whose name is specified by this attribute. The name match is performed in a case insensitive manner.

      ]]>
      name false true The variable to be compared is the JSP bean specified by this attribute, if property is not specified, or the value of the specified property of this bean, if property is specified.

      ]]>
      parameter false true The variable to be compared is the first, or only, value of the request parameter specified by this attribute.

      ]]>
      property false true The variable to be compared is the property (of the bean specified by the name attribute) specified by this attribute. The property reference can be simple, nested, and/or indexed.

      ]]>
      scope false true The bean scope within which to search for the bean named by the name property, or "any scope" if not specified.

      ]]>
      value true true The constant value to which the variable, specified by other attribute(s) of this tag, will be compared.

      ]]>
      greaterThan org.apache.struts.taglib.logic.GreaterThanTag JSP Evaluate the nested body content of this tag if the requested variable is greater than the specified value.

      Compares the variable specified by one of the selector attributes against the specified constant value. The nested body content of this tag is evaluated if the variable is greater than the value.

      ]]>
      cookie false true The variable to be compared is the value of the cookie whose name is specified by this attribute.

      ]]>
      header false true The variable to be compared is the value of the header whose name is specified by this attribute. The name match is performed in a case insensitive manner.

      ]]>
      name false true The variable to be compared is the JSP bean specified by this attribute, if property is not specified, or the value of the specified property of this bean, if property is specified.

      ]]>
      parameter false true The variable to be compared is the first, or only, value of the request parameter specified by this attribute.

      ]]>
      property false true The variable to be compared is the property (of the bean specified by the name attribute) specified by this attribute. The property reference can be simple, nested, or indexed.

      ]]>
      scope false true The bean scope within which to search for the bean named by the name property, or "any scope" if not specified.

      ]]>
      value true true The constant value to which the variable, specified by other attribute(s) of this tag, will be compared.

      ]]>
      iterate org.apache.struts.taglib.logic.IterateTag org.apache.struts.taglib.logic.IterateTei JSP Repeat the nested body content of this tag over a specified collection.

      Repeats the nested body content of this tag once for every element of the specified collection, which must be an Iterator, a Collection, a Map (whose values are to be iterated over), or an array. The collection to be iterated over must be specified in one of the following ways:

      • As a runtime expression specified as the value of the collection attribute.
      • As a JSP bean specified by the name attribute.
      • As the property, specified by the property, of the JSP bean specified by the name attribute.

      The collection to be iterated over MUST conform to one of the following requirements in order for iteration to be successful:

      • An array of Java objects or primitives.
      • An implementation of java.util.Collection, including ArrayList and Vector.
      • An implementation of java.util.Enumeration.
      • An implementation of java.util.Iterator.
      • An implementation of java.util.Map, including HashMap, Hashtable, and TreeMap. NOTE - See below for additional information about accessing Maps.

      Normally, each object exposed by the iterate tag is an element of the underlying collection you are iterating over. However, if you iterate over a Map, the exposed object is of type Map.Entry that has two properties:

      • key - The key under which this item is stored in the underlying Map.
      • value - The value that corresponds to this key.

      So, if you wish to iterate over the values of a Hashtable, you would implement code like the following:

      <logic:iterate id="element" name="myhashtable">
      Next element is <bean:write name="element" property="value"/>
      </logic:iterate>

      If the collection you are iterating over can contain null values, the loop will still be performed but no page scope attribute (named by the id attribute) will be created for that loop iteration. You can use the <logic:present> and <logic:notPresent> tags to test for this case.

      ]]>
      collection false true java.lang.Object A runtime expression that evaluates to a collection (conforming to the requirements listed above) to be iterated over.

      ]]>
      id true false The name of a page scope JSP bean that will contain the current element of the collection on each iteration, if it is not null.

      ]]>
      indexId false false The name of a page scope JSP bean that will contain the current index of the collection on each iteration.

      ]]>
      length false true The maximum number of entries (from the underlying collection) to be iterated through on this page. This can be either an integer that directly expresses the desired value, or the name of a JSP bean (in any scope) of type java.lang.Integer that defines the desired value. If not present, there will be no limit on the number of iterations performed.

      ]]>
      name false true The name of the JSP bean containing the collection to be iterated (if property is not specified), or the JSP bean whose property getter returns the collection to be iterated (if property is specified).

      ]]>
      offset false true The zero-relative index of the starting point at which entries from the underlying collection will be iterated through. This can be either an integer that directly expresses the desired value, or the name of a JSP bean (in any scope) of type java.lang.Integer that defines the desired value. If not present, zero is assumed (meaning that the collection will be iterated from the beginning.

      ]]>
      property false true Name of the property, of the JSP bean specified by name, whose getter returns the collection to be iterated.

      ]]>
      scope false true The bean scope within which to search for the bean named by the name property, or "any scope" if not specified.

      ]]>
      type false true Fully qualified Java class name of the element to be exposed through the JSP bean named from the id attribute. If not present, no type conversions will be performed. NOTE: The actual elements of the collection must be assignment-compatible with this class, or a request time ClassCastException will occur.

      ]]>
      lessEqual org.apache.struts.taglib.logic.LessEqualTag JSP Evaluate the nested body content of this tag if the requested variable is less than or equal to the specified value.

      Compares the variable specified by one of the selector attributes against the specified constant value. The nested body content of this tag is evaluated if the variable is less than or equal to the value.

      ]]>
      cookie false true The variable to be compared is the value of the cookie whose name is specified by this attribute.

      ]]>
      header false true The variable to be compared is the value of the header whose name is specified by this attribute. The name match is performed in a case insensitive manner.

      ]]>
      name false true The variable to be compared is the JSP bean specified by this attribute, if property is not specified, or the value of the specified property of this bean, if property is specified.

      ]]>
      parameter false true The variable to be compared is the first, or only, value of the request parameter specified by this attribute.

      ]]>
      property false true The variable to be compared is the property (of the bean specified by the name attribute) specified by this attribute. The property reference can be simple, nested, or indexed.

      ]]>
      scope false true The bean scope within which to search for the bean named by the name property, or "any scope" if not specified.

      ]]>
      value true true The constant value to which the variable, specified by other attribute(s) of this tag, will be compared.

      ]]>
      lessThan org.apache.struts.taglib.logic.LessThanTag JSP Evaluate the nested body content of this tag if the requested variable is less than the specified value.

      Compares the variable specified by one of the selector attributes against the specified constant value. The nested body content of this tag is evaluated if the variable is less than the value.

      ]]>
      cookie false true The variable to be compared is the value of the cookie whose name is specified by this attribute.

      ]]>
      header false true The variable to be compared is the value of the header whose name is specified by this attribute. The name match is performed in a case insensitive manner.

      ]]>
      name false true The variable to be compared is the JSP bean specified by this attribute, if property is not specified, or the value of the specified property of this bean, if property is specified.

      ]]>
      parameter false true The variable to be compared is the first, or only, value of the request parameter specified by this attribute.

      ]]>
      property false true The variable to be compared is the property (of the bean specified by the name attribute) specified by this attribute. The property reference can be simple, nested, and/or indexed.

      ]]>
      scope false true The bean scope within which to search for the bean named by the name property, or "any scope" if not specified.

      ]]>
      value true true The constant value to which the variable, specified by other attribute(s) of this tag, will be compared.

      ]]>
      match org.apache.struts.taglib.logic.MatchTag JSP Evaluate the nested body content of this tag if the specified value is an appropriate substring of the requested variable.

      Matches the variable specified by one of the selector attributes (as a String) against the specified constant value. If the value is a substring (appropriately limited by the location attribute), the nested body content of this tag is evaluated.

      ]]>
      cookie false true The variable to be matched is the value of the cookie whose name is specified by this attribute.

      ]]>
      header false true The variable to be matched is the value of the header whose name is specified by this attribute. The name match is performed in a case insensitive manner.

      ]]>
      location false true If not specified, a match between the variable and the value may occur at any position within the variable string. If specified, the match must occur at the specified location (either start or end) of the variable string.

      ]]>
      name false true The variable to be matched is the JSP bean specified by this attribute, if property is not specified, or the value of the specified property of this bean, if property is specified.

      ]]>
      parameter false true The variable to be matched is the first, or only, value of the request parameter specified by this attribute.

      ]]>
      property false true The variable to be matched is the property (of the bean specified by the name attribute) specified by this attribute. The property reference can be simple, nested, and/or indexed.

      ]]>
      scope false true The bean scope within which to search for the bean named by the name property, or "any scope" if not specified.

      ]]>
      value true true The constant value which is checked for existence as a substring of the specified variable.

      ]]>
      messagesNotPresent org.apache.struts.taglib.logic.MessagesNotPresentTag JSP Generate the nested body content of this tag if the specified message is not present in any scope.

      Evaluates the nested body content of this tag if an ActionMessages object, ActionErrors object, a String, or a String array is not present in any scope. If such a bean is found, nothing will be rendered.

      Since:
      Struts 1.1
      ]]>
      name false true The parameter key used to retrieve the message from page, request, session or application scope.

      ]]>
      property false true Name of the property for which messages should be retrieved. If not specified, all messages (regardless of property) are retrieved.

      ]]>
      message false true By default the tag will retrieve the bean it will iterate over from the Globals.ERROR_KEY constant string, but if this attribute is set to 'true' the bean will be retrieved from the Globals.MESSAGE_KEY constant string. Also if this is set to 'true', any value assigned to the name attribute will be ignored.

      ]]>
      messagesPresent org.apache.struts.taglib.logic.MessagesPresentTag JSP Generate the nested body content of this tag if the specified message is present in any scope.

      Evaluates the nested body content of this tag if an ActionMessages object, ActionErrors object, a String, or a String array is present in any scope. If such a bean is not found, nothing will be rendered.

      Since:
      Struts 1.1
      ]]>
      name false true The parameter key used to retrieve the message from page, request, session, or application scope.

      ]]>
      property false true Name of the property for which messages should be retrieved. If not specified, all messages (regardless of property) are retrieved.

      ]]>
      message false true By default the tag will retrieve the bean it will iterate over from the Globals.ERROR_KEY constant string, but if this attribute is set to 'true' the bean will be retrieved from the Globals.MESSAGE_KEY constant string. Also if this is set to 'true', any value assigned to the name attribute will be ignored.

      ]]>
      notEmpty org.apache.struts.taglib.logic.NotEmptyTag JSP Evaluate the nested body content of this tag if the requested variable is neither null, nor an empty string, nor an empty java.util.Collection (tested by the .isEmpty() method on the java.util.Collection interface).

      This tag evaluates its nested body content only if the specified value is present (i.e. not null) and is not an empty string (i.e. a java.lang.String with a length of zero).

      JSTL: The equivalent JSTL tag is <c:if> using the ! empty operator. For example,
      <c:if test="${ ! empty sessionScope.myBean.myProperty}"> do something </c:if>

      ]]>
      name false true The variable to be compared is the JSP bean specified by this attribute, if property is not specified, or the value of the specified property of this bean, if property is specified.

      ]]>
      property false true The variable to be compared is the property (of the bean specified by the name attribute) specified by this attribute. The property reference can be simple, nested, and/or indexed.

      ]]>
      scope false true The bean scope within which to search for the bean named by the name property, or "any scope" if not specified.

      ]]>
      notEqual org.apache.struts.taglib.logic.NotEqualTag JSP Evaluate the nested body content of this tag if the requested variable is not equal to the specified value.

      Compares the variable specified by one of the selector attributes against the specified constant value. The nested body content of this tag is evaluated if the variable and value are not equal.

      ]]>
      cookie false true The variable to be compared is the value of the cookie whose name is specified by this attribute.

      ]]>
      header false true The variable to be compared is the value of the header whose name is specified by this attribute. The name match is performed in a case insensitive manner.

      ]]>
      name false true The variable to be compared is the JSP bean specified by this attribute, if property is not specified, or the value of the specified property of this bean, if property is specified.

      ]]>
      parameter false true The variable to be compared is the first, or only, value of the request parameter specified by this attribute.

      ]]>
      property false true The variable to be compared is the property (of the bean specified by the name attribute) specified by this attribute. The property reference can be simple, nested, and/or indexed.

      ]]>
      scope false true The bean scope within which to search for the bean named by the name property, or "any scope" if not specified.

      ]]>
      value true true The constant value to which the variable, specified by other attribute(s) of this tag, will be compared.

      ]]>
      notMatch org.apache.struts.taglib.logic.NotMatchTag JSP Evaluate the nested body content of this tag if the specified value is not an appropriate substring of the requested variable.

      Matches the variable specified by one of the selector attributes (as a String) against the specified constant value. If the value is not a substring (appropriately limited by the location attribute), the nested body content of this tag is evaluated.

      ]]>
      cookie false true The variable to be matched is the value of the cookie whose name is specified by this attribute.

      ]]>
      header false true The variable to be matched is the value of the header whose name is specified by this attribute. The name match is performed in a case insensitive manner.

      ]]>
      location false true If not specified, a match between the variable and the value may occur at any position within the variable string. If specified, the match must occur at the specified location (either start or end) of the variable string.

      ]]>
      name false true The variable to be matched is the JSP bean specified by this attribute, if property is not specified, or the value of the specified property of this bean, if property is specified.

      ]]>
      parameter false true The variable to be matched is the first, or only, value of the request parameter specified by this attribute.

      ]]>
      property false true The variable to be matched is the property (of the bean specified by the name attribute) specified by this attribute. The property reference can be simple, nested, and/or indexed.

      ]]>
      scope false true The bean scope within which to search for the bean named by the name property, or "any scope" if not specified.

      ]]>
      value true true The constant value which is checked for existence as a substring of the specified variable.

      ]]>
      notPresent org.apache.struts.taglib.logic.NotPresentTag JSP Generate the nested body content of this tag if the specified value is not present in this request.

      Depending on which attribute is specified, this tag checks the current request, and evaluates the nested body content of this tag only if the specified value is not present. Only one of the attributes may be used in one occurrence of this tag, unless you use the property attribute, in which case the name attribute is also required.

      ]]>
      cookie false true Checks for the existence of a cookie with the specified name.

      ]]>
      header false true Checks for the existence of an HTTP header with the specified name. The name match is performed in a case insensitive manner.

      ]]>
      name false true Checks for the existence of a JSP bean, in any scope, with the specified name. If property is also specified, checks for a non-null property value for the specified property.

      ]]>
      parameter false true Checks for the existence of at least one occurrence of the specified request parameter on this request, even if the parameter value is a zero-length string.

      ]]>
      property false true Checks for the existence of a non-null property value, returned by a property getter method on the JSP bean (in any scope) that is specified by the name attribute. Property references can be simple, nested, and/or indexed.

      ]]>
      role false true Checks whether the currently authenticated user (if any) has been associated with the specified security role.

      ]]>
      scope false true The bean scope within which to search for the bean named by the name property, or "any scope" if not specified.

      ]]>
      user false true Checks whether the currently authenticated user principal has the specified name.

      ]]>
      present org.apache.struts.taglib.logic.PresentTag JSP Generate the nested body content of this tag if the specified value is present in this request.

      Depending on which attribute is specified, this tag checks the current request, and evaluates the nested body content of this tag only if the specified value is present. Only one of the attributes may be used in one occurrence of this tag, unless you use the property attribute, in which case the name attribute is also required.

      ]]>
      cookie false true Checks for the existence of a cookie with the specified name.

      ]]>
      header false true Checks for the existence of an HTTP header with the specified name. The name match is performed in a case insensitive manner.

      ]]>
      name false true Checks for the existence of a JSP bean, in any scope, with the specified name. If property is also specified, checks for a non-null property value for the specified property.

      ]]>
      parameter false true Checks for the existence of at least one occurrence of the specified request parameter on this request, even if the parameter value is a zero-length string.

      ]]>
      property false true Checks for the existence of a non-null property value, returned by a property getter method on the JSP bean (in any scope) that is specified by the name attribute. Property references can be simple, nested, and/or indexed.

      ]]>
      role false true Checks whether the currently authenticated user (if any) has been associated with any of the specified security roles. Use a comma-delimited list to check for multiple roles. Example: <logic:present role="role1,role2,role3"> code..... </logic:present>

      ]]>
      scope false true The bean scope within which to search for the bean named by the name property, or "any scope" if not specified.

      ]]>
      user false true Checks whether the currently authenticated user principal has the specified name.

      ]]>
      redirect org.apache.struts.taglib.logic.RedirectTag Render an HTTP Redirect

      Performs an HttpServletResponse.sendRedirect() call to the hyperlink specified by the attributes to this tag. URL rewriting will be applied automatically, to maintain session state in the absence of cookies.

      The base URL for this redirect is calculated based on which of the following attributes you specify (you must specify exactly one of them):

      • forward - Use the value of this attribute as the name of a global ActionForward to be looked up, and use the module-relative or context-relative URI found there.
      • href - Use the value of this attribute unchanged.
      • page - Use the value of this attribute as an module-relative URI, and generate a server-relative URI by including the context path.

      Normally, the redirect you specify with one of the attributes described in the previous paragraph will be left unchanged (other than URL rewriting if necessary). However, there are two ways you can append one or more dynamically defined query parameters to the hyperlink -- specify a single parameter with the paramId attribute (and its associated attributes to select the value), or specify the name (and optional property) attributes to select a java.util.Map bean that contains one or more parameter ids and corresponding values.

      To specify a single parameter, use the paramId attribute to define the name of the request parameter to be submitted. To specify the corresponding value, use one of the following approaches:

      • Specify only the paramName attribute - The named JSP bean (optionally scoped by the value of the paramScope attribute) must identify a value that can be converted to a String.
      • Specify both the paramName and paramProperty attributes - The specified property getter method will be called on the JSP bean identified by the paramName (and optional paramScope) attributes, in order to select a value that can be converted to a String.

      If you prefer to specify a java.util.Map that contains all of the request parameters to be added to the hyperlink, use one of the following techniques:

      • Specify only the name attribute - The named JSP bean (optionally scoped by the value of the scope attribute) must identify a java.util.Map containing the parameters.
      • Specify both name and property attributes - The specified property getter method will be called on the bean identified by the name (and optional scope) attributes, in order to return the java.util.Map containing the parameters.

      As the Map is processed, the keys are assumed to be the names of query parameters to be appended to the hyperlink. The value associated with each key must be either a String or a String array representing the parameter value(s). If a String array is specified, more than one value for the same query parameter name will be created.

      ]]>
      action false true Logical name of a global Action that contains the actual content-relative URI of the destination of this transfer. This hyperlink may be dynamically modified by the inclusion of query parameters, as described in the tag description. You must specify exactly one of the action attribute, the forward attribute, the href attribute, or the page attribute.

      ]]>
      anchor false true Optional anchor tag ("#xxx") to be added to the generated hyperlink. Specify this value without any "#" character.

      ]]>
      forward false true Logical name of a global ActionForward that contains the actual content-relative URI of the destination of this redirect. This URI may be dynamically modified by the inclusion of query parameters, as described in the tag description. You must specify exactly one of the forward attribute, the href attribute, the linkName attribute, or the page attribute.

      ]]>
      href false true The URL to which this redirect will transfer control. This URL may be dynamically modified by the inclusion of query parameters, as described in the tag description. You must specify exactly one of the forward attribute, the href attribute, the linkName attribute, or the page attribute.

      ]]>
      name false true The name of a JSP bean that contains a Map representing the query parameters (if property is not specified), or a JSP bean whose property getter is called to return a Map (if property is specified).

      ]]>
      page false true The context-relative path (beginning with a "/" character) to which this hyperlink will transfer control if activated. This hyperlink may be dynamically modified by the inclusion of query parameters, as described in the tag description. You must specify exactly one of the forward attribute, the href attribute, the linkName attribute, or the page attribute.

      ]]>
      paramId false true The name of the request parameter that will be dynamically added to the generated hyperlink. The corresponding value is defined by the paramName and (optional) paramProperty attributes, optionally scoped by the paramScope attribute

      ]]>
      paramName false true The name of a JSP bean that is a String containing the value for the request parameter named by paramId (if paramProperty is not specified), or a JSP bean whose property getter is called to return a String (if paramProperty is specified). The JSP bean is constrained to the bean scope specified by the paramScope property, if it is specified.

      ]]>
      paramProperty false true The name of a property of the bean specified by the paramName attribute, whose return value must be a String containing the value of the request parameter (named by the paramId attribute) that will be dynamically added to this hyperlink.

      ]]>
      paramScope false true The scope within which to search for the bean specified by the paramName attribute. If not specified, all scopes are searched.

      ]]>
      property false true The name of a property of the bean specified by the name attribute, whose return value must be a java.util.Map containing the query parameters to be added to the hyperlink. You must specify the name attribute if you specify this attribute.

      ]]>
      scope false true The scope within which to search for the bean specified by the name attribute. If not specified, all scopes are searched.

      ]]>
      transaction false true boolean Set to true if you want the current transaction control token included in the generated URL for this redirect.

      ]]>
      useLocalEncoding false true boolean If set to true, LocalCharacterEncoding will be used, that is, the characterEncoding set to the HttpServletResponse, as prefered character encoding rather than UTF-8, when URLEncoding is done on parameters of the URL.

      ]]>
      velocity-tools-2.0-src/examples/struts/WEB-INF/tld/struts-nested.tld100644 0 0 447100 11115263033 22651 0ustar 0 0 1.3 1.2 nested http://struts.apache.org/tags-nested [Since Struts 1.1]

      This tag library brings a nested context to the functionality of the Struts custom tag library.

      It's written in a layer that extends the current Struts tags, building on their logic and functionality. The layer enables the tags to be aware of the tags which surround them so they can correctly provide the nesting property reference to the Struts system.

      It's all about nesting beans...
      A bean holds a reference to another bean internally, and all access to that bean is handled through the current bean. This act of having one bean's access go through another bean is known as "nesting beans". The first bean is known as the parent bean. The bean which it references, is known as a child bean. The terms "parent" and "child" are commonly used to describe the model's hierarchy.

      A simple example...
      Take an object which represents a monkey. The monkey's job is to pick bunches of bananas. On each bunch picked hangs many bananas. If this case was translated to bean objects, the monkey object would have a reference to the bunch objects he picked, and each bunch object would hold a reference to the bananas hanging in the bunch.

      To describe this...
      The monkey object is the parent to the bunch object, and the bunch object is a child of the monkey object. The bunch object is parent to its child banana objects, and the child banana objects children of the bunch object. The monkey is higher in the hierarchy than the bananas, and the bananas lower in the hierarchy to the bunches.

      One special term to remember is for the most parent class, which is known as the "root" object which starts the hierarchy.

      Nested tags are all about efficiently managing this style of hierarchy structure within your JSP markup.

      Important Note: Nearly all these tags extend tags from other libraries to bring their functionality into the nested context. Nesting relies on the tags working against the one bean model, and managing the properties so that they become relative to the properties they are nested within. In doing so, the tags will set the "name" attribute internally (where applicable), and in many cases will rely on the "property" attribute being set so it can be updated internally to become nested. The original tags on occasion provide options that don't use the "name" and "property" attributes. These uses will then fall outside the nested context, and will most likely cause error. To take advantage of these options, markup using the original tag for these cases. For an example see the <nested:options> tag.

      ]]>
      nest org.apache.struts.taglib.nested.NestedPropertyTag JSP Defines a new level of nesting for child tags to reference to

      This tag provides a simple method of defining a logical nesting level in the nested hierarchy. It run no explicit logic, is simply a place holder. It also means you can remove the need for explicit setting of level properties in child tags.

      Just as the iterate tag provide a parent to other tags, this does the same but there is no logic for iterating or otherwise.

      Example...

      <nested:write property="myNestedLevel.propertyOne" />
      <nested:write property="myNestedLevel.propertyTwo" />
      <nested:write property="myNestedLevel.propertyThree" />
            

      Can instead become...

      <nested:nest property="myNestedLevel" >
        <nested:write property="propertyOne" />
        <nested:write property="propertyTwo" />
        <nested:write property="propertyThree" />
      </nested:nest >
            
      ]]>
      property false true
      writeNesting org.apache.struts.taglib.nested.NestedWriteNestingTag org.apache.struts.taglib.nested.NestedWriteNestingTei JSP Writes or makes a scripting variable of the current nesting level.

      This tag provides a way of accessing the nested property reference used by the nested tags. Can expose a scripting variable, or simply write out the value. ]]>
      property false true id false true id is supplied, then what would have been written out into the response stream, will instead be made available as a String object defined by the variable name provided. ]]> filter false true boolean
      root org.apache.struts.taglib.nested.NestedRootTag JSP To start off a nested hierarchy without the need for a form

      This tag is provided to allow the nested tags to find a common bean reference without the need for a form and its relative overhead. As long as the name attribute of this tag matches the name of a bean in scope of the JSP (ie: Struts tags can find it via usual means). For example you can load a bean for use with the jsp:useBean tag.

      The tag can also be used without specifying the name attribute, but this is only in the case that the current JSP is a dynamic include specified in another file. You will not be able to run the tag without a name unless this inclusion is in place. Otherwise the nested tags will not have the bean and property references that they need to provide their logic.

      Note: The access to a bean via the name attribute takes priority over looking for the reference from other parent tags. So if a name is specified, a bean will have to be there waiting for it. It was made this way so that you could use separate beans within a JSP that itself is an inclusion into another.

      ]]>
      name false true
      define org.apache.struts.taglib.nested.bean.NestedDefineTag org.apache.struts.taglib.nested.bean.NestedDefineTei empty Nested Extension - Define a scripting variable based on the value(s) of the specified bean property.

      This tag is an extension of the <bean:define> tag. Please consult its documentation for information on tag attributes and usage details.

      ]]>
      id true true name false true property false true scope false true toScope false true type false true value false true
      message org.apache.struts.taglib.nested.bean.NestedMessageTag empty Nested Extension - Render an internationalized message string to the response.

      This tag is an extension of the <bean:message> tag. Please consult its documentation for information on tag attributes and usage details.

      ]]>
      arg0 false true arg1 false true arg2 false true arg3 false true arg4 false true bundle false true key false true locale false true name false true property false true scope false true
      size org.apache.struts.taglib.nested.bean.NestedSizeTag org.apache.struts.taglib.bean.SizeTei empty Nested Extension - Define a bean containing the number of elements in a Collection or Map.

      This tag is an extension of the <bean:size> tag. Please consult its documentation for information on tag attributes and usage details.

      ]]>
      collection false true java.lang.Object id true true name false true property false true scope false true
      write org.apache.struts.taglib.nested.bean.NestedWriteTag empty Nested Extension - Render the value of the specified bean property to the current JspWriter.

      This tag is an extension of the <bean:write> tag. Please consult its documentation for information on tag attributes and usage details.

      ]]>
      bundle false true filter false true boolean format false true formatKey false true ignore false true boolean locale false true name false true property false true scope false true
      checkbox org.apache.struts.taglib.nested.html.NestedCheckboxTag Nested Extension - Render A Checkbox Input Field

      This tag is an extension of the <html:checkbox> tag. Please consult its documentation for information on tag attributes and usage details.

      ]]>
      accesskey false true alt false true altKey false true bundle false true
      Since:
      Struts 1.2.7
      ]]>
      disabled false true boolean errorKey false true
      Since:
      Struts 1.2.5
      ]]>
      errorStyle false true
      Since:
      Struts 1.2.5
      ]]>
      errorStyleClass false true
      Since:
      Struts 1.2.5
      ]]>
      errorStyleId false true
      Since:
      Struts 1.2.5
      ]]>
      indexed false true boolean name false true onblur false true onchange false true onclick false true ondblclick false true onfocus false true onkeydown false true onkeypress false true onkeyup false true onmousedown false true onmousemove false true onmouseout false true onmouseover false true onmouseup false true property true true style false true styleClass false true styleId false true tabindex false true title false true titleKey false true value false true
      errors org.apache.struts.taglib.nested.html.NestedErrorsTag empty Nested Extension - Conditionally display a set of accumulated error messages.

      This tag is an extension of the <html:errors> tag. Please consult its documentation for information on tag attributes and usage details.

      ]]>
      bundle false true footer false true
      Since:
      Struts 1.2.5
      ]]>
      header false true
      Since:
      Struts 1.2.5
      ]]>
      locale false true name false true prefix false true
      Since:
      Struts 1.2.5
      ]]>
      property false true suffix false true
      Since:
      Struts 1.2.5
      ]]>
      file org.apache.struts.taglib.nested.html.NestedFileTag Nested Extension - Render A File Select Input Field

      This tag is an extension of the <html:file> tag. Please consult its documentation for information on tag attributes and usage details.

      ]]>
      accesskey false true accept false true alt false true altKey false true bundle false true
      Since:
      Struts 1.2.7
      ]]>
      disabled false true boolean errorKey false true
      Since:
      Struts 1.2.5
      ]]>
      errorStyle false true
      Since:
      Struts 1.2.5
      ]]>
      errorStyleClass false true
      Since:
      Struts 1.2.5
      ]]>
      errorStyleId false true
      Since:
      Struts 1.2.5
      ]]>
      indexed false true boolean maxlength false true name false true onblur false true onchange false true onclick false true ondblclick false true onfocus false true onkeydown false true onkeypress false true onkeyup false true onmousedown false true onmousemove false true onmouseout false true onmouseover false true onmouseup false true property true true size false true style false true styleClass false true styleId false true tabindex false true title false true titleKey false true value false true
      form org.apache.struts.taglib.nested.html.NestedFormTag JSP Nested Extension - Define An Input Form

      This tag is an extension of the <html:form> tag. Please consult its documentation for information on tag attributes and usage details.

      ]]>
      action true true acceptCharset false true disabled false true boolean
      Since:
      Struts 1.2.7
      ]]>
      enctype false true focus false true focusIndex false true method false true onreset false true onsubmit false true readonly false true boolean
      Since:
      Struts 1.2.7
      ]]>
      scriptLanguage false true boolean style false true styleClass false true styleId false true target false true
      hidden org.apache.struts.taglib.nested.html.NestedHiddenTag Nested Extension - Render A Hidden Field

      This tag is an extension of the <html:hidden> tag. Please consult its documentation for information on tag attributes and usage details.

      ]]>
      alt false true altKey false true indexed false true boolean name false true property true true title false true titleKey false true styleClass false true styleId false true value false true write false true boolean
      image org.apache.struts.taglib.nested.html.NestedImageTag Nested Extension - Render an input tag of type "image"

      This tag is an extension of the <html:image> tag. Please consult its documentation for information on tag attributes and usage details.

      ]]>
      accesskey false true align false true alt false true altKey false true border false true bundle false true disabled false true boolean indexed false true boolean locale false true onblur false true onchange false true onclick false true ondblclick false true onfocus false true onkeydown false true onkeypress false true onkeyup false true onmousedown false true onmousemove false true onmouseout false true onmouseover false true onmouseup false true page false true pageKey false true property false true src false true srcKey false true style false true styleClass false true tabindex false true title false true titleKey false true value false true
      img org.apache.struts.taglib.nested.html.NestedImgTag empty Nested Extension - Render an HTML "img" tag

      This tag is an extension of the <html:img> tag. Please consult its documentation for information on tag attributes and usage details.

      ]]>
      accesskey false true align false true alt false true altKey false true border false true bundle false true height false true hspace false true imageName false true ismap false true locale false true name false true onkeydown false true onkeypress false true onkeyup false true paramId false true page false true pageKey false true action false true module false true paramName false true paramProperty false true paramScope false true property false true scope false true src false true srcKey false true style false true styleClass false true styleId false true title false true titleKey false true useLocalEncoding false true boolean usemap false true vspace false true width false true
      link org.apache.struts.taglib.nested.html.NestedLinkTag Nested Extension - Render an HTML anchor or hyperlink

      This tag is an extension of the <html:link> tag. Please consult its documentation for information on tag attributes and usage details.

      ]]>
      accesskey false true action false true module false true anchor false true forward false true href false true indexed false true boolean indexId false true bundle false true
      Since:
      Struts 1.2.7
      ]]>
      linkName false true name false true onblur false true onclick false true ondblclick false true onfocus false true onkeydown false true onkeypress false true onkeyup false true onmousedown false true onmousemove false true onmouseout false true onmouseover false true onmouseup false true page false true paramId false true paramName false true paramProperty false true paramScope false true property false true scope false true style false true styleClass false true styleId false true tabindex false true target false true title false true titleKey false true transaction false true boolean useLocalEncoding false true boolean
      messages org.apache.struts.taglib.nested.html.NestedMessagesTag org.apache.struts.taglib.html.MessagesTei JSP Nested Extension - Conditionally display a set of accumulated messages.

      This tag is an extension of the <html:messages> tag. Please consult its documentation for information on tag attributes and usage details.

      ]]>
      id true true bundle false true locale false true name false true property false true header false true footer false true message false true
      multibox org.apache.struts.taglib.nested.html.NestedMultiboxTag Nested Extension - Render A Checkbox Input Field

      This tag is an extension of the <html:multibox> tag. Please consult its documentation for information on tag attributes and usage details.

      ]]>
      accesskey false true alt false true altKey false true bundle false true
      Since:
      Struts 1.2.7
      ]]>
      disabled false true boolean errorKey false true
      Since:
      Struts 1.2.5
      ]]>
      errorStyle false true
      Since:
      Struts 1.2.5
      ]]>
      errorStyleClass false true
      Since:
      Struts 1.2.5
      ]]>
      errorStyleId false true
      Since:
      Struts 1.2.5
      ]]>
      name false true onblur false true onchange false true onclick false true ondblclick false true onfocus false true onkeydown false true onkeypress false true onkeyup false true onmousedown false true onmousemove false true onmouseout false true onmouseover false true onmouseup false true property true true style false true styleClass false true styleId false true tabindex false true title false true titleKey false true value false true
      options org.apache.struts.taglib.nested.html.NestedOptionsTag empty Nested Extension - Render a Collection of Select Options

      This tag is an extension of the <html:options> tag. Please consult its documentation for information on tag attributes and usage details.

      Note: The nested context of this tag relies on the use of the "property" property, and the internal use of the "name" property. The nested tags rely on these properties and will attempt to set them itself. The <html:options> tag this tag extended allows other options for the tag which don't use these properties. To take advantage of these options, markup using the <html:options> tag instead of the nested tag.

      For example, the "collections" option allows you to specify a separate bean reference which itself is a list of objects with properties to access the title and value parts of the html option tag. You can use this in a nested context (the list is a property of a nested bean) by using the nested define tag and the original options tag.

      <nested:nest property="myNestedLevel" />
        <nested:define property="collectionList" />
        <html:options collection="collectionList"
                        property="valueProperty"
                   labelProperty="labelProperty" />
      </nested:nest >
      
      ]]>
      collection false true java.lang.String filter false true boolean labelName false true labelProperty false true name false true property false true style false true styleClass false true
      optionsCollection org.apache.struts.taglib.nested.html.NestedOptionsCollectionTag empty Nested Extension - Render a Collection of Select Options

      This tag is an extension of the <html:optionsCollection> tag. Please consult its documentation for information on tag attributes and usage details.

      ]]>
      filter false true boolean label false true name false true property true true style false true styleClass false true value false true
      password org.apache.struts.taglib.nested.html.NestedPasswordTag Nested Extension - Render A Password Input Field

      This tag is an extension of the <html:password> tag. Please consult its documentation for information on tag attributes and usage details.

      ]]>
      accesskey false true alt false true altKey false true bundle false true
      Since:
      Struts 1.2.7
      ]]>
      disabled false true boolean errorKey false true
      Since:
      Struts 1.2.5
      ]]>
      errorStyle false true
      Since:
      Struts 1.2.5
      ]]>
      errorStyleClass false true
      Since:
      Struts 1.2.5
      ]]>
      errorStyleId false true
      Since:
      Struts 1.2.5
      ]]>
      indexed false true boolean maxlength false true name false true onblur false true onchange false true onclick false true ondblclick false true onfocus false true onkeydown false true onkeypress false true onkeyup false true onmousedown false true onmousemove false true onmouseout false true onmouseover false true onmouseup false true property true true readonly false true boolean redisplay false true boolean style false true styleClass false true styleId false true size false true tabindex false true title false true titleKey false true value false true
      radio org.apache.struts.taglib.nested.html.NestedRadioTag Nested Extension - Render A Radio Button Input Field

      This tag is an extension of the <html:radio> tag. Please consult its documentation for information on tag attributes and usage details.

      ]]>
      accesskey false true alt false true altKey false true bundle false true
      Since:
      Struts 1.2.7
      ]]>
      disabled false true boolean errorKey false true
      Since:
      Struts 1.2.5
      ]]>
      errorStyle false true
      Since:
      Struts 1.2.5
      ]]>
      errorStyleClass false true
      Since:
      Struts 1.2.5
      ]]>
      errorStyleId false true
      Since:
      Struts 1.2.5
      ]]>
      indexed false true boolean name false true onblur false true onchange false true onclick false true ondblclick false true onfocus false true onkeydown false true onkeypress false true onkeyup false true property true true onmousedown false true style false true styleClass false true styleId false true tabindex false true title false true titleKey false true value true true idName false true
      select org.apache.struts.taglib.nested.html.NestedSelectTag JSP Nested Extension - Render A Select Element

      This tag is an extension of the <html:select> tag. Please consult its documentation for information on tag attributes and usage details.

      ]]>
      accesskey false true alt false true altKey false true bundle false true
      Since:
      Struts 1.2.7
      ]]>
      disabled false true boolean errorKey false true
      Since:
      Struts 1.2.5
      ]]>
      errorStyle false true
      Since:
      Struts 1.2.5
      ]]>
      errorStyleClass false true
      Since:
      Struts 1.2.5
      ]]>
      errorStyleId false true
      Since:
      Struts 1.2.5
      ]]>
      indexed false true boolean multiple false true name false true onblur false true onchange false true onclick false true ondblclick false true onfocus false true onkeydown false true onkeypress false true onkeyup false true onmousedown false true onmousemove false true onmouseout false true onmouseover false true onmouseup false true property true true style false true styleClass false true styleId false true tabindex false true size false true title false true titleKey false true value false true
      submit org.apache.struts.taglib.nested.html.NestedSubmitTag Nested Extension - Render A Submit Button

      This tag is an extension of the <html:submit> tag. Please consult its documentation for information on tag attributes and usage details.

      ]]>
      accesskey false true alt false true altKey false true bundle false true
      Since:
      Struts 1.2.7
      ]]>
      disabled false true boolean indexed false true boolean onblur false true onchange false true onclick false true ondblclick false true onfocus false true onkeydown false true onkeypress false true onkeyup false true onmousedown false true onmousemove false true onmouseout false true onmouseover false true onmouseup false true property false true style false true styleClass false true styleId false true tabindex false true title false true titleKey false true value false true
      text org.apache.struts.taglib.nested.html.NestedTextTag Nested Extension - Render An Input Field of Type text

      This tag is an extension of the <html:text> tag. Please consult its documentation for information on tag attributes and usage details.

      ]]>
      accesskey false true alt false true altKey false true bundle false true
      Since:
      Struts 1.2.7
      ]]>
      disabled false true boolean errorKey false true
      Since:
      Struts 1.2.5
      ]]>
      errorStyle false true
      Since:
      Struts 1.2.5
      ]]>
      errorStyleClass false true
      Since:
      Struts 1.2.5
      ]]>
      errorStyleId false true
      Since:
      Struts 1.2.5
      ]]>
      indexed false true boolean maxlength false true name false true onblur false true onchange false true onclick false true ondblclick false true onfocus false true onkeydown false true onkeypress false true onkeyup false true onmousedown false true onmousemove false true onmouseout false true onmouseover false true onmouseup false true onselect false true property true true readonly false true boolean size false true style false true styleClass false true styleId false true tabindex false true title false true titleKey false true value false true
      textarea org.apache.struts.taglib.nested.html.NestedTextareaTag Nested Extension - Render A Textarea

      This tag is an extension of the <html:textarea> tag. Please consult its documentation for information on tag attributes and usage details.

      ]]>
      accesskey false true alt false true altKey false true bundle false true
      Since:
      Struts 1.2.7
      ]]>
      cols false true disabled false true boolean errorKey false true
      Since:
      Struts 1.2.5
      ]]>
      errorStyle false true
      Since:
      Struts 1.2.5
      ]]>
      errorStyleClass false true
      Since:
      Struts 1.2.5
      ]]>
      errorStyleId false true
      Since:
      Struts 1.2.5
      ]]>
      indexed false true boolean name false true onblur false true onchange false true onclick false true ondblclick false true onfocus false true onkeydown false true onkeypress false true onkeyup false true onmousedown false true onmousemove false true onmouseout false true onmouseover false true onmouseup false true onselect false true property true true readonly false true boolean rows false true style false true styleClass false true styleId false true tabindex false true title false true titleKey false true value false true
      empty org.apache.struts.taglib.nested.logic.NestedEmptyTag JSP Nested Extension - Evaluate the nested body content of this tag if the requested variable is either null or an empty string.

      This tag is an extension of the <logic:empty> tag. Please consult its documentation for information on tag attributes and usage details.

      ]]>
      name false true property false true scope false true
      equal org.apache.struts.taglib.nested.logic.NestedEqualTag JSP Nested Extension - Evaluate the nested body content of this tag if the requested variable is equal to the specified value.

      This tag is an extension of the <logic:equal> tag. Please consult its documentation for information on tag attributes and usage details.

      ]]>
      cookie false true header false true name false true parameter false true property false true scope false true value true true
      greaterEqual org.apache.struts.taglib.nested.logic.NestedGreaterEqualTag JSP Nested Extension - Evaluate the nested body content of this tag if the requested variable is greater than or equal to the specified value.

      This tag is an extension of the <logic:greaterEqual> tag. Please consult its documentation for information on tag attributes and usage details.

      ]]>
      cookie false true header false true name false true parameter false true property false true scope false true value true true
      greaterThan org.apache.struts.taglib.nested.logic.NestedGreaterThanTag JSP Nested Extension - Evaluate the nested body content of this tag if the requested variable is greater than the specified value.

      This tag is an extension of the <logic:greaterThan> tag. Please consult its documentation for information on tag attributes and usage details.

      ]]>
      cookie false true header false true name false true parameter false true property false true scope false true value true true
      iterate org.apache.struts.taglib.nested.logic.NestedIterateTag org.apache.struts.taglib.nested.logic.NestedIterateTei JSP Nested Extension - Repeat the nested body content of this tag over a specified collection.

      This tag is an extension of the <logic:iterate> tag. Please consult its documentation for information on tag attributes and usage details.

      ]]>
      collection false true java.lang.Object id false true indexId false true length false true name false true offset false true property false true scope false true type false true
      lessEqual org.apache.struts.taglib.nested.logic.NestedLessEqualTag JSP Nested Extension - Evaluate the nested body content of this tag if the requested variable is greater than or equal to the specified value.

      This tag is an extension of the <logic:lessEqual> tag. Please consult its documentation for information on tag attributes and usage details.

      ]]>
      cookie false true header false true name false true parameter false true property false true scope false true value true true
      lessThan org.apache.struts.taglib.nested.logic.NestedLessThanTag JSP Nested Extension - Evaluate the nested body content of this tag if the requested variable is less than the specified value.

      This tag is an extension of the <logic:lessThan> tag. Please consult its documentation for information on tag attributes and usage details.

      ]]>
      cookie false true header false true name false true parameter false true property false true scope false true value true true
      match org.apache.struts.taglib.nested.logic.NestedMatchTag JSP Nested Extension - Evaluate the nested body content of this tag if the specified value is an appropriate substring of the requested variable.

      This tag is an extension of the <logic:match> tag. Please consult its documentation for information on tag attributes and usage details.

      ]]>
      cookie false true header false true location false true name false true parameter false true property false true scope false true value true true
      messagesNotPresent org.apache.struts.taglib.nested.logic.NestedMessagesNotPresentTag JSP Nested Extension - Generate the nested body content of this tag if the specified message is not present in this request.

      This tag is an extension of the <logic:messagesNotPresent> tag. Please consult its documentation for information on tag attributes and usage details.

      ]]>
      name false true property false true message false true
      messagesPresent org.apache.struts.taglib.nested.logic.NestedMessagesPresentTag JSP Nested Extension - Generate the nested body content of this tag if the specified message is present in this request.

      This tag is an extension of the <logic:messagesPresent> tag. Please consult its documentation for information on tag attributes and usage details.

      ]]>
      name false true property false true message false true
      notEmpty org.apache.struts.taglib.nested.logic.NestedNotEmptyTag JSP Nested Extension - Evaluate the nested body content of this tag if the requested variable is neither null nor an empty string.

      This tag is an extension of the <logic:notEmpty> tag. Please consult its documentation for information on tag attributes and usage details.

      ]]>
      name false true property false true scope false true
      notEqual org.apache.struts.taglib.nested.logic.NestedNotEqualTag JSP Nested Extension - Evaluate the nested body content of this tag if the requested variable is not equal to the specified value.

      This tag is an extension of the <logic:notEqual> tag. Please consult its documentation for information on tag attributes and usage details.

      ]]>
      cookie false true header false true name false true parameter false true property false true scope false true value true true
      notMatch org.apache.struts.taglib.nested.logic.NestedNotMatchTag JSP Nested Extension - Evaluate the nested body content of this tag if the specified value is not an appropriate substring of the requested variable.

      This tag is an extension of the <logic:notMatch> tag. Please consult its documentation for information on tag attributes and usage details.

      ]]>
      cookie false true header false true location false true name false true parameter false true property false true scope false true value true true
      notPresent org.apache.struts.taglib.nested.logic.NestedNotPresentTag JSP Nested Extension - Generate the nested body content of this tag if the specified value is not present in this request.

      This tag is an extension of the <logic:notPresent> tag. Please consult its documentation for information on tag attributes and usage details.

      ]]>
      cookie false true header false true name false true parameter false true property false true role false true scope false true user false true
      present org.apache.struts.taglib.nested.logic.NestedPresentTag JSP Nested Extension - Generate the nested body content of this tag if the specified value is present in this request.

      This tag is an extension of the <logic:present> tag. Please consult its documentation for information on tag attributes and usage details.

      ]]>
      cookie false true header false true name false true parameter false true property false true role false true scope false true user false true
      velocity-tools-2.0-src/examples/struts/WEB-INF/tld/struts-tiles.tld100644 0 0 77525 11115263033 22501 0ustar 0 0 1.3 1.2 tiles http://struts.apache.org/tags-tiles This tag library provides tiles tags.Tiles were previously called Components. For historical reasons, names, pages, components and templates are used indifferently to design a tile. Also, a lot of tags and attribute names are left for backward compatibility.To know more about tags defined in this library, check the associated documentation: tiles-doc.

      ]]>
      insert org.apache.struts.tiles.taglib.InsertTag JSP Insert a tiles/component/template.

      Insert a tiles/component/template with the possibility to pass parameters (called attribute). A tile can be seen as a procedure that can take parameters or attributes. <tiles:insert> allows to define these attributes and pass them to the inserted jsp page, called template. Attributes are defined using nested tag <tiles:put> or <tiles:putList>.

      You must specify one of this tag attribute :

      • template, for inserting a tiles/component/template page,
      • component, for inserting a tiles/component/template page, (same as template)
      • page for inserting a JSP page, (same as template)
      • definition, for inserting a definition from definitions factory
      • attribute, surrounding tiles's attribute name whose value is used.
        If attribute is associated to 'direct' flag (see put), and flag is true, write attribute value (no insertion).
      • name, to let 'insert' determine the type of entities to insert. In this later case, search is done in this order : definitions, tiles/components/templates, pages.

      In fact, Page, component and template, are equivalent as a tile, component or template are jsp page.

      Example :

              
                <tiles:insert page="/basic/myLayout.jsp" flush="true">
                   <tiles:put name="title" value="My first page" />
                   <tiles:put name="header" value="/common/header.jsp" />
                   <tiles:put name="footer" value="/common/footer.jsp" />
                   <tiles:put name="menu" value="/basic/menu.jsp" />
                   <tiles:put name="body" value="/basic/helloBody.jsp" />
                </tiles:insert>
              
            
      ]]>
      template false true A string representing the URI of a tile or template (a JSP page).

      'page', 'component' and 'template' are synonyms : they have exactly the same behavior.

      ]]>
      component false true Path (relative or absolute to webapps) of the component to insert.

      'page', 'component' and 'template' are synonyms : they have exactly the same behavior.

      ]]>
      page false true Path (relative or absolute to webapps) of the page to insert.

      'page', 'component' and 'template' are synonyms : they have exactly the same behavior.

      ]]>
      definition false true Name of the definition to insert. Definition are defined in a centralized file. For now, only definition from factory can be inserted with this attribute. To insert a definition defined with tag <tiles:definition>, use beanName="".

      ]]>
      attribute false false Name of an attribute in current tile/component context. Value of this attribute is passed to 'name' (see attribute 'name').

      ]]>
      name false true Name of an entity to insert. Search is done in this order : definition, attribute, [tile/component/template/page].

      ]]>
      beanName false true Name of the bean used as value. Bean is retrieved from specified context, if any. Otherwise, method pageContext.findAttribute is used. If beanProperty is also specified, retrieve value from the corresponding bean property.

      If found bean (or property value) is instance of one of Attribute class (Direct, Instance, ...), insertion is done according to the class type. Otherwise, the toString method is called on the bean, and returned String is used as name to insert (see 'name' attribute).

      ]]>
      beanProperty false true Bean property name. If specified, value is retrieve from this property. Support nested/indexed properties.

      ]]>
      beanScope false false Scope into which bean is searched. If not specified, method pageContext.findAttribute is used. Scope can be any JSP scope, 'component', or 'template'. In these two later cases, bean is search in tile/component/template context.

      ]]>
      flush false false boolean True or false. If true, current page out stream is flushed before insertion.

      ]]>
      ignore false true boolean If this attribute is set to true, and the attribute specified by the name does not exist, simply return without writing anything. The default value is false, which will cause a runtime exception to be thrown.

      ]]>
      role false true If the user is in the specified role, the tag is taken into account; otherwise, the tag is ignored (skipped).

      ]]>
      controllerUrl false true Url of a controller called immediately before page is inserted.

      Url usually denote a Struts action. Controller (action) is used to prepare data to be render by inserted Tile.

      See also controlerClass. Only one of controllerUrl or controllerClass should be used.

      ]]>
      controllerClass false true Class type of a controller called immediately before page is inserted.

      Controller is used to prepare data to be render by inserted Tile.

      See also controlerUrl

      Class must implements or extends one of the following :

      • org.apache.struts.tiles.Controller
      • org.apache.struts.tiles.ControllerSupport
      • org.apache.struts.action.Action (wrapper org.apache.struts.action.ActionController is used)

      See also controllerUrl. Only one of controllerUrl or controllerClass should be used.

      ]]>
      definition org.apache.struts.tiles.taglib.DefinitionTag JSP Create a tile /component / template definition bean.

      Create a tile/component/template definition as a bean. Newly created bean will be saved under specified "id", in the requested "scope". Definition tag has same syntax as insert

      ]]>
      id true false Specifies the name under which the newly created definition bean will be saved.

      ]]>
      scope false false Specifies the variable scope into which the newly defined bean will be created. If not specified, the bean will be created in page scope.

      ]]>
      template false true A string representing the URI of a tile/component/template (a JSP page).

      ]]>
      page false true URL of the template / component to insert. Same as "template".

      ]]>
      role false true Role to check before inserting this definition. If role is not defined for current user, definition is not inserted. Checking is done at insert time, not during definition process.

      ]]>
      extends false true Name of a parent definition that is used to initialize this new definition. Parent definition is searched in definitions factory.

      ]]>
      put org.apache.struts.tiles.taglib.PutTag JSP Put an attribute into tile/component/template context.

      Define an attribute to pass to tile/component/template. This tag can only be used inside 'insert' or 'definition' tag. Value (or content) is specified using attribute 'value' (or 'content'), or using the tag body. It is also possible to specify the type of the value :

      • string : Content is written directly.
      • page | template : Content is included from specified URL. Name is used as an URL.
      • definition : Content come from specified definition (from factory). Name is used as definition name.

      If 'type' attribute is not specified, content is 'untyped', unless it comes from a typed bean.

      Note that using 'direct="true"' is equivalent to 'type="string"'.

      ]]>
      name false false Name of the attribute.

      ]]>
      value false true Attribute value. Could be a String or an Object. Value can come from a direct assignment (value="aValue") or from a bean. One of 'value' 'content' or 'beanName' must be present.

      ]]>
      content false true Content that's put into tile scope. Synonym to value. Attribute added for compatibility with JSP Template.

      ]]>
      direct false false Determines how content is handled: true means content is printed direct

      ]]>
      type false false Specify content type: string, page, template or definition.

      • String : Content is printed directly.
      • page | template : Content is included from specified URL. Name is used as an URL.
      • definition : Value is the name of a definition defined in factory (xml file). Definition will be searched in the inserted tile, in a <tiles:insert attribute="attributeName"> tag, where 'attributeName' is the name used for this tag.
      ]]>
      beanName false true Name of the bean used as value. Bean is retrieved from specified context, if any. Otherwise, method pageContext.findAttribute is used. If beanProperty is specified, retrieve value from the corresponding bean property.

      ]]>
      beanProperty false true Bean property name. If specified, value is retrieve from this property. Support nested/indexed properties.

      ]]>
      beanScope false false Scope into which bean is searched. If not specified, method pageContext.findAttribute is used. Scope can be any JSP scope, 'tile', 'component', or 'template'. In these three later cases, bean is search in tile/component/template context.

      ]]>
      role false true If the user is in the specified role, the tag is taken into account; otherwise, the tag is ignored (skipped).

      ]]>
      putList org.apache.struts.tiles.taglib.PutListTag JSP Declare a list that will be pass as attribute to tile.

      Declare a list that will be pass as attribute to tile. List elements are added using the tag 'add'. This tag can only be used inside 'insert' or 'definition' tag.

      ]]>
      name true false Name of the list.

      ]]>
      add org.apache.struts.tiles.taglib.AddTag JSP Add an element to the surrounding list. Equivalent to 'put', but for list element.

      Add an element to the surrounding list. This tag can only be used inside putList tag. Value can come from a direct assignment (value="aValue") or from a bean. One of 'value' or 'beanName' must be present.

      ]]>
      value false false Element value. Can be a String or Object.

      ]]>
      content false true Element value. Can be a String or Object. Synonym to value. Attribute added for compatibility with JSP Template.

      ]]>
      direct false false Determines how content is handled: true means content is printed direct

      ]]>
      type false false Specify content type: string, page, template or instance.

      • String : Content is printed directly.
      • page | template : Content is included from specified URL. Name is used as an URL.
      • definition : Value denote a definition defined in factory (xml file). Definition will be searched in the inserted tile, in a <insert attribute="attributeName"> tag, where 'attributeName' is the name used for this tag.
      ]]>
      beanName false true Name of the bean used as value. Bean is retrieved from specified context, if any. Otherwise, method pageContext.findAttribute is used. If beanProperty is specified, retrieve value from the corresponding bean property.

      ]]>
      beanProperty false true Bean property name. If specified, value is retrieve from this property. Support nested/indexed properties.

      ]]>
      beanScope false false Scope into which bean is searched. If not specified, method pageContext.findAttribute is used. Scope can be any JSP scope, 'component', or 'template'. In these two later cases, bean is search in tile/component/template context.

      ]]>
      role false true If the user is in the specified role, the tag is taken into account; otherwise, the tag is ignored (skipped).

      The role isn't taken into account if <add> tag is used in a definition.

      ]]>
      get org.apache.struts.tiles.taglib.GetTag empty Gets the content from request scope that was put there by a put tag.

      Retrieve content from tile context and include it.

      Take into account the 'type' attribute.

      ]]>
      name true true The name of the content to get from tile/component scope.

      ]]>
      ignore false true boolean If this attribute is set to true, and the attribute specified by the name does not exist, simply return without writing anything. The default value is false, which will cause a runtime exception to be thrown.

      ]]>
      flush false false boolean True or false. If true, current page out stream is flushed before insertion.

      ]]>
      role false true If the user is in the specified role, the tag is taken into account; otherwise, the tag is ignored (skipped).

      ]]>
      getAsString org.apache.struts.tiles.taglib.GetAttributeTag empty Render the value of the specified tile/component/template attribute to the current JspWriter

      Retrieve the value of the specified tile/component/template attribute property, and render it to the current JspWriter as a String. The usual toString() conversions is applied on found value.

      Throw a JSPException if named value is not found.

      ]]>
      name true true Attribute name.

      ]]>
      ignore false true boolean If this attribute is set to true, and the attribute specified by the name does not exist, simply return without writing anything. The default value is false, which will cause a runtime exception to be thrown.

      ]]>
      role false true If the user is in the specified role, the tag is taken into account; otherwise, the tag is ignored (skipped).

      ]]>
      useAttribute org.apache.struts.tiles.taglib.UseAttributeTag org.apache.struts.tiles.taglib.UseAttributeTei empty Use attribute value inside page.

      Declare a Java variable, and an attribute in the specified scope, using tile attribute value.

      Java variable and attribute will have the name specified by 'id', or the original name if not specified.

      ]]>
      id false false Declared attribute and variable name.

      ]]>
      classname false false Class of the declared variable.

      ]]>
      scope false false Scope of the declared attribute. Default to 'page'.

      ]]>
      name true true Tile's attribute name.

      ]]>
      ignore false true boolean If this attribute is set to true, and the attribute specified by the name does not exist, simply return without error. The default value is false, which will cause a runtime exception to be thrown.

      ]]>
      importAttribute org.apache.struts.tiles.taglib.ImportAttributeTag empty Import Tile's attribute in specified context.

      Import attribute from tile to requested scope. Attribute name and scope are optional. If not specified, all tile attributes are imported in page scope. Once imported, an attribute can be used as any other beans from jsp contexts.

      ]]>
      name false true Tile's attribute name. If not specified, all attributes are imported.

      ]]>
      scope false false Scope into which attribute is imported. Default to page.

      ]]>
      ignore false true boolean If this attribute is set to true, and the attribute specified by the name does not exist, simply return without error. The default value is false, which will cause a runtime exception to be thrown.

      ]]>
      initComponentDefinitions org.apache.struts.tiles.taglib.InitDefinitionsTag empty Initialize Tile/Component definitions factory.

      In order to use Tile/Component definitions factory, you need to initialize the factory. This is generally done in a initializing servlet. In particular, it is done in "ComponentActionServlet" if you use it. If you don't initialize factory in a servlet, you can initialize it using this tag. You need to provide the description file name, and optionally the factory classname. Initialization is done only once, at the first call of this tag. Subsequent calls are ignored (tag checks existence of the factory.

      ]]>
      file true false Definition file name.

      ]]>
      classname false false If specified, classname of the factory to create and initialized.

      ]]>
      velocity-tools-2.0-src/examples/struts/WEB-INF/tools.xml100644 0 0 2315 10730012256 20353 0ustar 0 0 velocity-tools-2.0-src/examples/struts/WEB-INF/validation.xml100644 0 0 2464 10730012256 21352 0ustar 0 0
      velocity-tools-2.0-src/examples/struts/WEB-INF/validator-rules.xml100644 0 0 34420 10730012256 22352 0ustar 0 0 velocity-tools-2.0-src/examples/struts/WEB-INF/velocity.properties100644 0 0 12103 10730012256 22461 0ustar 0 0 # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # ---------------------------------------------------------------------------- # These are the default properties for the # Velocity Runtime. These values are used when # Runtime.init() is called, and when Runtime.init(properties) # fails to find the specificed properties file. # ---------------------------------------------------------------------------- # ---------------------------------------------------------------------------- # R U N T I M E L O G # ---------------------------------------------------------------------------- # Velocity uses the Servlet APIs logging facilites. # ---------------------------------------------------------------------------- # This controls if Runtime.error(), info() and warn() messages include the # whole stack trace. The last property controls whether invalid references # are logged. # ---------------------------------------------------------------------------- runtime.log.invalid.reference = true # ---------------------------------------------------------------------------- # T E M P L A T E E N C O D I N G # ---------------------------------------------------------------------------- input.encoding=ISO-8859-1 output.encoding=ISO-8859-1 # ---------------------------------------------------------------------------- # F O R E A C H P R O P E R T I E S # ---------------------------------------------------------------------------- # These properties control how the counter is accessed in the #foreach # directive. By default the reference $velocityCount will be available # in the body of the #foreach directive. The default starting value # for this reference is 1. # ---------------------------------------------------------------------------- directive.foreach.counter.name = velocityCount directive.foreach.counter.initial.value = 1 # ---------------------------------------------------------------------------- # I N C L U D E P R O P E R T I E S # ---------------------------------------------------------------------------- # These are the properties that governed the way #include'd content # is governed. # ---------------------------------------------------------------------------- directive.include.output.errormsg.start = # ---------------------------------------------------------------------------- # P A R S E P R O P E R T I E S # ---------------------------------------------------------------------------- directive.parse.max.depth = 10 # ---------------------------------------------------------------------------- # VELOCIMACRO PROPERTIES # ---------------------------------------------------------------------------- # global : name of default global library. It is expected to be in the regular # template path. You may remove it (either the file or this property) if # you wish with no harm. # ---------------------------------------------------------------------------- # dev-changes by Marino webapp.resource.loader.cache = true webapp.resource.loader.modificationCheckInterval = 5 velocimacro.library.autoreload = false velocimacro.library = /WEB-INF/VM_global_library.vm velocimacro.permissions.allow.inline = true velocimacro.permissions.allow.inline.to.replace.global = false velocimacro.permissions.allow.inline.local.scope = false velocimacro.context.localscope = false # ---------------------------------------------------------------------------- # INTERPOLATION # ---------------------------------------------------------------------------- # turn off and on interpolation of references and directives in string # literals. ON by default :) # ---------------------------------------------------------------------------- runtime.interpolate.string.literals = true # ---------------------------------------------------------------------------- # RESOURCE MANAGEMENT # ---------------------------------------------------------------------------- # Allows alternative ResourceManager and ResourceCache implementations # to be plugged in. # ---------------------------------------------------------------------------- resource.manager.class = org.apache.velocity.runtime.resource.ResourceManagerImpl resource.manager.cache.class = org.apache.velocity.runtime.resource.ResourceCacheImpl velocity-tools-2.0-src/examples/struts/WEB-INF/web.xml100644 0 0 10162 10730012256 20007 0ustar 0 0 action org.apache.struts.action.ActionServlet chainConfig /WEB-INF/chain-config.xml config /WEB-INF/struts-config.xml config/app1 /WEB-INF/struts-app1-config.xml config/app2 /WEB-INF/struts-app2-config.xml config/app3 /WEB-INF/struts-app3-config.xml config/app4 /WEB-INF/struts-app4-config.xml config/app5 /WEB-INF/struts-app5-config.xml config/app6 /WEB-INF/struts-app6-config.xml config/app7 /WEB-INF/struts-app7-config.xml debug 2 detail 2 validate true 2 velocity org.apache.velocity.tools.view.VelocityViewServlet action *.do velocity *.vm index.vm /WEB-INF/sslext.tld /WEB-INF/tld/sslext.tld /WEB-INF/struts-bean.tld /WEB-INF/tld/struts-bean.tld /WEB-INF/struts-html.tld /WEB-INF/tld/struts-html.tld /WEB-INF/struts-logic.tld /WEB-INF/tld/struts-logic.tld /WEB-INF/struts-tiles.tld /WEB-INF/tld/struts-tiles.tld /WEB-INF/struts-nested.tld /WEB-INF/tld/struts-nested.tld velocity-tools-2.0-src/examples/struts/app1/edit-address.jsp100644 0 0 6776 10730012252 21404 0ustar 0 0 <%-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --%> <%@ page language="java" %> <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %> <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %> App1

      (JSP )

      :



      Template velocity-tools-2.0-src/examples/struts/app1/edit-address.txt100644 0 0 7025 10730012252 21413 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. $text.title

      $text.edit (Velocity $text.version)

      $text.firstname
      $text.lastname
      $text.street
      $text.zip
      $text.city
      $text.country
      $text.languages #set ($map = $address.languagesAsMap)
      $text.multiple


      Template velocity-tools-2.0-src/examples/struts/app1/edit-address.vm100644 0 0 6517 10730012252 21223 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. $text.title

      $text.edit (Velocity $text.version)

      $text.firstname
      $text.lastname
      $text.street
      $text.zip
      $text.city
      $text.country
      $text.languages #set ($map = $address.languagesAsMap)
      $text.multiple


      Template velocity-tools-2.0-src/examples/struts/app1/edit-addressjsp.txt100644 0 0 5441 10730012252 22130 0ustar 0 0 <%-- * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. --%> <%@ page language="java" %> <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %> <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %> App1

      (JSP )

      :

      " onclick="address.action.value='save'; document.address.submit(); return false;"> " onclick="address.action.value='list'; document.address.submit(); return false;">

      Template velocity-tools-2.0-src/examples/struts/app1/show-address.jsp100644 0 0 7105 10730012252 21422 0ustar 0 0 <%-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --%> <%@ page language="java" %> <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %> <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %> <%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %> <bean:message key="title"/>

      (JSP )

       
       
       
       
       
       
       
       

      (JSP)

      (Velocity)

      Template velocity-tools-2.0-src/examples/struts/app1/show-address.txt100644 0 0 5577 10730012252 21460 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. $text.title

      $text.title (Velocity $text.version)

      $text.intro

      $text.language

      $text.header

      $text.firstname   $!address.firstname
      $text.lastname   $!address.lastname
      $text.street   $!address.street
      $text.zip   $!address.zip
      $text.city   $!address.city
      $text.country   $!address.country
      $text.languages #foreach ($language in $!address.languages)   $text.get($language)
      #end  

      $text.edit (JSP)

      $text.edit (Velocity)

      Template velocity-tools-2.0-src/examples/struts/app1/show-address.vm100644 0 0 4601 10730012252 21246 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. $text.title

      $text.title (Velocity $text.version)

      $text.intro

      $text.language

      $text.header

      $text.firstname   $!address.firstname
      $text.lastname   $!address.lastname
      $text.street   $!address.street
      $text.zip   $!address.zip
      $text.city   $!address.city
      $text.country   $!address.country
      $text.languages #foreach ($language in $!address.languages)   $text.get($language)
      #end  

      $text.edit (JSP)

      $text.edit (Velocity)

      Template velocity-tools-2.0-src/examples/struts/app1/show-addressjsp.txt100644 0 0 6063 10730012252 22164 0ustar 0 0 <%-- * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. --%> <%@ page language="java" %> <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %> <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %> <bean:message key="title"/>

      (JSP )

       
       
       
       
       
       

      (JSP)

      (Velocity)

      Template velocity-tools-2.0-src/examples/struts/app2/tool-demo.txt100644 0 0 22461 10730012252 20764 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. Struts App2: Struts View Tools Demo

      Struts App2: Struts View Tools Demo

      A demonstration of the Velocity view tools provided for Struts support. Where available, the Velocity shorthand notation to method calls is shown as well.

      MessageTool

      \$text.title
      \$text.title
      $text.title
      \$text.test.insert('bear','dog','cat') $text.test.insert('bear','dog','cat')
      \$text.tutle.exists $text.tutle.exists

      ErrorsTool

      \$errors.exist() $errors.exist()
      \$errors.exist('language') $errors.exist('language')
      \$errors.getSize()
      \$errors.size
      $errors.getSize()
      \$errors.getSize('language') $errors.getSize('language')
      \$errors.getAll()
      \$errors.all
      [This is a String representation of the ArrayList that is returned]
      $errors.getAll()
      \$errors.get('language')
      \$errors.language
      [This is a String representation of the ArrayList that is returned]
      $errors.language
      \$errors.getMsgs()
      \$errors.msgs
      $errors.msgs
      \$errors.getMsgs('language') $errors.getMsgs('language')
      A Velocity macro to render all error messages:
      #macro (errorMarkup)
        #if ($errors.exist() )
          <ul>
          #foreach ($e in $errors.all )
            $e
          #end
          </ul>
        #end
      #end
      #errorMarkup()
      A Velocity macro to render error messages specific
      to a property:
      #macro (errorMarkup $property)
        #if ($errors.exist($property))
          <ul>
          #foreach ($er in $errors.get($property))
            $er
          #end
          </ul>
        #end
      #end
      #errorMarkupForProperty('language')

      FormTool

      \$form.getBean()
      \$form.bean
      $form.getBean()
      \$form.getCancelName()
      \$form.cancelName
      $form.getCancelName()
      \$form.getTokenName()
      \$form.tokenName
      $form.getTokenName()
      \$form.getToken()
      \$form.token
      $form.getToken()

      StrutsLinkTool

      \$link.uri('template/login.vm') $link.uri('template/login.vm')
      \$link.action.demo $link.action.demo  
      \$link.forward.src $link.forward.src  
      \$link.relative('examples/index.html') $link.relative('examples/index.html')
      \$link.uri('index.html').param('key1', 'val 1') $link.uri('index.html').param('key1', 'val 1')
      \$link.uri('index.html').param('key1', 'val 1').getURI()
      \$link.uri('index.html').param('key1', 'val 1').URI
      $link.uri('index.html').param('key1', 'val 1').getURI()
      \$link.uri('/index.html').param('key1', 'val 1').getQueryData()
      \$link.uri('/index.html').param('key1', 'val 1').queryData
      $link.uri('/index.html').param('key1', 'val 1').getQueryData()
      \$link.getContextURL()
      \$link.contextURL
      $link.getContextURL()
      \$link.getContextPath()
      \$link.contextPath
      $link.getContextPath()
      \$link.getBaseRef()
      \$link.baseRef
      $link.getBaseRef()
      \$link.setURI('index.vm').toString() $link.setURI('index.vm').toString()

      ActionMessagesTool

      \$messages.exist() $messages.exist()
      \$messages.exist('foobar') $messages.exist('foobar')
      \$messages.getSize()
      \$messages.size
      $messages.getSize()
      \$messages.getSize('foobar') $messages.getSize('foobar')
      \$messages.getAll()
      \$messages.all
      [This is a String representation of the ArrayList that is returned]
      $messages.getAll()
      \$messages.get('foobar')
      \$messages.foobar
      [This is a String representation of the ArrayList that is returned]
      $messages.get('foobar')
      A Velocity macro to render all actiontext messages:
      #macro (messageMarkup)
        #if ($messages.exist() )
          <ul>
          #foreach ($m in $messages.all )
            $m
          #end
          </ul>
        #end
      #end
      #messageMarkup()
      A Velocity macro to render actiontext messages specific
      to a property:
      #macro (messageMarkup $property)
        #if ($messages.exist($property))
          <ul>
          #foreach ($m in $messages.get($property))
            $m
          #end
          </ul>
        #end
      #end
      #messageMarkupForProperty('foobar')
      velocity-tools-2.0-src/examples/struts/app2/tool-demo.vm100644 0 0 21716 11110347753 20603 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. Struts App2: Struts View Tools Demo

      Struts App2: Struts View Tools Demo

      A demonstration of the Velocity view tools provided for Struts support. Where available, the Velocity shorthand notation to method calls is shown as well.

      MessageTool

      \$text.title
      \$text.title
      $text.title
      \$text.test.insert('bear','dog','cat') $text.test.insert('bear','dog','cat')
      \$text.tutle.exists $text.tutle.exists

      ErrorsTool

      \$errors.exist() $errors.exist()
      \$errors.exist('language') $errors.exist('language')
      \$errors.getSize()
      \$errors.size
      $errors.getSize()
      \$errors.getSize('language') $errors.getSize('language')
      \$errors.getAll()
      \$errors.all
      [This is a String representation of the ArrayList that is returned]
      $errors.getAll()
      \$errors.get('language')
      \$errors.language
      [This is a String representation of the ArrayList that is returned]
      $errors.language
      \$errors.getMsgs()
      \$errors.msgs
      $errors.msgs
      \$errors.getMsgs('language') $errors.getMsgs('language')
      A Velocity macro to render all error messages:
      #macro (errorMarkup)
        #if ($errors.exist() )
          <ul>
          #foreach ($e in $errors.all )
            $e
          #end
          </ul>
        #end
      #end
      #errorMarkup()
      A Velocity macro to render error messages specific
      to a property:
      #macro (errorMarkup $property)
        #if ($errors.exist($property))
          <ul>
          #foreach ($er in $errors.get($property))
            $er
          #end
          </ul>
        #end
      #end
      #errorMarkupForProperty('language')

      FormTool

      \$form.getBean()
      \$form.bean
      $form.getBean()
      \$form.getCancelName()
      \$form.cancelName
      $form.getCancelName()
      \$form.getTokenName()
      \$form.tokenName
      $form.getTokenName()
      \$form.getToken()
      \$form.token
      $form.getToken()

      StrutsLinkTool

      \$link.uri('template/login.vm') $link.uri('template/login.vm')
      \$link.action.demo $link.action.demo  
      \$link.forward.src $link.forward.src  
      \$link.path('index.html').param('key1', 'val 1') $link.path('index.html').param('key1', 'val 1')
      \$link.relative('examples/index.html') $link.relative('examples/index.html')
      \$link.absolute('index.html').param('key1', 'val 1') $link.absolute('index.html').param('key1', 'val 1')
      \$link.path('/index.html').param('key1', 'val 1').getQuery()
      \$link.path('/index.html').param('key1', 'val 1').query
      $link.path('/index.html').param('key1', 'val 1').query
      \$link.getContextURL()
      \$link.contextURL
      $link.getContextURL()
      \$link.getContextPath()
      \$link.contextPath
      $link.getContextPath()
      \$link.getBaseRef()
      \$link.baseRef
      $link.getBaseRef()
      \$link.uri('https://foo.com/index.vm').toString() $link.uri('https://foo.com/index.vm').toString()

      ActionMessagesTool

      \$messages.exist() $messages.exist()
      \$messages.exist('foobar') $messages.exist('foobar')
      \$messages.getSize()
      \$messages.size
      $messages.getSize()
      \$messages.getSize('foobar') $messages.getSize('foobar')
      \$messages.getAll()
      \$messages.all
      [This is a String representation of the ArrayList that is returned]
      $messages.getAll()
      \$messages.get('foobar')
      \$messages.foobar
      [This is a String representation of the ArrayList that is returned]
      $messages.get('foobar')
      A Velocity macro to render all actiontext messages:
      #macro (messageMarkup)
        #if ($messages.exist() )
          <ul>
          #foreach ($m in $messages.all )
            $m
          #end
          </ul>
        #end
      #end
      #messageMarkup()
      A Velocity macro to render actiontext messages specific
      to a property:
      #macro (messageMarkup $property)
        #if ($messages.exist($property))
          <ul>
          #foreach ($m in $messages.get($property))
            $m
          #end
          </ul>
        #end
      #end
      #messageMarkupForProperty('foobar')
      velocity-tools-2.0-src/examples/struts/app3/index.jsp100644 0 0 4173 10730012252 20132 0ustar 0 0 <%-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --%> <%@ page language="java" %> <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %> <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %> <%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %> <%-- If user is logged in, display "Welcome ${username}!" Else display "Welcome World!" Display link to log in page; maintain session id if needed. If user is logged in, display a link to the sign-out page. Note: Only the minimum required html or Sruts custom tags are used in this example. --%> Welcome World!!

      Welcome ! (JSP Version)

      Welcome World! (JSP Version)

      • Sign in
      • Sign out
      Switch to Velocity
      View Template
      velocity-tools-2.0-src/examples/struts/app3/index.vm100644 0 0 4001 10730012252 17746 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. #* If user is logged in, display "Welcome ${username}!" Else display "Welcome World!" Display link to log in page; maintain session id if needed. If user is logged in, display a link to the sign-out page. Note: Only the minimum required html or Sruts custom tags are used in this example. *# Welcome World! #if( $user )

      Welcome $user.username! (Velocity Version)

      #else

      Welcome World! (Velocity Version)

      #end #macro (errorMarkup) #if ($errors.exist() )
        #foreach ($e in $errors.all ) $e #end
      #end #end #errorMarkup() Switch to JSP
      View Template
      velocity-tools-2.0-src/examples/struts/app3/index_jsp.txt100644 0 0 4235 10730012252 21030 0ustar 0 0 <%-- * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. --%> <%@ page language="java" %> <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %> <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %> <%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %> <%-- If user is logged in, display "Welcome ${username}!" Else display "Welcome World!" Display link to log in page; maintain session id if needed. If user is logged in, display a link to the sign-out page. Note: Only the minimum required html or Sruts custom tags are used in this example. --%> Welcome World!!

      Welcome ! (JSP Version)

      Welcome World! (JSP Version)

      • Sign in
      • Sign out
      Switch to Velocity
      View Template
      velocity-tools-2.0-src/examples/struts/app3/index_vm.txt100644 0 0 3777 10730012252 20670 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. #* If user is logged in, display "Welcome ${username}!" Else display "Welcome World!" Display link to log in page; maintain session id if needed. If user is logged in, display a link to the sign-out page. Note: Only the minimum required html or Sruts custom tags are used in this example. *# Welcome World! #if( $user )

      Welcome $user.username! (Velocity Version)

      #else

      Welcome World! (Velocity Version)

      #end #macro (errorMarkup) #if ($errors.exist() )
        #foreach ($e in $errors.all ) $e #end
      #end #end #errorMarkup() Switch to JSP
      View Template
      velocity-tools-2.0-src/examples/struts/app3/logon.jsp100644 0 0 4212 10730012252 20133 0ustar 0 0 <%-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --%> <%@ page language="java" %> <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %> <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %> <%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %> Sign in, Please!

      Sign in, Please! (JSP Version)

      Username:
      Password:
      View Template
      velocity-tools-2.0-src/examples/struts/app3/logon.vm100644 0 0 4071 10730012252 17764 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. Sign in, Please! #errorMarkup()

      Sign in, Please! (Velocity Version)

      Username:
      Password:
      View Template
      velocity-tools-2.0-src/examples/struts/app3/logon_jsp.txt100644 0 0 4255 10730012252 21041 0ustar 0 0 <%-- ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. --%> <%@ page language="java" %> <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %> <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %> <%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %> Sign in, Please!

      Sign in, Please! (JSP Version)

      Username:
      Password:
      View Template
      velocity-tools-2.0-src/examples/struts/app3/logon_vm.txt100644 0 0 4071 10730012252 20663 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. Sign in, Please! #errorMarkup()

      Sign in, Please! (Velocity Version)

      Username:
      Password:
      View Template
      velocity-tools-2.0-src/examples/struts/app4/body_frontpage.jsp100644 0 0 2322 10730012254 22022 0ustar 0 0 <%-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --%> <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
      This tile features a TilesController that put a variable "foo" in request scope before the tile was rendered. the variable contains the value:
      velocity-tools-2.0-src/examples/struts/app4/body_frontpage.vm100644 0 0 3501 10730012254 21650 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. #* * Copyright 2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * $Id: body_frontpage.vm 477914 2006-11-21 21:52:11Z henning $ *#
      This tile features a TilesController that put a variable "foo" in request scope before the tile was rendered. the variable contains the value: $foo
      velocity-tools-2.0-src/examples/struts/app4/footer.jsp100644 0 0 1664 10730012254 20326 0ustar 0 0 <%-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --%>
      This be the mighty Footer
      velocity-tools-2.0-src/examples/struts/app4/footer.vm100644 0 0 3173 10730012254 20151 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. #* * Copyright 2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * $Id: footer.vm 477914 2006-11-21 21:52:11Z henning $ *#
      This be the mighty Footer
      velocity-tools-2.0-src/examples/struts/app4/header_frontpage.jsp100644 0 0 1634 10730012254 22322 0ustar 0 0 <%-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --%>
      The Mighty Header
      velocity-tools-2.0-src/examples/struts/app4/header_frontpage.vm100644 0 0 3134 10730012254 22145 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. #* * Copyright 2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * $Id: header_frontpage.vm 477914 2006-11-21 21:52:11Z henning $ *#
      The Mighty Header
      velocity-tools-2.0-src/examples/struts/app4/layout/bodyLayout.jsp100644 0 0 2163 10730012252 22471 0ustar 0 0 <%-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --%> <%@ taglib uri="/WEB-INF/struts-tiles.tld" prefix="tiles" %>
      velocity-tools-2.0-src/examples/struts/app4/layout/bodyLayout.vm100644 0 0 3324 10730012254 22321 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. #* * Copyright 2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * $Id: bodyLayout.vm 477914 2006-11-21 21:52:11Z henning $ *#
      $tiles.header
      $tiles.body
      velocity-tools-2.0-src/examples/struts/app4/layout/masterLayout.jsp100644 0 0 3045 10730012252 23027 0ustar 0 0 <%-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --%> <%@ taglib uri="/WEB-INF/struts-tiles.tld" prefix="tiles" %> <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %> <tiles:getAsString name="title"/>
      velocity-tools-2.0-src/examples/struts/app4/layout/masterLayout.vm100644 0 0 4020 10730012252 22647 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. #* * Copyright 2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * $Id: masterLayout.vm 477914 2006-11-21 21:52:11Z henning $ *# $tiles.getAttribute("title")
      $tiles.menu $text.get($tiles.getAttribute("someAttribute")) $tiles.body
      $tiles.footer
      velocity-tools-2.0-src/examples/struts/app4/menu_frontpage.jsp100644 0 0 2566 10730012254 22043 0ustar 0 0 <%-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --%> <%@ taglib uri="/WEB-INF/struts-tiles.tld" prefix="tiles" %> <%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %> <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>

      velocity-tools-2.0-src/examples/struts/app4/menu_frontpage.vm100644 0 0 3507 10730012254 21665 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. #* * Copyright 2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * $Id: menu_frontpage.vm 477914 2006-11-21 21:52:11Z henning $ *# ## import the menu items into page scope (velocity context = default) $tiles.importAttribute("items")
      #foreach($item in $items) $item.value
      #end
      velocity-tools-2.0-src/examples/struts/app5/success.jsp100644 0 0 2235 10730012254 20474 0ustar 0 0 <%-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --%> <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %> Struts App5: Struts ValidatorTool Demo

      The e-mail address is valid!

      Try again?

      velocity-tools-2.0-src/examples/struts/app5/success.vm100644 0 0 3443 10730012254 20324 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. #* * Copyright 2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * $Id: success.vm 477914 2006-11-21 21:52:11Z henning $ *# Struts App5: Struts ValidatorTool Demo

      The e-mail address is valid!

      Try again?

      velocity-tools-2.0-src/examples/struts/app5/validator-demo.jsp100644 0 0 3111 10730012254 21725 0ustar 0 0 <%-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --%> <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %> Struts App5: Struts ValidatorTool Demo (JSP Version)

      Struts App5: Struts ValidatorTool Demo (JSP Version)

      A demonstration of the Velocity ValidatorTool provided for Struts support.

        velocity-tools-2.0-src/examples/struts/app5/validator-demo.vm100644 0 0 4434 10730012254 21564 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. #* * Copyright 2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * $Id: validator-demo.vm 477914 2006-11-21 21:52:11Z henning $ *# Struts App5: Struts ValidatorTool Demo

      Struts App5: Struts ValidatorTool Demo

      A demonstration of the Velocity ValidatorTool provided for Struts support.

      #errorMarkup()
      $text.get("emailForm.label.email")    
      ## if this line is commented out, the form will be validated server-side ... go ahead, try it :) $validator.javascript velocity-tools-2.0-src/examples/struts/app6/any.jsp100644 0 0 2575 10730012254 17623 0ustar 0 0 <%-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --%> <%@ taglib uri="/WEB-INF/sslext.tld" prefix="sslext"%> <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean"%>
      <%=request.getRequestURI()%>


      We are on the any page. The action "any" forwards to this page.

      Try the false page.
      Try the true page.

      Go to form test page. velocity-tools-2.0-src/examples/struts/app6/any.vm100644 0 0 3615 10730012254 17445 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. #* * Copyright 2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * $Id: any.vm 477914 2006-11-21 21:52:11Z henning $ *#
      $request.getRequestURI()

      #include("/app6/top.html")
      We are on the any page. The action "any" forwards to this page.

      Try the false page.
      Try the true page.

      Go to form test page. velocity-tools-2.0-src/examples/struts/app6/false.jsp100644 0 0 2614 10730012254 20120 0ustar 0 0 <%-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --%> <%@ taglib uri="/WEB-INF/sslext.tld" prefix="sslext"%> <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean"%>
      <%=request.getRequestURI()%>


      We are on the false page. The non-secure (non-SSL) action "false" forwards to this page.

      Try the true page.
      Try the any page.

      Go to form test page. velocity-tools-2.0-src/examples/struts/app6/false.vm100644 0 0 3636 10730012254 17753 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. #* * Copyright 2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * $Id: false.vm 477914 2006-11-21 21:52:11Z henning $ *#
      $request.getRequestURI()

      #include("/app6/top.html")
      We are on the false page. The non-secure (non-SSL) action "false" forwards to this page.

      Try the true page.
      Try the any page.

      Go to form test page. velocity-tools-2.0-src/examples/struts/app6/form.jsp100644 0 0 3246 10730012254 17773 0ustar 0 0 <%-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --%> <%@ taglib uri="/WEB-INF/sslext.tld" prefix="sslext"%> <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html"%>
      <%=request.getRequestURI()%>

      We are on the form page. View the page source to see the difference in the action attribute values between the two forms.

      This posts to a secure action.


      This posts to a non-secure action.


      velocity-tools-2.0-src/examples/struts/app6/form.vm100644 0 0 4412 10730012254 17615 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. #* * Copyright 2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * $Id: form.vm 477914 2006-11-21 21:52:11Z henning $ *#
      $request.getRequestURI()

      We are on the form page. View the page source to see the difference in the action attribute values between the two forms.

      This posts to a secure action.


      This posts to a non-secure action.


      velocity-tools-2.0-src/examples/struts/app6/submitted.jsp100644 0 0 3000 10730012254 21014 0ustar 0 0 <%-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --%> <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %> <%@ taglib uri="/WEB-INF/sslext.tld" prefix="sslext"%>
      <%=request.getRequestURI()%>

      We are on the submitted page. These are the values that were posted:



      Return to form test page.

      Go to true page.
      Go to false page.
      Go to any page. velocity-tools-2.0-src/examples/struts/app6/submitted.vm100644 0 0 3730 10730012254 20654 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. #* * Copyright 2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * $Id: submitted.vm 477914 2006-11-21 21:52:11Z henning $ *#
      $request.getRequestURI()

      We are on the submitted page. These are the values that were posted:
      $testForm.propA
      $testForm.propB

      Return to form test page.

      Go to true page.
      Go to false page.
      Go to any page. velocity-tools-2.0-src/examples/struts/app6/top.html100644 0 0 2406 10730012254 17777 0ustar 0 0
      This app uses the extension custom tags and also uses the custom request processor (see the struts-config for this app). If the custom request processor is not used then the request will not be redirected to the correct protocol if an action URL is manually entered into the browser with the wrong protocol.

      Look at the URLs specified for each link. Note that the correct protocol is used for each, based on the security specification in the config files.
      velocity-tools-2.0-src/examples/struts/app6/true.jsp100644 0 0 2610 10730012254 20001 0ustar 0 0 <%-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --%> <%@ taglib uri="/WEB-INF/sslext.tld" prefix="sslext"%> <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean"%>
      <%=request.getRequestURI()%>


      We are on the true page. The secure (SSL) action "true" forwards to this page.

      Try the false page.
      Try the any page.

      Go to form test page. velocity-tools-2.0-src/examples/struts/app6/true.vm100644 0 0 3631 10730012254 17633 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. #* * Copyright 2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * $Id: true.vm 477914 2006-11-21 21:52:11Z henning $ *#
      $request.getRequestURI()

      #include("/app6/top.html")
      We are on the true page. The secure (SSL) action "true" forwards to this page.

      Try the false page.
      Try the any page.

      Go to form test page. velocity-tools-2.0-src/examples/struts/app7/any.jsp100644 0 0 2575 10730012260 17621 0ustar 0 0 <%-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --%> <%@ taglib uri="/WEB-INF/sslext.tld" prefix="sslext"%> <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean"%>
      <%=request.getRequestURI()%>


      We are on the any page. The action "any" forwards to this page.

      Try the false page.
      Try the true page.

      Go to form test page. velocity-tools-2.0-src/examples/struts/app7/any.vm100644 0 0 3615 10730012260 17443 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. #* * Copyright 2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * $Id: any.vm 477914 2006-11-21 21:52:11Z henning $ *#
      $request.getRequestURI()

      #include("/app7/top.html")
      We are on the any page. The action "any" forwards to this page.

      Try the false page.
      Try the true page.

      Go to form test page. velocity-tools-2.0-src/examples/struts/app7/false.jsp100644 0 0 2614 10730012260 20116 0ustar 0 0 <%-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --%> <%@ taglib uri="/WEB-INF/sslext.tld" prefix="sslext"%> <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean"%>
      <%=request.getRequestURI()%>


      We are on the false page. The non-secure (non-SSL) action "false" forwards to this page.

      Try the true page.
      Try the any page.

      Go to form test page. velocity-tools-2.0-src/examples/struts/app7/false.vm100644 0 0 3636 10730012260 17751 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. #* * Copyright 2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * $Id: false.vm 477914 2006-11-21 21:52:11Z henning $ *#
      $request.getRequestURI()

      #include("/app7/top.html")
      We are on the false page. The non-secure (non-SSL) action "false" forwards to this page.

      Try the true page.
      Try the any page.

      Go to form test page. velocity-tools-2.0-src/examples/struts/app7/form.jsp100644 0 0 3246 10730012260 17771 0ustar 0 0 <%-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --%> <%@ taglib uri="/WEB-INF/sslext.tld" prefix="sslext"%> <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html"%>
      <%=request.getRequestURI()%>

      We are on the form page. View the page source to see the difference in the action attribute values between the two forms.

      This posts to a secure action.


      This posts to a non-secure action.


      velocity-tools-2.0-src/examples/struts/app7/form.vm100644 0 0 4412 10730012260 17613 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. #* * Copyright 2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * $Id: form.vm 477914 2006-11-21 21:52:11Z henning $ *#
      $request.getRequestURI()

      We are on the form page. View the page source to see the difference in the action attribute values between the two forms.

      This posts to a secure action.


      This posts to a non-secure action.


      velocity-tools-2.0-src/examples/struts/app7/submitted.jsp100644 0 0 3000 10730012260 21012 0ustar 0 0 <%-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --%> <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %> <%@ taglib uri="/WEB-INF/sslext.tld" prefix="sslext"%>
      <%=request.getRequestURI()%>

      We are on the submitted page. These are the values that were posted:



      Return to form test page.

      Go to true page.
      Go to false page.
      Go to any page. velocity-tools-2.0-src/examples/struts/app7/submitted.vm100644 0 0 3730 10730012260 20652 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. #* * Copyright 2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * $Id: submitted.vm 477914 2006-11-21 21:52:11Z henning $ *#
      $request.getRequestURI()

      We are on the submitted page. These are the values that were posted:
      $testForm.propA
      $testForm.propB

      Return to form test page.

      Go to true page.
      Go to false page.
      Go to any page. velocity-tools-2.0-src/examples/struts/app7/top.html100644 0 0 2404 10730012260 17773 0ustar 0 0
      This app uses the extension custom tags and also uses the custom request processor (see the struts-config for this app). If the custom request processor is not used then the request will not be redirected to the correct protocol if an action URL is manually entered into the browser with the wrong protocol.

      Look at the URLs specified for each link. Note that the correct protocol is used for each, based on the security specification in the config files.
      velocity-tools-2.0-src/examples/struts/app7/true.jsp100644 0 0 2610 10730012260 17777 0ustar 0 0 <%-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --%> <%@ taglib uri="/WEB-INF/sslext.tld" prefix="sslext"%> <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean"%>
      <%=request.getRequestURI()%>


      We are on the true page. The secure (SSL) action "true" forwards to this page.

      Try the false page.
      Try the any page.

      Go to form test page. velocity-tools-2.0-src/examples/struts/app7/true.vm100644 0 0 3631 10730012260 17631 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. #* * Copyright 2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * $Id: true.vm 477914 2006-11-21 21:52:11Z henning $ *#
      $request.getRequestURI()

      #include("/app7/top.html")
      We are on the true page. The secure (SSL) action "true" forwards to this page.

      Try the false page.
      Try the any page.

      Go to form test page. velocity-tools-2.0-src/examples/struts/examples.vm100644 0 0 13016 10730012260 17637 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. VelocityStruts $version


      Velocity for Struts 1.3.x

      Home > Examples
      Examples
      • Struts App1: Address Editor
        This application is a very simple address editor. It consists of two dynamic pages, one ActionForm, one Action class and an AddressBean. Address information is gathered through a form and associated with a HTTP session. This information can be displayed and modified. It demonstrates how the Struts control framework can be used independently of a specific view technology. JSP and Velocity templates can be mixed and matched within the same application. The support for multiple languages demonstrates how Struts resources may be accessed from within templates.

         

      • Struts App2: Struts View Tools Demo
        This application demonstrates the Velocity view tools for Struts. These view tool enable view designers to access the resources of the Struts framework. Their functionality is a subset of the functionality provided by the Struts custom tag libraries for JSP.

         

      • Struts App3: Struts Logon Example
        This is the well known Struts logon example application by Ted Husted. Here it is implemented in both JSP and Velocity versions.

         

      • Struts App4: Struts Tiles Example
        This application demonstrates the Velocity TilesTool for Struts. It's functionality is a subset of the functionality provided by the Struts Tiles tag library for JSP.

         

      • Struts App5: Struts Validator Example
        This application demonstrates the Velocity ValidatorTool for Struts. It's functionality is a subset of the functionality provided by the Struts HTML tag library for JSP.

         

      • Struts App6: Struts SSL Ext. Example
        This application demonstrates the SecureLinkTool for Struts. It's functionality is a subset of the functionality provided by the SSL Ext. tag library for JSP.
        SSL Ext. is a very useful extension to the Struts framework that enables you to declare actions secure, non-secure or neutral in the struts-config. For more information see the project's homepage. This example app is a stripped down version of the demo that comes with the SSL Ext. package.
        In order to try out this example app you have to have SSL set up and enabled on your web server. The test app defaults to ports 8080 for http and 8443 for https - if you use other ports for these protocols you need to change the settings in the app's struts-config.

         

      • Struts App7: Struts Tiles + SSL Ext. Example
        This application is the same as app 6 except for the struts-config and the added tiles-config. It shows how to use Tiles and SSL Ext. together in the same application.

         

      velocity-tools-2.0-src/examples/struts/index.vm100644 0 0 6031 11110347753 17122 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. VelocityStruts $version


      VelocityStruts

      Version $version
       

      VelocityStruts is a subproject of the Apache Velocity project.
      This is an example web application demonstrating the integration of the Struts 1.x web application framework with the Velocity template engine.

      Highlights
      • Velocity is now becoming an alternative view technology for Struts-based Web applications.
      • Velocity templates can be mixed with JSP templates in the same application.
      • No changes are required to Struts. This works with Struts 1.3.x.
      Status

      A great deal of progress has been made since our 1.0 release. These include support for Struts 1.1 features like modules, Tiles, and Validator. These features have been enhanced further to support Struts 1.3.x. For a more complete listing, see the project change log.

      Application Examples

      Seven small application examples have been included. Look at example 2 for a demonstration of the Velocity view tools for Struts. JSP versions of some of the examples have been included to allow a direct comparison of the two view technologies.

      Documentation

      This project is hosted at velocity.apache.org. There you find the latest news and instructions to download the software.

      The project documentation is available online.

      Feedback

      We really appreciated your feedback. Please send your feedback and questions to the Velocity Users Mailing List at user@velocity.apache.org.

      velocity-tools-2.0-src/examples/struts/styles.css100644 0 0 6011 10730012260 17467 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ BODY { background-color: #C4CDEE; } A:link { color: #0000FF; text-decoration: underline; } A:visited { color: #880088; text-decoration: underline; } TD { font-family: sans-serif, Verdana, Arial, Helvetica, sans-serif; font-size: 10pt } P { font-family: sans-serif, Verdana, Arial, Helvetica, sans-serif; font-size: 10pt } UL { font-family: sans-serif, Verdana, Arial, Helvetica, sans-serif; font-size: 10pt } DIV { font-family: sans-serif, Verdana, Arial, Helvetica, sans-serif; font-size: 10pt } H1 { font-family: sans-serif, Verdana, Arial, Helvetica, sans-serif; font-size: 20pt; font-weight: bold; } H2 { font-family: sans-serif, Verdana, Arial, Helvetica, sans-serif; font-size: 18pt; font-weight: bold; } H3 { font-family: sans-serif, Verdana, Arial, Helvetica, sans-serif; font-size: 16pt; font-weight: bold; } H4 { font-family: sans-serif, Verdana, Arial, Helvetica, sans-serif; font-size: 14pt; font-weight: bold; } H5 { font-family: sans-serif, Verdana, Arial, Helvetica, sans-serif; font-size: 12pt; font-weight: bold; } H6 { font-family: sans-serif, Verdana, Arial, Helvetica, sans-serif; font-size: 10pt; font-weight: bold; } .menuecell { font-family: sans-serif, Verdana, Arial, Helvetica, sans-serif; font-size: 10pt; font-weight: bold; text-align: center } .errormsg { font-family: sans-serif, Verdana, Arial, Helvetica, sans-serif; font-size: 10pt; font-weight: bold; color: #FF0000; vertical-align: middle } #.tableWithBorder { border-width: 1px; border-color: #FF0000; border-style: solid } #.cellWithBorder { border-width: 1px; border-color: #FF0000; border-style: solid } #tableWithBorder { border-width: 1px; border-color: #FF0000; border-style: solid } #cellWithBorder { border-width: 1px; border-color: #FF0000; border-style: solid } .bg { background-color: #808080 } .fg { background-color: #C4CDEE } .inactive { background-color: #BBBBBB } .op { background-color: #DDDDDD } .opc { background-color: #DDDDDD; text-align: center } .calendarTag { font-size: 36pt } velocity-tools-2.0-src/pom.xml100644 0 0 43430 11360651464 13632 0ustar 0 0 4.0.0 org.apache.velocity velocity-tools VelocityTools 2.0 jar Apache Software Foundation http://velocity.apache.org/ http://velocity.apache.org/tools/devel/ VelocityTools is an integrated collection of Velocity subprojects with the common goal of creating tools and infrastructure to speed and ease development of both web and non-web applications using the Velocity template engine. 2002 The Apache Software License, Version 2.0 http://www.apache.org/licenses/LICENSE-2.0.txt repo A business-friendly OSS license install build/classes dist org.apache.maven.plugins maven-compiler-plugin 1.5 1.5 org.apache.maven.plugins maven-site-plugin UTF-8 UTF-8 org.apache.maven.plugins maven-surefire-plugin **/Test*.java **/*Test.java **/*TestCase.java **/*Tests.java src/main/java **/*.java velocity.apache.org scpexe://people.apache.org/www/velocity.apache.org/tools/releases/velocity-tools-2.0/ apache.releases Apache Release Distribution Repository scp://people.apache.org/www/people.apache.org/repo/m2-ibiblio-rsync-repository apache.snapshots Apache Development Snapshot Repository scp://people.apache.org/www/people.apache.org/repo/m2-snapshot-repository nbubna Nathan Bubna nbubna@apache.org ESHA Research -8 Java Developer henning Henning Schmiedehausen henning@apache.org Java Developer wglass Will Glass-Husain wglass@apache.org Java Developer geirm Geir Magnusson Jr. geirm@apache.org Java Developer dlr Daniel Rall dlr@apache.org Java Developer marino Marinó A. Jónsson marino@apache.org Java Developer cbrisson Claude Brisson cbrisson@apache.org Java Developer Craig R. McClanahan Christopher Schultz Chris Townsen Dave Bryson David Graham David Winterfeldt Denis Bredelet Dmitri Colebatch Gabriel Sidler Jon S. Stevens Kent Johnson Leon Messerschmidt Mike Kienenberger S. Brett Sutton Shinobu Kawai Ted Husted Tim Colson org.apache.maven.plugins maven-project-info-reports-plugin dependencies issue-tracking license summary scm org.apache.maven.plugins maven-changes-plugin changes-report jira-report sorter/field=issuekey&sorter/order=ASC 100 http://velocity.apache.org/who-we-are.html org.codehaus.mojo taglist-maven-plugin TODO FIXME org.apache.maven.plugins maven-jxr-plugin org.apache.maven.plugins maven-javadoc-plugin http://java.sun.com/j2se/1.5.0/docs/api http://jakarta.apache.org/commons/lang/api-release http://jakarta.apache.org/commons/logging/api-release http://jakarta.apache.org/commons/collections/api-release http://logging.apache.org/log4j/docs/api http://velocity.apache.org/engine/releases/velocity-1.5/apidocs org.apache.maven.plugins maven-changelog-plugin Velocity User List user-subscribe@velocity.apache.org user-unsubscribe@velocity.apache.org http://mail-archives.apache.org/mod_mbox/velocity-user/ http://marc.theaimsgroup.com/?l=velocity-user&r=1&w=2 http://dir.gmane.org/gmane.comp.jakarta.velocity.user http://www.nabble.com/Velocity---User-f347.html http://www.mail-archive.com/user%40velocity.apache.org/ http://www.mail-archive.com/velocity-user%40jakarta.apache.org/ Velocity Developer List dev-subscribe@velocity.apache.org dev-unsubscribe@velocity.apache.org http://mail-archives.apache.org/mod_mbox/velocity-dev/ http://marc.theaimsgroup.com/?l=velocity-dev&r=1&w=2/ http://dir.gmane.org/gmane.comp.jakarta.velocity.devel http://www.nabble.com/Velocity---Dev-f346.html http://www.mail-archive.com/dev%40velocity.apache.org/ http://www.mail-archive.com/velocity-dev%40jakarta.apache.org/ JIRA http://issues.apache.org/jira/browse/VELTOOLS scm:svn:http://svn.apache.org/repos/asf/velocity/tools/trunk scm:svn:https://svn.apache.org/repos/asf/velocity/tools/trunk HEAD http://svn.apache.org/repos/asf/velocity/tools/trunk commons-beanutils commons-beanutils 1.7.0 commons-digester commons-digester 1.8 commons-chain commons-chain 1.1 javax.portlet portlet-api myfaces myfaces-api commons-collections commons-collections 3.2 commons-lang commons-lang 2.2 true commons-logging commons-logging 1.1 avalon-framework avalon-framework logkit logkit log4j log4j commons-validator commons-validator 1.3.1 xml-apis xml-apis dom4j dom4j 1.1 compile javax.servlet servlet-api 2.3 provided oro oro 2.0.8 sslext sslext 1.2-0 struts struts org.apache.struts struts-core 1.3.8 org.apache.struts struts-taglib 1.3.8 org.apache.struts struts-tiles 1.3.8 org.apache.velocity velocity 1.6.2 httpunit httpunit 1.6.1 test org.mortbay.jetty jetty-embedded 6.0.1 test org.mortbay.jetty jetty-embedded 6.0.1 test nekohtml nekohtml 0.9.5 test rhino js 1.6R5 test xerces xercesImpl 2.8.1 test xerces xmlParserAPIs 2.6.2 test junit junit 4.1 test velocity-tools-2.0-src/src/main/java/META-INF/velocity-view.tld100644 0 0 10455 11360645210 21415 0ustar 0 0 1.0 1.2 velocity http://velocity.apache.org/velocity-view VelocityView Tag view org.apache.velocity.tools.view.jsp.VelocityViewTag tagdependent id false true cache false true var false true scope false true template false true bodyContentKey false true velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/ClassUtils.java100644 0 0 30007 11110347753 24700 0ustar 0 0 package org.apache.velocity.tools; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.io.InputStream; import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Enumeration; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.velocity.util.ArrayIterator; import org.apache.velocity.util.EnumerationIterator; /** * Repository for common class and reflection methods. * * @author Nathan Bubna * @version $Id: ClassUtils.java 511959 2007-02-26 19:24:39Z nbubna $ */ public class ClassUtils { public static final ClassUtils INSTANCE = new ClassUtils(); private ClassUtils() {} public ClassUtils getInstance() { return INSTANCE; } // shortcuts for readability... private static final ClassLoader getThreadContextLoader() { return Thread.currentThread().getContextClassLoader(); } private static final ClassLoader getClassLoader() { return ClassUtils.class.getClassLoader(); } private static final ClassLoader getCallerLoader(Object caller) { if (caller instanceof Class) { return ((Class)caller).getClassLoader(); } else { return caller.getClass().getClassLoader(); } } /** * Load a class with a given name. *

      * It will try to load the class in the following order: *

        *
      • From {@link Thread}.currentThread().getContextClassLoader() *
      • Using the basic {@link Class#forName(java.lang.String) } *
      • From {@link ClassUtils}.class.getClassLoader() *
      * * @param name Fully qualified class name to be loaded * @return Class object * @exception ClassNotFoundException if the class cannot be found */ public static Class getClass(String name) throws ClassNotFoundException { try { return getThreadContextLoader().loadClass(name); } catch (ClassNotFoundException e) { try { return Class.forName(name); } catch (ClassNotFoundException ex) { return getClassLoader().loadClass(name); } } } public static Object getInstance(String classname) throws ClassNotFoundException, IllegalAccessException, InstantiationException { return getClass(classname).newInstance(); } /** * Load all resources with the specified name. If none are found, we * prepend the name with '/' and try again. * * This will attempt to load the resources from the following methods (in order): *
        *
      • Thread.currentThread().getContextClassLoader().getResources(name)
      • *
      • {@link ClassUtils}.class.getClassLoader().getResources(name)
      • *
      • {@link ClassUtils}.class.getResource(name)
      • *
      • {@link #getCallerLoader(Object caller)}.getResources(name)
      • *
      • caller.getClass().getResource(name)
      • *
      * * @param name The name of the resources to load * @param caller The instance or {@link Class} calling this method */ public static List getResources(String name, Object caller) { Set urls = new LinkedHashSet(); // try to load all from the current thread context classloader addResources(name, urls, getThreadContextLoader()); // try to load all from this class' classloader if (!addResources(name, urls, getClassLoader())) { // ok, try to load one directly from this class addResource(name, urls, ClassUtils.class); } // try to load all from the classloader of the calling class if (!addResources(name, urls, getCallerLoader(caller))) { // try to load one directly from the calling class addResource(name, urls, caller.getClass()); } if (!urls.isEmpty()) { List result = new ArrayList(urls.size()); try { for (String url : urls) { result.add(new URL(url)); } } catch (MalformedURLException mue) { throw new IllegalStateException("A URL could not be recreated from its own toString() form", mue); } return result; } else if (!name.startsWith("/")) { // try again with a / in front of the name return getResources("/"+name, caller); } else { return Collections.emptyList(); } } private static final void addResource(String name, Set urls, Class c) { URL url = c.getResource(name); if (url != null) { urls.add(url.toString()); } } private static final boolean addResources(String name, Set urls, ClassLoader loader) { boolean foundSome = false; try { Enumeration e = loader.getResources(name); while (e.hasMoreElements()) { urls.add(e.nextElement().toString()); foundSome = true; } } catch (IOException ioe) { // ignore } return foundSome; } /** * Load a given resource. *

      * This method will try to load the resource using the following methods (in order): *

        *
      • Thread.currentThread().getContextClassLoader().getResource(name)
      • *
      • {@link ClassUtils}.class.getClassLoader().getResource(name)
      • *
      • {@link ClassUtils}.class.getResource(name)
      • *
      • caller.getClass().getResource(name) or, if caller is a Class, * caller.getResource(name)
      • *
      * * @param name The name of the resource to load * @param caller The instance or {@link Class} calling this method */ public static URL getResource(String name, Object caller) { URL url = getThreadContextLoader().getResource(name); if (url == null) { url = getClassLoader().getResource(name); if (url == null) { url = ClassUtils.class.getResource(name); if (url == null && caller != null) { Class callingClass = caller.getClass(); if (callingClass == Class.class) { callingClass = (Class)caller; } url = callingClass.getResource(name); } } } return url; } /** * This is a convenience method to load a resource as a stream. *

      * The algorithm used to find the resource is given in getResource() * * @param name The name of the resource to load * @param caller The instance or {@link Class} calling this method */ public static InputStream getResourceAsStream(String name, Object caller) { URL url = getResource(name, caller); try { return (url == null) ? null : url.openStream(); } catch (IOException e) { return null; } } public static Method findMethod(Class clazz, String name, Class[] params) throws SecurityException { try { // check for a public setup(Map) method first return clazz.getMethod(name, params); } catch (NoSuchMethodException nsme) { // ignore this } return findDeclaredMethod(clazz, name, params); } public static Method findDeclaredMethod(Class clazz, String name, Class[] params) throws SecurityException { try { // check for a protected one Method method = clazz.getDeclaredMethod(name, params); if (method != null) { // and give this class access to it method.setAccessible(true); return method; } } catch (NoSuchMethodException nsme) { // ignore this } // ok, didn't find it declared in this class, try the superclass Class supclazz = clazz.getSuperclass(); if (supclazz != null) { // recurse upward return findDeclaredMethod(supclazz, name, params); } // otherwise, return null return null; } public static Object getFieldValue(String fieldPath) throws ClassNotFoundException, NoSuchFieldException, SecurityException, IllegalAccessException { int lastDot = fieldPath.lastIndexOf('.'); String classname = fieldPath.substring(0, lastDot); String fieldname = fieldPath.substring(lastDot + 1, fieldPath.length()); Class clazz = getClass(classname); return getFieldValue(clazz, fieldname); } public static Object getFieldValue(Class clazz, String fieldname) throws NoSuchFieldException, SecurityException, IllegalAccessException { Field field = clazz.getField(fieldname); int mod = field.getModifiers(); if (!Modifier.isStatic(mod)) { throw new UnsupportedOperationException("Field "+fieldname+" in class "+clazz.getName()+" is not static. Only static fields are supported."); } return field.get(null); } /** * Retrieves an Iterator from or creates and Iterator for the specified object. * This method is almost entirely copied from Engine's UberspectImpl class. */ public static Iterator getIterator(Object obj) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { if (obj.getClass().isArray()) { return new ArrayIterator(obj); } else if (obj instanceof Collection) { return ((Collection) obj).iterator(); } else if (obj instanceof Map) { return ((Map) obj).values().iterator(); } else if (obj instanceof Iterator) { return ((Iterator) obj); } else if (obj instanceof Iterable) { return ((Iterable)obj).iterator(); } else if (obj instanceof Enumeration) { return new EnumerationIterator((Enumeration) obj); } else { // look for an iterator() method to support // any user tools/DTOs that want to work in // foreach w/o implementing the Collection interface Method iter = obj.getClass().getMethod("iterator"); if (Iterator.class.isAssignableFrom(iter.getReturnType())) { return (Iterator)iter.invoke(obj); } else { return null; } } } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/ConversionUtils.java100644 0 0 55300 11202122667 25760 0ustar 0 0 package org.apache.velocity.tools; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.io.File; import java.lang.reflect.Array; import java.net.URL; import java.text.DateFormat; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; import java.text.NumberFormat; import java.text.SimpleDateFormat; import java.util.Collection; import java.util.Date; import java.util.Calendar; import java.util.Locale; import java.util.TimeZone; /** * Utility methods for parsing or otherwise converting between types. * Current supported types are Number, Date, Calendar, * String, Boolean, Locale and URL * * @author Nathan Bubna */ public class ConversionUtils { public static final ConversionUtils INSTANCE = new ConversionUtils(); private static final int STYLE_NUMBER = 0; private static final int STYLE_CURRENCY = 1; private static final int STYLE_PERCENT = 2; //NOTE: '3' belongs to a non-public "scientific" style private static final int STYLE_INTEGER = 4; private ConversionUtils() {} public ConversionUtils getInstance() { return INSTANCE; } /** * Returns a {@link NumberFormat} instance for the specified * format and {@link Locale}. If the format specified is a standard * style pattern, then a number instance * will be returned with the number style set to the * specified style. If it is a custom format, then a customized * {@link NumberFormat} will be returned. * * @param format the custom or standard formatting pattern to be used * @param locale the {@link Locale} to be used * @return an instance of {@link NumberFormat} * @see NumberFormat */ public static NumberFormat getNumberFormat(String format, Locale locale) { if (format == null || locale == null) { return null; } NumberFormat nf = null; int style = getNumberStyleAsInt(format); if (style < 0) { // we have a custom format nf = new DecimalFormat(format, new DecimalFormatSymbols(locale)); } else { // we have a standard format nf = getNumberFormat(style, locale); } return nf; } /** * Returns a {@link NumberFormat} instance for the specified * number style and {@link Locale}. * * @param numberStyle the number style (number will be ignored if this is * less than zero or the number style is not recognized) * @param locale the {@link Locale} to be used * @return an instance of {@link NumberFormat} or null * if an instance cannot be constructed with the given * parameters */ public static NumberFormat getNumberFormat(int numberStyle, Locale locale) { try { NumberFormat nf; switch (numberStyle) { case STYLE_NUMBER: nf = NumberFormat.getNumberInstance(locale); break; case STYLE_CURRENCY: nf = NumberFormat.getCurrencyInstance(locale); break; case STYLE_PERCENT: nf = NumberFormat.getPercentInstance(locale); break; case STYLE_INTEGER: nf = NumberFormat.getIntegerInstance(locale); break; default: // invalid style was specified, return null nf = null; } return nf; } catch (Exception suppressed) { // let it go... return null; } } /** * Checks a string to see if it matches one of the standard * NumberFormat style patterns: * number, currency, percent, integer, or default. * if it does it will return the integer constant for that pattern. * if not, it will return -1. * * @see NumberFormat * @param style the string to be checked * @return the int identifying the style pattern */ public static int getNumberStyleAsInt(String style) { // avoid needlessly running through all the string comparisons if (style == null || style.length() < 6 || style.length() > 8) { return -1; } if (style.equalsIgnoreCase("default")) { //NOTE: java.text.NumberFormat returns "number" instances // as the default (at least in Java 1.3 and 1.4). return STYLE_NUMBER; } if (style.equalsIgnoreCase("number")) { return STYLE_NUMBER; } if (style.equalsIgnoreCase("currency")) { return STYLE_CURRENCY; } if (style.equalsIgnoreCase("percent")) { return STYLE_PERCENT; } if (style.equalsIgnoreCase("integer")) { return STYLE_INTEGER; } // ok, it's not any of the standard patterns return -1; } // ----------------- number conversion methods --------------- /** * Attempts to convert an unidentified {@link Object} into a {@link Number}, * just short of turning it into a string and parsing it. In other words, * this will convert to {@link Number} from a {@link Number}, {@link Calendar}, * or {@link Date}. If it can't do that, it will get the string value and have * {@link #toNumber(String,String,Locale)} try to parse it using the * default Locale and format. * @param obj - the object to convert */ public static Number toNumber(Object obj) { return toNumber(obj, true); } /** * Just like {@link #toNumber(Object)} except that you can tell * this to attempt parsing the object as a String by passing {@code true} * as the second parameter. If you do so, then it will have * {@link #toNumber(String,String,Locale)} try to parse it using the * default Locale and format. */ public static Number toNumber(Object obj, boolean handleStrings) { if (obj == null) { return null; } if (obj instanceof Number) { return (Number)obj; } if (obj instanceof Date) { return Long.valueOf(((Date)obj).getTime()); } if (obj instanceof Calendar) { Date date = ((Calendar)obj).getTime(); return Long.valueOf(date.getTime()); } if (handleStrings) { // try parsing with default format and locale return toNumber(obj.toString(), "default", Locale.getDefault()); } return null; } /** * Converts a string to an instance of {@link Number} using the * specified format and {@link Locale} to parse it. * * @param value - the string to convert * @param format - the format the number is in * @param locale - the {@link Locale} * @return the string as a {@link Number} or null if no * conversion is possible * @see NumberFormat#parse */ public static Number toNumber(String value, String format, Locale locale) { if (value == null || format == null || locale == null) { return null; } try { NumberFormat parser = getNumberFormat(format, locale); return parser.parse(value); } catch (Exception e) { return null; } } /** * Converts an object to an instance of {@link Number} using the * specified format and {@link Locale} to parse it, if necessary. * * @param value - the object to convert * @param format - the format the number is in * @param locale - the {@link Locale} * @return the object as a {@link Number} or null if no * conversion is possible * @see NumberFormat#parse */ public static Number toNumber(Object value, String format, Locale locale) { // first try the easy stuff Number number = toNumber(value, false); if (number != null) { return number; } // turn it into a string and try parsing it return toNumber(String.valueOf(value), format, locale); } // -------------------------- DateFormat creation methods -------------- /** * Returns a {@link DateFormat} instance for the specified * format, {@link Locale}, and {@link TimeZone}. If the format * specified is a standard style pattern, then a date-time instance * will be returned with both the date and time styles set to the * specified style. If it is a custom format, then a customized * {@link SimpleDateFormat} will be returned. * * @param format the custom or standard formatting pattern to be used * @param locale the {@link Locale} to be used * @param timezone the {@link TimeZone} to be used * @return an instance of {@link DateFormat} * @see SimpleDateFormat * @see DateFormat */ public static DateFormat getDateFormat(String format, Locale locale, TimeZone timezone) { if (format == null) { return null; } DateFormat df = null; // do they want a date instance if (format.endsWith("_date")) { String fmt = format.substring(0, format.length() - 5); int style = getDateStyleAsInt(fmt); df = getDateFormat(style, -1, locale, timezone); } // do they want a time instance? else if (format.endsWith("_time")) { String fmt = format.substring(0, format.length() - 5); int style = getDateStyleAsInt(fmt); df = getDateFormat(-1, style, locale, timezone); } // ok, they either want a custom or date-time instance else { int style = getDateStyleAsInt(format); if (style < 0) { // we have a custom format df = new SimpleDateFormat(format, locale); df.setTimeZone(timezone); } else { // they want a date-time instance df = getDateFormat(style, style, locale, timezone); } } return df; } /** * Returns a {@link DateFormat} instance for the specified * date style, time style, {@link Locale}, and {@link TimeZone}. * * @param dateStyle the date style * @param timeStyle the time style * @param locale the {@link Locale} to be used * @param timezone the {@link TimeZone} to be used * @return an instance of {@link DateFormat} * @see #getDateFormat(int timeStyle, int dateStyle, Locale locale, TimeZone timezone) */ public static DateFormat getDateFormat(String dateStyle, String timeStyle, Locale locale, TimeZone timezone) { int ds = getDateStyleAsInt(dateStyle); int ts = getDateStyleAsInt(timeStyle); return getDateFormat(ds, ts, locale, timezone); } /** * Returns a {@link DateFormat} instance for the specified * time style, date style, {@link Locale}, and {@link TimeZone}. * * @param dateStyle the date style (date will be ignored if this is * less than zero and the date style is not) * @param timeStyle the time style (time will be ignored if this is * less than zero and the date style is not) * @param locale the {@link Locale} to be used * @param timezone the {@link TimeZone} to be used * @return an instance of {@link DateFormat} or null * if an instance cannot be constructed with the given * parameters */ public static DateFormat getDateFormat(int dateStyle, int timeStyle, Locale locale, TimeZone timezone) { try { DateFormat df; if (dateStyle < 0 && timeStyle < 0) { // no style was specified, use default instance df = DateFormat.getInstance(); } else if (timeStyle < 0) { // only a date style was specified df = DateFormat.getDateInstance(dateStyle, locale); } else if (dateStyle < 0) { // only a time style was specified df = DateFormat.getTimeInstance(timeStyle, locale); } else { df = DateFormat.getDateTimeInstance(dateStyle, timeStyle, locale); } df.setTimeZone(timezone); return df; } catch (Exception suppressed) { // let it go... return null; } } /** * Checks a string to see if it matches one of the standard DateFormat * style patterns: full, long, medium, short, or default. If it does, * it will return the integer constant for that pattern. If not, it * will return -1. * * @see DateFormat * @param style the string to be checked * @return the int identifying the style pattern */ public static int getDateStyleAsInt(String style) { // avoid needlessly running through all the string comparisons if (style == null || style.length() < 4 || style.length() > 7) { return -1; } if (style.equalsIgnoreCase("full")) { return DateFormat.FULL; } if (style.equalsIgnoreCase("long")) { return DateFormat.LONG; } if (style.equalsIgnoreCase("medium")) { return DateFormat.MEDIUM; } if (style.equalsIgnoreCase("short")) { return DateFormat.SHORT; } if (style.equalsIgnoreCase("default")) { return DateFormat.DEFAULT; } // ok, it's not any of the standard patterns return -1; } // ----------------- date conversion methods --------------- /** * Attempts to convert an unidentified {@link Object} into a {@link Date}, * just short of turning it into a string and parsing it. In other words, * this will convert to {@link Date} from a {@link Date}, {@link Calendar}, * or {@link Number}. If it can't do that, it will return {@code null}. * * @param obj - the object to convert */ public static Date toDate(Object obj) { if (obj == null) { return null; } if (obj instanceof Date) { return (Date)obj; } if (obj instanceof Calendar) { return ((Calendar)obj).getTime(); } if (obj instanceof Number) { Date d = new Date(); d.setTime(((Number)obj).longValue()); return d; } return null; } /** * Converts an object to an instance of {@link Date} using the * specified format, {@link Locale}, and {@link TimeZone} if the * object is not already an instance of Date, Calendar, or Long. * * @param obj - the date to convert * @param format - the format the date is in * @param locale - the {@link Locale} * @param timezone - the {@link TimeZone} * @return the object as a {@link Date} or null if no * conversion is possible * @see #getDateFormat * @see SimpleDateFormat#parse */ public static Date toDate(Object obj, String format, Locale locale, TimeZone timezone) { // first try the easy stuff Date date = toDate(obj); if (date != null) { return date; } // turn it into a string and try parsing it return toDate(String.valueOf(obj), format, locale, timezone); } /** * Converts an object to an instance of {@link Date} using the * specified format, {@link Locale}, and {@link TimeZone} if the * object is not already an instance of Date, Calendar, or Long. * * @param str - the string to parse * @param format - the format the date is in * @param locale - the {@link Locale} * @param timezone - the {@link TimeZone} * @return the string as a {@link Date} or null if the * parsing fails * @see #getDateFormat * @see SimpleDateFormat#parse */ public static Date toDate(String str, String format, Locale locale, TimeZone timezone) { try { //try parsing w/a customized SimpleDateFormat DateFormat parser = getDateFormat(format, locale, timezone); return parser.parse(str); } catch (Exception e) { return null; } } public static Calendar toCalendar(Date date, Locale locale) { if (date == null) { return null; } Calendar cal; if (locale == null) { cal = Calendar.getInstance(); } else { cal = Calendar.getInstance(locale); } cal.setTime(date); // HACK: Force all fields to update. see link for explanation of this. //http://java.sun.com/j2se/1.4/docs/api/java/util/Calendar.html cal.getTime(); return cal; } // ----------------- misc conversion methods --------------- /** * Converts objects to String in a more Tools-ish way than * String.valueOf(Object), especially with nulls, Arrays and Collections. * Null returns null, Arrays and Collections return their first value, * or null if they have no values. * * @param value the object to be turned into a String * @return the string value of the object or null if the value is null * or it is an array whose first value is null */ public static String toString(Object value) { if (value instanceof String) { return (String)value; } if (value == null) { return null; } if (value.getClass().isArray()) { if (Array.getLength(value) > 0) { // recurse on the first value return toString(Array.get(value, 0)); } return null; } return String.valueOf(value); } /** * Returns the first value as a String, if any; otherwise returns null. * * @param values the Collection to be turned into a string * @return the string value of the first object in the collection * or null if the collection is empty */ public static String toString(Collection values) { if (values != null && !values.isEmpty()) { // recurse on the first value return toString(values.iterator().next()); } return null; } /** * Converts any Object to a boolean using {@link #toString(Object)} * and {@link Boolean#valueOf(String)}. * * @param value the object to be converted * @return a {@link Boolean} object for the specified value or * null if the value is null or the conversion failed */ public static Boolean toBoolean(Object value) { if (value instanceof Boolean) { return (Boolean)value; } String s = toString(value); return (s != null) ? Boolean.valueOf(s) : null; } /** * Converts a string to a {@link Locale} * * @param value - the string to parse * @return the {@link Locale} or null if the * parsing fails */ public static Locale toLocale(String value) { if (value.indexOf('_') < 0) { return new Locale(value); } String[] params = value.split("_"); if (params.length == 2) { return new Locale(params[0], params[1]); } else if (params.length == 3) { return new Locale(params[0], params[1], params[2]); } else { // there's only 3 possible params, so this must be invalid return null; } } /** * Converts a string to a {@link URL}. It will first try to * treat the string as a File name, then a classpath resource, * then finally as a literal URL. If none of these work, then * this will return {@code null}. * * @param value - the string to parse * @return the {@link URL} form of the string or {@code null} * @see File * @see ClassUtils#getResource(String,Object) * @see URL */ public static URL toURL(String value) { return toURL(value, ConversionUtils.class); } /** * Converts a string to a {@link URL}. It will first try to * treat the string as a File name, then a classpath resource, * then finally as a literal URL. If none of these work, then * this will return {@code null}. * * @param value - the string to parse * @param caller - the object or Class seeking the url * @return the {@link URL} form of the string or {@code null} * @see File * @see ClassUtils#getResource(String,Object) * @see URL */ public static URL toURL(String value, Object caller) { try { File file = new File(value); if (file.exists()) { return file.toURI().toURL(); } } catch (Exception e) {} try { URL url = ClassUtils.getResource(value, caller); if (url != null) { return url; } } catch (Exception e) {} try { return new URL(value); } catch (Exception e) {} return null; } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/OldToolInfo.java100644 0 0 5506 11030275254 24765 0ustar 0 0 package org.apache.velocity.tools; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.lang.reflect.Method; import java.util.Map; import org.apache.velocity.tools.ToolContext; /** * Manages old tools which still use the deprecated init() method. * * @author Nathan Bubna * @version $Id: OldToolInfo.java 511959 2007-02-26 19:24:39Z nbubna $ */ public class OldToolInfo extends ToolInfo { private static final long serialVersionUID = -4062162635847288761L; public static final String INIT_METHOD_NAME = "init"; private transient Method init; /** * Creates a new instance using the minimum required info * necessary for a tool. */ public OldToolInfo(String key, Class clazz) { super(key, clazz); } protected Method getInit() { if (this.init == null) { try { // try to get an init(Object) method this.init = getToolClass().getMethod("init", new Class[]{ Object.class }); } catch (NoSuchMethodException nsme) { // ignore } } return this.init; } /** * * * @param clazz the java.lang.Class of the tool */ @Override public void setClass(Class clazz) { super.setClass(clazz); // clear any existing init method this.init = null; } @Override protected void configure(Object tool, Map configuration) { // have specific setters and configure(Map) called first super.configure(tool, configuration); Method init = getInit(); if (init != null) { // ctx should, in all cases where a tool has such a method, // actually be a View(Tool)Context, but we don't want to link // to that class here, so as not to pollute the generic jar Object ctx = configuration.get(ToolContext.CONTEXT_KEY); if (ctx != null) { invoke(init, tool, ctx); } } } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/Scope.java100644 0 0 5304 10730012250 23631 0ustar 0 0 package org.apache.velocity.tools; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.util.ArrayList; import java.util.Collections; import java.util.List; /** * A specialized constants class to provide some compile-time typo checking and * runtime validation for scopes specified in annotations, toolbox configs, etc. * * @author Nathan Bubna * @version $Id: Toolbox.java 511959 2007-02-26 19:24:39Z nbubna $ */ public final class Scope { public static final String REQUEST = "request"; public static final String SESSION = "session"; public static final String APPLICATION = "application"; private static final List VALUES; static { List defaults = new ArrayList(3); defaults.add(REQUEST); defaults.add(SESSION); defaults.add(APPLICATION); VALUES = Collections.synchronizedList(defaults); } // keep an instance available in case someone wants to // drop this into a template for some reason private static final Scope INSTANCE = new Scope(); public static final Scope getInstance() { return INSTANCE; } public static final void add(String newScope) { // keep everything lower case newScope = newScope.toLowerCase(); // complain if it already exists if (VALUES.contains(newScope)) { throw new IllegalArgumentException("Scope '"+newScope+"' has already been registered."); } VALUES.add(newScope); } public static final boolean exists(String scope) { // keep everything lower case scope = scope.toLowerCase(); return VALUES.contains(scope); } public static final List values() { return Collections.unmodifiableList(VALUES); } private Scope() { // keep constructor private, this is a singleton } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/ToolContext.java100644 0 0 17070 11360645211 25076 0ustar 0 0 package org.apache.velocity.tools; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.context.Context; /** * {@link Context} implementation that keeps a list of {@link Toolbox}es * and returns them as requested, using its internal context Map as the * dynamic properties passed to the requested tools when they are first * created. * * @author Nathan Bubna * @version $Id: ToolContext.java 511959 2007-02-26 19:24:39Z nbubna $ */ public class ToolContext implements Context { public static final String PATH_KEY = "requestPath"; public static final String CONTEXT_KEY = "velocityContext"; public static final String ENGINE_KEY = "velocityEngine"; public static final String LOCALE_KEY = "locale"; public static final String LOG_KEY = "log"; public static final String CATCH_EXCEPTIONS_KEY = "catchExceptions"; private List toolboxes = new ArrayList(); // this is meant solely for tool setup, // values in here are not part of the Context private Map toolProps = new HashMap(12); // this is only for values added during use of this context private Map localContext = new HashMap(); private boolean userOverwrite = true; public ToolContext() { // add this as a common tool property putToolProperty(CONTEXT_KEY, this); } /** * Creates an instance that automatically has the specified * VelocityEngine and related tool properties set. */ public ToolContext(VelocityEngine engine) { this(); putVelocityEngine(engine); } /** * Creates an instance starting with the specified tool properties. */ public ToolContext(Map toolProps) { this(); if (toolProps != null) { this.toolProps.putAll(toolProps); } } /** * Set whether or not tool references can be overwritten within a template. * The default value is {@code true}. Set this to false if you want to * ensure that your tool references are never replaced within the course * of a template. */ public void setUserCanOverwriteTools(boolean overwrite) { this.userOverwrite = overwrite; } /** * Default is {@code true}. * @see #setUserCanOverwriteTools */ public boolean getUserCanOverwriteTools() { return this.userOverwrite; } public void addToolbox(Toolbox toolbox) { toolboxes.add(toolbox); } /** * Returns a {@link Map} of all tools available to this * context. NOTE: this is not a cheap operation as it will * request and initialize an instance of every available tool. */ public Map getToolbox() { Map aggregate = new HashMap(); Map toolProps = getToolProperties(); for (Toolbox toolbox : getToolboxes()) { aggregate.putAll(toolbox.getAll(toolProps)); } return aggregate; } /** * Gets a map of keys to classes for all available tools. * This does not include any data nor any local context values. */ public Map getToolClassMap() { Map toolClasses = new HashMap(); // go thru toolboxes backwards so final map matches // what would be found in lookups int n = getToolboxes().size(); for (int i = n - 1; i >= 0; i--) { Toolbox toolbox = getToolboxes().get(i); toolClasses.putAll(toolbox.getToolClassMap()); } return toolClasses; } protected List getToolboxes() { return this.toolboxes; } protected Map getToolProperties() { return this.toolProps; } /** * Puts the specified VelocityEngine in the tool properties, * as well as the Log for that engine. Last, if the specified * engine has a MethodExceptionEventHandler configured, then * this will automatically set {@link #CATCH_EXCEPTIONS_KEY} * to false in the tool properties. */ public void putVelocityEngine(VelocityEngine engine) { // add the engine and log as common tool properties putToolProperty(ENGINE_KEY, engine); putToolProperty(LOG_KEY, engine.getLog()); // tell interested tools not to catch exceptions whenever there's a // method exception event handler configured for the engine Object ehme = engine.getProperty(VelocityEngine.EVENTHANDLER_METHODEXCEPTION); if (ehme != null) { putToolProperty(CATCH_EXCEPTIONS_KEY, Boolean.FALSE); } } public Object putToolProperty(String key, Object value) { return toolProps.put(key, value); } public void putToolProperties(Map props) { if (props != null) { for (Map.Entry prop : props.entrySet()) { putToolProperty(prop.getKey(), prop.getValue()); } } } public Object put(String key, Object value) { return localContext.put(key, value); } public Object get(String key) { // for user overwriting, it's all a matter of which we check first Object value = userOverwrite ? internalGet(key) : findTool(key); if (value == null) { value = userOverwrite ? findTool(key) : internalGet(key); } return value; } protected Object internalGet(String key) { return localContext.get(key); } protected Object findTool(String key) { String path = (String)toolProps.get(PATH_KEY); for (Toolbox toolbox : getToolboxes()) { Object tool = toolbox.get(key, path, toolProps); if (tool != null) { return tool; } } return null; } public Set keySet() { Set keys = new HashSet(); for (Toolbox toolbox : getToolboxes()) { keys.addAll(toolbox.getKeys()); } keys.addAll(localContext.keySet()); return keys; } public boolean containsKey(Object key) { return keySet().contains(key); } public Object[] getKeys() { return keySet().toArray(); } public Object remove(Object key) { //tools and their props cannot be removed return localContext.remove(key); } public void putAll(Map context) { localContext.putAll(context); } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/ToolInfo.java100644 0 0 30136 11110347753 24346 0ustar 0 0 package org.apache.velocity.tools; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; import org.apache.commons.beanutils.PropertyUtils; import org.apache.velocity.tools.ClassUtils; import org.apache.velocity.tools.config.SkipSetters; /** * Manages data needed to create instances of a tool. New instances * are returned for every call to create(obj). * * @author Nathan Bubna * @author Henning P. Schmiedehausen * @version $Id: ToolInfo.java 511959 2007-02-26 19:24:39Z nbubna $ */ public class ToolInfo implements java.io.Serializable { private static final long serialVersionUID = -8145087882015742757L; public static final String CONFIGURE_METHOD_NAME = "configure"; private String key; private Class clazz; private boolean restrictToIsExact; private String restrictTo; private Map properties; private Boolean skipSetters; private transient Method configure = null; /** * Creates a new instance using the minimum required info * necessary for a tool. */ public ToolInfo(String key, Class clazz) { setKey(key); setClass(clazz); } /*********************** Mutators *************************/ public void setKey(String key) { this.key = key; if (this.key == null) { throw new NullPointerException("Key cannot be null"); } } /** * Tries to create an instance of the specified Class, then looks for a * configure(Map) method. * * @param clazz the java.lang.Class of the tool */ public void setClass(Class clazz) { if (clazz == null) { throw new NullPointerException("Tool class must not be null"); } this.clazz = clazz; //NOTE: we used to check here that we could get an instance of // the tool class, but that's been moved to ToolConfiguration // in order to fail as earlier as possible. most people won't // manually create ToolInfo. if they do and we can't get an // instance, they should be capable of figuring out what happened } /** * @param path the full or partial request path restriction of the tool */ public void restrictTo(String path) { if (path != null && !path.startsWith("/")) { path = "/" + path; } if (path == null || path.equals("*")) { // match all paths restrictToIsExact = false; this.restrictTo = null; } else if(path.endsWith("*")) { // match some paths restrictToIsExact = false; this.restrictTo = path.substring(0, path.length() - 1); } else { // match one path restrictToIsExact = true; this.restrictTo = path; } } public void setSkipSetters(boolean cfgOnly) { this.skipSetters = cfgOnly; } /** * Adds a map of properties from a parent scope to the properties * for this tool. Only new properties will be added; any that * are already set for this tool will be ignored. */ public void addProperties(Map parentProps) { // only add those new properties for which we // do not already have a value. first prop set wins. Map properties = getProps(); for (Map.Entry prop : parentProps.entrySet()) { if (!properties.containsKey(prop.getKey())) { properties.put(prop.getKey(), prop.getValue()); } } } /** * Puts a new property for this tool. */ public Object putProperty(String name, Object value) { return getProps().put(name, value); } protected synchronized Map getProps() { if (properties == null) { properties = new HashMap(); } return properties; } /*********************** Accessors *************************/ public String getKey() { return key; } public String getClassname() { return clazz.getName(); } public Class getToolClass() { return clazz; } public Map getProperties() { return getProps(); } public boolean hasConfigure() { return (getConfigure() != null); } public boolean isSkipSetters() { if (skipSetters == null) { skipSetters = (clazz.getAnnotation(SkipSetters.class) != null); } return skipSetters; } /** * @param path the path of a template requesting this tool * @return true if the specified * request path matches the restrictions of this tool. * If there is no request path restriction for this tool, * it will always return true. */ public boolean hasPermission(String path) { if (this.restrictTo == null) { return true; } else if (restrictToIsExact) { return this.restrictTo.equals(path); } else if (path != null) { return path.startsWith(this.restrictTo); } return false; } /*********************** create() *************************/ /** * Returns a new instance of the tool. If the tool * has an configure(Map) method, the new instance * will be initialized using the given properties combined with * whatever "constant" properties have been put into this * ToolInfo. */ public Object create(Map dynamicProperties) { /* Get the tool instance */ Object tool = newInstance(); /* put configured props into the combo last, since dynamic properties will almost always be conventions and we need to let configuration win out */ Map props; if (properties == null) { props = dynamicProperties; } else { props = combine(dynamicProperties, properties); } // perform the actual configuration of the new tool configure(tool, props); return tool; } /*********************** protected methods *************************/ /** * Actually performs configuration of the newly instantiated tool * using the combined final set of configuration properties. First, * if the class lacks the {@link SkipSetters} annotation, then any * specific setters matching the configuration keys are called, then * the general configure(Map) method (if any) is called. */ protected void configure(Object tool, Map configuration) { if (!isSkipSetters() && configuration != null) { try { // look for specific setters for (Map.Entry conf : configuration.entrySet()) { setProperty(tool, conf.getKey(), conf.getValue()); } } catch (RuntimeException re) { throw re; } catch (Exception e) { // convert to a runtime exception, and re-throw throw new RuntimeException(e); } } if (hasConfigure()) { invoke(getConfigure(), tool, configuration); } } protected Method getConfigure() { if (this.configure == null) { // search for a configure(Map params) method in the class try { this.configure = ClassUtils.findMethod(clazz, CONFIGURE_METHOD_NAME, new Class[]{ Map.class }); } catch (SecurityException se) { // fail early, rather than wait until String msg = "Unable to gain access to '" + CONFIGURE_METHOD_NAME + "(Map)'" + " method for '" + clazz.getName() + "' under the current security manager."+ " This tool cannot be properly configured for use."; throw new IllegalStateException(msg, se); } } return this.configure; } /* TODO? if we have performance issues with copyProperties, look at possibly finding and caching these common setters setContext(VelocityContext) setVelocityEngine(VelocityEngine) setLog(Log) setLocale(Locale) these four are tricky since we may not want servlet deps here setRequest(ServletRequest) setSession(HttpSession) setResponse(ServletResponse) setServletContext(ServletContext) */ protected Object newInstance() { try { return clazz.newInstance(); } /* we shouldn't get either of these exceptions here because * we already got an instance of this class during setClass(). * but to be safe, let's catch them and re-throw as RuntimeExceptions */ catch (IllegalAccessException iae) { String message = "Unable to instantiate instance of \"" + getClassname() + "\""; throw new IllegalStateException(message, iae); } catch (InstantiationException ie) { String message = "Exception while instantiating instance of \"" + getClassname() + "\""; throw new IllegalStateException(message, ie); } } protected void invoke(Method method, Object tool, Object param) { try { // call the setup method on the instance method.invoke(tool, new Object[]{ param }); } catch (IllegalAccessException iae) { String msg = "Unable to invoke " + method + " on " + tool; // restricting access to this method by this class ist verboten throw new IllegalStateException(msg, iae); } catch (InvocationTargetException ite) { String msg = "Exception when invoking " + method + " on " + tool; // convert to a runtime exception, and re-throw throw new RuntimeException(msg, ite.getCause()); } } protected void setProperty(Object tool, String name, Object value) throws Exception { if (PropertyUtils.isWriteable(tool, name)) { //TODO? support property conversion here? // heavy-handed way is BeanUtils.copyProperty(...) PropertyUtils.setProperty(tool, name, value); } } //TODO? move to Utils? protected Map combine(Map... maps) { Map combined = new HashMap(); for (Map map : maps) { if (map != null) { combined.putAll(map); } } return combined; } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/ToolManager.java100644 0 0 15224 11202122667 25023 0ustar 0 0 package org.apache.velocity.tools; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.util.Map; import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.runtime.log.Log; import org.apache.velocity.tools.Scope; import org.apache.velocity.tools.config.ConfigurationUtils; import org.apache.velocity.tools.config.FactoryConfiguration; /** * Manages tools for non-web applications. This simplifies the process * of getting a tool-populated Velocity context for merging with templates. * It allows for both direct configuration by passing in a {@link FactoryConfiguration} * as well as configuration via a tools.xml or tools.properties file in * either the classpath or the local file system. * * @author Nathan Bubna * @version $Id: ToolManager.java 511959 2007-02-26 19:24:39Z nbubna $ */ public class ToolManager { protected VelocityEngine velocity; protected ToolboxFactory factory; private Toolbox application; private boolean userOverwrite = true; /** * Constructs an instance already configured to use the * {@link ConfigurationUtils#getAutoLoaded()} configuration * and any configuration specified via a "org.apache.velocity.tools" * system property. */ public ToolManager() { this(true, true); } public ToolManager(boolean includeDefaults) { this(true, includeDefaults); } public ToolManager(boolean autoConfig, boolean includeDefaults) { this.factory = new ToolboxFactory(); if (autoConfig) { autoConfigure(includeDefaults); } } public void autoConfigure(boolean includeDefaults) { FactoryConfiguration config = ConfigurationUtils.getAutoLoaded(includeDefaults); // look for any specified via system property FactoryConfiguration sys = ConfigurationUtils.findFromSystemProperty(); if (sys != null) { config.addConfiguration(sys); } configure(config); } public void configure(FactoryConfiguration config) { // clear the cached application toolbox this.application = null; this.factory.configure(config); } public void configure(String path) { FactoryConfiguration config = findConfig(path); if (config != null) { configure(config); } else { throw new RuntimeException("Could not find any configuration at "+path); } } protected FactoryConfiguration findConfig(String path) { return ConfigurationUtils.find(path); } /** * Returns the underlying {@link ToolboxFactory} being used. */ public ToolboxFactory getToolboxFactory() { return this.factory; } /** * Sets the underlying ToolboxFactory being used. * If you use this, be sure that your ToolboxFactory * is already properly configured. */ public void setToolboxFactory(ToolboxFactory factory) { if (this.factory != factory) { if (factory == null) { throw new NullPointerException("ToolboxFactory cannot be null"); } debug("ToolboxFactory instance was changed to %s", factory); this.factory = factory; } } /** * Sets the underlying VelocityEngine being used. * If you use this, be sure that your VelocityEngine * is already properly configured and initialized. */ public void setVelocityEngine(VelocityEngine engine) { if (velocity != engine) { debug("VelocityEngine instance was changed to %s", engine); this.velocity = engine; } } public VelocityEngine getVelocityEngine() { return this.velocity; } public void setUserCanOverwriteTools(boolean overwrite) { this.userOverwrite = overwrite; } public boolean getUserCanOverwriteTools() { return this.userOverwrite; } public Log getLog() { if (velocity == null) { return null; } return velocity.getLog(); } protected final void debug(String msg, Object... args) { Log log = getLog(); if (log != null && log.isDebugEnabled()) { log.debug(String.format(msg, args)); } } public ToolContext createContext() { return createContext(null); } public ToolContext createContext(Map toolProps) { ToolContext context = new ToolContext(toolProps); prepareContext(context); return context; } protected void prepareContext(ToolContext context) { context.setUserCanOverwriteTools(this.userOverwrite); if (this.velocity != null) { context.putVelocityEngine(this.velocity); } addToolboxes(context); } protected void addToolboxes(ToolContext context) { if (hasApplicationTools()) { context.addToolbox(getApplicationToolbox()); } if (hasRequestTools()) { context.addToolbox(getRequestToolbox()); } } protected boolean hasTools(String scope) { return this.factory.hasTools(scope); } protected Toolbox createToolbox(String scope) { return this.factory.createToolbox(scope); } protected boolean hasRequestTools() { return hasTools(Scope.REQUEST); } protected Toolbox getRequestToolbox() { return createToolbox(Scope.REQUEST); } protected boolean hasApplicationTools() { return hasTools(Scope.APPLICATION); } protected Toolbox getApplicationToolbox() { if (this.application == null && hasApplicationTools()) { this.application = createToolbox(Scope.APPLICATION); } return this.application; } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/Toolbox.java100644 0 0 15267 11110347753 24253 0ustar 0 0 package org.apache.velocity.tools; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; /** *

      Instances of this class are typically created by a {@link ToolboxFactory} * on a one-per-scope basis. So, for each application, there would be one * application-scoped Toolbox from which you would retrieve tool instances, * and for each request, there would be one request-scoped Toolbox. * Of course, none of the above is enforced. There's no reason that you can't * manually create a Toolbox or have multiple Toolboxes for each scope. *

      * When a Toolbox creates a tool instance asked of it (see {@link #get}), * it will cache that instance for future requests. *

      * * @author Nathan Bubna * @version $Id: Toolbox.java 511959 2007-02-26 19:24:39Z nbubna $ */ public class Toolbox implements java.io.Serializable { /** * The key used to place instances in various scopes. */ public static final String KEY = Toolbox.class.getName(); private static final long serialVersionUID = 888081253188664649L; private Map infoMap; private Map properties; private Map cache; public Toolbox(Map toolInfo) { this(toolInfo, null); } public Toolbox(Map toolInfo, Map properties) { if (toolInfo == null) { this.infoMap = Collections.emptyMap(); } else { this.infoMap = toolInfo; } this.properties = properties; } protected void cacheData(Map data) { if (data != null && !data.isEmpty()) { cache = new HashMap(data); } } public Map getProperties() { return properties; } public Object get(String key) { return get(key, null, null); } public Object get(String key, String path) { return get(key, path, null); } public Object get(String key, Map context) { return get(key, null, context); } public Object get(String key, String path, Map context) { Object tool = null; if (cache != null) { tool = getFromCache(key, path); } if (tool == null) { tool = getFromInfo(key, path, context); } return tool; } protected Object getFromCache(String key, String path) { if (cache == null) { return null; } else { Object tool = cache.get(key); if (tool == null) { return null; } else if (path == null) { return tool; } else if (hasPermission(infoMap.get(key), path)) { return tool; } else { return null; } } } protected Object getFromInfo(String key, String path, Map context) { ToolInfo info = infoMap.get(key); if (info != null && (path == null || hasPermission(info, path))) { Object tool = info.create(context); if (cache == null) { cache = new HashMap(); } cache.put(key, tool); return tool; } return null; } protected boolean hasPermission(ToolInfo info, String path) { if (info == null || path == null) { return true; } return info.hasPermission(path); } public Set getKeys() { // add keys for all available tools Set keys = new HashSet(infoMap.keySet()); // be sure to add cache, which holds data keys if (cache != null) { keys.addAll(cache.keySet()); } return keys; } /** * Return a new {@link Map} link tools' keys to their {@link Class}es. * This will not instantiate any tools, it is merely informational. * This will not include the keys for any cached data. Note that inclusion * in this map does NOT mean that all these tools will be available for * all requests, as this map ignores all path restrictions on the tools. */ public Map getToolClassMap() { Map classMap = new HashMap(infoMap.size()); for (Map.Entry entry : infoMap.entrySet()) { classMap.put(entry.getKey(), entry.getValue().getToolClass()); } return classMap; } public Map getAll(Map context) { // request all tools we have info for for (ToolInfo info : infoMap.values()) { get(info.getKey(), context); } // then return a copy of the cache return new HashMap(this.cache); } /** * Returns a new {@link Toolbox} that is a combination of * this Toolbox with one or more specified {@link Toolbox}es. * Neither this instance nor those specified are modified. */ public Toolbox combine(Toolbox... toolboxes) { Map info = new HashMap(this.infoMap); Map props = new HashMap(this.properties); Map data = new HashMap(this.cache); for (Toolbox toolbox : toolboxes) { info.putAll(toolbox.infoMap); props.putAll(toolbox.properties); data.putAll(toolbox.cache); } Toolbox combination = new Toolbox(info, props); combination.cacheData(data); return combination; } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/ToolboxFactory.java100644 0 0 20762 11030275254 25574 0ustar 0 0 package org.apache.velocity.tools; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.util.HashMap; import java.util.Map; import org.apache.velocity.tools.config.Data; import org.apache.velocity.tools.config.FactoryConfiguration; import org.apache.velocity.tools.Scope; import org.apache.velocity.tools.config.ToolboxConfiguration; import org.apache.velocity.tools.config.ToolConfiguration; /** *

      This class is the central point of action for VelocityTools. * It manages the configured and scoped {@link ToolInfo} and {@link Data} * and is meant to stick around for the life of the application. *

      * It works like this: *

        *
      1. Build up your {@link FactoryConfiguration}(s)
      2. *
      3. Create a {@link ToolboxFactory} instance
      4. *
      5. Pass the configuration to {@link #configure}
      6. *
      7. When appropriate for each scope, use {@link #createToolbox} * to create the {@link Toolbox} for that scope and put that toolbox * somewhere appropriate to that scope.
      8. *
      9. When you want a tool, get that {@link Toolbox} and * ask it for the tool you want (e.g. toolbox.get("math")).
      10. *
      *

      * Of course, most users will not have to do any of this * as much of it is handled for them by some combination of * {@link ToolManager} or {@link org.apache.velocity.tools.view.VelocityView} * and a {@link ToolContext} or {@link org.apache.velocity.tools.view.ViewToolContext}. *

      * NOTE: While you are free to pass in new configuration info * at any time, that data will only affect {@link Toolbox}es created subsequently. * Any previously created toolboxes will have to be re-created and replaced to * reflect the changes to the configuration. *

      * * @author Nathan Bubna * @version $Id: ToolboxFactory.java 511959 2007-02-26 19:24:39Z nbubna $ */ public class ToolboxFactory { public static final String DEFAULT_SCOPE = Scope.REQUEST; private final Map> scopedToolInfo; private final Map> scopedProperties; private Map data; private Map globalProperties; public ToolboxFactory() { this.scopedToolInfo = new HashMap>(); this.scopedProperties = new HashMap>(); } public synchronized void configure(FactoryConfiguration config) { // this will throw a ConfigurationException if there is a problem config.validate(); // first do the easy part and add any data for (Data datum : config.getData()) { putData(datum.getKey(), datum.getConvertedValue()); } // property precedence follows two rules: // newer Foo-level props beat older ones // narrower-scoped props beat broader-scoped ones // next add the toolboxes for (ToolboxConfiguration toolbox : config.getToolboxes()) { String scope = toolbox.getScope(); // starting with the toolinfo for (ToolConfiguration tool : toolbox.getTools()) { addToolInfo(scope, tool.createInfo()); } // then add the properties for this toolbox Map newToolboxProps = toolbox.getPropertyMap(); putProperties(scope, newToolboxProps); // now go thru all toolinfo for this scope old and new for (ToolInfo info : getToolInfo(scope).values()) { // and add these new toolbox properties, which have // lower precedence than the props already in the info info.addProperties(newToolboxProps); } } // now set all the factory-level properties // new ones will override old ones Map newGlobalProps = config.getPropertyMap(); putGlobalProperties(newGlobalProps); // now go thru all toolboxes in this factory for (Map toolbox : scopedToolInfo.values()) { // iterating over all the toolinfo in them for (ToolInfo info : toolbox.values()) { // and adding the new global properties last // since they have the lowest precedence info.addProperties(newGlobalProps); } } } protected synchronized Object putData(String key, Object value) { if (data == null) { data = new HashMap(); } return data.put(key, value); } protected void addToolInfo(String scope, ToolInfo tool) { //TODO? check the scope against any "ValidScopes" // annotation on the tool class, or do we leave // validation like this to FactoryConfiguration? getToolInfo(scope).put(tool.getKey(), tool); } protected synchronized Map getToolInfo(String scope) { Map tools = scopedToolInfo.get(scope); if (tools == null) { tools = new HashMap(); scopedToolInfo.put(scope, tools); } return tools; } protected synchronized void putGlobalProperties(Map props) { if (props != null && !props.isEmpty()) { if (globalProperties == null) { globalProperties = new HashMap(props); } else { globalProperties.putAll(props); } } } protected synchronized void putProperties(String scope, Map props) { if (props != null && !props.isEmpty()) { Map properties = scopedProperties.get(scope); if (properties == null) { properties = new HashMap(props); scopedProperties.put(scope, properties); } else { properties.putAll(props); } } } public Object getGlobalProperty(String name) { if (globalProperties == null) { return null; } return globalProperties.get(name); } public Map getData() { return data; } public boolean hasTools(String scope) { Map tools = scopedToolInfo.get(scope); if (tools != null && !tools.isEmpty()) { return true; } else if (data != null && Scope.APPLICATION.equals(scope)) { return true; } return false; } public Toolbox createToolbox(String scope) { Map tools = scopedToolInfo.get(scope); Map properties = scopedProperties.get(scope); Toolbox toolbox; if (properties == null) { if (globalProperties == null) { toolbox = new Toolbox(tools); } else { toolbox = new Toolbox(tools, globalProperties); } } else { //TODO: this will waste cycles on subsequent retrievals // of the same toolbox. consider improving... if (globalProperties != null) { properties.putAll(globalProperties); } toolbox = new Toolbox(tools, properties); } // if application scoped or if there's only one toolbox, // then automatically include data, if we have any. if (data != null && (scopedToolInfo.size() == 1 || scope.equals(Scope.APPLICATION))) { toolbox.cacheData(getData()); } return toolbox; } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/config/CompoundConfiguration.java100644 0 0 10450 11110347747 30376 0ustar 0 0 package org.apache.velocity.tools.config; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.util.Collection; import java.util.SortedSet; import java.util.TreeSet; /** * This class manages a {@link SortedSet} of child {@link Configuration}s * as well as being a {@link Configuration} itself. * * @author Nathan Bubna * @version $Id: Configuration.java 511959 2007-02-26 19:24:39Z nbubna $ */ public class CompoundConfiguration extends Configuration { private final SortedSet children = new TreeSet(); protected void addChild(C newKid) { // check if we already have a matching child C child = getChild(newKid); if (child != null) { // compound children can just have the new props and kids // added to the old ones, we don't need to replace the old if (child instanceof CompoundConfiguration) { ((CompoundConfiguration)child) .addConfiguration((CompoundConfiguration)newKid); } else { // add newKid's values to childs (overwriting any dupes) child.addConfiguration(newKid); } } else { // simply adopt the new kid children.add(newKid); } } protected boolean removeChild(C config) { return children.remove(config); } protected boolean hasChildren() { return !children.isEmpty(); } protected Collection getChildren() { return children; } protected void setChildren(Collection kids) { for (C kid : kids) { addChild(kid); } } protected C getChild(C kid) { for (C child : children) { if (child.equals(kid)) { return child; } } return null; } public void addConfiguration(CompoundConfiguration config) { // add config's children to our own setChildren(config.getChildren()); // add config's properties to ours super.addConfiguration(config); } @Override public void validate() { super.validate(); for (C child : children) { child.validate(); } } protected void appendChildren(StringBuilder out, String childrenName, String childDelim) { if (hasChildren()) { if (hasProperties()) { out.append(" and "); } else { out.append(" with "); } out.append(children.size()); out.append(' '); out.append(childrenName); for (C child : children) { out.append(child); out.append(childDelim); } } } @Override public int hashCode() { // add the super's and the kid's return super.hashCode() + children.hashCode(); } @Override public boolean equals(Object obj) { // must be of this type and have super.equals() be true if (!(obj instanceof CompoundConfiguration) || !super.equals(obj)) { return false; } else { // they're of the same type CompoundConfiguration that = (CompoundConfiguration)obj; // if their children are equal, they're equal return this.children.equals(that.children); } } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/config/Configuration.java100644 0 0 12256 11110347747 26677 0ustar 0 0 package org.apache.velocity.tools.config; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.SortedSet; import java.util.TreeSet; /** *

      This base configuration class manages a set of {@link Property}s * for whatever thing the instance of this class represents. When * combined with another {@link Configuration} instance via * {@link #addConfiguration}, the {@link Property}s of both instances are * combined.

      NOTE: Though this class appears {@link Comparable}, * the {@link #compareTo} method is unsupported. Proper comparison is * left up to subclasses.

      * * @author Nathan Bubna * @version $Id: Configuration.java 511959 2007-02-26 19:24:39Z nbubna $ */ public class Configuration implements Comparable { private final SortedSet properties = new TreeSet(); public void addProperty(Property property) { if (property.getName() == null) { throw new IllegalArgumentException("All properties must be named before they can be added to the configuration."); } // remove any current properties with the same key properties.remove(property); // then add the new one properties.add(property); } public boolean removeProperty(Property property) { return properties.remove(property); } public void setProperty(String name, Object value) { if (name == null) { throw new NullPointerException("Property name cannot be null"); } Property prop = new Property(); prop.setName(name); prop.setValue(value); addProperty(prop); } public boolean removeProperty(String name) { Property prop = getProperty(name); return properties.remove(prop); } public boolean hasProperties() { return !properties.isEmpty(); } public Property getProperty(String name) { for (Property prop : properties) { if (name.equals(prop.getName())) { return prop; } } return null; } public SortedSet getProperties() { return new TreeSet(properties); } public Map getPropertyMap() { Map map = new HashMap(); for (Property prop : properties) { map.put(prop.getName(), prop.getConvertedValue()); } return map; } public void setPropertyMap(Map props) { for (Map.Entry entry : props.entrySet()) { setProperty(entry.getKey(), entry.getValue()); } } public void setProperties(Collection props) { for (Property newProp : props) { addProperty(newProp); } } public void addConfiguration(Configuration config) { setProperties(config.getProperties()); } public void validate() { for (Property property : properties) { property.validate(); } } public int compareTo(Configuration config) { throw new UnsupportedOperationException("Configuration is abstract and cannot be compared."); } @Override public int hashCode() { return properties.hashCode(); } @Override public boolean equals(Object obj) { if (this == obj) { return true; } else if (!(obj instanceof Configuration)) { return false; } else { // they're of the same type Configuration that = (Configuration)obj; // if their properties are equal, they're equal return this.properties.equals(that.properties); } } protected void appendProperties(StringBuilder out) { if (hasProperties()) { out.append("with "); out.append(properties.size()); out.append(" properties ["); for (Property prop : properties) { out.append(prop.getKey()); out.append(" -"); out.append(prop.getType()); out.append("-> "); out.append(prop.getValue()); out.append("; "); } out.append("]"); } } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/config/ConfigurationCleaner.java100644 0 0 10271 10730012242 30146 0ustar 0 0 package org.apache.velocity.tools.config; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional debugrmation * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.util.Iterator; /** * * * @author Nathan Bubna * @version $Id: Configuration.java 511959 2007-02-26 19:24:39Z nbubna $ */ public class ConfigurationCleaner extends LogSupport { private static final String LOG_PREFIX = "ConfigurationCleaner : "; @Override protected String logPrefix() { return LOG_PREFIX; } public void clean(FactoryConfiguration factory) { if (isTraceEnabled()) { trace("Cleaning factory: "+factory); } cleanProperties(factory); // go thru data to log and remove debug ones Iterator i = factory.getData().iterator(); while (i.hasNext()) { Data datum = i.next(); try { datum.validate(); } catch (ConfigurationException ce) { if (isDebugEnabled()) { debug(ce.getMessage()); } if (isWarnEnabled()) { warn("Removing "+datum); } i.remove(); } } // clean all toolboxes for (ToolboxConfiguration toolbox : factory.getToolboxes()) { clean(toolbox); } } public void clean(ToolboxConfiguration toolbox) { cleanProperties(toolbox); // go thru tools to log and remove debug ones Iterator i = toolbox.getTools().iterator(); while (i.hasNext()) { ToolConfiguration tool = i.next(); cleanProperties(tool); try { tool.validate(); } catch (ConfigurationException ce) { if (isDebugEnabled()) { debug(ce.getMessage()); } if (isWarnEnabled()) { warn("Removing "+tool); } i.remove(); } } //TODO: loop on validate() until all debug scoped tools are removed } public void clean(Configuration config) { // delegate to the appropriate method... if (config instanceof FactoryConfiguration) { clean((FactoryConfiguration)config); } else if (config instanceof ToolboxConfiguration) { clean((ToolboxConfiguration)config); } else { cleanProperties(config); } } public void cleanProperties(Configuration config) { // go thru properties to log and remove debug ones Iterator i = config.getProperties().iterator(); while (i.hasNext()) { Property prop = i.next(); try { prop.validate(); } catch (ConfigurationException ce) { if (isDebugEnabled()) { debug(ce.getMessage()); } if (isWarnEnabled()) { warn("Removing "+prop); } i.remove(); } } } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/config/ConfigurationException.java100644 0 0 3277 10730012242 30523 0ustar 0 0 package org.apache.velocity.tools.config; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ /** * * * @author Nathan Bubna * @version $Id: ConfigurationException.java 511959 2007-02-26 19:24:39Z nbubna $ */ public class ConfigurationException extends RuntimeException { private final Object source; public ConfigurationException(Data data, Throwable cause) { super(cause); this.source = data; } public ConfigurationException(Data data, String message) { super(message); this.source = data; } public ConfigurationException(Configuration config, Throwable cause) { super(cause); this.source = config; } public ConfigurationException(Configuration config, String message) { super(message); this.source = config; } public Object getSource() { return source; } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/config/ConfigurationUtils.java100644 0 0 44426 11030275244 27715 0ustar 0 0 package org.apache.velocity.tools.config; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.io.File; import java.io.InputStream; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.net.MalformedURLException; import java.net.URL; import java.util.List; import org.apache.velocity.exception.ResourceNotFoundException; import org.apache.velocity.tools.ClassUtils; import org.apache.velocity.tools.ToolboxFactory; /** * Utility methods for handling tool configurations. * * @author Nathan Bubna * @version $Id: ConfigurationUtils.java 511959 2007-02-26 19:24:39Z nbubna $ */ public class ConfigurationUtils { public static final String GENERIC_DEFAULTS_PATH = "/org/apache/velocity/tools/generic/tools.xml"; public static final String VIEW_DEFAULTS_PATH = "/org/apache/velocity/tools/view/tools.xml"; public static final String STRUTS_DEFAULTS_PATH = "/org/apache/velocity/tools/struts/tools.xml"; public static final String AUTOLOADED_XML_PATH = "tools.xml"; public static final String AUTOLOADED_PROPS_PATH = "tools.properties"; public static final String SYSTEM_PROPERTY_KEY = "org.apache.velocity.tools"; public static final ConfigurationUtils INSTANCE = new ConfigurationUtils(); private ConfigurationUtils() {} public ConfigurationUtils getInstance() { return INSTANCE; } /** * Returns the "default" {@link FactoryConfiguration}. This includes * all the standard tools developed by this project and available in * the jar being used. In other words, if the velocity-tools-generic-2.x.jar * is being used, then only the generic tools will be included. If * the velocity-tools-struts-2.x.jar is being used, then all VelocityTools * will be available. This also means that subclasses in the larger jars * will override their superclasses. So, if you are using the VelocityStruts * jar, then your $link reference will be a StrutsLinkTool. If you are using * the VelocityView jar, it will be a standard LinkTool. */ public static FactoryConfiguration getDefaultTools() { FileFactoryConfiguration config = new XmlFactoryConfiguration("ConfigurationUtils.getDefaultTools()"); config.read(GENERIC_DEFAULTS_PATH); // view tools and struts tools may not be available config.read(VIEW_DEFAULTS_PATH, false); config.read(STRUTS_DEFAULTS_PATH, false); // defaults should *always* be clean! clean(config); return config; } /** * Returns a {@link FactoryConfiguration} including all default * "GenericTools" available and no others. */ public static FactoryConfiguration getGenericTools() { FileFactoryConfiguration config = new XmlFactoryConfiguration("ConfigurationUtils.getGenericTools()"); config.read(GENERIC_DEFAULTS_PATH); // defaults should *always* be clean! clean(config); return config; } /** * Returns a {@link FactoryConfiguration} including all default * "VelocityView" tools available as well as the default "GenericTools". * @throws {@link ConfigurationException} if a tools.xml is not found * at the {@link #VIEW_DEFAULTS_PATH}. */ public static FactoryConfiguration getVelocityView() { FileFactoryConfiguration config = new XmlFactoryConfiguration("ConfigurationUtils.getVelocityView()"); config.read(GENERIC_DEFAULTS_PATH); config.read(VIEW_DEFAULTS_PATH); // defaults should *always* be clean! clean(config); return config; } /** * Returns a {@link FactoryConfiguration} including all default * "VelocityStruts" tools available as well as the default "VelocityView" * tools and "GenericTools". * @throws {@link ConfigurationException} if a tools.xml is not found * at the {@link #VIEW_DEFAULTS_PATH} or {@link #STRUTS_DEFAULTS_PATH}. */ public static FactoryConfiguration getVelocityStruts() { FileFactoryConfiguration config = new XmlFactoryConfiguration("ConfigurationUtils.getVelocityStruts()"); config.read(GENERIC_DEFAULTS_PATH); config.read(VIEW_DEFAULTS_PATH); config.read(STRUTS_DEFAULTS_PATH); // defaults should *always* be clean! clean(config); return config; } /** * Returns a {@link FactoryConfiguration} including all * {@link #getDefaultTools()} as well as any tools that can be * automatically loaded from "tools.xml" or "tools.properties" found * at the root of the classpath or in the current directory. * * @see #getAutoLoaded(boolean includeDefaults) */ public static FactoryConfiguration getAutoLoaded() { return getAutoLoaded(true); } /** * Returns a {@link FactoryConfiguration} composed, in order of the * following configurations: *
        *
      • {@link #getDefaultTools()} (only if includeDefaults is {@code true})
      • *
      • All "tools.xml" configurations found in the classpath root, in the order found
      • *
      • All "tools.properties" configurations found in the classpath root, in the order found
      • *
      • The "tools.xml" file in the current directory (if any)
      • *
      • The "tools.properties" file in the current directory (if any)
      • *
      * If the includeDefaults parameter is null and no such files described above * can be found, then the configuration returned by this method will be * empty, but it should never be {@code null}. */ public static FactoryConfiguration getAutoLoaded(boolean includeDefaults) { FactoryConfiguration auto; if (includeDefaults) { // start with the available defaults auto = getDefaultTools(); } else { // start out blank auto = new FactoryConfiguration("ConfigurationUtils.getAutoLoaded(false)"); } //TODO: look for any Tools classes in the root of the classpath // look for all tools.xml in the classpath FactoryConfiguration cpXml = findInClasspath(AUTOLOADED_XML_PATH); if (cpXml != null) { auto.addConfiguration(cpXml); } // look for all tools.properties in the classpath FactoryConfiguration cpProps = findInClasspath(AUTOLOADED_PROPS_PATH); if (cpProps != null) { auto.addConfiguration(cpProps); } // look for tools.xml in the current file system FactoryConfiguration fsXml = findInFileSystem(AUTOLOADED_XML_PATH); if (fsXml != null) { auto.addConfiguration(fsXml); } // look for tools.properties in the file system FactoryConfiguration fsProps = findInFileSystem(AUTOLOADED_PROPS_PATH); if (fsProps != null) { auto.addConfiguration(fsProps); } // return the config we've accumulated return auto; } /** * Returns a {@link FactoryConfiguration} loaded from the path specified * in the "org.apache.velocity.tools" system property (if any). * If no such property has been set {@code null} will be returned. * @throws ResourceNotFoundException if the system property has a value * but no configuration file was found at the specified location */ public static FactoryConfiguration findFromSystemProperty() { String path = System.getProperty(SYSTEM_PROPERTY_KEY); if (path == null || path.length() == 0) { return null; } return load(path); } /** * Returns a new, standard {@link ToolboxFactory} configured * with the results of both {@link #getAutoLoaded()} and * {@link #findFromSystemProperty()}. */ public static ToolboxFactory createFactory() { // get the automatically loaded config(s) FactoryConfiguration auto = getAutoLoaded(); // include any config specified via system property FactoryConfiguration sys = findFromSystemProperty(); if (sys != null) { auto.addConfiguration(sys); } ToolboxFactory factory = new ToolboxFactory(); factory.configure(auto); return factory; } /** * Convenience method that automatically creates a new * {@link ConfigurationCleaner} and applies it to the specified * {@link Configuration}. */ public static void clean(Configuration config) { // since most config will happen at startup and a cleaner // is not otherwise necessary, don't keep one of these statically ConfigurationCleaner cleaner = new ConfigurationCleaner(); cleaner.clean(config); } /** * Returns a {@link FactoryConfiguration} loaded from a configuration file * at the specified path. If no such file is found at that path, this * will throw a {@link ResourceNotFoundException}. * * @see #find(String path) */ public static FactoryConfiguration load(String path) { FactoryConfiguration config = find(path); if (config == null) { throw new ResourceNotFoundException("Could not find configuration at "+path); } return config; } /** * Searches for a configuration file at the specified path and returns * it in the form of a {@link FactoryConfiguration}. This method will * look for a matching file in both the classpath and the file system. * If perchance a match is found in both, then both are loaded and the * configuration loaded from the file system is given precedence (i.e. * it is added onto the other). If no match is found in either, then * this will return {@code null}. */ public static FactoryConfiguration find(String path) { FactoryConfiguration cp = findInClasspath(path); FactoryConfiguration fs = findInFileSystem(path); if (cp != null) { if (fs != null) { cp.addConfiguration(fs); } return cp; } else { return fs; } } /** * Searches the file system for a configuration file matching the * specified path. If found, it will read and return it as a * {@link FactoryConfiguration}. If not found, this will return * {@code null}. * @throws IllegalStateException if the file exists, but its path could not be converted to a URL for reading. */ public static FactoryConfiguration findInFileSystem(String path) { File file = new File(path); if (file.exists()) { try { return read(file.toURL()); } catch (MalformedURLException mue) { throw new IllegalStateException("Could not convert existing file path \""+path+"\" to URL", mue); } } return null; } /** * @see #findInClasspath(String path, Object caller) */ public static FactoryConfiguration findInClasspath(String path) { // pretend this was called by a non-static ConfigurationUtils return findInClasspath(path, new ConfigurationUtils()); } /** * Searches the classpath for a configuration file matching the * specified path. If found, it will read and return it as a * {@link FactoryConfiguration}. If not found, this will return * {@code null}. If there are multiple matching resources in the * classpath, then they will be added together in the order found * (i.e. the last one will have precedence). * @see ClassUtils#getResources(String path, Object caller) */ public static FactoryConfiguration findInClasspath(String path, Object caller) { // find all resources at this path List found = ClassUtils.getResources(path, caller); if (found.isEmpty()) { return null; } else if (found.size() == 1) { // load and return the one config at that URL (if any) return read(found.get(0)); } else { // create a base config to combine the others into FactoryConfiguration config = new FactoryConfiguration("ConfigurationUtils.findInClassPath("+path+","+caller+")"); boolean readAConfig = false; for (URL resource : found) { FactoryConfiguration c = read(resource); if (c != null) { readAConfig = true; config.addConfiguration(c); } } // only return a configuration if we really found one if (readAConfig) { return config; } else { return null; } } } /** * Returns a {@link FactoryConfiguration} read from a known configuration * file type at the specified {@link URL}. If the file is missing or unreadable, * this will simply return {@code null} (i.e. if an IOException is thrown). * @throws UnsupportedOperationException if the file type (identified via suffix) * is neither ".xml" or ".properties" */ public static FactoryConfiguration read(URL url) { FileFactoryConfiguration config = null; String path = url.toString(); String source = "ConfigurationUtils.read("+url.toString()+")"; if (path.endsWith(".xml")) { config = new XmlFactoryConfiguration(source); } else if (path.endsWith(".properties")) { config = new PropertiesFactoryConfiguration(source); } else if (path.endsWith(".class")) { // convert the url to a FQN String fqn = path.substring(0, path.indexOf('.')).replace('/','.'); // retrieve a configuration from that class return getFromClass(fqn); } else { String msg = "Unknown configuration file type: " + url.toString() + "\nOnly .xml and .properties configuration files are supported at this time."; throw new UnsupportedOperationException(msg); } // now, try to read the file InputStream inputStream = null; try { inputStream = url.openStream(); config.read(inputStream); } catch (IOException ioe) { return null; } finally { if (inputStream != null) { try { inputStream.close(); } catch (IOException ioe) { throw new RuntimeException("Could not close input stream for "+path, ioe); } } } return config; } public static FactoryConfiguration getFromClass(String classname) { try { Class configFactory = ClassUtils.getClass(classname); return getFromClass(configFactory); } catch (ClassNotFoundException cnfe) { throw new IllegalArgumentException("Could not find class "+classname, cnfe); } } public static final String CONFIG_FACTORY_METHOD = "getConfiguration"; public static FactoryConfiguration getFromClass(Class factory) { //TODO: look for a getConfiguration() method Method getConf = null; try { // check for a public setup(Map) method first getConf = factory.getMethod(CONFIG_FACTORY_METHOD, (Class[])null); } catch (NoSuchMethodException nsme) { throw new IllegalArgumentException("Could not find "+CONFIG_FACTORY_METHOD+" in class "+factory.getName(), nsme); } // get an instance if the method is not static Object instance = null; if (!Modifier.isStatic(getConf.getModifiers())) { try { instance = factory.newInstance(); } catch (Exception e) { throw new IllegalArgumentException(factory.getName()+" must have usable default constructor or else "+CONFIG_FACTORY_METHOD+" must be declared static", e); } } // invoke the method try { FactoryConfiguration result = (FactoryConfiguration)getConf.invoke(instance, (Object[])null); if (result == null) { throw new IllegalArgumentException("Method "+CONFIG_FACTORY_METHOD+" in class "+factory.getName()+" should not return null or void"); } else { return result; } } catch (IllegalAccessException iae) { throw new IllegalArgumentException("Failed to invoke "+CONFIG_FACTORY_METHOD+" in class "+factory.getName(), iae); } catch (IllegalArgumentException iae) { // if this happens, it's more a problem w/this code than the users throw iae; } catch (InvocationTargetException ite) { // if this happens, it's all their issue throw new IllegalArgumentException("There was an exception while executing "+CONFIG_FACTORY_METHOD+" in class "+factory.getName(), ite.getCause()); } } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/config/Data.java100644 0 0 32250 11110347747 24735 0ustar 0 0 package org.apache.velocity.tools.config; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.util.Arrays; import java.util.ArrayList; import java.util.List; import java.util.Locale; import org.apache.commons.beanutils.Converter; import org.apache.commons.beanutils.converters.BooleanConverter; import org.apache.commons.beanutils.converters.StringConverter; import org.apache.velocity.tools.ClassUtils; import org.apache.velocity.tools.ConversionUtils; /** *

      This class represents configured data. If added to a * {@link FactoryConfiguration}, its values will be made * available in the application-scoped toolboxes * produced by any ToolboxFactory configured using * that configuration.

      *

      This class also implements all the functionality of * {@link Property}s, which may added to any * {@link Configuration} subclass, including * {@link ToolConfiguration}, {@link ToolboxConfiguration}, * and {@link FactoryConfiguration}. In other words, * anything you can do in a {@link Data} configuration, you * can do with a {@link Property}.

      *

      Some features supported here are: *

        *
      • built in {@link Type}s for strings, booleans, numbers, fields * and lists thereof
      • *
      • auto-conversion of numbers, booleans and fields in data * with no explicit type
      • *
      • support for any Commons-BeanUtils {@link Converter} implementation
      • *
      *

      * * @author Nathan Bubna * @version $Id: Data.java 511959 2007-02-26 19:24:39Z nbubna $ */ public class Data implements Comparable { protected static final Type DEFAULT_TYPE = Type.AUTO; private String key; private String typeValue; private Object value; private boolean isList; private Class target; private Converter converter; public Data() { setType(DEFAULT_TYPE); } public void setKey(String key) { this.key = key; } public void setValue(Object value) { this.value = value; } public void setClassname(String classname) { try { setTargetClass(ClassUtils.getClass(classname)); } catch (ClassNotFoundException cnfe) { throw new IllegalArgumentException("Class "+classname+" could not be found.", cnfe); } } /** * This doesn't take a {@link Class} parameter because * this class was not created for all-java configuration. */ public void setClass(String classname) { setClassname(classname); } protected void setType(Type type) { this.isList = type.isList(); // make sure we don't override a custom target or converter if (!type.isCustom()) { this.typeValue = type.value(); this.target = type.getTarget(); this.converter = type.getConverter(); } else if (type.isList()) { // go ahead and set the target and type value for custom lists this.typeValue = type.value(); this.target = type.getTarget(); } } public void setType(String t) { // save the set type value (good for error feedback and whatnot) this.typeValue = t; // and try to convert it to a Type Type type = Type.get(this.typeValue); if (type != null) { setType(type); } } public void setTargetClass(Class clazz) { this.target = clazz; } public void setConverter(Class clazz) { try { convertWith((Converter)clazz.newInstance()); } catch (Exception e) { throw new IllegalArgumentException("Class "+clazz+" is not a valid "+Converter.class, e); } } public void setConverter(String classname) { try { convertWith((Converter)ClassUtils.getInstance(classname)); } catch (Exception e) { throw new IllegalArgumentException("Class "+classname+" is not a valid "+Converter.class, e); } } /** * This is a convenience method for those doing configuration in java. * It cannot be named setConverter(), or else it would confuse BeanUtils. */ public void convertWith(Converter converter) { this.converter = converter; } public String getKey() { return this.key; } public String getType() { return this.typeValue; } public Object getValue() { return this.value; } public Class getTargetClass() { return this.target; } public Converter getConverter() { return this.converter; } public Object getConvertedValue() { return convert(this.value); } public void validate() { // make sure the key is not null if (getKey() == null) { throw new NullKeyException(this); } // make sure we have value and that it can be converted if (getValue() == null) { throw new ConfigurationException(this, "No value has been set for '"+getKey()+'\''); } else if (this.converter != null) { try { if (getConvertedValue() == null && getValue() != null) { throw new ConfigurationException(this, "Conversion of "+getValue()+" for '"+getKey()+"' failed and returned null"); } } catch (Throwable t) { throw new ConfigurationException(this, t); } } } public int compareTo(Data datum) { if (getKey() == null && datum.getKey() == null) { return 0; } else if (getKey() == null) { return -1; } else if (datum.getKey() == null) { return 1; } else { return getKey().compareTo(datum.getKey()); } } @Override public int hashCode() { if (getKey() == null) { return super.hashCode(); } return getKey().hashCode(); } @Override public boolean equals(Object obj) { if (getKey() == null || !(obj instanceof Data)) { return super.equals(obj); } return getKey().equals(((Data)obj).getKey()); } @Override public String toString() { StringBuilder out = new StringBuilder(); out.append("Data '"); out.append(key); out.append('\''); out.append(" -"); out.append(this.typeValue); out.append("-> "); out.append(value); return out.toString(); } protected Object convert(Object value) { if (this.isList) { return convertList(value); } else if (this.converter == null) { return value; } else { return convertValue(value); } } private Object convertValue(Object value) { return this.converter.convert(this.target, value); } private List convertList(Object val) { // we assume it is a string String value = (String)val; if (value == null || value.trim().length() == 0) { return null; } else { //TODO: make sure this works as expected... List list = Arrays.asList(value.split(",")); if (this.converter == null || this.target.equals(String.class)) { return list; } else { List convertedList = new ArrayList(); for (String item : list) { convertedList.add(convertValue(item)); } return convertedList; } } } // ------------- Subclasses ----------------- /** * Delineates the standard, known types and their * associated target classes ({@link #setTargetClass} and * converters ({@link #setConverter}). */ protected static enum Type { AUTO(Object.class, new AutoConverter()), BOOLEAN(Boolean.class, new BooleanConverter()), CUSTOM(null, null), FIELD(Object.class, new FieldConverter()), NUMBER(Number.class, new NumberConverter()), STRING(String.class, new StringConverter()), LIST(List.class, null), LIST_AUTO(List.class, AUTO.getConverter()), LIST_BOOLEAN(List.class, BOOLEAN.getConverter()), LIST_FIELD(List.class, FIELD.getConverter()), LIST_NUMBER(List.class, NUMBER.getConverter()), LIST_STRING(List.class, STRING.getConverter()); private Class target; private Converter converter; Type(Class t, Converter c) { this.target = t; this.converter = c; } public boolean isCustom() { // custom ones require the user to provide the converter return (this.converter == null); } public boolean isList() { // all list types return lists return (this.target == List.class); } public Class getTarget() { return this.target; } public Converter getConverter() { return this.converter; } public String value() { // make 'LIST_AUTO' into 'list.auto' return name().replace('_','.').toLowerCase(); } public static Type get(String type) { if (type == null || type.length() == 0) { return CUSTOM; } // make 'list.auto' eq 'LIST_AUTO' return valueOf(type.replace('.','_').toUpperCase()); } } protected static class FieldConverter implements Converter { public Object convert(Class type, Object value) { String fieldpath = (String)value; try { return ClassUtils.getFieldValue(fieldpath); } catch (Exception e) { throw new IllegalArgumentException("Could not retrieve value for field at "+fieldpath, e); } } } protected static class AutoConverter implements Converter { public Object convert(Class type, Object obj) { // only bother with strings for now if (obj instanceof String) { try { return convert((String)obj); } catch (Exception e) { return obj; } } return obj; } public Object convert(String value) { // check if this looks like a typical boolean type if (value.matches("true|false|yes|no|y|n|on|off")) { return Type.BOOLEAN.getConverter().convert(Boolean.class, value); } // check if this looks like a typical number else if (value.matches("-?[0-9]+(\\.[0-9]+)?")) { return Type.NUMBER.getConverter().convert(Number.class, value); } // check if this looks like a typical field else if (value.matches("(\\w+\\.)+\\w+")) { return Type.FIELD.getConverter().convert(Object.class, value); } return value; } } protected static class NumberConverter implements Converter { public Object convert(Class type, Object obj) { Number num = ConversionUtils.toNumber(obj,"default",Locale.US); if (num == null) { throw new IllegalArgumentException("Could not convert "+obj+" to a number"); } // now, let's return integers for integer values else if (obj.toString().indexOf('.') < 0) { // unless, of course, we need a long if (num.doubleValue() > Integer.MAX_VALUE || num.doubleValue() < Integer.MIN_VALUE) { num = Long.valueOf(num.longValue()); } else { num = Integer.valueOf(num.intValue()); } } return num; } } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/config/DefaultKey.java100644 0 0 2707 10730012242 26067 0ustar 0 0 package org.apache.velocity.tools.config; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Annotation specifying the default key to use for a tool class in the * case none was specified. * * @author Nathan Bubna * @version $Id: DefaultKey.java 511959 2007-02-26 19:24:39Z nbubna $ */ @Documented @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Inherited public @interface DefaultKey { String value(); } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/config/EasyFactoryConfiguration.java100644 0 0 26654 11030275244 31051 0ustar 0 0 package org.apache.velocity.tools.config; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.util.List; import org.apache.velocity.tools.ToolboxFactory; /** *

      {@link FactoryConfiguration} subclass that simplifies the process of * configuring a {@link ToolboxFactory} in Java without the use of an * xml or properties configuration file. Below is an example: * *

      
       * EasyFactoryConfiguration config = new EasyFactoryConfiguration();
       * config.toolbox(Scope.REQUEST).property("locale", Locale.US)
       *  .tool(DateTool.class)
       *  .tool("myTool", MyTool.class);
       * config.toolbox(Scope.APPLICATION)
       *  .tool(NumberTool.class).property("locale", Locale.FR);
       * ToolboxFactory factory = config.createFactory();
       * 

      * *

      Doing the above without this class would require the following to * create an equivalent {@link FactoryConfiguration} in Java: * *

      
       * FactoryConfiguration factoryConfig = new FactoryConfiguration();
       * ToolboxConfiguration toolbox = new ToolboxConfiguration();
       * toolbox.setScope(Scope.REQUEST);
       * toolbox.setProperty("locale", Locale.US);
       * ToolConfiguration tool = new ToolConfiguration();
       * tool.setClassname(DateTool.class.getName());
       * tool = new ToolConfiguration();
       * tool.setKey("myTool");
       * tool.setClassname(MyTool.class.getName());
       * toolbox.addTool(tool);
       * toolbox = new ToolboxConfiguration();
       * toolbox.setScope(Scope.APPLICATION);
       * tool = new ToolConfiguration();
       * tool.setClassname(NumberTool.class.getName());
       * tool.setProperty("locale", Locale.FR);
       * toolbox.addTool(tool);
       * factoryConfig.addToolbox(toolbox);
       * ToolboxFactory factory = factoryConfig.createFactory();
       * 

      * *

      Of course, you could directly configure a {@link ToolboxFactory} * with relatively little effort as well: * *

      
       * ToolboxFactory factory = new ToolboxFactory();
       * factory.putProperty(Scope.REQUEST, "locale", Locale.US);
       * factory.addToolInfo(Scope.REQUEST, new ToolInfo("date", DateTool.class));
       * factory.addToolInfo(Scope.REQUEST, new ToolInfo("render", ViewRenderTool.class));
       * ToolInfo info = new ToolInfo("number", NumberTool.class);
       * info.setProperty("locale", Locale.FR);
       * factory.addToolInfo(Scope.APPLICATION, info);
       * 
      * * But this is not reusable. Why does that matter? Well, it doesn't matter * for application developers. But, if another framework wishes to provide * a common VelocityTools configuration for application developers, this may * come in handy. Or it may not. In any case, it was mildly fun to write. :) *

      * * @author Nathan Bubna * @version $Id: EasyFactoryConfiguration.java 511959 2007-02-26 19:24:39Z nbubna $ */ public class EasyFactoryConfiguration extends FactoryConfiguration { private boolean addedDefaults = false; private EasyWrap toolbox; public EasyFactoryConfiguration() { this(false); } /** * @param includeDefaults Sets whether this instance should start with the * {@link ConfigurationUtils#getDefaultTools()} configuration or not. */ public EasyFactoryConfiguration(boolean includeDefaults) { // just give the param name as source this(includeDefaults, String.valueOf(includeDefaults)); } /** * @param includeDefaults Sets whether this instance should start with the * {@link ConfigurationUtils#getDefaultTools()} configuration or not. * @param source a string identify where this instance was created, or * something else useful to identify this instance during debugging */ public EasyFactoryConfiguration(boolean includeDefaults, String source) { super(EasyFactoryConfiguration.class, source); if (includeDefaults) { addDefaultTools(); // now put the root source last, since the defaults were really first // and nothing could have been added prior to them List sources = getSources(); String first = sources.remove(0); sources.add(first); } } /** * Adds the {@link ConfigurationUtils#getDefaultTools()} configuration to this * the current configuration. */ public EasyFactoryConfiguration addDefaultTools() { if (!addedDefaults) { addConfiguration(ConfigurationUtils.getDefaultTools()); addedDefaults = true; } return this; } public EasyFactoryConfiguration autoLoad() { return autoLoad(true); } public EasyFactoryConfiguration autoLoad(boolean includeDefaults) { addConfiguration(ConfigurationUtils.getAutoLoaded(includeDefaults)); addedDefaults = true; return this; } public EasyData data(String key, Object value) { Data datum = new Data(); datum.setKey(key); datum.setValue(value); addData(datum); return new EasyData(datum, this); } public EasyFactoryConfiguration data(String key, String type, Object value) { EasyData datum = data(key, value); datum.type(type); return this; } protected EasyFactoryConfiguration data(String key, Data.Type type, Object value) { EasyData datum = data(key, value); datum.type(type); return this; } public EasyFactoryConfiguration string(String key, Object value) { return data(key, Data.Type.STRING, value); } public EasyFactoryConfiguration number(String key, Object value) { return data(key, Data.Type.NUMBER, value); } public EasyFactoryConfiguration bool(String key, Object value) { return data(key, Data.Type.BOOLEAN, value); } public EasyWrap toolbox(String scope) { ToolboxConfiguration toolbox = new ToolboxConfiguration(); toolbox.setScope(scope); addToolbox(toolbox); this.toolbox = new EasyWrap(toolbox, this); return this.toolbox; } public EasyWrap tool(String classname) { return tool(null, classname); } public EasyWrap tool(Class clazz) { return tool(null, clazz); } public EasyWrap tool(String key, String classname) { if (toolbox == null) { toolbox(ToolboxFactory.DEFAULT_SCOPE); } return toolbox.tool(key, classname); } public EasyWrap tool(String key, Class clazz) { return tool(key, clazz.getName()); } public EasyFactoryConfiguration property(String name, Object value) { setProperty(name, value); return this; } public static class EasyData { private final Data datum; private final Configuration parent; public EasyData(Data datum, Configuration parent) { this.datum = datum; this.parent = parent; } public Data getData() { return this.datum; } public Configuration getParent() { return this.parent; } public EasyData type(String type) { this.datum.setType(type); return this; } protected EasyData type(Data.Type type) { this.datum.setType(type); return this; } public EasyData target(Class clazz) { this.datum.setTargetClass(clazz); return this; } public EasyData classname(String classname) { this.datum.setClassname(classname); return this; } public EasyData converter(String converter) { this.datum.setConverter(converter); return this; } public EasyData converter(Class clazz) { this.datum.setConverter(clazz); return this; } } public class EasyWrap { private final C config; private final Configuration parent; public EasyWrap(C config, Configuration parent) { this.config = config; this.parent = parent; } public C getConfiguration() { return this.config; } public Configuration getParent() { return this.parent; } public EasyWrap property(String name, Object value) { this.config.setProperty(name, value); return this; } public EasyWrap restrictTo(String path) { if (this.config instanceof ToolConfiguration) { ToolConfiguration tool = (ToolConfiguration)this.config; tool.setRestrictTo(path); return this; } else if (this.config instanceof ToolboxConfiguration) { ToolboxConfiguration toolbox = (ToolboxConfiguration)this.config; for (ToolConfiguration tool : toolbox.getTools()) { tool.setRestrictTo(path); } return this; } throw new IllegalStateException("Wrapping unknown "+Configuration.class.getName()+": "+getConfiguration()); } public EasyWrap addDefaultTools() { EasyFactoryConfiguration.this.addDefaultTools(); return this; } public EasyWrap tool(Class clazz) { return tool(null, clazz); } public EasyWrap tool(String classname) { return tool(null, classname); } public EasyWrap tool(String key, Class clazz) { return tool(key, clazz.getName()); } public EasyWrap tool(String key, String classname) { ToolConfiguration tool = new ToolConfiguration(); if (key != null) { tool.setKey(key); } tool.setClassname(classname); if (this.config instanceof ToolConfiguration) { ToolboxConfiguration toolbox = (ToolboxConfiguration)getParent(); toolbox.addTool(tool); return new EasyWrap(tool, toolbox); } else if (this.config instanceof ToolboxConfiguration) { ToolboxConfiguration toolbox = (ToolboxConfiguration)getConfiguration(); toolbox.addTool(tool); return new EasyWrap(tool, toolbox); } throw new IllegalStateException("Wrapping unknown "+Configuration.class.getName()+": "+getConfiguration()); } } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/config/FactoryConfiguration.java100644 0 0 22123 11110347747 30221 0ustar 0 0 package org.apache.velocity.tools.config; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.SortedSet; import java.util.TreeSet; import org.apache.velocity.tools.ToolboxFactory; /** *

      This class serves to define configuration info for a {@link ToolboxFactory}. * It contains the {@link ToolboxConfiguration}s for the factory as well * as any {@link Data} which is to be made available in the application scope * by the factory and any {@link Property}s which you intend to be available * to all tools managed by the factory, regardless of * toolbox or scope. *

      * Most users will not find themselves directly using the API of this class, * as its subclasses generally provide much simpler means of inputting * the actual configuration info whether from XML, Java or a Properties files. *

      * When combining any {@link Configuration}s via the various * {@link #addConfiguration} methods in each class, it is * essential to remember that subsequent configurations * always override previous ones. This is a "last entry wins" approach * to configuration! *

      * For debugging, this class tracks its "sources", keeping a chronological list * of all sources for configuration data. When you add configuration info * to this class via {@link #addConfiguration}, the source lists from those * {@link FactoryConfiguration}s is appended to this instance's list. The * initial item in this list will typically be the name of the FactoryConfiguration * class (or subclass) along with a caller-provided string identifying where * this instance was created. This aids greatly in debugging combined, complex * configurations. You may add further sources at any time via * {@link #addSource}. *

      * The {@link #toString()} method of this class provides a complete and * well-formatted listing of the configuration info contained within this * instance and is also very useful for debugging. *

      * * @author Nathan Bubna * @version $Id: FactoryConfiguration.java 511959 2007-02-26 19:24:39Z nbubna $ */ public class FactoryConfiguration extends CompoundConfiguration { private final SortedSet data = new TreeSet(); private final List sources = new ArrayList(); public FactoryConfiguration() { this(""); } /** * Creates a new instance with the specified source name * combined with this class's name as the initial source. */ public FactoryConfiguration(String source) { this(FactoryConfiguration.class, source); } /** * Allows subclasses to construct an instance that uses their classname. */ protected FactoryConfiguration(Class clazz, String source) { addSource(clazz.getName()+"("+source+")"); } /** * Returns the original source of this particular instance. */ public String getSource() { return this.sources.get(0); } /** * Sets the name of the original source of this particular instance. * This does not affect subsequently added sources. */ public void setSource(String source) { this.sources.set(0, source); } /** * Returns the list of sources for this configuration info in * order starting from the source name given to this instance * (if any) and going to the most recently added source. */ public List getSources() { return this.sources; } public void addSource(String source) { this.sources.add(source); } public void addData(Data newDatum) { // check if we already have a matching datum Data datum = getData(newDatum); if (datum != null) { // newer overrides older, so... // remove the old datum removeData(datum); } // add the new datum data.add(newDatum); } public boolean removeData(Data datum) { return data.remove(datum); } public Data getData(String key) { // create an example to search with Data findme = new Data(); findme.setKey(key); return getData(findme); } public Data getData(Data findme) { for (Data datum : data) { if (datum.equals(findme)) { return datum; } } return null; } public boolean hasData() { return !data.isEmpty(); } public SortedSet getData() { return data; } public void setData(Collection data) { for (Data datum : data) { addData(datum); } } public void addToolbox(ToolboxConfiguration toolbox) { addChild(toolbox); } public void removeToolbox(ToolboxConfiguration toolbox) { removeChild(toolbox); } public ToolboxConfiguration getToolbox(String scope) { for (ToolboxConfiguration toolbox : getToolboxes()) { if (scope.equals(toolbox.getScope())) { return toolbox; } } return null; } public Collection getToolboxes() { return getChildren(); } public void setToolboxes(Collection toolboxes) { setChildren(toolboxes); } public void addConfiguration(FactoryConfiguration config) { // add config's Data to our own setData(config.getData()); // add config's sources to our own for (String source : config.getSources()) { addSource(source); } // pass to CompoundConfiguration's to add properties super.addConfiguration(config); } @Override public void validate() { super.validate(); for (Data datum : data) { datum.validate(); } } /** * This will consider the object equal if it is a FactoryConfiguration * and whose {@link #toString(boolean)} method, when passed false, * returns a String equal to that returned by a call to toString(false) on this * instance. {@link #toString(boolean)} is used since that returns a String * encompassing all relevant info about the configuration except for the * source information. In other words, two FactoryConfigurations are considered * equal if they have the same data, properties and toolboxes in String form. */ @Override public boolean equals(Object o) { if (o instanceof FactoryConfiguration) { FactoryConfiguration that = (FactoryConfiguration)o; return that.toString(false).equals(this.toString(false)); } return false; } @Override public int hashCode() { return toString(false).hashCode(); } @Override public String toString() { return toString(true); } public String toString(boolean includeSources) { StringBuilder out = new StringBuilder(); out.append("\nFactoryConfiguration from "); if (includeSources) { out.append(getSources().size()); out.append(" sources "); } appendProperties(out); if (hasData()) { out.append("including "); out.append(data.size()); out.append(" data"); } if (getToolboxes().isEmpty()) { out.append("\n "); } else { appendChildren(out, "toolboxes: \n ", "\n "); } if (hasData()) { for (Data datum : data) { out.append(datum); out.append("\n "); } } if (includeSources) { int count = 0; for (String source : getSources()) { out.append("\n Source "); out.append(count++); out.append(": "); out.append(source); } out.append("\n"); } return out.toString(); } public ToolboxFactory createFactory() { ToolboxFactory factory = new ToolboxFactory(); factory.configure(this); return factory; } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/config/FileFactoryConfiguration.java100644 0 0 11207 11110347747 31022 0ustar 0 0 package org.apache.velocity.tools.config; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.io.InputStream; import java.io.IOException; import java.net.URL; import org.apache.velocity.exception.ResourceNotFoundException; import org.apache.velocity.runtime.log.Log; import org.apache.velocity.tools.ConversionUtils; /** * Provides support for reading a configuration file from a specified path, * This frees the user from having to obtain an InputStream themselves. * * @author Nathan Bubna * @version $Id: XmlFactoryConfiguration.java 511959 2007-02-26 19:24:39Z nbubna $ */ public abstract class FileFactoryConfiguration extends FactoryConfiguration { protected FileFactoryConfiguration(Class clazz, String id) { super(clazz, id); } /** *

      Reads an configuration from an {@link InputStream}.

      * * @param input the InputStream to read from */ public abstract void read(InputStream input) throws IOException; /** *

      Reads a configuration file from the specified file path * and sets up the configuration from that. If the file does not * exist, a {@link ResourceNotFoundException} will be thrown.

      * * @param path the path to the file to be read from */ public void read(String path) { read(path, true); } public void read(URL url) { read(url, true); } public void read(String path, boolean required) { read(path, required, null); } public void read(URL url, boolean required) { read(url, required, null); } public void read(String path, boolean required, Log log) { if (path == null) { throw new NullPointerException("Path value cannot be null"); } if (log != null && log.isTraceEnabled()) { log.trace("Attempting to read configuration file at: "+path); } URL url = findURL(path); if (url != null) { read(url, required, log); } else { String msg = "Could not find configuration file at: "+path; if (log != null) { log.debug(msg); } if (required) { throw new ResourceNotFoundException(msg); } } } protected URL findURL(String path) { return ConversionUtils.toURL(path, this); } protected void read(URL url, boolean required, Log log) { try { read(url, url.openStream(), required, log); // only add the sources which can be read addSource(" .read("+url.toString()+")"); } catch (IOException ioe) { String msg = "Could not open stream from: "+url; if (log != null) { log.debug(msg, ioe); } if (required) { throw new RuntimeException(msg, ioe); } } } protected void read(Object source, InputStream inputStream, boolean required, Log log) { try { read(inputStream); } catch (IOException ioe) { String msg = "InputStream could not be read from: "+source; if (log != null) { log.debug(msg, ioe); } if (required) { throw new RuntimeException(msg, ioe); } } finally { try { if (inputStream != null) { inputStream.close(); } } catch (IOException ioe) { if (log != null) { log.error("Failed to close input stream for "+source, ioe); } } } } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/config/InvalidScope.java100644 0 0 2555 10730012242 26413 0ustar 0 0 package org.apache.velocity.tools.config; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * * * @author Nathan Bubna * @version $Id: InvalidScope.java 511959 2007-02-26 19:24:39Z nbubna $ */ @Documented @Inherited @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface InvalidScope { String[] value(); } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/config/InvalidScopeException.java100644 0 0 3163 10730012242 30266 0ustar 0 0 package org.apache.velocity.tools.config; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ /** * * * @author Nathan Bubna * @version $Id: InvalidScopeException.java 511959 2007-02-26 19:24:39Z nbubna $ */ public class InvalidScopeException extends ConfigurationException { // this isn't crucial to keep around if the exception is serialized private final transient ToolConfiguration tool; public InvalidScopeException(ToolboxConfiguration toolbox, ToolConfiguration tool) { super(toolbox, "Toolbox with scope '" + toolbox.getScope() + "' may not contain a " + tool.getClassname() + '.'); this.tool = tool; } public ToolConfiguration getToolConfiguration() { return tool; } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/config/LogSupport.java100644 0 0 5214 10730012242 26144 0ustar 0 0 package org.apache.velocity.tools.config; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import org.apache.velocity.runtime.log.Log; /** * This allows for a {@link Log} to optionally be attached to * a subclass in order to output logging messages. This is simpler * than constantly checking whether we have a Log or not in each * usage throughout the classes which could use logging. Methods should * only be added to this as necessary. Performance considerations * can also be made later if deemed necessary. This is meant for internal * use and should NOT be relied upon by VelocityTools users. * * @author Nathan Bubna * @version $Id: LogSupport.java 511959 2007-02-26 19:24:39Z nbubna $ */ public abstract class LogSupport { private static final String DEFAULT_PREFIX = ""; private Log log; /** * Override this to set a class-specific prefix */ protected String logPrefix() { return DEFAULT_PREFIX; } public void setLog(Log log) { this.log = log; } protected Log getLog() { return this.log; } protected boolean isWarnEnabled() { return (log != null && log.isWarnEnabled()); } protected void warn(String msg) { if (isWarnEnabled()) { log.warn(logPrefix() + msg); } } protected boolean isDebugEnabled() { return (log != null && log.isDebugEnabled()); } protected void debug(String msg) { if (isDebugEnabled()) { log.debug(logPrefix() + msg); } } protected boolean isTraceEnabled() { return (log != null && log.isTraceEnabled()); } protected void trace(String msg) { if (isTraceEnabled()) { log.trace(logPrefix() + msg); } } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/config/NullKeyException.java100644 0 0 2516 10730012242 27272 0ustar 0 0 package org.apache.velocity.tools.config; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ /** * * * @author Nathan Bubna * @version $Id: NullKeyException.java 511959 2007-02-26 19:24:39Z nbubna $ */ public class NullKeyException extends ConfigurationException { public NullKeyException(Data data) { super(data, "Key is null for data with value of '"+data.getValue()+'\''); } public NullKeyException(ToolConfiguration tool) { super(tool, "Key is null for tool whose class is '"+tool.getClassname()+'\''); } } ././@LongLink100644 0 0 155 11365341753 10264 Lustar 0 0 velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/config/OldXmlFactoryConfigurationRuleSet.javavelocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/config/OldXmlFactoryConfigurationRule100644 0 0 14035 10730012242 31236 0ustar 0 0 package org.apache.velocity.tools.config; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import org.apache.commons.digester.Digester; import org.apache.commons.digester.Rule; import org.apache.commons.digester.RuleSetBase; import org.xml.sax.Attributes; /** *

      The set of Digester rules required to parse a old toolbox * configuration file (toolbox.xml).

      * * @author Nathan Bubna * @deprecated This is provided merely for 1.x compatibility. * @version $Id: OldXmlFactoryConfigurationRuleSet.java 511959 2007-02-26 19:24:39Z nbubna $ */ @Deprecated public class OldXmlFactoryConfigurationRuleSet extends RuleSetBase { public void addRuleInstances(Digester digester) { digester.addRule("toolbox/create-session", new CreateSessionRule()); digester.addRule("toolbox/xhtml", new XhtmlRule()); digester.addObjectCreate("toolbox", ToolboxConfiguration.class); digester.addRule("toolbox", new DeprecationRule()); digester.addSetNext("toolbox", "addToolbox"); digester.addObjectCreate("toolbox/tool", ToolConfiguration.class); digester.addBeanPropertySetter("toolbox/tool/key", "key"); digester.addBeanPropertySetter("toolbox/tool/class", "classname"); digester.addBeanPropertySetter("toolbox/tool/request-path", "restrictTo"); digester.addRule("toolbox/tool/scope", new ScopeRule()); digester.addRule("toolbox/tool/parameter", new ParameterRule()); digester.addSetNext("toolbox/tool", "addTool"); digester.addObjectCreate("toolbox/data", Data.class); digester.addSetProperties("toolbox/data"); digester.addBeanPropertySetter("toolbox/data/key", "key"); digester.addBeanPropertySetter("toolbox/data/value", "value"); digester.addRule("toolbox/data", new SetNextDataRule()); } protected static class DeprecationRule extends Rule { public void begin(String ns, String ln, Attributes attributes) throws Exception { // add a property to the FactoryConfiguration that // will trigger a deprecation warning in the logs FactoryConfiguration factory = (FactoryConfiguration)digester.getRoot(); factory.setProperty("deprecationSupportMode", true); } } protected static class ScopeRule extends Rule { public void body(String namespace, String element, String value) throws Exception { ToolConfiguration tool = (ToolConfiguration)digester.peek(0); ToolboxConfiguration toolbox = (ToolboxConfiguration)digester.peek(1); // if the scope is different than that of the current toolbox if (value != null && !value.equals(toolbox.getScope())) { // add the old ToolboxConfiguration to the FactoryConfiguration FactoryConfiguration factory = (FactoryConfiguration)digester.peek(2); factory.addToolbox(toolbox); // pop off the old toolbox and the tool digester.pop(); digester.pop(); // and push a new toolbox on the stack with the new scope ToolboxConfiguration newbox = new ToolboxConfiguration(); newbox.setScope(value); digester.push(newbox); // push the tool back on the stack digester.push(tool); } } } protected static class ParameterRule extends Rule { public void begin(String ns, String ln, Attributes attributes) throws Exception { ToolConfiguration config = (ToolConfiguration)digester.peek(); String name = attributes.getValue("name"); String value = attributes.getValue("value"); config.setProperty(name, value); } } protected static class SetNextDataRule extends Rule { public void end() throws Exception { Data data = (Data)digester.peek(0); FactoryConfiguration factory = (FactoryConfiguration)digester.getRoot(); factory.addData(data); } } protected static abstract class BooleanConfigRule extends Rule { public void body(String ns, String name, String text) throws Exception { FactoryConfiguration factory = (FactoryConfiguration)digester.getRoot(); if ("yes".equalsIgnoreCase(text)) { setBoolean(factory, Boolean.TRUE); } else { setBoolean(factory, Boolean.valueOf(text)); } } public abstract void setBoolean(FactoryConfiguration parent, Boolean value); } protected static class CreateSessionRule extends BooleanConfigRule { public void setBoolean(FactoryConfiguration factory, Boolean b) { factory.setProperty("createSession", b); } } protected static class XhtmlRule extends BooleanConfigRule { public void setBoolean(FactoryConfiguration factory, Boolean b) { factory.setProperty("XHTML", b); } } } ././@LongLink100644 0 0 152 11365341753 10261 Lustar 0 0 velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/config/PropertiesFactoryConfiguration.javavelocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/config/PropertiesFactoryConfiguration100644 0 0 17430 11110347747 31363 0ustar 0 0 package org.apache.velocity.tools.config; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.io.InputStream; import java.io.IOException; import java.util.Iterator; import org.apache.commons.beanutils.BeanUtils; import org.apache.commons.collections.ExtendedProperties; /** *

      This reads in configuration info formatted as a property * file using {@link ExtendedProperties} from Commons-Collections.

      *

      Example usage: *

       * FactoryConfiguration cfg = new PropertiesFactoryConfiguration();
       * cfg.read("my.properties");
       * ToolboxFactory factory = cfg.createFactory();
       * 

      *

      This reads in a configuration such as: *

       * tools.toolbox = request,application
       * tools.property.locale = en_us
       * tools.property.locale.class = java.util.Locale
       * tools.property.locale.converter = org.apache.velocity.tools.config.LocaleConverter
       * tools.request.property.xhtml = true
       * tools.request.render = org.apache.velocity.tools.view.ViewRenderTool
       * tools.request.render.parseDepth = 5
       * tools.request.search = com.foo.tools.MySearchTool
       * tools.request.search.itemsPerPage = 10
       * tools.application.math = org.apache.velocity.tools.generic.MathTool
       * tools.data.foo = bar
       * tools.data.foo.class = java.lang.String
       * tools.data.foo.converter = org.apache.commons.beanutils.converter.StringConverter
       * tools.data.version = 1.0
       * tools.data.version.type = number
       * tools.data.debug = false
       * tools.data.debug.type = boolean
       * 
      * NOTE: "property", "data", and "toolbox" are * reserved words do not use them as tool keys or toolbox scopes.

      * * @author Nathan Bubna * @version $Id: PropertiesFactoryConfiguration.java 511959 2007-02-26 19:24:39Z nbubna $ */ public class PropertiesFactoryConfiguration extends FileFactoryConfiguration { public PropertiesFactoryConfiguration() { this(""); } /** * Creates an instance using the specified string * as an identifier to distinguish this instance when debugging. * * @param id the name of the "source" of this instance * @see FactoryConfiguration#setSource(String) */ public PropertiesFactoryConfiguration(String id) { super(PropertiesFactoryConfiguration.class, id); } /** *

      Reads an properties file from an {@link InputStream} * and uses it to configure this {@link FactoryConfiguration}.

      * * @param input the InputStream to read from */ public void read(InputStream input) throws IOException { ExtendedProperties props = new ExtendedProperties(); props.load(input); // all factory settings should be prefixed with "tools" read(props.subset("tools")); } public void read(ExtendedProperties factory) { // get the global properties readProperties(factory, this); // get the toolboxes readToolboxes(factory); // get the data readData(factory.subset("data")); } protected void readProperties(ExtendedProperties configProps, Configuration config) { ExtendedProperties properties = configProps.subset("property"); if (properties != null) { for (Iterator i = properties.getKeys(); i.hasNext(); ) { String name = (String)i.next(); String value = properties.getString(name); ExtendedProperties propProps = properties.subset(name); if (propProps.size() == 1) { // then set this as a 'simple' property config.setProperty(name, value); } else { // add it as a convertable property Property property = new Property(); property.setName(name); property.setValue(value); // set the type/converter properties setProperties(propProps, property); } } } } protected void readToolboxes(ExtendedProperties factory) { String[] scopes = factory.getStringArray("toolbox"); for (String scope : scopes) { ToolboxConfiguration toolbox = new ToolboxConfiguration(); toolbox.setScope(scope); addToolbox(toolbox); ExtendedProperties toolboxProps = factory.subset(scope); readTools(toolboxProps, toolbox); readProperties(toolboxProps, toolbox); } } protected void readTools(ExtendedProperties tools, ToolboxConfiguration toolbox) { for (Iterator i = tools.getKeys(); i.hasNext(); ) { String key = (String)i.next(); // if it contains a period, it can't be a context key; // it must be a tool property. ignore it for now. if (key.indexOf('.') >= 0) { continue; } String classname = tools.getString(key); ToolConfiguration tool = new ToolConfiguration(); tool.setClassname(classname); tool.setKey(key); toolbox.addTool(tool); // get tool properties prefixed by 'property' ExtendedProperties toolProps = tools.subset(key); readProperties(toolProps, tool); // ok, get tool properties that aren't prefixed by 'property' for (Iterator j = toolProps.getKeys(); j.hasNext(); ) { String name = (String)j.next(); if (!name.equals(tool.getKey())) { tool.setProperty(name, toolProps.getString(name)); } } // get special props explicitly String restrictTo = toolProps.getString("restrictTo"); tool.setRestrictTo(restrictTo); } } protected void readData(ExtendedProperties dataset) { if (dataset != null) { for (Iterator i = dataset.getKeys(); i.hasNext(); ) { String key = (String)i.next(); // if it contains a period, it can't be a context key; // it must be a data property. ignore it for now. if (key.indexOf('.') >= 0) { continue; } Data data = new Data(); data.setKey(key); data.setValue(dataset.getString(key)); // get/set the type/converter properties ExtendedProperties props = dataset.subset(key); setProperties(props, data); addData(data); } } } protected void setProperties(ExtendedProperties props, Data data) { // let's just set/convert anything we can // this could be simplified to just check for type/class/converter try { BeanUtils.populate(data, props); } catch (Exception e) { throw new RuntimeException(e); } } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/config/Property.java100644 0 0 2362 11030275244 25662 0ustar 0 0 package org.apache.velocity.tools.config; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ /** * Simple extension of {@link Data} that treats "name" as an alias * for "key". See {@link Data} for a description and feature list. * * @author Nathan Bubna * @version $Id: Property.java 511959 2007-02-26 19:24:39Z nbubna $ */ public class Property extends Data { public void setName(String name) { setKey(name); } public String getName() { return getKey(); } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/config/SkipSetters.java100644 0 0 3021 11110347747 26316 0ustar 0 0 package org.apache.velocity.tools.config; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Annotation specifying that {@link org.apache.velocity.tools.ToolInfo} * should only use the public void configure(Map) method for configuration of * a tool, and skip over the step of trying to find individual * property setters. * * @author Nathan Bubna * @version $Id: SkipSetters.java 511959 2007-02-26 19:24:39Z nbubna $ */ @Documented @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Inherited public @interface SkipSetters { } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/config/ToolConfiguration.java100644 0 0 30701 11110347747 27530 0ustar 0 0 package org.apache.velocity.tools.config; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.lang.reflect.Method; import org.apache.velocity.tools.OldToolInfo; import org.apache.velocity.tools.ToolInfo; import org.apache.velocity.tools.ClassUtils; /** *

      This class handles configuration info for tools, including their key, * classname, path restriction, and properties. It also does fairly * aggresive validation and is able to identify if the tool is "old" * (i.e. designed for VelocityTools 1.x). Once configuration is * complete, a {@link ToolInfo} instance can be created by calling * {@link #createInfo}.

      *

      * Most users will not find themselves directly using the API of this class. *

      * * @author Nathan Bubna * @version $Id: ToolConfiguration.java 511959 2007-02-26 19:24:39Z nbubna $ */ public class ToolConfiguration extends Configuration { private enum Status { VALID, OLD, NONE, MISSING, UNSUPPORTED, UNINSTANTIABLE; } private String key; private String classname; private String restrictTo; private Boolean skipSetters; private Status status; private Throwable problem; public void setKey(String key) { this.key = key; // ensure any non-default key is also set as a property if (key != null && !key.equals(getDefaultKey())) { setProperty("key", key); } } public void setClass(Class clazz) { setClassname(clazz.getName()); } public void setClassname(String classname) { this.classname = classname; this.status = null; } public void setRestrictTo(String path) { this.restrictTo = path; } public void setSkipSetters(Boolean cfgOnly) { this.skipSetters = cfgOnly; } /** * Returns the key set for this tool. If no key has been explicitly * set, this will return the result of {@link #getDefaultKey()}. */ public String getKey() { if (this.key != null) { return this.key; } return getDefaultKey(); } /** * Returns the default key value for the set tool class. First, this * looks for a {@link DefaultKey} annotation on the tool class. Then, * if there is no default key annotation, the {@link Class#getSimpleName()} * is transformed into the key by removing any 'Tool' suffix and * lowercasing the first character. This will only return {@code null} * if there is both no key and no classname set for this tool. */ public String getDefaultKey() { if (getClassname() != null) { Class clazz = getToolClass(); DefaultKey defaultKey = (DefaultKey)clazz.getAnnotation(DefaultKey.class); if (defaultKey != null) { return defaultKey.value(); } else { // convert 'FooTool' to 'foo' to mirror most default keys String name = clazz.getSimpleName(); if (name.endsWith("Tool")) { int i = name.indexOf("Tool"); name = name.substring(0, i); } if (name.length() > 1) { name = name.substring(0, 1).toLowerCase() + name.substring(1, name.length()); } else { name = name.toLowerCase(); } return name; } } return null; } public String getClassname() { return this.classname; } public Class getToolClass() { try { return ClassUtils.getClass(getClassname()); } catch (ClassNotFoundException cnfe) { throw new ConfigurationException(this, cnfe); } } public String[] getInvalidScopes() { InvalidScope invalid = (InvalidScope)getToolClass().getAnnotation(InvalidScope.class); if (invalid != null) { return invalid.value(); } else { return new String[] {}; } } public String[] getValidScopes() { ValidScope valid = (ValidScope)getToolClass().getAnnotation(ValidScope.class); if (valid != null) { return valid.value(); } else { return new String[] {}; } } private final Status getStatus() { if (this.status == null) { if (getClassname() == null) { this.status = Status.NONE; } // check for mere presence of init() or configure() try { // make sure the classname resolves to a class we have Class clazz = ClassUtils.getClass(getClassname()); // try hard to ensure we have all necessary supporting classes digForDependencies(clazz); // create an instance to make sure we can do that clazz.newInstance(); // check for an init method Method init = clazz.getMethod("init", new Class[]{ Object.class }); // if init is deprecated, then we'll consider it a // new tool with BC support, not an old tool Deprecated bc = init.getAnnotation(Deprecated.class); if (bc == null) { this.status = Status.OLD; this.problem = null; } else { this.status = Status.VALID; this.problem = null; } } catch (NoSuchMethodException nsme) { // ignore this this.status = Status.VALID; this.problem = null; } catch (ClassNotFoundException cnfe) { this.status = Status.MISSING; this.problem = cnfe; } catch (NoClassDefFoundError ncdfe) { this.status = Status.UNSUPPORTED; this.problem = ncdfe; } catch (Throwable t) { // for all other problems... this.status = Status.UNINSTANTIABLE; this.problem = t; } } return this.status; } private void digForDependencies(Class clazz) { clazz.getDeclaredMethods(); clazz.getDeclaredFields(); Class superClass = clazz.getSuperclass(); if (superClass != null) { digForDependencies(superClass); } } public String getRestrictTo() { return this.restrictTo; } public Boolean getSkipSetters() { return this.skipSetters; } public ToolInfo createInfo() { ToolInfo info = null; Status status = getStatus(); switch (status) { case VALID: info = new ToolInfo(getKey(), getToolClass()); break; case OLD: info = new OldToolInfo(getKey(), getToolClass()); break; default: throw new ConfigurationException(this, getError(status)); } info.restrictTo(getRestrictTo()); if (getSkipSetters() != null) { info.setSkipSetters(getSkipSetters()); } // it's ok to use this here, because we know it's the // first time properties have been added to this ToolInfo info.addProperties(getPropertyMap()); return info; } private final String getError(Status status) { switch (status) { case NONE: return "No classname set for: "+this; case MISSING: return "Couldn't find tool class in the classpath for: "+this+ "("+this.problem+")"; case UNSUPPORTED: return "Couldn't find necessary supporting classes for: "+this+ "("+this.problem+")"; case UNINSTANTIABLE: return "Couldn't instantiate instance of tool for: "+this+ "("+this.problem+")"; default: return ""; } } @Override public void addConfiguration(Configuration config) { // copy properties super.addConfiguration(config); // copy values specific to tool configs if (config instanceof ToolConfiguration) { ToolConfiguration that = (ToolConfiguration)config; if (that.getClassname() != null) { setClassname(that.getClassname()); } if (that.getRestrictTo() != null) { setRestrictTo(that.getRestrictTo()); } } } @Override public void validate() { super.validate(); // make sure the key is not null if (getKey() == null) { throw new NullKeyException(this); } Status status = getStatus(); switch (status) { case VALID: case OLD: break; default: throw new ConfigurationException(this, getError(status)); } } @Override public int compareTo(Configuration conf) { if (!(conf instanceof ToolConfiguration)) { throw new UnsupportedOperationException("ToolConfigurations can only be compared to other ToolConfigurations"); } ToolConfiguration tool = (ToolConfiguration)conf; if (getKey() == null && tool.getKey() == null) { return 0; } else if (getKey() == null) { return -1; } else if (tool.getKey() == null) { return 1; } else { return getKey().compareTo(tool.getKey()); } } @Override public int hashCode() { if (getKey() == null) { return super.hashCode(); } return getKey().hashCode(); } @Override public boolean equals(Object obj) { if (getKey() == null || !(obj instanceof ToolConfiguration)) { return super.equals(obj); } return getKey().equals(((ToolConfiguration)obj).getKey()); } @Override public String toString() { StringBuilder out = new StringBuilder(); if (getClassname() == null) { out.append("Tool '"); out.append(this.key); } else { switch (getStatus()) { case VALID: break; case OLD: out.append("Old "); break; case NONE: case MISSING: out.append("Invalid "); break; case UNSUPPORTED: out.append("Unsupported "); break; case UNINSTANTIABLE: out.append("Unusable "); break; default: break; } out.append("Tool '"); out.append(getKey()); } out.append("' "); out.append("=> "); out.append(getClassname()); if (getRestrictTo() != null) { out.append(" only for '"); out.append(getRestrictTo()); out.append('\''); } out.append(" "); appendProperties(out); return out.toString(); } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/config/ToolboxConfiguration.java100644 0 0 13232 11110347747 30241 0ustar 0 0 package org.apache.velocity.tools.config; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.util.Collection; import java.util.SortedSet; import org.apache.velocity.tools.Scope; import org.apache.velocity.tools.ToolboxFactory; /** *

      This class handles configuration info for the Toolbox instances * that will eventually be produced by {@link ToolboxFactory}. * It contains {@link ToolConfiguration}s for tools which will be managed * by those toolboxes, as well the toolboxes' scope and * any other {@link Property}s which you intend to be available * to all the tools in the toolbox.

      *

      * Most users will not find themselves directly using the API of this class. *

      *

      NOTE: Two instances of this class are considered equal() if their scopes * are equal. This is not the intuitive behavior at this level but is done * to facilitate intuitive behavior in the higher APIs, which are much more * likely to be used directly.

      * * @author Nathan Bubna * @version $Id: ToolboxConfiguration.java 511959 2007-02-26 19:24:39Z nbubna $ */ public class ToolboxConfiguration extends CompoundConfiguration { private String scope = ToolboxFactory.DEFAULT_SCOPE; public ToolboxConfiguration() { // ensure that even the default scope is set as a property setProperty("scope", this.scope); } public void setScope(String scope) { if (scope == null) { throw new NullPointerException("Toolbox scope cannot be null"); } this.scope = scope; // ensure the scope is also set as a property of the toolbox setProperty("scope", scope); } public String getScope() { return this.scope; } public void addTool(ToolConfiguration tool) { addChild(tool); } public void removeTool(ToolConfiguration tool) { removeChild(tool); } public ToolConfiguration getTool(String key) { for (ToolConfiguration tool : getTools()) { if (key.equals(tool.getKey())) { return tool; } } return null; } public Collection getTools() { return getChildren(); } public void setTools(Collection tools) { setChildren(tools); } @Override public void validate() { super.validate(); if (getScope() == null) { throw new ConfigurationException(this, "Toolbox scope cannot be null"); } if (!Scope.exists(getScope())) { throw new ConfigurationException(this, "Scope '"+getScope()+"' is not recognized. Please correct or add your new custom scope with "+Scope.class.getName()+".add(\""+getScope()+"\")."); } // validate that all tools are allowed in this scope for (ToolConfiguration tool : getTools()) { // check if this toolbox's scope has been declared invalid for (String invalidScope : tool.getInvalidScopes()) { if (getScope().equals(invalidScope)) { throw new InvalidScopeException(this, tool); } } // if the set of valid scopes has been limited, check to be // sure that this toolbox's scope is in the set String[] validScopes = tool.getValidScopes(); if (validScopes != null && validScopes.length > 0) { boolean found = false; for (String validScope : validScopes) { if (getScope().equals(validScope)) { found = true; break; } } if (!found) { throw new InvalidScopeException(this, tool); } } } } @Override public int compareTo(Configuration conf) { if (!(conf instanceof ToolboxConfiguration)) { throw new UnsupportedOperationException("ToolboxConfigurations can only be compared to other ToolboxConfigurations"); } ToolboxConfiguration toolbox = (ToolboxConfiguration)conf; return getScope().compareTo(toolbox.getScope()); } @Override public int hashCode() { return scope.hashCode(); } @Override public boolean equals(Object obj) { if (obj instanceof ToolboxConfiguration) { return scope.equals(((ToolboxConfiguration)obj).scope); } return false; } public String toString() { StringBuilder out = new StringBuilder(); out.append("Toolbox '"); out.append(this.scope); out.append("' "); appendProperties(out); appendChildren(out, "tools: \n ", "\n "); return out.toString(); } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/config/ValidScope.java100644 0 0 2551 10730012242 26060 0ustar 0 0 package org.apache.velocity.tools.config; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * * * @author Nathan Bubna * @version $Id: ValidScope.java 511959 2007-02-26 19:24:39Z nbubna $ */ @Documented @Inherited @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface ValidScope { String[] value(); } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/config/XmlFactoryConfiguration.java100644 0 0 10443 11110347747 30704 0ustar 0 0 package org.apache.velocity.tools.config; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.io.InputStream; import java.io.IOException; import org.xml.sax.SAXException; import org.apache.commons.digester.Digester; import org.apache.commons.digester.RuleSet; /** *

      This reads in configuration info formatted as an XML file * using Commons-{@link Digester}. This uses * {@link XmlFactoryConfigurationRuleSet} as the default set of rules * for processing the XML. However, you may always change this by * passing a new {@link RuleSet} to the {@link #setRuleSet} method. * See the configuration documentation on the main web site for * instructions on the XML format supported by the default rules.

      *

      Example usage: *

       * FactoryConfiguration cfg = new XmlFactoryConfiguration("Dev Tools");
       * cfg.read("devtools.xml");
       * ToolboxFactory factory = cfg.createFactory();
       * 

      * * @author Nathan Bubna * @version $Id: XmlFactoryConfiguration.java 511959 2007-02-26 19:24:39Z nbubna $ */ public class XmlFactoryConfiguration extends FileFactoryConfiguration { private RuleSet ruleSet; private boolean supportOldXml; public XmlFactoryConfiguration() { this(false, ""); } public XmlFactoryConfiguration(boolean supportOldConfig) { this(supportOldConfig, String.valueOf(supportOldConfig)); } /** * Creates an instance using the specified string * as an identifier to distinguish this instance when debugging. * * @param id the name of the "source" of this instance * @see FactoryConfiguration#setSource(String) */ public XmlFactoryConfiguration(String id) { this(false, id); } /** * Creates an instance using the specified string * as an identifier to distinguish this instance when debugging * and using the specified setting for supporting the old toolbox.xml * format from VelocityTools 1.x. * * @param supportOldConfig whether the old toolbox.xml format should be supported * @param id the name of the "source" of this instance * @see FactoryConfiguration#setSource(String) */ public XmlFactoryConfiguration(boolean supportOldConfig, String id) { super(XmlFactoryConfiguration.class, id); setRuleSet(new XmlFactoryConfigurationRuleSet()); this.supportOldXml = supportOldConfig; } /** * Sets the {@link RuleSet} this loader will use to * digest the xml toolbox. */ public void setRuleSet(RuleSet rules) { this.ruleSet = rules; } /** *

      Retrieves the rule set Digester should use to parse and load * the toolbox for this manager.

      */ public RuleSet getRuleSet() { return ruleSet; } /** *

      Reads an XML document from an {@link InputStream} * and uses it to configure this {@link FactoryConfiguration}.

      * * @param input the InputStream to read from */ public void read(InputStream input) throws IOException { Digester digester = new Digester(); digester.setValidating(false); digester.setUseContextClassLoader(true); digester.push(this); digester.addRuleSet(getRuleSet()); if (supportOldXml) { digester.addRuleSet(new OldXmlFactoryConfigurationRuleSet()); } try { digester.parse(input); } catch (SAXException saxe) { throw new RuntimeException("There was an error while parsing the InputStream", saxe); } } } ././@LongLink100644 0 0 152 11365341753 10261 Lustar 0 0 velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/config/XmlFactoryConfigurationRuleSet.javavelocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/config/XmlFactoryConfigurationRuleSet100644 0 0 14752 11110347747 31277 0ustar 0 0 package org.apache.velocity.tools.config; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import org.apache.commons.digester.Digester; import org.apache.commons.digester.Rule; import org.apache.commons.digester.RuleSetBase; import org.xml.sax.Attributes; /** *

      This provides set of {@link Rule}s used by * Commons-{@link Digester} to process configuration info * formatted as XML. This is the default RuleSet used by * {@link XmlFactoryConfiguration}.

      *

      Here is a short example XML: *

      
       * <tools> 
       *     <data type="number" key="version" value="1.1"/>
       *     <data key="isConvertedProp" value="false" class="java.lang.Boolean" converter="org.apache.commons.beanutils.converters.BooleanConverter"/>
       *     <data type="boolean" key="isKnownType" value="true"/>
       *     <data key="isAutoType" value="true"/>
       *     <data key="foo" value="this is foo."/>
       *     <data key="bar">this is bar.</data>
       *     <toolbox scope="request" xhtml="true">
       *         <tool key="toytool" class="ToyTool" restrictTo="index.vm"/>
       *     </toolbox>
       *     <toolbox scope="session">
       *         <property name="createSession" value="true" type="boolean"/>
       *         <tool key="map" class="java.util.HashMap"/>
       *     </toolbox>
       *     <toolbox scope="application">
       *         <tool class="org.apache.velocity.tools.generic.DateTool"/>
       *     </toolbox>
       * </tools>
       * 

      * * @author Nathan Bubna * @version $Id: XmlConfiguration.java 511959 2007-02-26 19:24:39Z nbubna $ */ public class XmlFactoryConfigurationRuleSet extends RuleSetBase { protected Class toolboxConfigurationClass = ToolboxConfiguration.class; protected Class toolConfigurationClass = ToolConfiguration.class; protected Class dataClass = Data.class; protected Class propertyClass = Property.class; public void setToolboxConfigurationClass(Class clazz) { this.toolboxConfigurationClass = clazz; } public void setToolConfigurationClass(Class clazz) { this.toolConfigurationClass = clazz; } public void setDataClass(Class clazz) { this.dataClass = clazz; } public void setPropertyClass(Class clazz) { this.propertyClass = clazz; } /** *

      Add the set of Rule instances defined in this RuleSet to the * specified Digester instance, associating them with * our namespace URI (if any). This method should only be called * by a Digester instance. These rules assume that an instance of * org.apache.velocity.tools.view.ToolboxManager is pushed * onto the evaluation stack before parsing begins.

      * * @param digester Digester instance to which the new Rule instances * should be added. */ public void addRuleInstances(Digester digester) { // create the config objects digester.addObjectCreate("tools/property", propertyClass); digester.addObjectCreate("tools/*/property", propertyClass); digester.addObjectCreate("tools/data", dataClass); digester.addObjectCreate("tools/toolbox", toolboxConfigurationClass); digester.addObjectCreate("tools/toolbox/tool", toolConfigurationClass); // to apply matching attributes to specific setters of config objects digester.addSetProperties("tools/property"); digester.addSetProperties("tools/*/property"); digester.addSetProperties("tools"); digester.addSetProperties("tools/data"); digester.addSetProperties("tools/toolbox"); digester.addSetProperties("tools/toolbox/tool"); // to add all attributes to config via setProperty(name,value) digester.addRule("tools", new PropertyAttributeRule()); digester.addRule("tools/toolbox", new PropertyAttributeRule()); digester.addRule("tools/toolbox/tool", new PropertyAttributeRule()); // for config data & properties whose values are in the body of the tag digester.addRule("tools/data", new DataValueInBodyRule()); digester.addRule("tools/*/property", new DataValueInBodyRule()); // to finish a config and move on to the next digester.addSetNext("tools/property", "addProperty"); digester.addSetNext("tools/*/property", "addProperty"); digester.addSetNext("tools/data", "addData"); digester.addSetNext("tools/toolbox", "addToolbox"); digester.addSetNext("tools/toolbox/tool", "addTool"); } /****************************** Custom Rules *****************************/ /** * Rule for adding configuration properties */ public static class DataValueInBodyRule extends Rule { public void body(String namespace, String element, String value) throws Exception { Data data = (Data)digester.peek(); if (data.getValue() == null) { data.setValue(value); } } } public static class PropertyAttributeRule extends Rule { public void begin(String namespace, String element, Attributes attributes) throws Exception { Configuration config = (Configuration)digester.peek(); for (int i=0; i < attributes.getLength(); i++) { String name = attributes.getLocalName(i); if ("".equals(name)) { name = attributes.getQName(i); } // don't treat "class" as a property if (!"class".equals(name)) { String value = attributes.getValue(i); config.setProperty(name, value); } } } } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/generic/AbstractLockConfig.java100644 0 0 3026 11030275252 27704 0ustar 0 0 package org.apache.velocity.tools.generic; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ /** *

      Apologies to anyone who stepped up to use Tools 2.0-beta1 * and made their tools extend this class. Please just extend * the SafeConfig class now. It is better named and no longer * requires implementation of {@link #configure(ValueParser)}, * as that may not be needed by subclasses that may simply want * to know safeMode and/or lockConfig settings. *

      *

      * Sorry for any inconvenience, but this class will be removed * before Tools 2.0 goes final. Please update your subclasses * before that time. Thanks. *

      * * @since VelocityTools 2.0 * @deprecated Use {@link SafeConfig} instead */ @Deprecated public abstract class AbstractLockConfig extends SafeConfig { } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/generic/Alternator.java100644 0 0 7737 10730012250 26323 0ustar 0 0 package org.apache.velocity.tools.generic; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.util.Collection; /** * Utility class for easily alternating over values in a list. * *

      Example usage: *

       * java...
       *      String[] myColors = new String[]{"red", "blue"};
       *      context.put("color", new Alternator(myColors));
       *      String[] myStyles = new String[]{"hip", "fly", "groovy"};
       *      // demonstrate manual alternation with this one
       *      context.put("style", new Alternator(false, myStyles));
       *
       * template...
       *      #foreach( $foo in [1..5] )
       *       $foo is $color and $style.next
       *      #end
       *
       * output...
       *      1 is red and hip
       *      2 is blue and fly
       *      3 is red and groovy
       *      4 is blue and hip
       *      5 is red and fly
       * 

      * * @since Velocity Tools 1.2 * @version $Id: Alternator.java 603419 2007-12-12 00:04:07Z nbubna $ */ public class Alternator { private Object[] list; private int index = 0; private boolean auto = true; /** * Creates a new Alternator for the specified list. Alternation * defaults to automatic. */ public Alternator(Object... list) { this(true, list); } /** * Creates a new Alternator for the specified list with the specified * automatic shifting preference. * * @param auto See {@link #setAuto(boolean auto)}. * @param list The elements to alternate over */ public Alternator(boolean auto, Object... list) { this.auto = auto; if (list.length == 1 && list[0] instanceof Collection) { this.list = ((Collection)list[0]).toArray(); } else { this.list = list; } } /** * @return Whether this Alternator shifts the list index * automatically after a call to {@link #toString()}. */ public boolean isAuto() { return auto; } /** * If set to true, the list index will shift automatically after a * call to toString(). */ public void setAuto(boolean auto) { this.auto = auto; } /** * Manually shifts the list index. If it reaches the end of the list, * it will start over again at zero. */ public void shift() { index = (index + 1) % list.length; } /** * Returns the current item without shifting the list index. */ public Object getCurrent() { return list[index]; } /** * Returns the current item, then shifts the list index. */ public Object getNext() { Object o = getCurrent(); shift(); return o; } /** * Returns a string representation of the current item or * null if the current item is null. If {@link * #auto} is true, this will shift after returning the current * item. */ public String toString() { Object o = list[index]; if (auto) { shift(); } if (o == null) { return null; } return o.toString(); } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/generic/AlternatorTool.java100644 0 0 14542 11030275253 27201 0ustar 0 0 package org.apache.velocity.tools.generic; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.util.Collection; import org.apache.velocity.tools.config.DefaultKey; /** * Simple tool to provide easy in-template instantiation of * {@link Alternator}s from varying "list" types or individual * arguments. * *

      Example Use: *

       * tools.xml...
       * <tools>
       *   <toolbox scope="application">
       *     <tool class="org.apache.velocity.tools.generic.AlternatorTool"/>
       *   </toolbox>
       * </tools>
       *
       * template...
       * #set( $color = $alternator.auto('red', 'blue') )
       * ## use manual alternation for this one
       * #set( $style = $alternator.manual('hip','fly','groovy') )
       * #foreach( $i in [1..5] )
       *   Number $i is $color and $style. I dig $style.next numbers.
       * #end *
       *
       * output...
       *   Number 1 is red and hip. I dig hip numbers.
       *   Number 2 is blue and fly. I dig fly numbers.
       *   Number 3 is red and groovy. I dig groovy numbers.
       *   Number 4 is blue and hip. I dig hip numbers.
       *   Number 5 is red and fly. I dig fly numbers.
       * 

      * * @since Velocity Tools 1.2 * @version $Revision: 671010 $ $Date: 2008-06-23 20:40:41 -0700 (Mon, 23 Jun 2008) $ */ @DefaultKey("alternator") public class AlternatorTool extends SafeConfig { @Deprecated public static final String OLD_AUTO_ALTERNATE_DEFAULT_KEY = "auto-alternate"; public static final String AUTO_ALTERNATE_DEFAULT_KEY = "autoAlternate"; // it's true by default in Alternator private boolean autoAlternateDefault = true; /** * Looks for a default auto-alternate value in the given params, * if not, set the default to true. */ protected void configure(ValueParser parser) { Boolean auto = parser.getBoolean(AUTO_ALTERNATE_DEFAULT_KEY); if (auto == null) { // check for old key, use true as default (just like Alternator) auto = parser.getBoolean(OLD_AUTO_ALTERNATE_DEFAULT_KEY, Boolean.TRUE); } this.autoAlternateDefault = auto.booleanValue(); } /** * Returns true if the default for auto-alternating is true. * @since VelocityTools 1.3 */ public boolean getAutoAlternateDefault() { return autoAlternateDefault; } /** * Sets the default for auto-alternating. * @since VelocityTools 1.3 */ protected void setAutoAlternateDefault(boolean bool) { this.autoAlternateDefault = bool; } /** * Make an automatic {@link Alternator} from the specifed objects. */ public Alternator make(Object... list) { return make(autoAlternateDefault, list); } /** * @deprecated Will be unnecessary with Velocity 1.6 */ @Deprecated public Alternator make(Collection list) { return make(autoAlternateDefault, list); } /** * Returns a new Alternator for the specified list with the specified * automatic shifting preference. * * @param auto See {@link Alternator#setAuto(boolean auto)}. * @param list The list of elements to alternate. */ public Alternator make(boolean auto, Object... list) { if (list == null || list.length == 0) { return null; } else if (list.length == 1 && list[0] instanceof Collection && ((Collection)list[0]).isEmpty()) { return null; } return new Alternator(auto, list); } /** * @deprecated Will be unnecessary with Velocity 1.6 */ @Deprecated public Alternator make(boolean auto, Collection list) { return make(auto, new Object[] { list }); } /** * @deprecated Will be unnecessary with Velocity 1.6 */ @Deprecated public Alternator make(Object o1, Object o2) { return make(autoAlternateDefault, o1, o2); } /** * @deprecated Will be unnecessary with Velocity 1.6 */ @Deprecated public Alternator make(boolean auto, Object o1, Object o2) { if (o1 == null || o2 == null) { return null; } return new Alternator(auto, new Object[] { o1, o2 }); } /** * Make an automatic {@link Alternator} from the specified objects. * * @return a new, automatic Alternator with the specified values or * null if there are none specified. * @since VelocityTools 1.3 */ public Alternator auto(Object... list) { return make(true, list); } /** * @deprecated Will be unnecessary with Velocity 1.6 */ @Deprecated public Alternator auto(Collection list) { return make(true, list); } /** * @deprecated Will be unnecessary with Velocity 1.6 */ @Deprecated public Alternator auto(Object o1, Object o2) { return make(true, o1, o2); } /** * Make a manual {@link Alternator} from the specified objects. * * @return a new, manual Alternator with the values in the array or * null if the array is null. * @since VelocityTools 1.3 */ public Alternator manual(Object... list) { return make(false, list); } /** * @deprecated Will be unnecessary with Velocity 1.6 */ @Deprecated public Alternator manual(Collection list) { return make(false, list); } /** * @deprecated Will be unnecessary with Velocity 1.6 */ @Deprecated public Alternator manual(Object o1, Object o2) { return make(false, o1, o2); } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/generic/ClassTool.java100644 0 0 67034 11202122666 26137 0ustar 0 0 package org.apache.velocity.tools.generic; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.lang.annotation.Annotation; import java.lang.reflect.AnnotatedElement; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.HashSet; import java.util.Set; import org.apache.velocity.runtime.log.Log; import org.apache.velocity.tools.ClassUtils; import org.apache.velocity.tools.config.DefaultKey; /** *

      * This tool is meant to simplify reflective lookup of information about * a {@link Class} and its {@link Field}s, {@link Method}s, and {@link Constructor}s. * This is ideally aimed at those wishing to generate documentation, demo code, or * other content based on runtime reflection of a specified Class or Classes. It was not * designed with reflective execution of code in mind and thus provides no facilities * for code execution, nor direct access to the actual methods, constructors or fields * of the class being inspected. *

      * *

      *

       * Example tools.xml config:
       * <tools>
       *   <toolbox scope="application">
       *     <tool class="org.apache.velocity.tools.generic.ClassTool"
       *              inspect="com.org.Foo"/>
       *   </toolbox>
       * </tools>
       * 

      *

      * If no Class to be inspected is specified, the default is java.lang.Object. *

      * * @author Nathan Bubna * @since VelocityTools 2.0 * @version $Id: ClassTool.java 463298 2006-10-12 16:10:32Z henning $ */ @DefaultKey("class") public class ClassTool extends SafeConfig { public static final String INSPECT_KEY = "inspect"; public static final String SHOW_DEPRECATED_KEY = "showDeprecated"; protected Log log; protected Class type; protected List methods; protected List constructors; protected List fields; private boolean showDeprecated = false; /** * Creates an instance with target type of {@link Object}. */ public ClassTool() { setType(Object.class); } /** * Creates a new instance that inspects the specified type * and otherwise shares the configuration values of the specified "parent" * ClassTool instance. */ protected ClassTool(ClassTool tool, Class type) { setType(type); if (tool == null) { throw new IllegalArgumentException("parent tool must not be null"); } // manually duplicate configuration of the parent tool this.log = tool.log; this.showDeprecated = tool.showDeprecated; setSafeMode(tool.isSafeMode()); setLockConfig(tool.isConfigLocked()); } protected void configure(ValueParser values) { this.log = (Log)values.getValue("log"); this.showDeprecated = values.getBoolean(SHOW_DEPRECATED_KEY, showDeprecated); String classname = values.getString(INSPECT_KEY); if (classname != null) { setType(toClass(classname)); } } private Class toClass(String name) { try { return ClassUtils.getClass(name); } catch (Exception e) { if (this.log != null) { this.log.error("Could not load Class for "+name); } return null; } } protected void setType(Class type) { if (type == null) { throw new IllegalArgumentException("target type is null or invalid"); } this.type = type; } protected static boolean isDeprecated(AnnotatedElement element) { return (element.getAnnotation(Deprecated.class) != null); } /** * Returns the current showDeprecated setting. */ public boolean getShowDeprecated() { return this.showDeprecated; } /** * Returns the {@link Class} being inspected by this instance. */ public Class getType() { return this.type; } /** * Returns a new ClassTool instance that is inspecting the * Class with the specified name. If the specified Class cannot * be found, then this will return {@code null}. All other * configuration settings will be copied to the new instance. */ public ClassTool inspect(String name) { if (name == null) { return null; } return inspect(toClass(name)); } /** * Returns a new ClassTool instance that is inspecting the * Class of the specified {@link Object}. If the specified object * is null, then this will return {@code null}. All other * configuration settings will be copied to the new instance. */ public ClassTool inspect(Object obj) { if (obj == null) { return null; } return inspect(obj.getClass()); } /** * Returns a new ClassTool instance that is inspecting the * superclass of the Class being inspected by this instance. * If the current inspectee has no super class, * then this will return {@code null}. All other * configuration settings will be copied to the new instance. */ public ClassTool getSuper() { Class sup = getType().getSuperclass(); if (sup == null) { return null; } return inspect(sup); } /** * Returns a new ClassTool instance that is inspecting the * the specified {@link Class}. If the specified class * is null, then this will return {@code null}. All other * configuration settings will be copied to the new instance. * If {@link #isSafeMode()} is {@code true} and the specified Class * is not declared {@code public}, then this will return * {@code null}. */ public ClassTool inspect(Class type) { if (type == null) { return null; } // create the new tool, but only return it if // it is public or isSafeMode() is off ClassTool tool = new ClassTool(this, type); if (isSafeMode() && !tool.isPublic()) { return null; } return tool; } /** * Returns the name of the package to which the inspected Class belongs. */ public String getPackage() { return getType().getPackage().getName(); } /** * Returns the simple name (i.e. full name with package name removed) of * the inspected Class. */ public String getName() { return getType().getSimpleName(); } /** * Returns the fully-qualified name for the inspected Class. */ public String getFullName() { return getType().getName(); } /** * Returns true if a call to newInstance() on the Class being * inspected is successful; otherwise returns false. Unlike calling * newInstance() directly from a template, this will not throw an * Exception if it fails, as all Exceptions are caught. */ public boolean supportsNewInstance() { try { type.newInstance(); return true; } catch (Exception e) { return false; } } /** * Returns true if the inspected Class has been deprecated. */ public boolean isDeprecated() { return isDeprecated(getType()); } /** * Returns true if the inspected Class is declared public. */ public boolean isPublic() { return Modifier.isPublic(getType().getModifiers()); } /** * Returns true if the inspected Class is declared protected. */ public boolean isProtected() { return Modifier.isProtected(getType().getModifiers()); } /** * Returns true if the inspected Class is declared private. */ public boolean isPrivate() { return Modifier.isPrivate(getType().getModifiers()); } /** * Returns true if the inspected Class is an inner class * that has been declared static or is a standard outer class.. */ public boolean isStatic() { return Modifier.isStatic(getType().getModifiers()); } /** * Returns true if the inspected Class is declared final. */ public boolean isFinal() { return Modifier.isFinal(getType().getModifiers()); } /** * Returns true if the inspected Class is an interface. */ public boolean isInterface() { return Modifier.isInterface(getType().getModifiers()); } /** * Returns true if the inspected Class is declared strictfp * (uses strict floating point math). */ public boolean isStrict() { return Modifier.isStrict(getType().getModifiers()); } /** * Returns true if the inspected Class is declared abstract. */ public boolean isAbstract() { return Modifier.isAbstract(getType().getModifiers()); } /** * Returns a {@link List} of {@link MethodSub}s for each * method declared method in the inspected class. However, * in safe mode (which *is* the default), this will only return * the public methods. You must configure safe mode to be off * to receive a list of all methods. */ public List getMethods() { if (methods == null) { Method[] declared = getType().getDeclaredMethods(); List subs = new ArrayList(declared.length); for (Method method : declared) { MethodSub sub = new MethodSub(method); if ((!isSafeMode() || sub.isPublic()) && (showDeprecated || !sub.isDeprecated())) { subs.add(sub); } } Collections.sort(subs); methods = Collections.unmodifiableList(subs); } return methods; } /** * Returns a {@link List} of {@link ConstructorSub}s for each * constructor declared constructor in the inspected class. However, * in safe mode (which *is* the default), this will only return * the public constructors. You must configure safe mode to be off * to receive a list of all constructors. */ public List getConstructors() { if (constructors == null) { Constructor[] declared = getType().getDeclaredConstructors(); List subs = new ArrayList(declared.length); for (Constructor constructor : declared) { ConstructorSub sub = new ConstructorSub(constructor); if ((!isSafeMode() || sub.isPublic()) && (showDeprecated || !sub.isDeprecated())) { subs.add(sub); } } Collections.sort(subs); constructors = Collections.unmodifiableList(subs); } return constructors; } /** * Returns a {@link List} of {@link FieldSub}s for each * field declared field in the inspected class. However, * in safe mode (which *is* the default), this will only return * the public fields. You must configure safe mode to be off * to receive a list of all fields. */ public List getFields() { if (fields == null) { Field[] declared = getType().getDeclaredFields(); List subs = new ArrayList(declared.length); for (Field field : declared) { FieldSub sub = new FieldSub(field); if ((!isSafeMode() || sub.isPublic()) && (showDeprecated || !sub.isDeprecated())) { subs.add(sub); } } Collections.sort(subs); fields = Collections.unmodifiableList(subs); } return fields; } /** * Returns a {@link Set} of all {@link Class}es that are * part of the signatures (i.e. parameters or return types) * of the inspected Class's methods, constructors and fields. */ public Set getTypes() { Set types = new HashSet(); for (MethodSub method : getMethods()) { if (!isSafeMode() || method.isPublic()) { if (!method.isVoid()) { addType(types, method.getReturns()); } for (Class type : method.getParameters()) { addType(types, type); } } } for (ConstructorSub constructor : getConstructors()) { if (!isSafeMode() || constructor.isPublic()) { for (Class type : constructor.getParameters()) { addType(types, type); } } } for (FieldSub field : getFields()) { if (!isSafeMode() || field.isPublic()) { addType(types, field.getType()); } } return types; } private void addType(Set types, Class type) { if (type.isArray()) { type = type.getComponentType(); } if (!type.isPrimitive()) { types.add(type); } } /** * Returns the {@link Annotation}s of the Class being inspected. */ public List getAnnotations() { return Arrays.asList(getType().getAnnotations()); } public String toString() { return getType().toString(); } /** * A simplified wrapping interface for inspecting features * of a {@link Field} in an inspected Class. */ public static class FieldSub extends Sub { protected Field field; public FieldSub(Field field) { this.field = field; } protected AnnotatedElement getElement() { return field; } public String getName() { return field.getName(); } /** * Simply returns the name of the field, since field names * cannot be overloaded. */ public String getUniqueName() { // field names can't be overloaded return field.getName(); } /** * Simply returns the name of the field. */ public String getJavadocRef() { return field.getName(); } public Class getType() { return field.getType(); } /** * Returns the value of the field if and only if * it is a static field that has no access restrictions * set by the security manager. */ public Object getStaticValue() { if (isStatic()) { try { return field.get(null); } catch(IllegalAccessException iae) { //ignore } } return null; } protected int getModifiers() { return field.getModifiers(); } protected String getSubType() { return "field"; } } /** * A simplified wrapping interface for inspecting features * of a {@link Constructor} in an inspected Class. */ public static class ConstructorSub extends CallableSub { protected Constructor constructor; public ConstructorSub(Constructor constructor) { this.constructor = constructor; } protected AnnotatedElement getElement() { return constructor; } public String getName() { return constructor.getDeclaringClass().getSimpleName(); } public Class[] getParameters() { return constructor.getParameterTypes(); } /** * Returns true if the final parameter for the constructor was declared * as a vararg. */ public boolean isVarArgs() { return constructor.isVarArgs(); } protected int getModifiers() { return constructor.getModifiers(); } protected String getSubType() { return "constructor"; } } /** * A simplified wrapping interface for inspecting features * of a {@link Method} in an inspected Class. */ public static class MethodSub extends CallableSub { protected Method method; public MethodSub(Method method) { this.method = method; } protected AnnotatedElement getElement() { return method; } public String getName() { return method.getName(); } /** * If this method can be treated as a bean property in Velocity * (which does not exactly follow the javabean spec for such things) * then it will return the "bean property" equivalent of the method name. * (e.g. for getFoo(), isFoo() or setFoo(foo) it will return "foo") */ public String getPropertyName() { String name = getName(); switch (getParameterCount()) { case 0: if (name.startsWith("get") && name.length() > 3) { return uncapitalize(name.substring(3, name.length())); } else if (name.startsWith("is") && name.length() > 2) { return uncapitalize(name.substring(2, name.length())); } break; case 1: if (name.startsWith("set") && name.length() > 3) { return uncapitalize(name.substring(3, name.length())); } default: } return null; } private String uncapitalize(String string) { if (string.length() > 1) { StringBuilder out = new StringBuilder(string.length()); out.append(string.substring(0,1).toLowerCase()); out.append(string.substring(1, string.length())); return out.toString(); } else { return string.toLowerCase(); } } /** * Returns true if the final parameter for the method was declared * as a vararg. */ public boolean isVarArgs() { return method.isVarArgs(); } /** * Returns true if the return type of this method is void. */ public boolean isVoid() { return (getReturns() == Void.TYPE); } public Class getReturns() { return method.getReturnType(); } public Class[] getParameters() { return method.getParameterTypes(); } protected int getModifiers() { return method.getModifiers(); } protected String getSubType() { return "method"; } } public abstract static class CallableSub extends Sub { protected String uniqueName; protected String javadocRef; protected String signature; public abstract Class[] getParameters(); public abstract boolean isVarArgs(); public boolean takesParameters() { return (getParameterCount() > 0); } /** * Returns the number of expected parameters. If this method or * constructor is declared with varargs, the vararg only counts as one. */ public int getParameterCount() { return getParameters().length; } /** * Build a unique method/ctor name by appending the simple names of * the expected parameter types, thereby distinguishing constructors * and overloaded methods with a useful name that would still be a * valid method name. This is particularly useful for generating * JUnit test method names. */ public String getUniqueName() { if (uniqueName == null) { Class[] params = getParameters(); if (params.length == 0) { uniqueName = getName(); } else { StringBuilder out = new StringBuilder(30); out.append(getName()); out.append('_'); for (int i=0; i < params.length; i++) { Class param = params[i]; if (param.isArray()) { out.append(param.getComponentType().getSimpleName()); // check for vararg on last param if (i == params.length - 1 && isVarArgs()) { out.append("VarArgs"); } else { out.append("Array"); } } else { out.append(param.getSimpleName()); } } uniqueName = out.toString(); } } return uniqueName; } public String getSignature() { if (signature == null) { signature = signature(false); } return signature; } public String getJavadocRef() { if (javadocRef == null) { javadocRef = signature(true); } return javadocRef; } protected String signature(boolean fullNames) { Class[] params = getParameters(); if (params.length == 0) { return getName() + "()"; } else { StringBuilder out = new StringBuilder(30); out.append(getName()); out.append('('); boolean first = true; for (int i=0; i < params.length; i++) { Class param = params[i]; if (first) { first = false; } else { out.append(','); } if (param.isArray()) { if (fullNames) { out.append(param.getComponentType().getName()); } else { out.append(param.getComponentType().getSimpleName()); } if (i == params.length - 1 && isVarArgs()) { out.append("..."); } else { out.append("[]"); } } else { if (fullNames) { out.append(param.getName()); } else { out.append(param.getSimpleName()); } } } out.append(')'); return out.toString(); } } } public abstract static class Sub implements Comparable { protected abstract AnnotatedElement getElement(); protected abstract int getModifiers(); protected abstract String getSubType(); public abstract String getName(); public abstract String getUniqueName(); public abstract String getJavadocRef(); /** * Returns the {@link Annotation}s of the element being inspected. */ public List getAnnotations() { return Arrays.asList(getElement().getAnnotations()); } public boolean isDeprecated() { return ClassTool.isDeprecated(getElement()); } public boolean isPublic() { return Modifier.isPublic(getModifiers()); } public boolean isProtected() { return Modifier.isProtected(getModifiers()); } public boolean isPrivate() { return Modifier.isPrivate(getModifiers()); } public boolean isStatic() { return Modifier.isStatic(getModifiers()); } public boolean isFinal() { return Modifier.isFinal(getModifiers()); } public boolean isInterface() { return Modifier.isInterface(getModifiers()); } public boolean isNative() { return Modifier.isNative(getModifiers()); } public boolean isStrict() { return Modifier.isStrict(getModifiers()); } public boolean isSynchronized() { return Modifier.isSynchronized(getModifiers()); } public boolean isTransient() { return Modifier.isTransient(getModifiers()); } public boolean isVolatile() { return Modifier.isVolatile(getModifiers()); } public boolean isAbstract() { return Modifier.isAbstract(getModifiers()); } public int compareTo(T that) { return this.getUniqueName().compareTo(that.getUniqueName()); } public int hashCode() { return this.getUniqueName().hashCode(); } public boolean equals(Object obj) { if (obj instanceof Sub) { Sub that = (Sub)obj; return this.getUniqueName().equals(that.getUniqueName()); } return false; } public String toString() { return getSubType() + ' ' + getJavadocRef(); } } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/generic/ComparisonDateTool.java100644 0 0 57176 10730012250 30000 0ustar 0 0 package org.apache.velocity.tools.generic; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.util.Collections; import java.util.Calendar; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Locale; import java.util.Map; import java.util.MissingResourceException; import java.util.ResourceBundle; /** * Tool for comparing {@link java.util.Date} and {@link Calendar} values * in Velocity templates. This is a subclass of {@link DateTool} * and thus provides all the functionality of that tool and * augments it with the ability to find the relationship between * any date and the current date, or between any two dates. * This comparison can result in either a textual representation * of the relationship (e.g. "3 weeks, 2 days ago", "tomorrow", or * "3 hrs away") or the value of a specific time unit may be requested. * When using the textual representations, you can configure the * tool to use alternate resource bundles and to skip over units * you do not want to be included. *

       * Example of formatting the "current" date:
       *  $date.whenIs('2005-07-04')                -> 1 year ago
       *  $date.whenIs('2007-02-15').full           -> 1 year 32 weeks 2 days 17 hours 38 minutes 44 seconds 178 milliseconds ago
       *  $date.whenIs('2007-02-15').days           -> -730
       *  $date.whenIs($date.calendar)              -> now
       *  $date.whenIs('2005-07-04', '2005-07-04')  -> same time
       *  $date.difference('2005-07-04','2005-07-04')      -> 0 milliseconds
       *  $date.difference('2005-07-04','2007-02-15').abbr -> 1 yr
       *
       * Example tools.xml config (if you want to use this with VelocityView):
       * <tools>
       *   <toolbox scope="application">
       *     <tool class="org.apache.velocity.tools.generic.ComparisonDateTool"
       *              format="yyyy-MM-dd" depth="1" skip="month,week,millisecond"
       *              bundle="org.apache.velocity.tools.generic.times"/>
       *   </toolbox>
       * </tools>
       * 

      * * @author Nathan Bubna * @author Chris Townsen * @since VelocityTools 1.4 * @version $Revision: 595822 $ $Date: 2006-04-04 12:35:17 -0700 (Tue, 04 Apr 2006) $ */ public class ComparisonDateTool extends DateTool { /** The number of milliseconds in a second. */ public static final long MILLIS_PER_SECOND = 1000l; /** The number of millseconds in a minute. */ public static final long MILLIS_PER_MINUTE = 60l * MILLIS_PER_SECOND; /** The number of milliseconds in an hour. */ public static final long MILLIS_PER_HOUR = 60l * MILLIS_PER_MINUTE; /** The number of milliseconds in a day. */ public static final long MILLIS_PER_DAY = 24l * MILLIS_PER_HOUR; /** The number of milliseconds in a week. */ public static final long MILLIS_PER_WEEK = 7l * MILLIS_PER_DAY; /** An approximation of the number of milliseconds in a month. */ public static final long MILLIS_PER_MONTH = 30l * MILLIS_PER_DAY; /** An approximation of the number of milliseconds in a year. */ public static final long MILLIS_PER_YEAR = 365l * MILLIS_PER_DAY; /** The key used for specifying a default locale via toolbox params. */ public static final String BUNDLE_NAME_KEY = "bundle"; /** The key used for specifying a different default depth via toolbox params. */ public static final String DEPTH_KEY = "depth"; /** The key used for specifying time units to be skipped over. */ public static final String SKIPPED_UNITS_KEY = "skip"; /** The default path of the relative format resource bundles. */ public static final String DEFAULT_BUNDLE_NAME = "org.apache.velocity.tools.generic.times"; // time unit message keys protected static final String MILLISECOND_KEY = "millisecond"; protected static final String SECOND_KEY = "second"; protected static final String MINUTE_KEY = "minute"; protected static final String HOUR_KEY = "hour"; protected static final String DAY_KEY = "day"; protected static final String WEEK_KEY = "week"; protected static final String MONTH_KEY = "month"; protected static final String YEAR_KEY = "year"; /** Array of all time unit message keys to their millisecond conversion factor. */ protected static final Map TIME_UNITS; static { Map units = new LinkedHashMap(8); units.put(MILLISECOND_KEY, Long.valueOf(1)); units.put(SECOND_KEY, Long.valueOf(MILLIS_PER_SECOND)); units.put(MINUTE_KEY, Long.valueOf(MILLIS_PER_MINUTE)); units.put(HOUR_KEY, Long.valueOf(MILLIS_PER_HOUR)); units.put(DAY_KEY, Long.valueOf(MILLIS_PER_DAY)); units.put(WEEK_KEY, Long.valueOf(MILLIS_PER_WEEK)); units.put(MONTH_KEY, Long.valueOf(MILLIS_PER_MONTH)); units.put(YEAR_KEY, Long.valueOf(MILLIS_PER_YEAR)); TIME_UNITS = Collections.unmodifiableMap(units); } // special message keys/prefixes/suffixes protected static final String CURRENT_PREFIX = "current."; protected static final String AFTER_KEY = "after"; protected static final String BEFORE_KEY = "before"; protected static final String EQUAL_KEY = "equal"; protected static final String ZERO_KEY = "zero"; protected static final String ABBR_SUFFIX = ".abbr"; protected static final String ONE_DAY_SUFFIX = ".day"; protected static final String PLURAL_SUFFIX = "s"; // display types protected static final int CURRENT_TYPE = 0; protected static final int RELATIVE_TYPE = 1; protected static final int DIFF_TYPE = 2; private String bundleName = DEFAULT_BUNDLE_NAME; private ResourceBundle defaultBundle; private Map timeUnits = TIME_UNITS; private int depth = 1; /** * Calls the superclass implementation, then looks for a bundle name * and any time units to be skipped. */ protected void configure(ValueParser values) { // do DateTool config super.configure(values); // look for an alternate bundle String bundle = values.getString(BUNDLE_NAME_KEY); if (bundle != null) { this.bundleName = bundle; } this.depth = values.getInt(DEPTH_KEY, 1); // look for time units to be ignored String[] skip = values.getStrings(SKIPPED_UNITS_KEY); if (skip != null) { timeUnits = new LinkedHashMap(TIME_UNITS); for (int i=0; i < skip.length; i++) { timeUnits.remove(skip[i]); } } } /** * Retrieves the specified text resource. */ protected String getText(String key, Locale locale) { Locale defaultLocale = getLocale(); ResourceBundle bundle = null; // if there is no locale or the specified locale equals the tool's default if (locale == null || locale.equals(defaultLocale)) { if (defaultBundle == null) { // load the bundle for the default locale try { // and cache it defaultBundle = ResourceBundle.getBundle(this.bundleName, defaultLocale); } catch (MissingResourceException e) {} } // use the default locale's bundle bundle = defaultBundle; } else { // load the bundle for the specified locale try { bundle = ResourceBundle.getBundle(this.bundleName, locale); } catch (MissingResourceException e) {} } // if we found a bundle... if (bundle != null) { try { // try to return the specified key return bundle.getString(key); } catch (MissingResourceException e) {} } // otherwise, return the key as an error return "???" + key + "???"; } // ------------------------- static millisecond conversions ---------------- /** * Returns the number of whole Years in the specified number of milliseconds. */ public static long toYears(long ms) { return ms / MILLIS_PER_YEAR; } /** * Returns the number of whole Months in the specified number of milliseconds. */ public static long toMonths(long ms) { return ms / MILLIS_PER_MONTH; } /** * Returns the number of whole Weeks in the specified number of milliseconds. */ public static long toWeeks(long ms) { return ms / MILLIS_PER_WEEK; } /** * Returns the number of whole Days in the specified number of milliseconds. */ public static long toDays(long ms) { return ms / MILLIS_PER_DAY; } /** * Returns the number of whole Hours in the specified number of milliseconds. */ public static long toHours(long ms) { return ms / MILLIS_PER_HOUR; } /** * Returns the number of whole Minutes in the specified number of milliseconds. */ public static long toMinutes(long ms) { return ms / MILLIS_PER_MINUTE; } /** * Returns the number of whole Seconds in the specified number of milliseconds. */ public static long toSeconds(long ms) { return ms / MILLIS_PER_SECOND; } // ------------------------- date comparison --------------------------- /** * Returns a {@link Comparison} between the result of * {@link #getCalendar()} and the specified date. The default * rendering of that Comparison will be the largest unit difference * between the dates followed by a description of their relative position. * * @param then The date in question */ public Comparison whenIs(Object then) { return compare(getCalendar(), then, CURRENT_TYPE); } /** * Returns a {@link Comparison} between the second specified date * and the first specified date. The default * rendering of that Comparison will be the largest unit difference * between the dates followed by a description of their relative position. * * @param now The date to use as representative of "now" * @param then The date in question */ public Comparison whenIs(Object now, Object then) { return compare(now, then, RELATIVE_TYPE); } /** * Returns a {@link Comparison} between the result of * the second specified date and the first specified date. The default * rendering of that Comparison will be the largest unit difference * between the dates. * * @param now The date to use as representative of "now" * @param then The secondary date */ public Comparison difference(Object now, Object then) { return compare(now, then, DIFF_TYPE); } protected Comparison compare(Object now, Object then, int type) { Calendar calThen = toCalendar(then); Calendar calNow = toCalendar(now); if (calThen == null || calNow == null) { return null; } long ms = calThen.getTimeInMillis() - calNow.getTimeInMillis(); return new Comparison(ms, type, this.depth, false, null); } /** * @param ms The time in milliseconds * @param type Whether the time should be represented as relative to "now", * relative to some other time, or as a mere difference. * @param depth The maximum number of units deep to show * @param abbr Whether the units should be abbreviated or not * @param loc The locale to be used when looking up resources */ protected String toString(long ms, int type, int depth, boolean abbr, Locale loc) { // first check if there is a difference if (ms == 0) { String sameKey = (abbr) ? ABBR_SUFFIX : ""; if (type == CURRENT_TYPE) { sameKey = CURRENT_PREFIX + EQUAL_KEY + sameKey; } else if (type == RELATIVE_TYPE) { sameKey = EQUAL_KEY + sameKey; } else { sameKey = ZERO_KEY + sameKey; } return getText(sameKey, loc); } boolean isBefore = false; if (ms < 0) { isBefore = true; // convert() only works with positive values ms *= -1; } // get the base value String friendly = toString(ms, depth, abbr, loc); // if we only want the difference... if (type == DIFF_TYPE) { // add the sign (if negative) if (isBefore) { friendly = "-" + friendly; } // then return without direction suffix return friendly; } // otherwise, get the appropriate direction key String directionKey = (isBefore) ? BEFORE_KEY : AFTER_KEY; if (type == CURRENT_TYPE) { directionKey = CURRENT_PREFIX + directionKey; if (friendly != null && friendly.startsWith("1")) { // check for the corner case of "1 day ago" or "1 day away" // and convert those to "yesterday" or "tomorrow" String dayKey = (abbr) ? DAY_KEY + ABBR_SUFFIX : DAY_KEY; if (friendly.equals("1 " + getText(dayKey, loc))) { // add .day directionKey += ONE_DAY_SUFFIX; // and return only the value of this key // (which means we throw away the friendly value // and don't bother abbreviating things) return getText(directionKey, loc); } } } // in the default bundle, this doesn't change anything. // but in may in user-provided bundles if (abbr) { directionKey += ABBR_SUFFIX; } // then combine them return friendly + " " + getText(directionKey, loc); } /** * Converts the specified positive duration of milliseconds into larger * units up to the specified number of positive units, beginning with the * largest positive unit. e.g. * toString(181453, 3, false, null) will return * "3 minutes 1 second 453 milliseconds", * toString(181453, 2, false, null) will return * "3 minutes 1 second", and * toString(180000, 2, true, null) will return * "3 min". */ protected String toString(long diff, int maxUnitDepth, boolean abbreviate, Locale locale) { // these cases should be handled elsewhere if (diff <= 0) { return null; } // can't go any deeper than we have units if (maxUnitDepth > timeUnits.size()) { maxUnitDepth = timeUnits.size(); } long value = 0; long remainder = 0; // determine the largest unit and calculate the value and remainder Iterator i = timeUnits.keySet().iterator(); String unitKey = (String)i.next(); Long unit = (Long)timeUnits.get(unitKey); while (i.hasNext()) { // get the next unit String nextUnitKey = (String)i.next(); Long nextUnit = (Long)timeUnits.get(nextUnitKey); // e.g. if diff < if (diff < nextUnit.longValue()) { // then we're working with value = diff / unit.longValue(); remainder = diff - (value * unit.longValue()); break; } // shift to the next unit unitKey = nextUnitKey; unit = nextUnit; } // if it was years, then we haven't done the math yet if (unitKey.equals(YEAR_KEY)) { value = diff / unit.longValue(); remainder = diff - (value * unit.longValue()); } // select proper pluralization if (value != 1) { unitKey += PLURAL_SUFFIX; } if (abbreviate) { unitKey += ABBR_SUFFIX; } // combine the value and the unit String output = value + " " + getText(unitKey, locale); // recurse over the remainder if it exists and more units are allowed if (maxUnitDepth > 1 && remainder > 0) { output += " " + toString(remainder, maxUnitDepth - 1, abbreviate, locale); } return output; } public class Comparison { private final long milliseconds; private final int type; private final int maxUnitDepth; private final boolean abbreviate; private final Locale locale; public Comparison(long ms, int type, int depth, boolean abbr, Locale loc) { this.milliseconds = ms; this.type = type; this.maxUnitDepth = depth; this.abbreviate = abbr; this.locale = loc; } /** * Sets whether or not this comparison is to be rendered in * abbreviated form or not. By default, it is not abbreviated. */ public Comparison abbr(boolean abbr) { return new Comparison(this.milliseconds, this.type, this.maxUnitDepth, abbr, this.locale); } /** * Set the maximum number of units to render for this comparison. * By default, this is set to 1 unit. */ public Comparison depth(int depth) { return new Comparison(this.milliseconds, this.type, depth, this.abbreviate, this.locale); } /** * Sets the locale used to look up the textual portions of the * rendering. This defaults to the Locale configured for this tool, * if any. If no locale was configured, this defaults to the system * default. */ public Comparison locale(Locale loc) { return new Comparison(this.milliseconds, this.type, this.maxUnitDepth, this.abbreviate, loc); } /** * Return the approximate number of years between the dates being compared. */ public long getYears() { return ComparisonDateTool.toYears(this.milliseconds); } /** * Return the approximate number of months between the dates being compared. */ public long getMonths() { return ComparisonDateTool.toMonths(this.milliseconds); } /** * Return the number of weeks between the dates being compared. */ public long getWeeks() { return ComparisonDateTool.toWeeks(this.milliseconds); } /** * Return the number of days between the dates being compared. */ public long getDays() { return ComparisonDateTool.toDays(this.milliseconds); } /** * Return the number of hours between the dates being compared. */ public long getHours() { return ComparisonDateTool.toHours(this.milliseconds); } /** * Return the number of minutes between the dates being compared. */ public long getMinutes() { return ComparisonDateTool.toMinutes(this.milliseconds); } /** * Return the number of seconds between the dates being compared. */ public long getSeconds() { return ComparisonDateTool.toSeconds(this.milliseconds); } /** * Return the number of milliseconds between the dates being compared. */ public long getMilliseconds() { return this.milliseconds; } /** * Sets the {@link #depth(int depth)} to which this comparison is rendered * to the maximum number of time units available to the tool. By default, * there are 8 units available, but the tool may be configured to "skip" * any of the standard units, thus shortening the maximum depth. */ public Comparison getFull() { return depth(ComparisonDateTool.this.timeUnits.size()); } /** * Sets this comparison to be rendered as a * {@link ComparisonDateTool#difference}. This effectively means that * the comparison will render as a period of time, without any suffix * to describe the relative position of the dates being compared (e.g. "later" * or "ago"). */ public Comparison getDifference() { return new Comparison(this.milliseconds, DIFF_TYPE, this.maxUnitDepth, this.abbreviate, this.locale); } /** * Sets this comparison to be rendered as if it where generated using * the {@link ComparisonDateTool#whenIs(Object now, Object then)} method. * This effectively means that the comparison will render with a suffix * to describe the relative position of the dates being compared (e.g. "later" * or "ago"). */ public Comparison getRelative() { return new Comparison(this.milliseconds, RELATIVE_TYPE, this.maxUnitDepth, this.abbreviate, this.locale); } /** * This is equivalent to calling {@link #abbr(boolean abbr)} with * {@code true} as the argument, thus setting this comparison to be * rendered in abbreviated form. */ public Comparison getAbbr() { return abbr(true); } /** * Renders this comparison to a String. */ public String toString() { return ComparisonDateTool.this.toString(this.milliseconds, this.type, this.maxUnitDepth, this.abbreviate, this.locale); } } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/generic/ContextTool.java100644 0 0 13370 11202122666 26510 0ustar 0 0 package org.apache.velocity.tools.generic; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.util.Arrays; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Set; import org.apache.velocity.context.AbstractContext; import org.apache.velocity.context.Context; import org.apache.velocity.tools.Scope; import org.apache.velocity.tools.ToolContext; import org.apache.velocity.tools.config.DefaultKey; import org.apache.velocity.tools.config.InvalidScope; import org.apache.velocity.tools.generic.ValueParser; /** *

      Tool for convenient access to {@link Context} data and * meta-data.

      *

       * Template example(s):
       *  #foreach( $key in $context.keys )
       *    $key = $context.get($key)
       *  #end
       *
       * Toolbox configuration:
       * <tools>
       *   <toolbox scope="request">
       *     <tool class="org.apache.velocity.tools.generic.ContextTool"/>
       *   </toolbox>
       * </tools>
       * 

      * *

      This class is only designed for use as a request-scope tool.

      * * @author Nathan Bubna * @since VelocityTools 2.0 * @version $Id: ContextTool.java 385122 2006-03-11 18:37:42Z nbubna $ */ @DefaultKey("context") @InvalidScope({Scope.APPLICATION,Scope.SESSION}) public class ContextTool extends SafeConfig { protected Context context; protected Map toolbox; /** * Initializes this instance for the current request. * Also looks for a safe-mode configuration setting. By default, * safeMode is true and thus keys with '.' in them are hidden. */ protected void configure(ValueParser parser) { this.context = (Context)parser.getValue(ToolContext.CONTEXT_KEY); } /** * Returns the context being analyzed by this tool. */ public Context getThis() { return this.context; } /** *

      Returns a read-only view of the toolbox {@link Map} * for this context.

      * @return a map of all available tools for this request * or {@code null} if such a map is not available */ public Map getToolbox() { if (this.toolbox == null && this.context instanceof ToolContext) { this.toolbox = ((ToolContext)context).getToolbox(); } return this.toolbox; } /** *

      Return a {@link Set} of the available reference keys in the current * context.

      */ public Set getKeys() { Set keys = new HashSet(); // fill the keyset in extendable method fillKeyset(keys); // if we're in safe mode, remove keys that contain '.' if (isSafeMode()) { for (Iterator i = keys.iterator(); i.hasNext(); ) { String key = String.valueOf(i.next()); if (key.indexOf('.') >= 0) { i.remove(); } } } // return the key set return keys; } /** * Actually do the work of filling in the set of keys * for {@link #getKeys} here so subclasses can add keys too. */ protected void fillKeyset(Set keys) { //NOTE: we don't need to manually add the toolbox keys here // because retrieval of those depends on the context being // a ToolContext which would already give tool keys below // recurse down the velocity context collecting keys Context velctx = this.context; while (velctx != null) { Object[] ctxKeys = velctx.getKeys(); keys.addAll(Arrays.asList(ctxKeys)); if (velctx instanceof AbstractContext) { velctx = ((AbstractContext)velctx).getChainedContext(); } else { velctx = null; } } } /** *

      Return a {@link Set} of the available values in the current * context.

      */ public Set getValues() { //TODO: this could be a lot more efficient Set keys = getKeys(); Set values = new HashSet(keys.size()); for (Iterator i = keys.iterator(); i.hasNext(); ) { String key = String.valueOf(i.next()); values.add(this.context.get(key)); } return values; } /** *

      Returns {@code true} if the context contains a value for the specified * reference name (aka context key).

      */ public boolean contains(Object refName) { return (get(refName) != null); } /** * Retrieves the value for the specified reference name (aka context key). */ public Object get(Object refName) { String key = String.valueOf(refName); if (isSafeMode() && key.indexOf('.') >= 0) { return null; } return this.context.get(key); } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/generic/ConversionTool.java100644 0 0 60263 11360645210 27214 0ustar 0 0 package org.apache.velocity.tools.generic; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.lang.reflect.Array; import java.util.Collection; import java.util.Date; import java.util.Calendar; import java.util.Iterator; import java.util.Locale; import java.util.TimeZone; import org.apache.velocity.tools.ConversionUtils; import org.apache.velocity.tools.config.DefaultKey; import org.apache.velocity.tools.config.SkipSetters; /** *

      Utility class for easy conversion of String values to richer types.

      *

       * Template example(s):
       *   $convert.toNumber('12.6')   ->  12.6
       *   $convert.toInt('12.6')      ->  12
       *   $convert.toNumbers('12.6,42')  ->  [12.6, 42]
       *
       * Toolbox configuration:
       * <tools>
       *   <toolbox scope="application">
       *     <tool class="org.apache.velocity.tools.generic.ConversionTool"
       *              dateFormat="yyyy-MM-dd"/>
       *   </toolbox>
       * </tools>
       * 

      * *

      This comes in very handy when parsing anything.

      * * @author Nathan Bubna * @version $Revision: 932578 $ $Date: 2007-02-26 11:24:39 -0800 (Mon, 26 Feb 2007) $ * @since VelocityTools 2.0 */ @DefaultKey("convert") @SkipSetters public class ConversionTool extends LocaleConfig { public static final String STRINGS_DELIMITER_FORMAT_KEY = "stringsDelimiter"; public static final String STRINGS_TRIM_KEY = "trimStrings"; public static final String DATE_FORMAT_KEY = "dateFormat"; public static final String NUMBER_FORMAT_KEY = "numberFormat"; public static final String DEFAULT_STRINGS_DELIMITER = ","; public static final boolean DEFAULT_STRINGS_TRIM = true; public static final String DEFAULT_NUMBER_FORMAT = "default"; public static final String DEFAULT_DATE_FORMAT = "default"; private String stringsDelimiter = DEFAULT_STRINGS_DELIMITER; private boolean stringsTrim = DEFAULT_STRINGS_TRIM; private String numberFormat = DEFAULT_NUMBER_FORMAT; private String dateFormat = DEFAULT_DATE_FORMAT; /** * Does the actual configuration. This is protected, so * subclasses may share the same ValueParser and call configure * at any time, while preventing templates from doing so when * configure(Map) is locked. */ protected void configure(ValueParser values) { super.configure(values); String delimiter = values.getString(STRINGS_DELIMITER_FORMAT_KEY); if (delimiter != null) { setStringsDelimiter(delimiter); } String dateFormat = values.getString(DATE_FORMAT_KEY); if (dateFormat != null) { setDateFormat(dateFormat); } String numberFormat = values.getString(NUMBER_FORMAT_KEY); if (numberFormat != null) { setNumberFormat(numberFormat); } } /** * Sets the delimiter used for separating values in a single String value. * The default string delimiter is a comma. * * @see #parseStringList */ protected final void setStringsDelimiter(String stringsDelimiter) { this.stringsDelimiter = stringsDelimiter; } public final String getStringsDelimiter() { return this.stringsDelimiter; } /** * Sets whether strings should be trimmed when separated from * a delimited string value. * The default is true. * * @see #parseStringList */ protected final void setStringsTrim(boolean stringsTrim) { this.stringsTrim = stringsTrim; } public final boolean getStringsTrim() { return this.stringsTrim; } protected final void setNumberFormat(String format) { this.numberFormat = format; } public final String getNumberFormat() { return this.numberFormat; } protected final void setDateFormat(String format) { this.dateFormat = format; } public final String getDateFormat() { return this.dateFormat; } // ----------------- public parsing methods -------------------------- /** * Converts objects to String in a more Tools-ish way than * String.valueOf(Object), especially with nulls, Arrays and Collections. * Null returns null, Arrays and Collections return the toString(Object) * of their first value, or null if they have no values. * * @param value the object to be turned into a String * @return the string value of the object or null if the value is null * or it is an array or collection whose first value is null */ public String toString(Object value) { return ConversionUtils.toString(value); } /** * @param value the object to be converted * @return a {@link Boolean} object for the specified value or * null if the value is null or the conversion failed */ public Boolean toBoolean(Object value) { if (value instanceof Boolean) { return (Boolean)value; } String s = toString(value); return (s != null) ? parseBoolean(s) : null; } /** * @param value the object to be converted * @return a {@link Integer} for the specified value or * null if the value is null or the conversion failed */ public Integer toInteger(Object value) { if (value == null || value instanceof Integer) { return (Integer)value; } Number num = toNumber(value); return Integer.valueOf(num.intValue()); } /** * @param value the object to be converted * @return a {@link Double} for the specified value or * null if the value is null or the conversion failed */ public Double toDouble(Object value) { if (value == null || value instanceof Double) { return (Double)value; } Number num = toNumber(value); return new Double(num.doubleValue()); } /** * @param value the object to be converted * @return a {@link Number} for the specified value or * null if the value is null or the conversion failed */ public Number toNumber(Object value) { // don't do string conversion yet Number number = ConversionUtils.toNumber(value, false); if (number != null) { return number; } String s = toString(value); if (s == null || s.length() == 0) { return null; } return parseNumber(s); } /** * @param value the object to be converted * @return a {@link Locale} for the specified value or * null if the value is null or the conversion failed */ public Locale toLocale(Object value) { if (value instanceof Locale) { return (Locale)value; } String s = toString(value); if (s == null || s.length() == 0) { return null; } return parseLocale(s); } /** * Converts an object to an instance of {@link Date}, when necessary * using the configured date parsing format, the configured default * {@link Locale}, and the system's default {@link TimeZone} to parse * the string value of the specified object. * * @param value the date to convert * @return the object as a {@link Date} or null if no * conversion is possible */ public Date toDate(Object value) { Date d = ConversionUtils.toDate(value); if (d != null) { return d; } String s = toString(value); if (s == null || s.length() == 0) { return null; } return parseDate(s); } public Calendar toCalendar(Object value) { if (value == null) { return null; } if (value instanceof Calendar) { return (Calendar)value; } Date date = toDate(value); if (date == null) { return null; } //convert the date to a calendar return ConversionUtils.toCalendar(date, getLocale()); } /** * @param value the value to be converted * @return an array of String objects containing all of the values * derived from the specified array, Collection, or delimited String */ public String[] toStrings(Object value) { if (value == null) { return null; } if (value instanceof String[]) { return (String[])value; } String[] strings = null; if (value instanceof Collection) { Collection values = (Collection)value; if (!values.isEmpty()) { strings = new String[values.size()]; int index = 0; for (Iterator i = values.iterator(); i.hasNext(); ) { strings[index++] = toString(i.next()); } } } else if (value.getClass().isArray()) { strings = new String[Array.getLength(value)]; for (int i=0; i < strings.length; i++) { strings[i] = toString(Array.get(value, i)); } } else { strings = parseStringList(toString(value)); } return strings; } /** * @param value the value to be converted * @return an array of Boolean objects derived from the specified value, * or null. */ public Boolean[] toBooleans(Object value) { if (value != null && !value.getClass().isArray()) { value = toStrings(value); } if (value == null) { return null; } Boolean[] bools = new Boolean[Array.getLength(value)]; for (int i=0; i < bools.length; i++) { bools[i] = toBoolean(Array.get(value, i)); } return bools; } /** * @param values the collection of values to be converted * @return an array of Boolean objects derived from the specified values, * or null. */ public Boolean[] toBooleans(Collection values) { if (values == null || !values.isEmpty()) { return null; } Boolean[] bools = new Boolean[values.size()]; int index = 0; for (Object val : values) { bools[index++] = toBoolean(val); } return bools; } /** * @param value the value to be converted * @return an array of Number objects derived from the specified value, * or null. */ public Number[] toNumbers(Object value) { if (value != null && !value.getClass().isArray()) { value = toStrings(value); } if (value == null) { return null; } Number[] numbers = new Number[Array.getLength(value)]; for (int i=0; i < numbers.length; i++) { numbers[i] = toNumber(Array.get(value, i)); } return numbers; } /** * @param values the collection of values to be converted * @return an array of Number objects derived from the specified values, * or null. */ public Number[] toNumbers(Collection values) { if (values == null || !values.isEmpty()) { return null; } Number[] numbers = new Number[values.size()]; int index = 0; for (Object val : values) { numbers[index++] = toNumber(val); } return numbers; } /** * @param value the value to be converted * @return an array of int values derived from the specified value, * or null. */ public int[] toInts(Object value) { Number[] numbers = toNumbers(value); if (numbers == null) { return null; } int[] ints = new int[numbers.length]; for (int i=0; inull. */ public int[] toIntegers(Object value) { return toInts(value); } /** * @param value the value to be converted * @return an array of double values derived from the specified value, * or null. */ public double[] toDoubles(Object value) { Number[] numbers = toNumbers(value); if (numbers == null) { return null; } double[] doubles = new double[numbers.length]; for (int i=0; inull. */ public Locale[] toLocales(Object value) { if (value != null && !value.getClass().isArray()) { value = toStrings(value); } if (value == null) { return null; } Locale[] locales = new Locale[Array.getLength(value)]; for (int i=0; i < locales.length; i++) { locales[i] = toLocale(Array.get(value, i)); } return locales; } /** * @param values the collection of values to be converted * @return an array of Locale objects derived from the specified values, * or null. */ public Locale[] toLocales(Collection values) { if (values == null || !values.isEmpty()) { return null; } Locale[] locales = new Locale[values.size()]; int index = 0; for (Object val : values) { locales[index++] = toLocale(val); } return locales; } /** * @param value the value to be converted * @return an array of Date objects derived from the specified value, * or null. */ public Date[] toDates(Object value) { if (value != null && !value.getClass().isArray()) { value = toStrings(value); } if (value == null) { return null; } Date[] dates = new Date[Array.getLength(value)]; for (int i=0; i < dates.length; i++) { dates[i] = toDate(Array.get(value, i)); } return dates; } /** * @param values the collection of values to be converted * @return an array of Date objects derived from the specified values, * or null. */ public Date[] toDates(Collection values) { if (values == null || !values.isEmpty()) { return null; } Date[] dates = new Date[values.size()]; int index = 0; for (Object val : values) { dates[index++] = toDate(val); } return dates; } /** * @param value the value to be converted * @return an array of Calendar objects derived from the specified value, * or null. */ public Calendar[] toCalendars(Object value) { if (value != null && !value.getClass().isArray()) { value = toStrings(value); } if (value == null) { return null; } Calendar[] calendars = new Calendar[Array.getLength(value)]; for (int i=0; i < calendars.length; i++) { calendars[i] = toCalendar(Array.get(value, i)); } return calendars; } /** * @param values the collection of values to be converted * @return an array of Calendar objects derived from the specified values, * or null. */ public Calendar[] toCalendars(Collection values) { if (values == null || !values.isEmpty()) { return null; } Calendar[] calendars = new Calendar[values.size()]; int index = 0; for (Object val : values) { calendars[index++] = toCalendar(val); } return calendars; } // --------------------- basic string parsing methods -------------- /** * Converts a parameter value into a {@link Boolean} * Sub-classes can override to allow for customized boolean parsing. * (e.g. to handle "Yes/No" or "T/F") * * @param value the string to be parsed * @return the value as a {@link Boolean} */ protected Boolean parseBoolean(String value) { return Boolean.valueOf(value); } /** * Converts a single String value into an array of Strings by splitting * it on the tool's set stringsDelimiter. The default stringsDelimiter is a comma, * and by default, all strings parsed out are trimmed before returning. */ protected String[] parseStringList(String value) { String[] values; if (value.indexOf(this.stringsDelimiter) < 0) { values = new String[] { value }; } else { values = value.split(this.stringsDelimiter); } if (this.stringsTrim) { for (int i=0,l=values.length; i < l; i++) { values[i] = values[i].trim(); } } return values; } /** * Converts a String value into a Locale. * */ protected Locale parseLocale(String value) { return ConversionUtils.toLocale(value); } // ------------------------- number parsing methods --------------- /** * Converts an object to an instance of {@link Number} using the * format returned by {@link #getNumberFormat()} and the default {@link Locale} * if the object is not already an instance of Number. * * @param value the string to parse * @return the string as a {@link Number} or null if no * conversion is possible */ public Number parseNumber(String value) { return parseNumber(value, this.numberFormat); } /** * Converts an object to an instance of {@link Number} using the * specified format and the {@link Locale} returned by * {@link #getLocale()}. * * @param value - the string to parse * @param format - the format the number is in * @return the string as a {@link Number} or null if no * conversion is possible * @see #parseNumber(String value, String format, Object locale) */ public Number parseNumber(String value, String format) { return parseNumber(value, format, getLocale()); } /** * Converts an object to an instance of {@link Number} using the * configured number format and the specified {@link Locale}. * * @param value - the string to parse * @param locale - the Locale to use * @return the string as a {@link Number} or null if no * conversion is possible * @see java.text.NumberFormat#parse */ public Number parseNumber(String value, Object locale) { return parseNumber(value, this.numberFormat, locale); } /** * Converts an object to an instance of {@link Number} using the * specified format and {@link Locale}. * * @param value - the string to parse * @param format - the format the number is in * @param locale - the Locale to use * @return the string as a {@link Number} or null if no * conversion is possible * @see java.text.NumberFormat#parse */ public Number parseNumber(String value, String format, Object locale) { Locale lcl = toLocale(locale); if (lcl == null && locale != null) { // then they gave a broken locale value; fail, to inform them return null; } return ConversionUtils.toNumber(value, format, lcl); } // ----------------- date parsing methods --------------- /** * Converts a string to an instance of {@link Date}, * using the configured date parsing format, the configured default * {@link Locale}, and the system's default {@link TimeZone} to parse it. * * @param value the date to convert * @return the object as a {@link Date} or null if no * conversion is possible */ public Date parseDate(String value) { return parseDate(value, this.dateFormat); } /** * Converts a string to an instance of {@link Date} using the * specified format,the configured default {@link Locale}, * and the system's default {@link TimeZone} to parse it. * * @param value - the date to convert * @param format - the format the date is in * @return the string as a {@link Date} or null if no * conversion is possible * @see ConversionUtils#toDate(String str, String format, Locale locale, TimeZone timezone) */ public Date parseDate(String value, String format) { return parseDate(value, format, getLocale()); } /** * Converts a string to an instance of {@link Date} using the * configured date format and specified {@link Locale} to parse it. * * @param value - the date to convert * @param locale - the Locale to use * @return the string as a {@link Date} or null if no * conversion is possible * @see java.text.SimpleDateFormat#parse */ public Date parseDate(String value, Object locale) { return parseDate(value, this.dateFormat, locale); } /** * Converts a string to an instance of {@link Date} using the * specified format and {@link Locale} to parse it. * * @param value - the date to convert * @param format - the format the date is in * @param locale - the Locale to use * @return the string as a {@link Date} or null if no * conversion is possible * @see java.text.SimpleDateFormat#parse */ public Date parseDate(String value, String format, Object locale) { return parseDate(value, format, locale, TimeZone.getDefault()); } /** * Converts a string to an instance of {@link Date} using the * specified format, {@link Locale}, and {@link TimeZone}. * * @param value - the date to convert * @param format - the format the date is in * @param locale - the Locale to use * @param timezone - the {@link TimeZone} * @return the string as a {@link Date} or null if no * conversion is possible * @see #getDateFormat * @see java.text.SimpleDateFormat#parse */ public Date parseDate(String value, String format, Object locale, TimeZone timezone) { Locale lcl = toLocale(locale); if (lcl == null && locale != null) { // the 'locale' passed in was broken, so don't pretend it worked return null; } return ConversionUtils.toDate(value, format, lcl, timezone); } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/generic/DateTool.java100644 0 0 64257 11111607666 25762 0ustar 0 0 package org.apache.velocity.tools.generic; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.lang.reflect.Field; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Calendar; import java.util.Locale; import java.util.TimeZone; import org.apache.velocity.tools.ConversionUtils; import org.apache.velocity.tools.ToolContext; import org.apache.velocity.tools.config.DefaultKey; /** * Tool for working with {@link Date} and {@link Calendar} * in Velocity templates. It is useful for accessing and * formatting the "current" date as well as for formatting * arbitrary {@link Date} and {@link Calendar} objects. Also * the tool can be used to retrieve {@link DateFormat} instances * or make conversions to and from various date types. *

       * Example of formatting the "current" date:
       *  $date                         -> Oct 19, 2003 9:54:50 PM
       *  $date.long                    -> October 19, 2003 9:54:50 PM PDT
       *  $date.medium_time             -> 9:54:50 PM
       *  $date.full_date               -> Sunday, October 19, 2003
       *  $date.get('default','short')  -> Oct 19, 2003 9:54 PM
       *  $date.get('yyyy-M-d H:m:s')   -> 2003-10-19 21:54:50
       *
       * Example of formatting an arbitrary date:
       *  $myDate                        -> Tue Oct 07 03:14:50 PDT 2003
       *  $date.format('medium',$myDate) -> Oct 7, 2003 3:14:50 AM
       *
       * Example tools.xml config (if you want to use this with VelocityView):
       * <tools>
       *   <toolbox scope="application">
       *     <tool class="org.apache.velocity.tools.generic.DateTool"
       *              format="yyyy-MM-dd"/>
       *   </toolbox>
       * </tools>
       * 

      * *

      The methods of this tool are highly interconnected, and overriding * key methods provides an easy way to create subclasses that use * a non-default format, calendar, locale, or timezone.

      * * @author Nathan Bubna * @since VelocityTools 1.0 * @version $Revision: 719489 $ $Date: 2008-11-20 22:05:11 -0800 (Thu, 20 Nov 2008) $ */ @DefaultKey("date") public class DateTool extends FormatConfig { @Deprecated public static final String DEFAULT_FORMAT_KEY = FORMAT_KEY; @Deprecated public static final String DEFAULT_LOCALE_KEY = ToolContext.LOCALE_KEY; /** * The key used for specifying a default timezone via tool configuration. */ public static final String TIMEZONE_KEY = "timezone"; private TimeZone timezone = TimeZone.getDefault(); /** * Does the actual configuration. This is protected, so * subclasses may share the same ValueParser and call configure * at any time, while preventing templates from doing so when * configure(Map) is locked. */ protected void configure(ValueParser values) { super.configure(values); String tzId = values.getString(TIMEZONE_KEY); if (tzId != null) { setTimeZone(TimeZone.getTimeZone(tzId)); } } protected void setTimeZone(TimeZone timezone) { if (timezone == null) { throw new NullPointerException("timezone may not be null"); } this.timezone = timezone; } // ------------------------- system date access ------------------ /** * @return the system's current time as the number of milliseconds * elapsed since January 1, 1970, 00:00:00 GMT. */ public static final long getSystemTime() { return getSystemCalendar().getTime().getTime(); } /** * @return the system's current time as a {@link Date} */ public static final Date getSystemDate() { return getSystemCalendar().getTime(); } /** * @return the system's current time as a {@link Calendar} */ public static final Calendar getSystemCalendar() { return Calendar.getInstance(); } // ------------------------- default parameter access ---------------- /** * Returns the configured {@link TimeZone}. Default value is * from {@link TimeZone#getDefault()}. * * @return the configured {@link TimeZone} */ public TimeZone getTimeZone() { return timezone; } /** * Returns a {@link Date} derived from the result of {@link #getCalendar} * * @return a {@link Date} derived from the result of {@link #getCalendar} */ public Date getDate() { return getCalendar().getTime(); } /** * Returns a {@link Calendar} instance created using the timezone and * locale returned by getTimeZone() and getLocale(). This allows subclasses * to easily override the default locale and timezone used by this tool. * *

      Sub-classes may override this method to return a Calendar instance * not based on the system date. * Doing so will also cause the getDate(), get(String), get(String,String), * and toString() methods to return dates equivalent to the Calendar * returned by this method, because those methods return values derived * from the result of this method.

      * * @return a {@link Calendar} instance created using the results of * {@link #getTimeZone()} and {@link #getLocale()}. * @see Calendar#getInstance(TimeZone zone, Locale aLocale) */ public Calendar getCalendar() { return Calendar.getInstance(getTimeZone(), getLocale()); } // ------------------------- date value access --------------------------- /** * Returns the year value of the date returned by {@link #getCalendar()}. * * @since VelocityTools 1.2 */ public Integer getYear() { return getYear(getCalendar()); } /** * Returns the year value of the specified date. * * @since VelocityTools 1.2 */ public Integer getYear(Object date) { return getValue(Calendar.YEAR, date); } /** * Returns the month value of the date returned by {@link #getCalendar()}. * * @since VelocityTools 1.2 */ public Integer getMonth() { return getMonth(getCalendar()); } /** * Returns the month value of the specified date. * * @since VelocityTools 1.2 */ public Integer getMonth(Object date) { return getValue(Calendar.MONTH, date); } /** * Returns the day (of the month) value of the date * returned by {@link #getCalendar()}. *

      * NOTE: Unlike java.util.Date, this returns the day of the month. * It is equivalent to Date.getDate() and * Calendar.get(Calendar.DAY_OF_MONTH). We could not call this method * getDate() because that already exists in this class with a different * function. * * @since VelocityTools 1.2 */ public Integer getDay() { return getDay(getCalendar()); } /** * Returns the day (of the month) value for the specified date. *

      * NOTE: Unlike java.util.Date, this returns the day of the month. * It is equivalent to Date.getDate() and * Calendar.get(Calendar.DAY_OF_MONTH). We could not call this method * getDate() because that already exists in this class with a different * function. * * @since VelocityTools 1.2 */ public Integer getDay(Object date) { return getValue(Calendar.DAY_OF_MONTH, date); } /** * Return the specified value of the date returned by * {@link #getCalendar()} or null if the field is invalid. * * @since VelocityTools 1.2 */ public Integer getValue(Object field) { return getValue(field, getCalendar()); } /** * Returns the specified value of the specified date, * or null if the field or date is invalid. The field may be * an Integer or it may be the name of the field as a String. * * @param field the corresponding Integer value or String name of the desired value * @param date the date/calendar from which the field value will be taken * @since VelocityTools 1.2 */ public Integer getValue(Object field, Object date) { if (field == null) { return null; } int fieldValue; if (field instanceof Integer) { fieldValue = ((Integer)field).intValue(); } // all the public static field names are upper case String fstr = field.toString().toUpperCase(); try { Field clsf = Calendar.class.getField(fstr); fieldValue = clsf.getInt(Calendar.getInstance()); } catch (Exception e) { return null; } return getValue(fieldValue, date); } /** * Returns the specified value of the specified date, * or null if the field or date is invalid. * * @param field the int for the desired field (e.g. Calendar.MONTH) * @param date the date/calendar from which the field value will be taken * @since VelocityTools 1.2 */ public Integer getValue(int field, Object date) { Calendar cal = toCalendar(date); if (cal == null) { return null; } return Integer.valueOf(cal.get(field)); } // ------------------------- formatting methods --------------------------- /** * Returns a formatted string representing the date returned by * {@link #getDate()}. In its default implementation, this method * allows you to retrieve the current date in standard formats by * simply doing things like $date.medium or * $date.full. If you want only the date or time portion * you can specify that along with the standard formats. (e.g. * $date.medium_date or $date.short_time) * More complex or custom formats can be retrieved * by using the full method syntax. (e.g. $date.get('E, MMMM d')) * * @param format the formatting instructions * @return a formatted representation of the date returned by * {@link #getDate()} * @see #format(String format, Object obj, Locale locale, TimeZone timezone) * @since VelocityTools 1.1 */ public String get(String format) { return format(format, getDate()); } /** * Returns a formatted string representing the date and/or time given by * {@link #getDate()} in standard, localized patterns. * * @param dateStyle the style pattern for the date * @param timeStyle the style pattern for the time * @return a formatted representation of the date returned by * {@link #getDate()} * @see DateFormat * @see #format(String dateStyle, String timeStyle, Object obj, Locale locale, TimeZone timezone) * @since VelocityTools 1.1 */ public String get(String dateStyle, String timeStyle) { return format(dateStyle, timeStyle, getDate(), getLocale()); } /** * Converts the specified object to a date and formats it according to * the pattern or style returned by {@link #getFormat()}. * * @param obj the date object to be formatted * @return the specified date formatted as a string * @see #format(String format, Object obj, Locale locale, TimeZone timezone) * @since VelocityTools 1.1 */ public String format(Object obj) { return format(getFormat(), obj); } /** * Converts the specified object to a date and returns * a formatted string representing that date in the locale * returned by {@link #getLocale()}. * * @param format the formatting instructions * @param obj the date object to be formatted * @return a formatted string for this locale representing the specified * date or null if the parameters are invalid * @see #format(String format, Object obj, Locale locale, TimeZone timezone) */ public String format(String format, Object obj) { return format(format, obj, getLocale()); } /** * Converts the specified object to a date and returns * a formatted string representing that date in the specified * {@link Locale}. * * @param format the formatting instructions * @param obj the date object to be formatted * @param locale the locale to be used when formatting * @return the given date as a formatted string * @see #format(String format, Object obj, Locale locale, TimeZone timezone) */ public String format(String format, Object obj, Locale locale) { return format(format, obj, locale, getTimeZone()); } /** * Returns a formatted string representing the specified date, * {@link Locale}, and {@link TimeZone}. * *

      * The specified format may be a standard style pattern ('full', 'long', * 'medium', 'short', or 'default'). *

      *

      * You may also specify that you want only the date or time portion be * appending '_date' or '_time' respectively to the standard style pattern. * (e.g. 'full_date' or 'long_time') *

      *

      * If the format fits neither of these patterns, then the output * will be formatted according to the symbols defined by * {@link SimpleDateFormat}: *

           *   Symbol   Meaning                 Presentation        Example
           *   ------   -------                 ------------        -------
           *   G        era designator          (Text)              AD
           *   y        year                    (Number)            1996
           *   M        month in year           (Text & Number)     July & 07
           *   d        day in month            (Number)            10
           *   h        hour in am/pm (1~12)    (Number)            12
           *   H        hour in day (0~23)      (Number)            0
           *   m        minute in hour          (Number)            30
           *   s        second in minute        (Number)            55
           *   S        millisecond             (Number)            978
           *   E        day in week             (Text)              Tuesday
           *   D        day in year             (Number)            189
           *   F        day of week in month    (Number)            2 (2nd Wed in July)
           *   w        week in year            (Number)            27
           *   W        week in month           (Number)            2
           *   a        am/pm marker            (Text)              PM
           *   k        hour in day (1~24)      (Number)            24
           *   K        hour in am/pm (0~11)    (Number)            0
           *   z        time zone               (Text)              Pacific Standard Time
           *   '        escape for text         (Delimiter)
           *   ''       single quote            (Literal)           '
           *
           *   Examples: "E, MMMM d" will result in "Tue, July 24"
           *             "EEE, M-d (H:m)" will result in "Tuesday, 7-24 (14:12)"
           * 
      *

      * * @param format the custom or standard pattern to be used * @param obj the date to format * @param locale the {@link Locale} to format the date for * @param timezone the {@link TimeZone} to be used when formatting * @return a formatted string representing the specified date or * null if the parameters are invalid * @since VelocityTools 1.1 */ public String format(String format, Object obj, Locale locale, TimeZone timezone) { Date date = toDate(obj); DateFormat df = getDateFormat(format, locale, timezone); if (date == null || df == null) { return null; } return df.format(date); } /** * Returns the specified date as a string formatted according to the * specified date and/or time styles. * * @param dateStyle the style pattern for the date * @param timeStyle the style pattern for the time * @param obj the date to be formatted * @return a formatted representation of the given date * @see #format(String dateStyle, String timeStyle, Object obj, Locale locale, TimeZone timezone) * @since VelocityTools 1.1 */ public String format(String dateStyle, String timeStyle, Object obj) { return format(dateStyle, timeStyle, obj, getLocale()); } /** * Returns the specified date as a string formatted according to the * specified {@link Locale} and date and/or time styles. * * @param dateStyle the style pattern for the date * @param timeStyle the style pattern for the time * @param obj the date to be formatted * @param locale the {@link Locale} to be used for formatting the date * @return a formatted representation of the given date * @see #format(String dateStyle, String timeStyle, Object obj, Locale locale, TimeZone timezone) * @since VelocityTools 1.1 */ public String format(String dateStyle, String timeStyle, Object obj, Locale locale) { return format(dateStyle, timeStyle, obj, locale, getTimeZone()); } /** * Returns the specified date as a string formatted according to the * specified {@link Locale} and date and/or time styles. * * @param dateStyle the style pattern for the date * @param timeStyle the style pattern for the time * @param obj the date to be formatted * @param locale the {@link Locale} to be used for formatting the date * @param timezone the {@link TimeZone} the date should be formatted for * @return a formatted representation of the given date * @see java.text.DateFormat * @see #format(String dateStyle, String timeStyle, Object obj, Locale locale, TimeZone timezone) * @since VelocityTools 1.1 */ public String format(String dateStyle, String timeStyle, Object obj, Locale locale, TimeZone timezone) { Date date = toDate(obj); DateFormat df = getDateFormat(dateStyle, timeStyle, locale, timezone); if (date == null || df == null) { return null; } return df.format(date); } // -------------------------- DateFormat creation methods -------------- /** * Returns a {@link DateFormat} instance for the specified * format, {@link Locale}, and {@link TimeZone}. If the format * specified is a standard style pattern, then a date-time instance * will be returned with both the date and time styles set to the * specified style. If it is a custom format, then a customized * {@link SimpleDateFormat} will be returned. * * @param format the custom or standard formatting pattern to be used * @param locale the {@link Locale} to be used * @param timezone the {@link TimeZone} to be used * @return an instance of {@link DateFormat} * @see SimpleDateFormat * @see DateFormat * @since VelocityTools 1.1 */ public DateFormat getDateFormat(String format, Locale locale, TimeZone timezone) { return ConversionUtils.getDateFormat(format, locale, timezone); } /** * Returns a {@link DateFormat} instance for the specified * date style, time style, {@link Locale}, and {@link TimeZone}. * * @param dateStyle the date style * @param timeStyle the time style * @param locale the {@link Locale} to be used * @param timezone the {@link TimeZone} to be used * @return an instance of {@link DateFormat} * @see #getDateFormat(int timeStyle, int dateStyle, Locale locale, TimeZone timezone) * @since VelocityTools 1.1 */ public DateFormat getDateFormat(String dateStyle, String timeStyle, Locale locale, TimeZone timezone) { return ConversionUtils.getDateFormat(dateStyle, timeStyle, locale, timezone); } /** * Returns a {@link DateFormat} instance for the specified * time style, date style, {@link Locale}, and {@link TimeZone}. * * @param dateStyle the date style (date will be ignored if this is * less than zero and the date style is not) * @param timeStyle the time style (time will be ignored if this is * less than zero and the date style is not) * @param locale the {@link Locale} to be used * @param timezone the {@link TimeZone} to be used * @return an instance of {@link DateFormat} or null * if an instance cannot be constructed with the given * parameters * @since VelocityTools 1.1 */ @Deprecated protected DateFormat getDateFormat(int dateStyle, int timeStyle, Locale locale, TimeZone timezone) { return ConversionUtils.getDateFormat(dateStyle, timeStyle, locale, timezone); } /** * Checks a string to see if it matches one of the standard DateFormat * style patterns: FULL, LONG, MEDIUM, SHORT, or DEFAULT. If it does, * it will return the integer constant for that pattern. If not, it * will return -1. * * @see DateFormat * @param style the string to be checked * @return the int identifying the style pattern * @since VelocityTools 1.1 */ @Deprecated protected int getStyleAsInt(String style) { return ConversionUtils.getDateStyleAsInt(style); } // ------------------------- date conversion methods --------------- /** * Converts an object to an instance of {@link Date} using the * format returned by {@link #getFormat()},the {@link Locale} returned * by {@link #getLocale()}, and the {@link TimeZone} returned by * {@link #getTimeZone()} if the object is not already an instance * of Date, Calendar, or Long. * * @param obj the date to convert * @return the object as a {@link Date} or null if no * conversion is possible */ public Date toDate(Object obj) { return toDate(getFormat(), obj, getLocale(), getTimeZone()); } /** * Converts an object to an instance of {@link Date} using the * specified format,the {@link Locale} returned by * {@link #getLocale()}, and the {@link TimeZone} returned by * {@link #getTimeZone()} if the object is not already an instance * of Date, Calendar, or Long. * * @param format - the format the date is in * @param obj - the date to convert * @return the object as a {@link Date} or null if no * conversion is possible * @see #toDate(String format, Object obj, Locale locale) */ public Date toDate(String format, Object obj) { return toDate(format, obj, getLocale(), getTimeZone()); } /** * Converts an object to an instance of {@link Date} using the * specified format and {@link Locale} if the object is not already * an instance of Date, Calendar, or Long. * * @param format - the format the date is in * @param obj - the date to convert * @param locale - the {@link Locale} * @return the object as a {@link Date} or null if no * conversion is possible * @see SimpleDateFormat#parse */ public Date toDate(String format, Object obj, Locale locale) { return toDate(format, obj, locale, getTimeZone()); } /** * Converts an object to an instance of {@link Date} using the * specified format, {@link Locale}, and {@link TimeZone} if the * object is not already an instance of Date, Calendar, or Long. * * @param format - the format the date is in * @param obj - the date to convert * @param locale - the {@link Locale} * @param timezone - the {@link TimeZone} * @return the object as a {@link Date} or null if no * conversion is possible * @see #getDateFormat * @see SimpleDateFormat#parse */ public Date toDate(String format, Object obj, Locale locale, TimeZone timezone) { return ConversionUtils.toDate(obj, format, locale, timezone); } /** * Converts an object to an instance of {@link Calendar} using the * locale returned by {@link #getLocale()} if necessary. * * @param obj the date to convert * @return the converted date * @see #toCalendar(Object obj, Locale locale) */ public Calendar toCalendar(Object obj) { return toCalendar(obj, getLocale()); } /** * Converts an object to an instance of {@link Calendar} using the * locale returned by {@link #getLocale()} if necessary. * * @param obj the date to convert * @param locale the locale used * @return the converted date * @see #toDate(String format, Object obj, Locale locale) * @see Calendar */ public Calendar toCalendar(Object obj, Locale locale) { if (obj == null) { return null; } if (obj instanceof Calendar) { return (Calendar)obj; } //try to get a date out of it Date date = toDate(obj); if (date == null) { return null; } // if the locale is null, do as the javadoc claims if (locale == null) { locale = getLocale(); } //convert the date to a calendar return ConversionUtils.toCalendar(date, locale); } // ------------------------- default toString() implementation ------------ /** * @return the result of {@link #getDate()} formatted according to the result * of {@link #getFormat()}. * @see #format(String format, Object obj) */ public String toString() { return format(getFormat(), getDate()); } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/generic/DisplayTool.java100644 0 0 65517 11202122666 26503 0ustar 0 0 package org.apache.velocity.tools.generic; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.lang.reflect.Array; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.regex.Pattern; import org.apache.commons.beanutils.PropertyUtils; import org.apache.velocity.tools.config.DefaultKey; /** * Provides general utility methods for controlling the display of references. * Currently, this class contains methods for "pretty printing" an array or * {@link Collection}, methods for truncating the string value of a reference * at a configured or specified length, methods for displaying an alternate * value when a specified value is null, a method for generating whitespace, * a "printf" type of method for formatting messages, and * methods for forcing values into "cells" of equal size (via truncation or * padding with whitespace). * *

      Example Use: *

       * tools.xml...
       * <tools>
       *   <toolbox scope="application">
       *     <tool class="org.apache.velocity.tools.generic.DisplayTool"/>
       *   </toolbox>
       * </tools>
       *
       * template...
       *   #set( $list = [1..5] )
       *   $display.list($list)
       *   $display.truncate("This is a long string.", 10)
       *   Not Null: $display.alt("not null", "--")
       *   Null: $display.alt($null, "--")
       *
       * output...
       *   1, 2, 3, 4 and 5
       *   This is...
       *   Not Null: not null
       *   Null: --
       *   
       * 

      * * @since VelocityTools 2.0 * @author Sean Legassick * @author Daniel Rall * @author Nathan Bubna * @version $Id: DisplayTool.java 463298 2006-10-12 16:10:32Z henning $ */ @DefaultKey("display") public class DisplayTool extends LocaleConfig { public static final String LIST_DELIM_KEY = "listDelim"; public static final String LIST_FINAL_DELIM_KEY = "listFinalDelim"; public static final String TRUNCATE_LENGTH_KEY = "truncateLength"; public static final String TRUNCATE_SUFFIX_KEY = "truncateSuffix"; public static final String TRUNCATE_AT_WORD_KEY = "truncateAtWord"; public static final String CELL_LENGTH_KEY = "cellLength"; public static final String CELL_SUFFIX_KEY = "cellSuffix"; public static final String DEFAULT_ALTERNATE_KEY = "defaultAlternate"; public static final String ALLOWED_TAGS_KEY = "allowedTags"; private String defaultDelim = ", "; private String defaultFinalDelim = " and "; private int defaultTruncateLength = 30; private String defaultTruncateSuffix = "..."; private boolean defaultTruncateAtWord = false; private int defaultCellLength = 30; private String defaultCellSuffix = "..."; private String defaultAlternate = "null"; private String[] defaultAllowedTags = null; /** * Does the actual configuration. This is protected, so * subclasses may share the same ValueParser and call configure * at any time, while preventing templates from doing so when * configure(Map) is locked. */ protected void configure(ValueParser values) { String listDelim = values.getString(LIST_DELIM_KEY); if (listDelim != null) { setListDelimiter(listDelim); } String listFinalDelim = values.getString(LIST_FINAL_DELIM_KEY); if (listFinalDelim != null) { setListFinalDelimiter(listFinalDelim); } Integer truncateLength = values.getInteger(TRUNCATE_LENGTH_KEY); if (truncateLength != null) { setTruncateLength(truncateLength); } String truncateSuffix = values.getString(TRUNCATE_SUFFIX_KEY); if (truncateSuffix != null) { setTruncateSuffix(truncateSuffix); } Boolean truncateAtWord = values.getBoolean(TRUNCATE_AT_WORD_KEY); if (truncateAtWord != null) { setTruncateAtWord(truncateAtWord); } Integer cellLength = values.getInteger(CELL_LENGTH_KEY); if (cellLength != null) { setCellLength(cellLength); } String cellSuffix = values.getString(CELL_SUFFIX_KEY); if (cellSuffix != null) { setCellSuffix(cellSuffix); } String defaultAlternate = values.getString(DEFAULT_ALTERNATE_KEY); if (defaultAlternate != null) { setDefaultAlternate(defaultAlternate); } String[] allowedTags = values.getStrings(ALLOWED_TAGS_KEY); if (allowedTags != null) { setAllowedTags(allowedTags); } } public String getListDelimiter() { return this.defaultDelim; } protected void setListDelimiter(String delim) { this.defaultDelim = delim; } public String getListFinalDelimiter() { return this.defaultFinalDelim; } protected void setListFinalDelimiter(String finalDelim) { this.defaultFinalDelim = finalDelim; } public int getTruncateLength() { return this.defaultTruncateLength; } protected void setTruncateLength(int maxlen) { this.defaultTruncateLength = maxlen; } public String getTruncateSuffix() { return this.defaultTruncateSuffix; } protected void setTruncateSuffix(String suffix) { this.defaultTruncateSuffix = suffix; } public boolean getTruncateAtWord() { return this.defaultTruncateAtWord; } protected void setTruncateAtWord(boolean atWord) { this.defaultTruncateAtWord = atWord; } public String getCellSuffix() { return this.defaultCellSuffix; } protected void setCellSuffix(String suffix) { this.defaultCellSuffix = suffix; } public int getCellLength() { return this.defaultCellLength; } protected void setCellLength(int maxlen) { this.defaultCellLength = maxlen; } public String getDefaultAlternate() { return this.defaultAlternate; } protected void setDefaultAlternate(String dflt) { this.defaultAlternate = dflt; } public String[] getAllowedTags() { return this.defaultAllowedTags; } protected void setAllowedTags(String[] tags) { this.defaultAllowedTags = tags; } /** * Formats a collection or array into the form "A, B and C". * * @param list A collection or array. * @return A String. */ public String list(Object list) { return list(list, this.defaultDelim, this.defaultFinalDelim); } /** * Formats a collection or array into the form * "A<delim>B<delim>C". * * @param list A collection or array. * @param delim A String. * @return A String. */ public String list(Object list, String delim) { return list(list, delim, delim); } /** * Formats a collection or array into the form * "A<delim>B<finaldelim>C". * * @param list A collection or array. * @param delim A String. * @param finaldelim A String. * @return A String. */ public String list(Object list, String delim, String finaldelim) { return list(list, delim, finaldelim, null); } /** * Formats a specified property of collection or array of objects into the * form "A<delim>B<finaldelim>C". * * @param list A collection or array. * @param delim A String. * @param finaldelim A String. * @param property An object property to format. * @return A String. */ public String list(Object list, String delim, String finaldelim, String property) { if (list == null) { return null; } if (list instanceof Collection) { return format((Collection) list, delim, finaldelim, property); } Collection items; if (list.getClass().isArray()) { int size = Array.getLength(list); items = new ArrayList(size); for (int i = 0; i < size; i++) { items.add(Array.get(list, i)); } } else { items = Collections.singletonList(list); } return format(items, delim, finaldelim, property); } /** * Does the actual formatting of the collection. */ protected String format(Collection list, String delim, String finaldelim, String property) { StringBuilder sb = new StringBuilder(); int size = list.size(); Iterator iterator = list.iterator(); for (int i = 0; i < size; i++) { if (property != null && property.length() > 0) { sb.append(getProperty(iterator.next(), property)); } else { sb.append(iterator.next()); } if (i < size - 2) { sb.append(delim); } else if (i < size - 1) { sb.append(finaldelim); } } return sb.toString(); } /** * @deprecated Will be unnecessary with Velocity 1.6 */ @Deprecated public String message(String format, Collection args) { return message(format, new Object[] { args }); } /** * @deprecated Will be unnecessary with Velocity 1.6 */ @Deprecated public String message(String format, Object arg) { return message(format, new Object[] { arg }); } /** * @deprecated Will be unnecessary with Velocity 1.6 */ @Deprecated public String message(String format, Object arg1, Object arg2) { return message(format, new Object[] { arg1, arg2 }); } /** * Uses {@link MessageFormat} to format the specified String with * the specified arguments. If there are no arguments, then the String * is returned directly. Please note that the format * required here is quite different from that of * {@link #printf(String,Object...)}. * * @since VelocityTools 2.0 */ public String message(String format, Object... args) { if (format == null) { return null; } if (args == null || args.length == 0) { return format; } else if (args.length == 1 && args[0] instanceof Collection) { Collection list = (Collection)args[0]; if (list.isEmpty()) { return format; } else { args = list.toArray(); } } return MessageFormat.format(format, args); } /** * Uses {@link String#format(Locale,String,Object...} to format the specified String * with the specified arguments. Please note that the format * required here is quite different from that of * {@link #message(String,Object...)}. * * @see java.util.Formatter * @since VelocityTools 2.0 */ public String printf(String format, Object... args) { if (format == null) { return null; } if (args == null || args.length == 0) { return format; } if (args.length == 1 && args[0] instanceof Collection) { Collection list = (Collection)args[0]; if (list.isEmpty()) { return format; } else { args = list.toArray(); } } return String.format(getLocale(), format, args); } /** * Limits the string value of 'truncateMe' to the configured max length * in characters (default is 30 characters). * If the string gets curtailed, the configured suffix * (default is "...") is used as the ending of the truncated string. * * @param truncateMe The value to be truncated. * @return A String. */ public String truncate(Object truncateMe) { return truncate(truncateMe, this.defaultTruncateLength); } /** * Limits the string value of 'truncateMe' to 'maxLength' characters. * If the string gets curtailed, the configured suffix * (default is "...") is used as the ending of the truncated string. * * @param maxLength An int with the maximum length. * @param truncateMe The value to be truncated. * @return A String. */ public String truncate(Object truncateMe, int maxLength) { return truncate(truncateMe, maxLength, this.defaultTruncateSuffix); } /** * Limits the string value of 'truncateMe' to the configured max length * in characters (default is 30 characters). * If the string gets curtailed, the specified suffix * is used as the ending of the truncated string. * * @param truncateMe The value to be truncated. * @param suffix A String. * @return A String. */ public String truncate(Object truncateMe, String suffix) { return truncate(truncateMe, this.defaultTruncateLength, suffix); } /** * Limits the string value of 'truncateMe' to the specified max length in * characters. If the string gets curtailed, the specified suffix is used as * the ending of the truncated string. * * @param truncateMe The value to be truncated. * @param maxLength An int with the maximum length. * @param suffix A String. * @return A String. */ public String truncate(Object truncateMe, int maxLength, String suffix) { return truncate(truncateMe, maxLength, suffix, defaultTruncateAtWord); } /** * Limits the string value of 'truncateMe' to the latest complete word * within the specified maxLength. If the string gets curtailed, the * specified suffix is used as the ending of the truncated string. * * @param truncateMe The value to be truncated. * @param maxLength An int with the maximum length. * @param suffix A String. * @param defaultTruncateAtWord Truncate at a word boundary if true. * @return A String. */ public String truncate(Object truncateMe, int maxLength, String suffix, boolean defaultTruncateAtWord) { if (truncateMe == null || maxLength <= 0) { return null; } String string = String.valueOf(truncateMe); if (string.length() <= maxLength) { return string; } if (suffix == null || maxLength - suffix.length() <= 0) { // either no need or no room for suffix return string.substring(0, maxLength); } if (defaultTruncateAtWord) { // find the latest space within maxLength int lastSpace = string.substring(0, maxLength - suffix.length() + 1) .lastIndexOf(" "); if (lastSpace > suffix.length()) { return string.substring(0, lastSpace) + suffix; } } // truncate to exact character and append suffix return string.substring(0, maxLength - suffix.length()) + suffix; } /** * Returns a string of spaces of the specified length. * @param length the number of spaces to return */ public String space(int length) { if (length < 0) { return null; } StringBuilder space = new StringBuilder(); for (int i=0; i < length; i++) { space.append(' '); } return space.toString(); } /** * Truncates or pads the string value of the specified object as necessary * to ensure that the returned string's length equals the default cell size. * @param obj the value to be put in the 'cell' */ public String cell(Object obj) { return cell(obj, this.defaultCellLength); } /** * Truncates or pads the string value of the specified object as necessary * to ensure that the returned string's length equals the specified cell size. * @param obj the value to be put in the 'cell' * @param cellsize the size of the cell into which the object must be placed */ public String cell(Object obj, int cellsize) { return cell(obj, cellsize, this.defaultCellSuffix); } /** * Truncates or pads the string value of the specified object as necessary * to ensure that the returned string's length equals the default cell size. * If truncation is necessary, the specified suffix will replace the end of * the string value to indicate that. * @param obj the value to be put in the 'cell' * @param suffix the suffix to put at the end of any values that need truncating * to indicate that they've been truncated */ public String cell(Object obj, String suffix) { return cell(obj, this.defaultCellLength, suffix); } /** * Truncates or pads the string value of the specified object as necessary * to ensure that the returned string's length equals the specified cell size. * @param obj the value to be put in the 'cell' * @param cellsize the size of the cell into which the object must be placed * @param suffix the suffix to put at the end of any values that need truncating * to indicate that they've been truncated */ public String cell(Object obj, int cellsize, String suffix) { if (obj == null || cellsize <= 0) { return null; } String value = String.valueOf(obj); if (value.length() == cellsize) { return value; } else if (value.length() > cellsize) { return truncate(value, cellsize, suffix); } else { return value + space(cellsize - value.length()); } } /** * Changes the first character of the string value of the specified object * to upper case and returns the resulting string. * * @param capitalizeMe The value to be capitalized. */ public String capitalize(Object capitalizeMe) { if (capitalizeMe == null) { return null; } String string = String.valueOf(capitalizeMe); switch (string.length()) { case 0: return string; case 1: return string.toUpperCase(); default: StringBuilder out = new StringBuilder(string.length()); out.append(string.substring(0,1).toUpperCase()); out.append(string.substring(1, string.length())); return out.toString(); } } /** * Changes the first character of the string value of the specified object * to lower case and returns the resulting string. * * @param uncapitalizeMe The value to be uncapitalized. */ public String uncapitalize(Object uncapitalizeMe) { if (uncapitalizeMe == null) { return null; } String string = String.valueOf(uncapitalizeMe); switch (string.length()) { case 0: return string; case 1: return string.toLowerCase(); default: StringBuilder out = new StringBuilder(string.length()); out.append(string.substring(0,1).toLowerCase()); out.append(string.substring(1, string.length())); return out.toString(); } } /** * Returns a configured default value if specified value is null. * @param checkMe * @return a configured default value if the specified value is null. */ public Object alt(Object checkMe) { return alt(checkMe, this.defaultAlternate); } /** * Returns the second argument if first argument specified is null. * @param checkMe * @param alternate * @return the second argument if the first is null. */ public Object alt(Object checkMe, Object alternate) { if (checkMe == null) { return alternate; } return checkMe; } /** * Inserts HTML line break tag (<br />) in front of all newline * characters of the string value of the specified object and returns the * resulting string. * @param obj */ public String br(Object obj) { if (obj == null) { return null; } else { return String.valueOf(obj).replaceAll("\n", "
      \n"); } } /** * Removes HTML tags from the string value of the specified object and * returns the resulting string. * @param obj */ public String stripTags(Object obj) { return stripTags(obj, defaultAllowedTags); } /** * Removes all not allowed HTML tags from the string value of the specified * object and returns the resulting string. * @param obj * @param allowedTags An array of allowed tag names (i.e. "h1","br","img") */ public String stripTags(Object obj, String... allowedTags) { if (obj == null) { return null; } //build list of tags to be used in regex pattern StringBuilder allowedTagList = new StringBuilder(); if (allowedTags != null) { for (String tag : allowedTags) { if (tag !=null && tag.matches("[a-zA-Z0-9]+")) { if (allowedTagList.length() > 0) { allowedTagList.append("|"); } allowedTagList.append(tag); } } } String tagRule = "<[^>]*?>"; if (allowedTagList.length() > 0) { tagRule = "<(?!/?(" + allowedTagList.toString() + ")[\\s>/])[^>]*?>"; } return Pattern.compile(tagRule, Pattern.CASE_INSENSITIVE) .matcher(String.valueOf(obj)).replaceAll(""); } /** * Builds plural form of a passed word if 'value' is plural, otherwise * returns 'singular'. Plural form is built using some basic English * language rules for nouns which does not guarantee correct syntax of a * result in all cases. * @param value * @param singular Singular form of a word. */ public String plural(int value, String singular) { return plural(value, singular, null); } /** * Returns 'plural' parameter if passed 'value' is plural, otherwise * 'singular' is returned. * @param value * @param singular Singular form of a word. * @param plural Plural form of a word. */ public String plural(int value, String singular, String plural) { if (value == 1 || value == -1) { return singular; } else if (plural != null) { return plural; } else if (singular == null || singular.length() == 0) { return singular; } else { //if the last letter is capital then we will append capital letters boolean isCapital = !singular.substring(singular.length() - 1) .toLowerCase().equals(singular .substring(singular.length() - 1)); String word = singular.toLowerCase(); if (word.endsWith("x") || word.endsWith("sh") || word.endsWith("ch") || word.endsWith("s")) { return singular.concat(isCapital ? "ES" : "es"); } else if (word.length() > 1 && word.endsWith("y") && !word.substring(word.length() - 2, word.length() - 1) .matches("[aeiou]")) { return singular.substring(0, singular.length() - 1) .concat(isCapital ? "IES" : "ies"); } else { return singular.concat(isCapital ? "S" : "s"); } } } /** * Safely retrieves the specified property from the specified object. * Subclasses that wish to perform more advanced, efficient, or just * different property retrieval methods should override this method to do * so. */ protected Object getProperty(Object object, String property) { try { return PropertyUtils.getProperty(object, property); } catch (Exception e) { throw new IllegalArgumentException("Could not retrieve '" + property + "' from " + object + ": " + e); } } /** * Returns the {@link Measurements} of the string value of the specified object. */ public Measurements measure(Object measureMe) { if (measureMe == null) { return null; } return new Measurements(String.valueOf(measureMe)); } /** * Measures the dimensions of the string given to its constructor. * Height is the number of lines in the string. * Width is the number of characters in the longest line. */ public static class Measurements { private int height; private int width; public Measurements(String s) { String[] lines = s.split("\n"); height = lines.length; for (String line : lines) { if (line.length() > width) { width = line.length(); } } } public int getHeight() { return height; } public int getWidth() { return width; } public String toString() { StringBuilder out = new StringBuilder(28); out.append("{ height: "); out.append(height); out.append(", width: "); out.append(width); out.append(" }"); return out.toString(); } } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/generic/EscapeTool.java100644 0 0 37357 11030275254 26300 0ustar 0 0 package org.apache.velocity.tools.generic; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.net.URLEncoder; import java.io.UnsupportedEncodingException; import org.apache.commons.lang.StringEscapeUtils; import org.apache.velocity.tools.config.DefaultKey; /** * Tool for working with escaping in Velocity templates. * It provides methods to escape outputs for Velocity, Java, JavaScript, HTML, HTTP, XML and SQL. * Also provides methods to render VTL characters that otherwise needs escaping. * *

       * Example uses:
       *  $velocity                    -> Please escape $ and #!
       *  $esc.velocity($velocity)     -> Please escape ${esc.d} and ${esc.h}!
       *
       *  $java                        -> He didn't say, "Stop!"
       *  $esc.java($java)             -> He didn't say, \"Stop!\"
       *
       *  $javascript                  -> He didn't say, "Stop!"
       *  $esc.javascript($javascript) -> He didn\'t say, \"Stop!\"
       *
       *  $html                        -> "bread" & "butter"
       *  $esc.html($html)             -> &quot;bread&quot; &amp; &quot;butter&quot;
       *
       *  $xml                         -> "bread" & "butter"
       *  $esc.xml($xml)               -> &quot;bread&quot; &amp; &quot;butter&quot;
       *
       *  $sql                         -> McHale's Navy
       *  $esc.sql($sql)               -> McHale''s Navy
       *
       *  $url                         -> hello here & there
       *  $esc.url                     -> hello+here+%26+there
       *
       *  $esc.dollar                  -> $
       *  $esc.d                       -> $
       *
       *  $esc.hash                    -> #
       *  $esc.h                       -> #
       *
       *  $esc.backslash               -> \
       *  $esc.b                       -> \
       *
       *  $esc.quote                   -> "
       *  $esc.q                       -> "
       *
       *  $esc.singleQuote             -> '
       *  $esc.s                       -> '
       *
       *  $esc.newline                 -> 
       *
       *  $esc.n                       -> 
       *
       *
       *  $esc.exclamation             -> !
       *  $esc.e                       -> !
       *
       * Example tools.xml config (if you want to use this with VelocityView):
       * <tools>
       *   <toolbox scope="application">
       *     <tool class="org.apache.velocity.tools.generic.EscapeTool"/>
       *   </toolbox>
       * </tools>
       * 

      * *

      This tool is entirely threadsafe, and has no instance members. * It may be used in any scope (request, session, or application). *

      * * @author Shinobu Kawai * @version $Id: $ * @since VelocityTools 1.2 * @see StringEscapeUtils */ @DefaultKey("esc") public class EscapeTool extends SafeConfig { public static final String DEFAULT_KEY = "esc"; private String key = DEFAULT_KEY; /** * Does the actual configuration. This is protected, so * subclasses may share the same ValueParser and call configure * at any time, while preventing templates from doing so when * configure(Map) is locked. */ protected void configure(ValueParser values) { String altkey = values.getString("key"); if (altkey != null) { setKey(altkey); } } /** * Sets the key under which this tool has been configured. * @see #velocity */ protected void setKey(String key) { if (key == null) { throw new NullPointerException("EscapeTool key cannot be null"); } this.key = key; } /** * Should return the key under which this tool has been configured. * The default is 'esc'. * @see #velocity */ public String getKey() { return this.key; } /** *

      Escapes the characters in a String using "poor man's * escaping" for Velocity templates by replacing all '$' characters * with '${esc.d}' and all '#' characters with '${esc.h}'. This form * of escaping is far more reliable and consistent than using '\' to * escape valid references, directives and macros, though it does require * that you have the EscapeTool available in the context when you later * go to process the result returned by this method. *

      * NOTE: This will only work so long as the EscapeTool is placed * in the context using its default key 'esc' or you are using * VelocityTools 2.0+ and have put this tool in one of your toolboxes * under an alternate key (in which case the EscapeTool will automatically * be told what its new key is). If for some strange reason you wish * to use an alternate key and are not using the tool management facilities * of VelocityTools 2.0+, you must subclass this tool and manually call * setKey(String) before using this method. *

      * * @param obj the string value that needs escaping * @return String with escaped values, null if null string input */ public String velocity(Object obj) { if (obj == null) { return null; } String string = String.valueOf(obj); // must escape $ first, so we don't escape our hash escapes! return string.replace("$", "${"+getKey()+".d}") .replace("#", "${"+getKey()+".h}"); } /** * Escapes the characters in a String using Java String rules. *
      * Delegates the process to {@link StringEscapeUtils#escapeJava(String)}. * * @param string the string to escape values, may be null * @return String with escaped values, null if null string input * * @see StringEscapeUtils#escapeJava(String) */ public String java(Object string) { if (string == null) { return null; } return StringEscapeUtils.escapeJava(String.valueOf(string)); } /** * Escapes the characters in a String using java.util.Properties rules for escaping property keys. * * @param string the string to escape values, may be null * @return String with escaped values, null if null string input * @see #dumpString(String, boolean) */ public String propertyKey(Object string) { if (string == null) { return null; } return dumpString(String.valueOf(string), true); } /** * Escapes the characters in a String using java.util.Properties rules for escaping property values. * * @param string the string to escape values, may be null * @return String with escaped values, null if null string input * @see #dumpString(String, boolean) */ public String propertyValue(Object string) { if (string == null) { return null; } return dumpString(String.valueOf(string), false); } /** * This code was pulled from the Apache Harmony project. See * https://svn.apache.org/repos/asf/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/util/Properties.java */ protected String dumpString(String string, boolean key) { StringBuilder builder = new StringBuilder(); int i = 0; if (!key && i < string.length() && string.charAt(i) == ' ') { builder.append("\\ "); //$NON-NLS-1$ i++; } for (; i < string.length(); i++) { char ch = string.charAt(i); switch (ch) { case '\t': builder.append("\\t"); //$NON-NLS-1$ break; case '\n': builder.append("\\n"); //$NON-NLS-1$ break; case '\f': builder.append("\\f"); //$NON-NLS-1$ break; case '\r': builder.append("\\r"); //$NON-NLS-1$ break; default: if ("\\#!=:".indexOf(ch) >= 0 || (key && ch == ' ')) { builder.append('\\'); } if (ch >= ' ' && ch <= '~') { builder.append(ch); } else { String hex = Integer.toHexString(ch); builder.append("\\u"); //$NON-NLS-1$ for (int j = 0; j < 4 - hex.length(); j++) { builder.append("0"); //$NON-NLS-1$ } builder.append(hex); } } } return builder.toString(); } /** * Escapes the characters in a String using JavaScript String rules. *
      * Delegates the process to {@link StringEscapeUtils#escapeJavaScript(String)}. * * @param string the string to escape values, may be null * @return String with escaped values, null if null string input * * @see StringEscapeUtils#escapeJavaScript(String) */ public String javascript(Object string) { if (string == null) { return null; } return StringEscapeUtils.escapeJavaScript(String.valueOf(string)); } /** * Escapes the characters in a String using HTML entities. *
      * Delegates the process to {@link StringEscapeUtils#escapeHtml(String)}. * * @param string the string to escape, may be null * @return a new escaped String, null if null string input * * @see StringEscapeUtils#escapeHtml(String) */ public String html(Object string) { if (string == null) { return null; } return StringEscapeUtils.escapeHtml(String.valueOf(string)); } /** * Escape the characters in a String to be suitable to use as an HTTP parameter value. *
      * Uses UTF-8 as default character encoding. * @param string the string to escape, may be null * @return a new escaped String, null if null string input * * See java.net.URLEncoder#encode(String,String). * @since VelocityTools 1.3 */ public String url(Object string) { if (string == null) { return null; } try { return URLEncoder.encode(String.valueOf(string),"UTF-8"); } catch(UnsupportedEncodingException uee) { return null; } } /** * Escapes the characters in a String using XML entities. *
      * Delegates the process to {@link StringEscapeUtils#escapeXml(String)}. * * @param string the string to escape, may be null * @return a new escaped String, null if null string input * * @see StringEscapeUtils#escapeXml(String) */ public String xml(Object string) { if (string == null) { return null; } return StringEscapeUtils.escapeXml(String.valueOf(string)); } /** * Escapes the characters in a String to be suitable to pass to an SQL query. *
      * Delegates the process to {@link StringEscapeUtils#escapeSql(String)}. * * @param string the string to escape, may be null * @return a new String, escaped for SQL, null if null string input * * @see StringEscapeUtils#escapeSql(String) */ public String sql(Object string) { if (string == null) { return null; } return StringEscapeUtils.escapeSql(String.valueOf(string)); } /** * Converts the specified Unicode code point and/or escape sequence into * the associated Unicode character. This allows numeric * code points or String versions of the numeric code point to be correctly * translated within a template. This is especially useful for those * creating unicode from a reference value, or injecting a unicode character * into a template with a version of Velocity prior to 1.6. * @param code the code to be translated/escaped, may be null * @return the unicode character for that code, {@code null} if input was null * @see Character#toChars(int codePoint) */ public String unicode(Object code) { if (code == null) { return null; } String s = String.valueOf(code); if (s.startsWith("\\u")) { s = s.substring(2, s.length()); } int codePoint = Integer.valueOf(s, 16); return String.valueOf(Character.toChars(codePoint)); } /** * Renders a dollar sign ($). * @return a dollar sign ($). * @see #getD() */ public String getDollar() { return "$"; } /** * Renders a dollar sign ($). * @return a dollar sign ($). * @see #getDollar() */ public String getD() { return this.getDollar(); } /** * Renders a hash (#). * @return a hash (#). * @see #getH() */ public String getHash() { return "#"; } /** * Renders a hash (#). * @return a hash (#). * @see #getHash() */ public String getH() { return this.getHash(); } /** * Renders a backslash (\). * @return a backslash (\). * @see #getB() */ public String getBackslash() { return "\\"; } /** * Renders a backslash (\). * @return a backslash (\). * @see #getBackslash() */ public String getB() { return this.getBackslash(); } /** * Renders a double quotation mark ("). * @return a double quotation mark ("). * @see #getQ() */ public String getQuote() { return "\""; } /** * Renders a double quotation mark ("). * @return a double quotation mark ("). * @see #getQuote() */ public String getQ() { return this.getQuote(); } /** * Renders a single quotation mark ('). * @return a single quotation mark ('). * @see #getS() */ public String getSingleQuote() { return "'"; } /** * Renders a single quotation mark ('). * @return a single quotation mark ('). * @see #getSingleQuote() */ public String getS() { return this.getSingleQuote(); } /** * Renders a new line character appropriate for the * operating system ("\n" in java). * @see #getN() */ public String getNewline() { return "\n"; } /** * Renders a new line character appropriate for the * operating system ("\n" in java). * @see #getNewline() */ public String getN() { return this.getNewline(); } /** * Renders an exclamation mark (!). * @return an exclamation mark (!). * @see #getE() */ public String getExclamation() { return "!"; } /** * Renders an exclamation mark (!). * @return an exclamation mark (!). * @see #getExclamation() */ public String getE() { return this.getExclamation(); } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/generic/FieldTool.java100644 0 0 27102 11030275253 26105 0ustar 0 0 package org.apache.velocity.tools.generic; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.HashMap; import java.util.Map; import org.apache.velocity.runtime.log.Log; import org.apache.velocity.tools.ClassUtils; import org.apache.velocity.tools.config.DefaultKey; /** *

      * This is a simple tools class to allow easy access to static fields in a class, * such as string constants from within a template. Velocity will not introspect * for class fields (and won't in the future :), but writing setter/getter methods * to do this is a pain, so use this if you really have to access fields. * *

      *

       * Example uses in a template:
       *   ## here we access a constant in a class include in the configuration
       *     $field.COUNTER_NAME
       *
       *   ## here we dynamically lookup a class' fields to find another constant
       *     $field.in("org.com.SomeClass").ANOTHER_CONSTANT
       *
       *   ## here we pass an object instance in (an Integer in this case) and
       *   ## retrieve a static constant from that instance's class
       *     $field.in(0).MIN_VALUE
       *
       *   ## by default, once we've searched a class' fields, those fields stay
       *   ## available in the tool (change this by storeDynamicLookups="false")
       *   ## so here we get another constant from the Integer class
       *     $field.MAX_VALUE
       *
       *
       * Example tools.xml config:
       * <tools>
       *   <toolbox scope="application">
       *     <tool class="org.apache.velocity.tools.generic.FieldTool"
       *              include="org.apache.velocity.runtime.RuntimeConstants,com.org.MyConstants"/>
       *   </toolbox>
       * </tools>
       * 

      * *

      * Right now, this tool only gives access to public static fields. * It seems that anything else is too dangerous. This is for convenient access * to 'constants'. If you have fields that aren't static, * handle them by explicitly placing them into the context or writing a getter * method. * * @author Geir Magnusson Jr. * @author Nathan Bubna * @since VelocityTools 2.0 * @version $Id: FieldTool.java 463298 2006-10-12 16:10:32Z henning $ */ @DefaultKey("field") public class FieldTool extends SafeConfig { /** * The key used for specifying which classes should be inspected * for public static methods to be made available. */ public static final String INCLUDE_KEY = "include"; /** * The key used for specifying whether or not the tool should store * fields in classes dynamically looked up from within a template. * The default value is true. */ public static final String STORE_DYNAMIC_KEY = "storeDynamicLookups"; protected Log log; protected HashMap storage = new HashMap(); protected boolean storeDynamicLookups = true; protected void configure(ValueParser values) { // see if there's a log in there this.log = (Log)values.getValue("log"); // retrieve any classnames to be inspected and inspect them // *before* setting the storeDynamicLookups property! String[] classnames = values.getStrings(INCLUDE_KEY); if (classnames != null) { for (String classname : classnames) { // make sure we get results for each classname // since these come from the configuration, it's // an error if they're invalid if (in(classname) == null) { // shame that ClassNotFoundException is checked... throw new RuntimeException("Could not find "+classname+" in the classpath"); } } } // find out whether or not we should store dynamic lookups this.storeDynamicLookups = values.getBoolean(STORE_DYNAMIC_KEY, this.storeDynamicLookups); } /** * Returns the value for the specified field name as found * in the stored {@link Map} of field names to values (or placeholders). * Returns {@code null} if there is no matching field. */ public Object get(String name) { Object o = storage.get(name); // if it was not a final field, get the current value if (o instanceof MutableField) { return ((MutableField)o).getValue(); } // if we have no value and the name looks like a path else if (o == null && name.indexOf('.') > 0) { // treat the name as a full fieldpath try { return ClassUtils.getFieldValue(name); } catch (Exception e) { if (log != null) { log.debug("Unable to retrieve value of field at "+name, e); } } } // otherwise, we should have stored the value directly return o; } /** * Returns a {@link FieldToolSub} holding a {@link Map} * of all the public static field names to values (or a placeholder * if the value is not final) for the specified class(name). If the * {@link Class} with the specified name cannot be loaded, this will * return {@code null}, rather than throw an exception. * * @see #in(Class clazz) */ public FieldToolSub in(String classname) { try { return in(ClassUtils.getClass(classname)); } catch (ClassNotFoundException cnfe) { return null; } } /** * Returns a {@link FieldToolSub} holding a {@link Map} * of all the public static field names to values (or a placeholder * if the value is not final) for the {@link Class} of the * specified Object. * @see #in(Class clazz) */ public FieldToolSub in(Object instance) { if (instance == null) { return null; } return in(instance.getClass()); } /** * Returns a {@link FieldToolSub} holding a {@link Map} * of all the public static field names to values (or a placeholder * if the value is not final) for the specified {@link Class}. */ public FieldToolSub in(Class clazz) { if (clazz == null) { return null; } Map results = inspect(clazz); if (storeDynamicLookups && !results.isEmpty()) { storage.putAll(results); } return new FieldToolSub(results); } /** * Looks for all public, static fields in the specified class and * stores their value (if final) or else a {@link MutableField} for * in a {@link Map} under the fields' names. This will never return * null, only an empty Map if there are no public static fields. */ protected Map inspect(Class clazz) { Map results = new HashMap(); for(Field field : clazz.getFields()) { // ignore anything non-public or non-static int mod = field.getModifiers(); if (Modifier.isStatic(mod) && Modifier.isPublic(mod)) { // make it easy to debug key collisions if (log != null && log.isDebugEnabled() && results.containsKey(field.getName())) { log.debug("FieldTool: "+field.getName()+ " is being overridden by "+clazz.getName()); } // if the field is final if (Modifier.isFinal(mod)) { // just get the value now results.put(field.getName(), retrieve(field, clazz, log)); } else { // put a wrapper with easy access results.put(field.getName(), new MutableField(field, clazz, log)); } } } return results; } /** * Retrieves and returns the value of the specified {@link Field} * in the specified {@link Class}. If {@link Log} is provided, then * access errors will be logged, otherwise this will fail silently * and return {@code null}. */ protected static Object retrieve(Field field, Class clazz, Log log) { try { return field.get(clazz); } catch(IllegalAccessException iae) { if (log != null) { log.warn("IllegalAccessException while trying to access " + field.getName(), iae); } return null; } } /** * Holds a {@link Map} of results for a particular class. * This exists simply to enable the $field.in("class.Name").FOO * syntax, even when storeDynamicLookups is set to false. * NOTE: we can't simply return the results Map when the in() * methods are called, because the Map contains placeholders * for any mutable fields found. We want to put off reading non-final * field values to the last moment, in case their values change. */ public static class FieldToolSub { private final Map results; public FieldToolSub(Map results) { if (results == null) { throw new NullPointerException("Cannot create sub with null field results map"); } this.results = results; } public Object get(String name) { Object o = results.get(name); // if it was not a final field, get the current value if (o instanceof MutableField) { return ((MutableField)o).getValue(); } // otherwise, we should have stored the value directly return o; } /** * Return the toString() value of the internal results Map for this sub. */ public String toString() { return results.toString(); } } /** * Holds a {@link Field} and {@link Class} reference for later * retrieval of the value of a field that is not final and may * change at different lookups. If a {@link Log} is passed in, * then this will log errors, otherwise it will fail silently. */ public static class MutableField { private final Class clazz; private final Field field; private final Log log; public MutableField(Field f, Class c, Log l) { if (f == null || c == null) { throw new NullPointerException("Both Class and Field must NOT be null"); } field = f; clazz = c; log = l; } public Object getValue() { return FieldTool.retrieve(field, clazz, log); } } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/generic/FormatConfig.java100644 0 0 4402 10730012250 26550 0ustar 0 0 package org.apache.velocity.tools.generic; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ /** * Implements common logic and constants for tools which allow their * default format to be configured. * * @author Nathan Bubna * @since VelocityTools 2.0 */ public class FormatConfig extends LocaleConfig { /** * The default format to be used when none is specified. */ public static final String DEFAULT_FORMAT = "default"; /** * The key used for specifying a default format via tool configuration. */ public static final String FORMAT_KEY = "format"; private String format = DEFAULT_FORMAT; /** * Does the actual configuration. This is protected, so * subclasses may share the same ValueParser and call configure * at any time, while preventing templates from doing so when * configure(Map) is locked. */ protected void configure(ValueParser values) { super.configure(values); String format = values.getString(FORMAT_KEY); if (format != null) { setFormat(format); } } /** * This returns the configured default format for this tool. * * @return the default {@link String} */ public String getFormat() { return this.format; } /** * Sets the default format for this instance. */ protected void setFormat(String format) { this.format = format; } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/generic/IteratorTool.java100644 0 0 25002 10730012250 26640 0ustar 0 0 package org.apache.velocity.tools.generic; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.util.Collection; import java.util.Enumeration; import java.util.Iterator; import java.util.Map; import org.apache.velocity.util.ArrayIterator; import org.apache.velocity.util.EnumerationIterator; import org.apache.velocity.tools.config.DefaultKey; /** *

      * A convenience tool to use with #foreach loops. It wraps a list * to let the designer specify a condition to terminate the loop, * and reuse the same list in different loops. *

      *

      * Example of use: *

       *  Java
       *  ----
       *  context.put("mill", new IteratorTool());
       *
       *
       *  VTL
       *  ---
       *
       *  #set ($list = [1, 2, 3, 5, 8, 13])
       *  #set ($numbers = $mill.wrap($list))
       *
       *  #foreach ($item in $numbers)
       *  #if ($item < 8) $numbers.more()#end
       *  #end
       *
       *  $numbers.more()
       *
       *
       *  Output
       *  ------
       *
       *   1 2 3 5
       *  8
       *
       * Example tools.xml config (if you want to use this with VelocityView):
       * <tools>
       *   <toolbox scope="request">
       *     <tool class="org.apache.velocity.tools.generic.IteratorTool"/>
       *   </toolbox>
       * </tools>
       * 
      *

      *

      * Warning: It is not recommended to use hasNext() with this * tool as it is used to control the #foreach. Use hasMore() instead. *

      * * @author Denis Bredelet * @version $Id: IteratorTool.java 598471 2007-11-27 00:26:10Z nbubna $ * @deprecated Use {@link LoopTool} instead */ @DefaultKey("mill") @Deprecated public class IteratorTool implements Iterator { private Object wrapped; private Iterator iterator; private boolean wantMore; private boolean cachedNext; protected Object next; /** * Create a IteratorTool instance to use as tool. * When it is created this way, the tool returns a new * instance each time wrap() is called. This is * useful when you want to allow the designers to create instances. */ public IteratorTool() { this(null); } /** * Create a IteratorTool instance to use in #foreach. * * @param wrapped The list to wrap. */ public IteratorTool(Object wrapped) { internalWrap(wrapped); } /** * Wraps a list with the tool. *
      The list can be an array, a Collection, a Map, an Iterator * or an Enumeration. *
      If the list is a Map, the tool iterates over the values. *
      If the list is an Iterator or an Enumeration, the tool can * be used only once. * * @param list The list to wrap. * @return A new wrapper if this object is used as a tool, or * itself if it is a wrapper. */ public IteratorTool wrap(Object list) { if (this.wrapped == null) { return new IteratorTool(list); } else if (list != null) { internalWrap(list); return this; } else { throw new IllegalArgumentException("Need a valid list to wrap"); } } /** * Wraps a list with the tool. This object can therefore * be used instead of the list itself in a #foreach. * The list can be an array, a Collection, a Map, an * Iterator or an Enumeration. *
      - If the list is a Map, the tool iterates over the values. *
      - If the list is an Iterator or an Enumeration, the tool * can be used only once. * * @param wrapped The list to wrap. */ private void internalWrap(Object wrapped) { if (wrapped != null) { /* rip-off from org/apache/velocity/runtime/directive/ForEach.java */ if (wrapped.getClass().isArray()) { this.iterator = new ArrayIterator((Object[])wrapped); } else if (wrapped instanceof Collection) { this.iterator = ((Collection)wrapped).iterator(); } else if (wrapped instanceof Map) { this.iterator = ((Map)wrapped).values().iterator(); } else if (wrapped instanceof Iterator) { this.iterator = (Iterator)wrapped; } else if (wrapped instanceof Enumeration) { this.iterator = new EnumerationIterator((Enumeration)wrapped); } else { /* Don't know what is the object. * Should we put it in a one-item array? */ throw new IllegalArgumentException("Don't know how to wrap: "+wrapped); } this.wrapped = wrapped; this.wantMore = true; this.cachedNext = false; } else { this.iterator = null; this.wrapped = null; this.wantMore = false; this.cachedNext = false; } } /** *

      * Resets the wrapper so that it starts over at the beginning of the list. *

      *

      * Note to programmers: This method has no effect if the wrapped * object is an enumeration or an iterator. */ public void reset() { if (this.wrapped != null) { internalWrap(this.wrapped); } } /** *

      * Gets the next object in the list. This method is called * by #foreach to define $item in: *

           * #foreach( $item in $list )
           * 
      *

      *

      * This method is not intended for template designers, but they can use * them if they want to read the value of the next item without doing * more(). *

      * * @return The next item in the list. * @throws NoSuchElementException if there are no more * elements in the list. */ public Object next() { if (this.wrapped == null) { throw new IllegalStateException("Use wrap() before calling next()"); } if (!this.cachedNext) { this.cachedNext = true; this.next = this.iterator.next(); return this.next; } else { return this.next; } } /** * Returns true if there are more elements in the * list and more() was called. *
      This code always return false: *
           * tool.hasNext()? tool.hasNext(): false;
           * 
      * * @return true if there are more elements, and either more() * or hasNext() was called since last call. */ public boolean hasNext() { if (this.wantMore) { /* don't want more unless more is called */ this.wantMore = false; return hasMore(); } else { /* prepare for next #foreach */ this.wantMore = true; return false; } } /** * Removes the current element from the list. * The current element is defined as the last element that was read * from the list, either with next() or with more(). * * @throws UnsupportedOperationException if the wrapped list * iterator doesn't support this operation. */ public void remove() throws UnsupportedOperationException { if (this.wrapped == null) { throw new IllegalStateException("Use wrap() before calling remove()"); } /* Let the iterator decide whether to implement this or not */ this.iterator.remove(); } /** *

      * Asks for the next element in the list. This method is to be used * by the template designer in #foreach loops. *

      *

      * If this method is called in the body of #foreach, the loop * continues as long as there are elements in the list. *
      If this method is not called the loop terminates after the * current iteration. *

      * * @return The next element in the list, or null if there are no * more elements. */ public Object more() { this.wantMore = true; if (hasMore()) { Object next = next(); this.cachedNext = false; return next; } else { return null; } } /** * Returns true if there are more elements in the wrapped list. *
      If this object doesn't wrap a list, the method always returns false. * * @return true if there are more elements in the list. */ public boolean hasMore() { if (this.wrapped == null) { return false; } return cachedNext || this.iterator.hasNext(); } /** * Puts a condition to break out of the loop. * The #foreach loop will terminate after this iteration, unless more() * is called after stop(). */ public void stop() { this.wantMore = false; } /** * Returns this object as a String. *
      If this object is used as a tool, it just gives the class name. *
      Otherwise it appends the wrapped list to the class name. * * @return A string representation of this object. */ public String toString() { StringBuilder out = new StringBuilder(this.getClass().getName()); if (this.wrapped != null) { out.append('('); out.append(this.wrapped); out.append(')'); } return out.toString(); } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/generic/LinkTool.java100644 0 0 145055 11202122666 26007 0ustar 0 0 package org.apache.velocity.tools.generic; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.io.UnsupportedEncodingException; import java.net.URI; import java.net.URLDecoder; import java.net.URLEncoder; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import org.apache.velocity.runtime.log.Log; import org.apache.velocity.tools.Scope; import org.apache.velocity.tools.ToolContext; import org.apache.velocity.tools.config.DefaultKey; import org.apache.velocity.tools.config.SkipSetters; import org.apache.velocity.tools.config.ValidScope; /** *

      The LinkTool provides many methods to work with URIs and can help you: *

        *
      • construct full URIs (opaque, absolute or relative)
      • *
      • encode and decode URLs (part or whole)
      • *
      • retrieve path info for the current request
      • *
      • and more..
      • *

      * *

      This GenericTools (i.e. non-servlet based) version of LinkTool * is largely based upon the same API and behavior as the older * VelocityView version, with a few differences, particularly in * internal representation and query handling. You can expect that * in the future work will be done to more closely align the APIs. * It is likely that the VelocityView version will become a subclass * of this version that adds on servlet-awareness and related features. * For now, though, they are entirely separate but similar tools. *

      * *

      The LinkTool is somewhat special in that nearly all public methods return * a new instance of LinkTool. This facilitates greatly the repeated use * of the LinkTool in Velocity and leads to an elegant syntax.

      * *

       * Template example(s):
       *   #set( $base = $link.relative('MyPage.vm').anchor('view') )
       *   <a href="$base.param('select','this')">this</a>
       *   <a href="$base.param('select','that')">that</a>
       *
       * Toolbox configuration:
       * <tools>
       *   <toolbox scope="request">
       *     <tool class="org.apache.velocity.tools.generic.LinkTool"
       *              uri="http://velocity.apache.org/tools/devel/"/>
       *   </toolbox>
       * </tools>
       * 

      * * @author Nathan Bubna * @since VelocityTools 2.0 * @version $Id: LinkTool.java 601976 2007-12-07 03:50:51Z nbubna $ */ @DefaultKey("link") @SkipSetters @ValidScope(Scope.REQUEST) public class LinkTool extends SafeConfig implements Cloneable { /** Standard HTML delimiter for query data ('&') */ public static final String HTML_QUERY_DELIMITER = "&"; /** XHTML delimiter for query data ('&amp;') */ public static final String XHTML_QUERY_DELIMITER = "&"; public static final String APPEND_PARAMS_KEY = "appendParameters"; public static final String FORCE_RELATIVE_KEY = "forceRelative"; public static final String DEFAULT_CHARSET = "UTF-8"; public static final String DEFAULT_SCHEME = "http"; public static final String SECURE_SCHEME = "https"; public static final String URI_KEY = "uri"; public static final String SCHEME_KEY = "scheme"; public static final String USER_KEY = "user"; public static final String HOST_KEY = "host"; public static final String PORT_KEY = "port"; public static final String PATH_KEY = ToolContext.PATH_KEY; public static final String QUERY_KEY = "params"; public static final String FRAGMENT_KEY = "anchor"; public static final String CHARSET_KEY = "charset"; public static final String XHTML_MODE_KEY = "xhtml"; protected Log LOG; protected String scheme; protected String user; protected String host; protected int port; protected String path; protected Map query; protected String fragment; protected String charset; protected String queryDelim; protected boolean appendParams; protected boolean forceRelative; protected boolean opaque; protected final LinkTool self; /** * Default constructor. Tool typically is configured before use. */ public LinkTool() { scheme = null; user = null; host = null; port = -1; path = null; query = null; fragment = null; charset = DEFAULT_CHARSET; queryDelim = XHTML_QUERY_DELIMITER; opaque = false; appendParams = true; forceRelative = false; self = this; } protected final void debug(String msg, Object... args) { debug(msg, null, args); } protected final void debug(String msg, Throwable t, Object... args) { if (LOG != null && LOG.isDebugEnabled()) { LOG.debug("LinkTool: "+String.format(msg, args), t); } } // --------------------------------------- Setup Methods ------------- protected void configure(ValueParser props) { this.LOG = (Log)props.getValue(ToolContext.LOG_KEY); String link = props.getString(URI_KEY); if (link != null) { setFromURI(link); } String schm = props.getString(SCHEME_KEY); if (schm != null) { setScheme(schm); } String info = props.getString(USER_KEY); if (info != null) { setUserInfo(info); } String hst = props.getString(HOST_KEY); if (hst != null) { setHost(hst); } Integer prt = props.getInteger(PORT_KEY); if (prt != null) { setPort(prt.intValue()); } String pth = props.getString(PATH_KEY); if (pth != null) { setPath(pth); } String params = props.getString(QUERY_KEY); if (params != null) { setQuery(params); } String anchor = props.getString(FRAGMENT_KEY); if (anchor != null) { setFragment(anchor); } String chrst = props.getString(CHARSET_KEY); if (chrst != null) { setCharacterEncoding(chrst); } Boolean xhtml = props.getBoolean(XHTML_MODE_KEY); if (xhtml != null) { setXHTML(xhtml); } Boolean addParams = props.getBoolean(APPEND_PARAMS_KEY); if (addParams != null) { setAppendParams(addParams); } Boolean forceRelative = props.getBoolean(FORCE_RELATIVE_KEY); if (forceRelative != null) { setForceRelative(forceRelative); } } /** * Equivalent to clone, but with no checked exceptions. * If for some unfathomable reason clone() doesn't work, * this will throw a RuntimeException. */ protected LinkTool duplicate() { return duplicate(false); } /** * Equivalent to clone, but with no checked exceptions. * If for some unfathomable reason clone() doesn't work, * this will throw a RuntimeException. If doing a deep * clone, then the parameter Map will also be cloned. */ protected LinkTool duplicate(boolean deep) { try { LinkTool that = (LinkTool)this.clone(); if (deep && query != null) { that.query = new LinkedHashMap(query); } return that; } catch (CloneNotSupportedException e) { String msg = "Could not properly clone " + getClass(); if (LOG != null) { LOG.error(msg, e); } throw new RuntimeException(msg, e); } } public void setCharacterEncoding(String chrst) { this.charset = chrst; } /** *

      Controls the delimiter used for separating query data pairs. * By default, the standard '&' character is used.

      *

      This is not exposed to templates as this decision is best not * made at that level.

      *

      Subclasses may easily override the init() method to set this * appropriately and then call super.init()

      * * @param xhtml if true, the XHTML query data delimiter ('&amp;') * will be used. if false, then '&' will be used. * @see Using Ampersands in Attribute Values (and Elsewhere) */ public void setXHTML(boolean xhtml) { queryDelim = (xhtml) ? XHTML_QUERY_DELIMITER : HTML_QUERY_DELIMITER; } /** * Sets whether or not the {@link #setParam} method * will override existing query values for the same key or simply append * the new value to a list of existing values. */ public void setAppendParams(boolean addParams) { this.appendParams = addParams; } /** * Sets whether or not the {@link #createURI} method should ignore the * scheme, user, port and host values for non-opaque URIs, thus making * {@link #toString} print the link as a relative one, not an absolute * one. NOTE: using {@link #absolute()}, {@link #absolute(Object)}, * {@link #relative()}, or {@link #relative(Object)} will alter this * setting accordingly on the new instances they return. */ public void setForceRelative(boolean forceRelative) { this.forceRelative = forceRelative; } /** * This will treat empty strings like null values * and will trim any trailing ':' character. */ public void setScheme(Object obj) { if (obj == null) { this.scheme = null; } else { this.scheme = String.valueOf(obj); if (scheme.length() == 0) { this.scheme = null; } if (scheme.endsWith(":")) { this.scheme = scheme.substring(0, scheme.length() - 1); } } } public void setUserInfo(Object obj) { this.user = obj == null ? null : String.valueOf(obj); } public void setHost(Object obj) { this.host = obj == null ? null : String.valueOf(obj); } /** * If the specified object is null, this will set the port value * to -1 to indicate that. If it is non-null and cannot be converted * to an integer, then it will be set to -2 to indicate an error. */ public void setPort(Object obj) { if (obj == null) { this.port = -1; } else if (obj instanceof Number) { this.port = ((Number)obj).intValue(); } else { try { this.port = Integer.parseInt(String.valueOf(obj)); } catch (NumberFormatException nfe) { debug("Could convert '%s' to int", nfe, obj); this.port = -2; // use this to mean error } } } /** * If this instance is not opaque and the specified value does * not start with a '/' character, then that will be prepended * automatically. */ public void setPath(Object obj) { if (obj == null) { this.path = null; } else { this.path = String.valueOf(obj); if (!this.opaque && !path.startsWith("/")) { this.path = '/' + this.path; } } } /** * Uses {@link #combinePath} to add the specified value * to the current {@link #getPath} value. If the specified * value is null or this instance is opaque, then this is * a no-op. */ public void appendPath(Object obj) { if (obj != null && !this.opaque) { setPath(combinePath(getPath(), String.valueOf(obj))); } } /** * If end is null, this will return start and vice versa. * If neither is null, this will append the end to the start, * making sure that there is only one '/' character between * the two values. */ protected String combinePath(String start, String end) { if (end == null) { return start; } if (start == null) { return end; } // make sure we don't get // or nothing between start and end boolean startEnds = start.endsWith("/"); boolean endStarts = end.startsWith("/"); if (startEnds ^ endStarts) //one { return start + end; } else if (startEnds & endStarts) //both { return start + end.substring(1, end.length()); } else //neither { return start + '/' + end; } } /** * If the specified value is null, it will set the query to null. * If a Map, it will copy all those values into a new LinkedHashMap and * replace any current query value with that. If it is a String, * it will use {@link #parseQuery(String)} to parse it into a map * of keys to values. */ public void setQuery(Object obj) { if (obj == null) { this.query = null; } else if (obj instanceof Map) { this.query = new LinkedHashMap((Map)obj); } else { String qs = normalizeQuery(String.valueOf(obj)); this.query = parseQuery(qs); } } protected String normalizeQuery(String qs) { // if we have multiple pairs... if (qs.indexOf('&') >= 0) { // ensure the delimeters match the xhtml setting // this impl is not at all efficient, but it's easy qs = qs.replaceAll("&(amp;)?", queryDelim); } return qs; } /** * Converts the map of keys to values into a query string. */ public String toQuery(Map parameters) { if (parameters == null) { return null; } StringBuilder query = new StringBuilder(); for (Object e : parameters.entrySet()) { Map.Entry entry = (Map.Entry)e; //add new pair to this LinkTool's query data if (query.length() > 0) { query.append(queryDelim); } query.append(toQuery(entry.getKey(), entry.getValue())); } return query.toString(); } /** * Uses {@link #combineQuery} to append the specified value * to the current {@link #getQuery} value. */ public void appendQuery(Object obj) { if (obj != null) { setQuery(combineQuery(getQuery(), String.valueOf(obj))); } } /** * If there is no existing value for this key in the query, it * will simply add it and its value to the query. If the key * already is present in the query and append * is true, this will add the specified value to those * already under that key. If {@link #appendParams} is * false, this will override the existing values with the * specified new value. */ public void setParam(Object key, Object value, boolean append) { // use all keys as strings, even null -> "null" key = String.valueOf(key); if (this.query == null) { this.query = new LinkedHashMap(); putParam(key, value); } else if (append) { appendParam((String)key, value); } else { putParam(key, value); } } private void appendParam(String key, Object value) { if (query.containsKey(key)) { Object cur = query.get(key); if (cur instanceof List) { addToList((List)cur, value); } else { List vals = new ArrayList(); vals.add(cur); addToList(vals, value); putParam(key, vals); } } else { putParam(key, value); } } private void putParam(Object key, Object value) { if (value instanceof Object[]) { List vals = new ArrayList(); for (Object v : ((Object[])value)) { vals.add(v); } value = vals; } query.put(key, value); } private void addToList(List vals, Object value) { if (value instanceof List) { for (Object v : ((List)value)) { vals.add(v); } } else if (value instanceof Object[]) { for (Object v : ((Object[])value)) { vals.add(v); } } else { vals.add(value); } } /** * If append is false, this simply delegates to {@link #setQuery}. * Otherwise, if the specified object is null, it does nothing. If the object * is not a Map, it will turn it into a String and use {@link #parseQuery} to * parse it. Once it is a Map, it will iterate through the entries appending * each key/value to the current query data. */ public void setParams(Object obj, boolean append) { if (!append) { setQuery(obj); } else if (obj != null) { if (!(obj instanceof Map)) { obj = parseQuery(String.valueOf(obj)); } if (obj != null) { if (query == null) { this.query = new LinkedHashMap(); } for (Object e : ((Map)obj).entrySet()) { Map.Entry entry = (Map.Entry)e; String key = String.valueOf(entry.getKey()); appendParam(key, entry.getValue()); } } } } /** * Removes the query pair(s) with the specified key from the * query data and returns the remove value(s), if any. */ public Object removeParam(Object key) { if (query != null) { key = String.valueOf(key); return query.remove(key); } return null; } /** * In this class, this method ignores true values. If passed a false value, * it will call {@link #setQuery} with a null value to clear all query data. */ protected void handleParamsBoolean(boolean keep) { if (!keep) { setQuery(null); } } /** * If the second param is null or empty, this will simply return the first * and vice versa. Otherwise, it will trim any '?' * at the start of the second param and any '&' or '&amp;' at the * end of the first one, then combine the two, making sure that they * are separated by only one delimiter. */ protected String combineQuery(String current, String add) { if (add == null || add.length() == 0) { return current; } if (add.startsWith("?")) { add = add.substring(1, add.length()); } if (current == null || current.length() == 0) { return add; } if (current.endsWith(queryDelim)) { current = current.substring(0, current.length() - queryDelim.length()); } else if (current.endsWith("&")) { current = current.substring(0, current.length() - 1); } if (add.startsWith(queryDelim)) { return current + add; } else if (add.startsWith("&")) { // drop the html delim in favor of the xhtml one add = add.substring(1, add.length()); } return current + queryDelim + add; } /** * Turns the specified key and value into a properly encoded * query pair string. If the value is an array or List, then * this will create a delimited string of query pairs, reusing * the same key for each of the values separately. */ protected String toQuery(Object key, Object value) { StringBuilder out = new StringBuilder(); if (value == null) { out.append(encode(key)); out.append('='); /* Interpret null as "no value" */ } else if (value instanceof List) { appendAsArray(out, key, ((List)value).toArray()); } else if (value instanceof Object[]) { appendAsArray(out, key, (Object[])value); } else { out.append(encode(key)); out.append('='); out.append(encode(value)); } return out.toString(); } /* Utility method to avoid logic duplication in toQuery() */ protected void appendAsArray(StringBuilder out, Object key, Object[] arr) { String encKey = encode(key); for (int i=0; i < arr.length; i++) { out.append(encKey); out.append('='); if (arr[i] != null) { out.append(encode(arr[i])); } if (i+1 < arr.length) { out.append(queryDelim); } } } /** * Uses {@link #normalizeQuery} to make all delimiters in the * specified query string match the current query delimiter * and then uses {@link #parseQuery(String,String)} to parse it * according to that same delimiter. */ protected Map parseQuery(String query) { return parseQuery(normalizeQuery(query), this.queryDelim); } /** * This will use the specified query delimiter to parse the specified * query string into a map of keys to values. * If there are multiple query pairs in the string that have the same * key, then the values will be combined into a single List value * associated with that key. */ protected Map parseQuery(String query, String queryDelim) { if (query.startsWith("?")) { query = query.substring(1, query.length()); } String[] pairs = query.split(queryDelim); if (pairs.length == 0) { return null; } Map params = new LinkedHashMap(pairs.length); for (String pair : pairs) { String[] kv = pair.split("="); String key = kv[0]; Object value = kv.length > 1 ? kv[1] : null; if (params.containsKey(kv[0])) { Object oldval = params.get(key); if (oldval instanceof List) { ((List)oldval).add((String)value); value = oldval; } else { List list = new ArrayList(); list.add((String)oldval); list.add((String)value); value = list; } } params.put(key, value); } return params; } /** * Sets the anchor for this instance and treats empty strings like null. */ public void setFragment(Object obj) { if (obj == null) { this.fragment = null; } else { this.fragment = String.valueOf(obj); if (this.fragment.length() == 0) { this.fragment = null; } } } /** * If the specified value is null, this will set the scheme, userInfo, * host, port, path, query, and fragment all to their null-equivalent * values. Otherwise, this will * convert the specified object into a {@link URI}, then those same * values from the URI object to this instance. */ protected boolean setFromURI(Object obj) { if (obj == null) { // clear everything out... setScheme(null); setUserInfo(null); setHost(null); setPort(null); setPath(null); setQuery(null); setFragment(null); return true; } URI uri = toURI(obj); if (uri == null) { return false; } setScheme(uri.getScheme()); if (uri.isOpaque()) { this.opaque = true; // path is used as scheme-specific part setPath(uri.getSchemeSpecificPart()); } else { setUserInfo(uri.getUserInfo()); setHost(uri.getHost()); setPort(uri.getPort()); String pth = uri.getPath(); if (pth.equals("/") || pth.length() == 0) { pth = null; } setPath(pth); setQuery(uri.getQuery()); } setFragment(uri.getFragment()); return true; } /** * Turns the specified object into a string and thereby a URI. */ protected URI toURI(Object obj) { if (obj instanceof URI) { return (URI)obj; } else { try { return new URI(String.valueOf(obj)); } catch (Exception e) { debug("Could convert '%s' to URI", e, obj); return null; } } } /** * Tries to create a URI from the current port, opacity, scheme, * userInfo, host, path, query and fragment set for this instance, * using the {@link URI} constructor that is appropriate to the opacity. */ protected URI createURI() { try { // fail if there was an error in setting the port if (port > -2) { if (opaque) { // path is used as scheme-specific part return new URI(scheme, path, fragment); } else if (forceRelative) { if (path == null && query == null && fragment == null) { return null; } return new URI(null, null, null, -1, path, toQuery(query), fragment); } else { // only create the URI if we have some values besides a port if (scheme == null && user == null && host == null && path == null && query == null && fragment == null) { return null; } return new URI(scheme, user, host, port, path, toQuery(query), fragment); } } } catch (Exception e) { debug("Could not create URI", e); } return null; } // --------------------------------------------- Template Methods ----------- /** * Returns the configured charset used by the {@link #encode} and * {@link #decode} methods. */ public String getCharacterEncoding() { return this.charset; } /** * Returns true if the query delimiter used by this instance is * using &amp; as the delimiter for query data pairs * or just using &. */ public boolean isXHTML() { return queryDelim.equals(XHTML_QUERY_DELIMITER); } /** * Returns true if {@link #param(Object,Object)} appends values; * false if the method overwrites existing value(s) for the specified key. */ public boolean getAppendParams() { return this.appendParams; } /** * Returns a new instance with the specified value set as its scheme. */ public LinkTool scheme(Object scheme) { LinkTool copy = duplicate(); copy.setScheme(scheme); return copy; } /** * Returns a new instance with the scheme set to "https". */ public LinkTool secure() { return scheme(SECURE_SCHEME); } /** * Returns a new instance with the scheme set to "http". */ public LinkTool insecure() { return scheme(DEFAULT_SCHEME); } /** * Return the scheme value for this instance. */ public String getScheme() { return scheme; } /** * Returns true if this instance's scheme is "https". */ public boolean isSecure() { return SECURE_SCHEME.equalsIgnoreCase(getScheme()); } /** * Returns true if this instance represents an opaque URI. * @see URI */ public boolean isOpaque() { return this.opaque; } /** * Returns a new instance with the specified value * set as its user info. */ public LinkTool user(Object info) { LinkTool copy = duplicate(); copy.setUserInfo(info); return copy; } /** * Returns the {@link URI#getUserInfo()} value for this instance. */ public String getUser() { return this.user; } /** * Returns a new instance with the specified value set as its * host. If no scheme has yet been set, the new instance will * also have its scheme set to the {@link #DEFAULT_SCHEME} (http). */ public LinkTool host(Object host) { LinkTool copy = duplicate(); copy.setHost(host); // if we have host but no scheme if (copy.getHost() != null && !copy.isAbsolute()) { // use default scheme copy.setScheme(DEFAULT_SCHEME); } return copy; } /** * Return the host value for this instance. */ public String getHost() { return this.host; } /** * Returns a new instance with the specified value set * as its port number. If the value cannot be parsed into * an integer, the returned instance will always return * null for {@link #toString} and other * {@link #createURI}-dependent methods to alert the user * to the error. */ public LinkTool port(Object port) { LinkTool copy = duplicate(); copy.setPort(port); return copy; } /** * Returns the port value, if any. */ public Integer getPort() { if (this.port < 0) { return null; } return this.port; } /** * Returns a new instance with the specified value * set as its path. */ public LinkTool path(Object pth) { LinkTool copy = duplicate(); copy.setPath(pth); return copy; } /** * Returns the current path value for this instance. */ public String getPath() { return this.path; } /** * Appends the given value to the end of the current * path value. */ public LinkTool append(Object pth) { LinkTool copy = duplicate(); copy.appendPath(pth); return copy; } /** * Returns the directory stack * in the set {@link #getPath()} value, by just trimming * off all that follows the last "/". */ public String getDirectory() { if (this.path == null || this.opaque) { return null; } int lastSlash = this.path.lastIndexOf('/'); if (lastSlash < 0) { return ""; } return this.path.substring(0, lastSlash + 1); } /** * Returns the last section of the path, * which is all that follows the final "/". */ public String getFile() { if (this.path == null || this.opaque) { return null; } int lastSlash = this.path.lastIndexOf('/'); if (lastSlash < 0) { return this.path; } return this.path.substring(lastSlash + 1, this.path.length()); } /** * Returns the "root" for this URI, if it has one. * This does not stick close to URI dogma and will * try to insert the default scheme if there is none, * and will return null if there is no host or if there * was an error when the port value was last set. It will * return null for any opaque URLs as well, as those have * no host or port. */ public String getRoot() { LinkTool root = root(); if (root == null) { return null; } return root.toString(); } /** * Returns a new LinkTool instance that represents * the "root" of the current one, if it has one. * This essentially calls {@link #absolute()} and * sets the path, query, and fragment to null on * the returned instance. * @see #getRoot() */ public LinkTool root() { if (host == null || opaque || port == -2) { return null; } LinkTool copy = absolute(); copy.setPath(null); copy.setQuery(null); copy.setFragment(null); return copy; } /** * Returns a new LinkTool instance with * the path set to the result of {@link #getDirectory()} * and the query and fragment set to null. */ public LinkTool directory() { LinkTool copy = root(); if (copy == null) { copy = duplicate(); // clear query and fragment, since root() didn't copy.setQuery(null); copy.setFragment(null); } copy.setPath(getDirectory()); return copy; } /** * Returns true if this instance is being forced to * return relative URIs or has a null scheme value. */ public boolean isRelative() { return (this.forceRelative || this.scheme == null); } /** * Returns a copy of this LinkTool instance that has * {@link #setForceRelative} set to true. */ public LinkTool relative() { LinkTool copy = duplicate(); copy.setForceRelative(true); return copy; } /** *

      Returns a copy of the link with the specified directory-relative * URI reference set as the end of the path and {@link #setForceRelative} * set to true. If the specified relative path is null, that is treated * the same as an empty path.

      * * Example:
      * <a href='$link.relative("/login/index.vm")'>Login Page</a>
      * produces something like
      * <a href="/myapp/login/index.vm">Login Page</a>
      * * @param obj A directory-relative URI reference (e.g. file path in current directory) * @return a new instance of LinkTool with the specified changes * @see #relative() */ public LinkTool relative(Object obj) { LinkTool copy = relative(); // prepend relative paths with the current directory String pth; if (obj == null) { pth = getContextPath(); } else { pth = combinePath(getContextPath(), String.valueOf(obj)); } copy.setPath(pth); return copy; } /** * At this level, this only returns the result of {@link #getDirectory}. * It is here as an extension hook for subclasses to change the * "context" for relative links. * @see #relative(Object) * @see #getDirectory */ public String getContextPath() { return getDirectory(); } /** * Returns true if this instance has a scheme value * and is not being forced to create relative URIs. */ public boolean isAbsolute() { return (this.scheme != null && !this.forceRelative); } /** * Returns a copy of this LinkTool instance that has * {@link #setForceRelative} set to false and sets the * scheme to the "http" if no scheme has been set yet. */ public LinkTool absolute() { LinkTool copy = duplicate(); copy.setForceRelative(false); if (copy.getScheme() == null) { copy.setScheme(DEFAULT_SCHEME); } return copy; } /** *

      Returns a copy of the link with the specified URI reference * either used as or converted to an absolute (non-relative) * URI reference. Unless the specified URI contains a query * or anchor, those values will not be overwritten when using * this method.

      * * Example:
      * <a href='$link.absolute("login/index.vm")'>Login Page</a>
      * produces something like
      * <a href="http://myserver.net/myapp/login/index.vm">Login Page</a>;
      * <a href='$link.absolute("/login/index.vm")'>Login Page</a>
      * produces something like
      * <a href="http://myserver.net/login/index.vm">Login Page</a>;
      * and
      * <a href='$link.absolute("http://theirserver.com/index.jsp")'>Their, Inc.</a>
      * produces something like
      * <a href="http://theirserver.net/index.jsp">Their, Inc.</a>
      * * @param obj A root-relative or context-relative path or an absolute URI. * @return a new instance of LinkTool with the specified path or URI * @see #absolute() */ public LinkTool absolute(Object obj) { // assume it's just a path value to go with current scheme/host/port LinkTool copy = absolute(); String pth; if (obj == null) { // just use the current directory path, if any pth = getDirectory(); } else { pth = String.valueOf(obj); if (pth.startsWith(DEFAULT_SCHEME)) { // looks absolute already URI uri = toURI(pth); if (uri == null) { return null; } copy.setScheme(uri.getScheme()); copy.setUserInfo(uri.getUserInfo()); copy.setHost(uri.getHost()); copy.setPort(uri.getPort()); // handle path, query and fragment with care pth = uri.getPath(); if (pth.equals("/") || pth.length() == 0) { pth = null; } copy.setPath(pth); if (uri.getQuery() != null) { copy.setQuery(uri.getQuery()); } if (uri.getFragment() != null) { copy.setFragment(uri.getFragment()); } return copy; } else if (!pth.startsWith("/")) { // paths that don't start with '/' // are considered relative to the current directory pth = combinePath(getDirectory(), pth); } } copy.setPath(pth); return copy; } /** *

      Returns a copy of the link with the given URI reference set. * Few changes are applied to the given URI reference. The URI * reference can be absolute, server-relative, relative and may * contain query parameters. This method will overwrite all previous * settings for scheme, host port, path, query and anchor.

      * * @param uri URI reference to set * @return a new instance of LinkTool */ public LinkTool uri(Object uri) { LinkTool copy = duplicate(); if (copy.setFromURI(uri)) { return copy; } return null; } /** * If the tool is not in "safe mode"--which it is by default-- * this will return the {@link URI} representation of this instance, * if any. * @see SafeConfig#isSafeMode() */ public URI getUri() { if (!isSafeMode()) { return createURI(); } return null; } /** * Returns the full URI of this template without any query data. * e.g. http://myserver.net/myapp/stuff/View.vm * Note! The returned String will not represent any URI reference * or query data set for this LinkTool. A typical application of * this method is with the HTML base tag. For example: * <base href="$link.baseRef"> */ public String getBaseRef() { LinkTool copy = duplicate(); copy.setQuery(null); copy.setFragment(null); return copy.toString(); } /** * Sets the specified value as the current query data, * after normalizing the pair delimiters. This overrides * any existing query. */ public LinkTool query(Object query) { LinkTool copy = duplicate(); copy.setQuery(query); return copy; } /** * Returns the current query as a string, if any. */ public String getQuery() { return toQuery(this.query); } /** *

      Adds a key=value pair to the query data. Whether * this new query pair is appended to the current query * or overwrites any previous pair(s) with the same key * is controlled by the {@link #getAppendParams} value. * The default behavior is to append.

      * * @param key key of new query parameter * @param value value of new query parameter * @return a new instance of LinkTool */ public LinkTool param(Object key, Object value) { LinkTool copy = duplicate(true); copy.setParam(key, value, this.appendParams); return copy; } /** * Appends a new key=value pair to the existing query * data. * * @param key key of new query parameter * @param value value of new query parameter * @return a new instance of LinkTool */ public LinkTool append(Object key, Object value) { LinkTool copy = duplicate(true); copy.setParam(key, value, true); return copy; } /** * Sets a new key=value pair to the existing query * data, overwriting any previous pair(s) that have * the same key. * * @param key key of new query parameter * @param value value of new query parameter * @return a new instance of LinkTool */ public LinkTool set(Object key, Object value) { LinkTool copy = duplicate(true); copy.setParam(key, value, false); return copy; } /** * Returns a new LinkTool instance that has any * value(s) under the specified key removed from the query data. * * @param key key of the query pair(s) to be removed * @return a new instance of LinkTool */ public LinkTool remove(Object key) { LinkTool copy = duplicate(true); copy.removeParam(key); return copy; } /** * This method can do two different things. If you pass in a * boolean, it will create a new LinkTool duplicate and call * {@link #handleParamsBoolean(boolean)} on it. In this class, true * values do nothing (subclasses may have use for them), but false * values will clear out all params in the query for that instance. * If you pass in a query string or a Map of parameters, those * values will be added to the new LinkTool, either overwriting * previous value(s) with those keys or appending to them, * depending on the {@link #getAppendParams} value. * * @param parameters a boolean or new query data (either Map or query string) * @return a new instance of LinkTool */ public LinkTool params(Object parameters) { // don't waste time with null/empty data if (parameters == null) { return this; } if (parameters instanceof Boolean) { Boolean action = ((Boolean)parameters).booleanValue(); LinkTool copy = duplicate(true); copy.handleParamsBoolean(action); return copy; } if (parameters instanceof Map && ((Map)parameters).isEmpty()) { return duplicate(false); } LinkTool copy = duplicate(this.appendParams); copy.setParams(parameters, this.appendParams); return copy; } public Map getParams() { if (this.query == null || this.query.isEmpty()) { return null; } return this.query; } /** *

      Returns a copy of the link with the specified anchor to be * added to the end of the generated hyperlink.

      * * Example:
      * <a href='$link.setAnchor("foo")'>Foo</a>
      * produces something like
      * <a href="#foo">Foo</a>
      * * @param anchor an internal document reference * @return a new instance of LinkTool with the set anchor */ public LinkTool anchor(Object anchor) { LinkTool copy = duplicate(); copy.setFragment(anchor); return copy; } /** * Returns the anchor (internal document reference) set for this link. */ public String getAnchor() { return this.fragment; } public LinkTool getSelf() { // there are no self-params to bother with at this level, return self; } /** * Returns the full URI reference that's been built with this tool, * including the query string and anchor, e.g. * http://myserver.net/myapp/stuff/View.vm?id=42&type=blue#foo. * Typically, it is not necessary to call this method explicitely. * Velocity will call the toString() method automatically to obtain * a representable version of an object. */ public String toString() { URI uri = createURI(); if (uri == null) { return null; } if (query != null) { return decodeQueryPercents(uri.toString()); } return uri.toString(); } /** * This is an ugly (but fast) hack that's needed because URI encodes * things that we don't need encoded while not encoding things * that we do need encoded. So, we have to encode query data * before creating the URI to ensure they are properly encoded, * but then URI encodes all the % from that encoding. Here, * we isolate the query data and manually decode the encoded * %25 in that section back to %, without decoding anything else. */ protected String decodeQueryPercents(String url) { StringBuilder out = new StringBuilder(url.length()); boolean inQuery = false, havePercent = false, haveTwo = false; for (int i=0; i * With the release of Velocity 1.6, this class is largely obsolete since * Velocity 1.6 now allows all List methods to be called on arrays * within templates. *

      *

      * It provides a method to get and set specified elements. * Also provides methods to perform the following actions to Lists and arrays: *

        *
      • Check if it is empty.
      • *
      • Check if it contains a certain element.
      • *
      *

      *

       * Example uses:
       *  $primes                    -> new int[] {2, 3, 5, 7}
       *  $lists.size($primes)        -> 4
       *  $lists.get($primes, 2)      -> 5
       *  $lists.set($primes, 2, 1)   -> (primes[2] becomes 1)
       *  $lists.get($primes, 2)      -> 1
       *  $lists.isEmpty($primes)     -> false
       *  $lists.contains($primes, 7) -> true
       *
       * Example tools.xml config (if you want to use this with VelocityView):
       * <tools>
       *   <toolbox scope="application">
       *     <tool class="org.apache.velocity.tools.generic.ListTool"/>
       *   </toolbox>
       * </tools>
       * 

      * *

      This tool is entirely threadsafe, and has no instance members. * It may be used in any scope (request, session, or application). *

      * * @author Shinobu Kawai * @version $Id: $ * @since VelocityTools 1.2 */ @Deprecated @DefaultKey("lists") public class ListTool { /** * Gets the specified element of a List/array. * It will return null under the following conditions: *
        *
      • list is null.
      • *
      • list is not a List/array.
      • *
      • list doesn't have an indexth value.
      • *
      * @param list the List/array object. * @param index the index of the List/array to get. * @return the specified element of the List/array. */ public Object get(Object list, int index) { if (isArray(list)) { return getFromArray(list, index); } if (!isList(list)) { return null; } try { return ((List) list).get(index); } catch (IndexOutOfBoundsException e) { // The index was wrong. return null; } } /** * Gets the specified element of an array. * @param array the array object. * @param index the index of the array to get. * @return the specified element of the array. */ private Object getFromArray(Object array, int index) { try { return Array.get(array, index); } catch (IndexOutOfBoundsException e) { // The index was wrong. return null; } } /** * Sets the specified element of a List/array. * It will return null under the following conditions: *
        *
      • list is null.
      • *
      • list is not a List/array.
      • *
      • list doesn't have an indexth value.
      • *
      * @param list the List/array object. * @param index the index of the List/array to set. * @param value the element to set. * @return blank if set, null if not set. */ public Object set(Object list, int index, Object value) { if (isArray(list)) { return setToArray(list, index, value); } if (!isList(list)) { return null; } try { ((List) list).set(index, value); return ""; } catch (IndexOutOfBoundsException e) { // The index was wrong. return null; } } /** * Sets the specified element of an array. * @param array the array object. * @param index the index of the array to set. * @param value the element to set. * @return blank if set, null if not set. */ private Object setToArray(Object array, int index, Object value) { try { Array.set(array, index, value); return ""; } catch (IndexOutOfBoundsException e) { // The index was wrong. return null; } } /** * Gets the size of a List/array. * It will return null under the following conditions: *
        *
      • list is null.
      • *
      • list is not a List/array.
      • *
      * @param list the List object. * @return the size of the List. */ public Integer size(Object list) { if (isArray(list)) { // Thanks to Eric Fixler for this refactor. return Integer.valueOf(Array.getLength(list)); } if (!isList(list)) { return null; } return Integer.valueOf(((List) list).size()); } /** * Checks if an object is an array. * @param object the object to check. * @return true if the object is an array. */ public boolean isArray(Object object) { if (object == null) { return false; } return object.getClass().isArray(); } /** * Checks if an object is a List. * @param object the object to check. * @return true if the object is a List. */ public boolean isList(Object object) { return object instanceof List; } /** * Checks if a List/array is empty. * @param list the List/array to check. * @return true if the List/array is empty. */ public Boolean isEmpty(Object list) { Integer size = size(list); if (size == null) { return null; } return Boolean.valueOf(size.intValue() == 0); } /** * Checks if a List/array contains a certain element. * @param list the List/array to check. * @param element the element to check. * @return true if the List/array contains the element. */ public Boolean contains(Object list, Object element) { if (isArray(list)) { return arrayContains(list, element); } if (!isList(list)) { return null; } return Boolean.valueOf(((List) list).contains(element)); } /** * Checks if an array contains a certain element. * @param array the array to check. * @param element the element to check. * @return true if the array contains the element. */ private Boolean arrayContains(Object array, Object element) { int size = size(array).intValue(); for (int index = 0; index < size; ++index) { if (equals(element, getFromArray(array, index))) { return Boolean.TRUE; } } return Boolean.FALSE; } /** * Check if two objects are equal. * @param what an object * @param with another object. * @return true if the two objects are equal. */ private boolean equals(Object what, Object with) { if (what == null) { return with == null; } return what.equals(with); } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/generic/LocaleConfig.java100644 0 0 4163 11030275253 26533 0ustar 0 0 package org.apache.velocity.tools.generic; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.util.Locale; import org.apache.velocity.tools.ToolContext; /** * Implements common logic and constants for tools which allow their * default {@link Locale} to be configured. * * @author Nathan Bubna * @since VelocityTools 2.0 */ public class LocaleConfig extends SafeConfig { /** * The default {@link Locale} to be used when none is specified. */ public static final Locale DEFAULT_LOCALE = Locale.getDefault(); private Locale locale = DEFAULT_LOCALE; /** * Does the actual configuration. This is protected, so * subclasses may share the same ValueParser and call configure * at any time, while preventing templates from doing so when * configure(Map) is locked. */ protected void configure(ValueParser values) { Locale locale = values.getLocale(ToolContext.LOCALE_KEY); if (locale != null) { setLocale(locale); } } /** * This returns the configured default {@link Locale} for this tool. * * @return the default {@link Locale} */ public Locale getLocale() { return this.locale; } /** * Sets the default locale for this instance. */ protected void setLocale(Locale locale) { this.locale = locale; } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/generic/LoopTool.java100644 0 0 101514 11360645210 26013 0ustar 0 0 package org.apache.velocity.tools.generic; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.NoSuchElementException; import java.util.Stack; import org.apache.velocity.tools.ClassUtils; import org.apache.velocity.tools.Scope; import org.apache.velocity.tools.config.DefaultKey; import org.apache.velocity.tools.config.ValidScope; /** *

      * A convenience tool to use with #foreach loops. It wraps a list * with a custom iterator to provide additional controls and feedback * for managing loops. *

      *

      * This tool was originally inspired the now-deprecated IteratorTool, * which provided similar base functionality but was somewhat more difficult * to understand and use. Rather than try to migrate that implementation * via deprecation and new methods, it was simplest to just create an * entirely new tool that simplified the original API and was easy * to augment with useful new features like support for nested * (and nameable) loops, skipping ahead in loops, synchronizing multiple * iterators, getting the iteration count of loops, identifying if a loop is * on its first or last iteration, and so on. *

      *

      * Most functions of this tool will be obsolete with the release of * Velocity 1.7, which will provide $foreach.hasNext, $foreach.isFirst, * $foreach.isLast, $foreach.index and $foreach.count automatically. * However, this will still be useful for the more advanced sync * and skip features. Also, for very complicated nested loops, the * loop naming feature may be easier than doing things like $foreach.parent.parent. *

      *

      * Example of use: *

       *  Template
       *  ---
       *  #set( $list = [1..7] )
       *  #set( $others = [3..10] )
       *  #foreach( $item in $loop.watch($list).sync($others, 'other') )
       *  $item -> $loop.other
       *  #if( $item >= 5 )$loop.stop()#end
       *  #end
       *
       *  Output
       *  ------
       *  1 -> 3
       *  2 -> 4
       *  3 -> 5
       *  4 -> 6
       *  5 -> 7
       *
       * Example tools.xml config (if you want to use this with VelocityView):
       * <tools>
       *   <toolbox scope="request">
       *     <tool class="org.apache.velocity.tools.generic.LoopTool"/>
       *   </toolbox>
       * </tools>
       * 
      *

      * * @author Nathan Bubna * @version $Id: LoopTool.java 590893 2007-11-01 04:40:21Z nbubna $ */ @DefaultKey("loop") @ValidScope(Scope.REQUEST) public class LoopTool { private Stack iterators = new Stack(); private ManagedIterator last; /** *

      Tells the LoopTool to watch the specified Array, Collection, Map, * Iterator, Iterable, Enumeration or POJO with an iterator() method * while the template iterates over the values within it. *

      *

      Under the covers, this is returning an iterable wrapper that * is also pushed onto this tool's stack. That allows this tool to * know which iterator to give later commands (i.e. stop() or skip()). *

      * @param obj an object that Velocity's #foreach directive can iterate over * @return a {@link ManagedIterator} that this tool instance will track */ public ManagedIterator watch(Object obj) { Iterator iterator = getIterator(obj); if (iterator == null) { return null; } ManagedIterator managed = manage(iterator, null); iterators.push(managed); this.last = managed; return managed; } /** * This is just like {@link #watch(Object)} except that it also takes * a name which is given to the {@link ManagedIterator} that is returned. * This allows the user to send stop or skip commands to that specific * iterator even when there are nested iterators within it that are being * watched. If the given name is {@code null}, then this will return * {@code null} even if the object can be watched. Provided names cannot * be {@code null}. * @see #watch(Object) */ public ManagedIterator watch(Object obj, String name) { // don't mess around with null names if (name == null) { return null; } Iterator iterator = getIterator(obj); if (iterator == null) { return null; } ManagedIterator managed = manage(iterator, name); iterators.push(managed); this.last = managed; return managed; } public ManagedIterator sync(Object main, Object synced) { return watch(main).sync(synced); } protected ManagedIterator manage(Iterator iterator, String name) { return new ManagedIterator(name, iterator, this); } /** * This tells the current loop to stop after the current iteration. * This is different from "break" common to most programming languages, * in that it does not immediately cease activity in the current iteration. * Instead, it merely tells the #foreach loop that this is the last time * around. */ public void stop() { // if we have an iterator on the stack if (!iterators.empty()) { // stop the top one, so #foreach doesn't loop again iterators.peek().stop(); } } /** * This is just like {@link #stop()} except that the stop command is issued * only to the loop/iterator with the specified name. * If no such loop is found with that name, then no stop command is issued. * @see #stop() */ public void stop(String name) { // just stop the matching one for (ManagedIterator iterator : iterators) { if (iterator.getName().equals(name)) { iterator.stop(); break; } } } /** * This is just like {@link #stop(String)} except that the stop command is issued * both to the loop/iterator with the specified name and all loops nested within * it. If no such loop is found with that name, then no stop commands are * issued. * @see #stop() * @see #stop(String) */ public void stopTo(String name) { if (!iterators.empty()) { // create a backup stack to put things back as they were Stack backup = new Stack(); // look for the iterator with the specified name boolean found = false; while (!found && !iterators.empty()) { ManagedIterator iterator = iterators.pop(); if (iterator.getName().equals(name)) { found = true; iterator.stop(); } else { // keep a backup of the ones that don't match backup.push(iterator); } } while (!backup.empty()) { // push the nested iterators back ManagedIterator iterator = backup.pop(); iterators.push(iterator); if (found) { iterator.stop(); } } } } /** * This is just like {@link #stop()} except that the stop command is issued * all the loops being watched by this tool. * @see #stop() */ public void stopAll() { // just stop them all for (ManagedIterator iterator : iterators) { iterator.stop(); } } /** * Skips ahead the specified number of iterations (if possible). * Since this is manual skipping (unlike the automatic skipping * provided by the likes of {@link ManagedIterator#exclude(Object)}, any elements * skipped are still considered in the results returned by {@link #getCount()} * and {@link #isFirst()}. */ public void skip(int number) { // if we have an iterator on the stack if (!iterators.empty()) { // tell the top one to skip the specified number skip(number, iterators.peek()); } } /** * This tells the specified loop to skip ahead the specified number of * iterations. * @see #skip(int) */ public void skip(int number, String name) { // just tell the matching one to skip ManagedIterator iterator = findIterator(name); if (iterator != null) { skip(number, iterator); } } // does the actual skipping by manually advancing the ManagedIterator private void skip(int number, ManagedIterator iterator) { for (int i=0; i < number; i++) { if (iterator.hasNext()) { iterator.next(); } else { break; } } } /** * Returns {@code true} if the current loop is on its first iteration. */ public Boolean isFirst() { if (last != null) { return last.isFirst(); } return null; } /** * Returns {@code true} if the loop with the specified name * is on its first iteration. */ public Boolean isFirst(String name) { // just tell the matching one to skip ManagedIterator iterator = findIterator(name); if (iterator != null) { return iterator.isFirst(); } return null; } /** * Returns the result of {@link #isFirst}. Exists to allow $loop.first syntax. */ public Boolean getFirst() { return isFirst(); } /** * Returns {@code true} if the current loop is on its last iteration. */ public Boolean isLast() { if (last != null) { return last.isLast(); } return null; } /** * Returns {@code true} if the loop with the specified name * is on its last iteration. */ public Boolean isLast(String name) { // just tell the matching one to skip ManagedIterator iterator = findIterator(name); if (iterator != null) { return iterator.isLast(); } return null; } /** * Returns the result of {@link #isLast}. Exists to allow $loop.last syntax. */ public Boolean getLast() { return isLast(); } /** *

      This serves two purposes: *

      • Getting the current value of a sync'ed iterator
      • *
      • Abbreviate syntax for properties of outer loops

      *

      First, it searches all the loops being managed for one * with a sync'ed Iterator under the specified name and * returns the current value for that sync'ed iterator, * if any. If there is no sync'ed iterators or none with * that name, then this will check if the specified key * is requesting a "property" of an outer loop (e.g. * {@code $loop.count_foo} or {@code $loop.first_foo}). * This syntax is shorter and clearer than {@code $loop.getCount('foo')}. * If the key starts with a property name and ends with an outer loop * name, then the value of that property for that loop is returned. */ public Object get(String key) { // search all iterators in reverse // (so nested ones take priority) // for one that is responsible for synced for (int i=iterators.size() - 1; i >= 0; i--) { ManagedIterator iterator = iterators.get(i); if (iterator.isSyncedWith(key)) { return iterator.get(key); } } // shortest key would be "last_X" where X is the loop name if (key == null || key.length() < 6) { return null; } if (key.startsWith("last_")) { return isLast(key.substring(5, key.length())); } if (key.startsWith("count_")) { return getCount(key.substring(6, key.length())); } if (key.startsWith("index_")) { return getIndex(key.substring(6, key.length())); } if (key.startsWith("first_")) { return isFirst(key.substring(6, key.length())); } return null; } /** * Asks the loop with the specified name for the current value * of the specified sync'ed iterator, if any. */ public Object get(String name, String synced) { // just ask the matching iterator for the sync'ed value ManagedIterator iterator = findIterator(name); if (iterator != null) { return iterator.get(synced); } return null; } /** * Returns the 0-based index of the item the current loop is handling. * So, if this is the first iteration, then the index will be 0. If * you {@link #skip} ahead in this loop, those skipped iterations will * still be reflected in the index. If iteration has not begun, this * will return {@code null}. */ public Integer getIndex() { Integer count = getCount(); if (count == null || count == 0) { return null; } return count - 1; } /** * Returns the 0-based index of the item the specified loop is handling. * So, if this is the first iteration, then the index will be 0. If * you {@link #skip} ahead in this loop, those skipped iterations will * still be reflected in the index. If iteration has not begun, this * will return {@code null}. */ public Integer getIndex(String name) { Integer count = getCount(name); if (count == null || count == 0) { return null; } return count - 1; } /** * Returns the number of items the current loop has handled. So, if this * is the first iteration, then the count will be 1. If you {@link #skip} * ahead in this loop, those skipped iterations will still be included in * the count. */ public Integer getCount() { if (last != null) { return last.getCount(); } return null; } /** * Returns the number of items the specified loop has handled. So, if this * is the first iteration, then the count will be 1. If you {@link #skip} * ahead in this loop, those skipped iterations will still be included in * the count. */ public Integer getCount(String name) { // just tell the matching one to skip ManagedIterator iterator = findIterator(name); if (iterator != null) { return iterator.getCount(); } return null; } /** * Returns the most recent {@link ManagedIterator} for this instance. * This can be used to access properties like the count, index, * isFirst, isLast, etc which would otherwise fail on the last item * in a loop due to the necessity of popping iterators off the * stack when the last item is retrieved. (See VELTOOLS-124) */ public ManagedIterator getThis() { return last; } /** * Returns the number of loops currently on the stack. * This is only useful for debugging, as iterators are * popped off the stack at the start of their final iteration, * making this frequently "incorrect". */ public int getDepth() { return iterators.size(); } /** * Finds the {@link ManagedIterator} with the specified name * if it is in this instance's iterator stack. */ protected ManagedIterator findIterator(String name) { // look for the one with the specified name for (ManagedIterator iterator : iterators) { if (iterator.getName().equals(name)) { return iterator; } } return null; } /** * Don't let templates call this, but allow subclasses * and ManagedIterator to have access. */ protected ManagedIterator pop() { return iterators.pop(); } /** * Wraps access to {@link ClassUtils#getIterator} is a * nice little try/catch block to prevent exceptions from * escaping into the template. In the case of such problems, * this will return {@code null}. */ protected static Iterator getIterator(Object obj) { if (obj == null) { return null; } try { return ClassUtils.getIterator(obj); } catch (Exception e) { //TODO: pick up a log so we can log this } return null; } /** * Iterator implementation that wraps a standard {@link Iterator} * and allows it to be prematurely stopped, skipped ahead, and * associated with a name for advanced nested loop control. * This also allows a arbitrary {@link ActionCondition}s to be added * in order to have it automatically skip over or stop before * certain elements in the iterator. */ public static class ManagedIterator implements Iterator { private String name; private Iterator iterator; private LoopTool owner; private boolean stopped = false; private Boolean first = null; private int count = 0; private Object next; private List conditions; private Map synced; public ManagedIterator(String name, Iterator iterator, LoopTool owner) { if (name == null) { this.name = "loop"+owner.getDepth(); } else { this.name = name; } this.iterator = iterator; this.owner = owner; } /** * Returns the name of this instance. */ public String getName() { return this.name; } /** * Returns true if either 0 or 1 elements have been returned * by {@link #next()}. */ public boolean isFirst() { if (first == null || first.booleanValue()) { return true; } return false; } /** * Returns true if the last element returned by {@link #next()} * is the last element available in the iterator being managed * which satisfies any/all {@link ActionCondition}s set for this * instance. Otherwise, returns false. */ public boolean isLast() { return !hasNext(false); } /** * Returns the result of {@link #isFirst}. Exists to allow $loop.this.first syntax. */ public boolean getFirst() { return isFirst(); } /** * Returns the result of {@link #isLast}. Exists to allow $loop.this.last syntax. */ public boolean getLast() { return isLast(); } /** * Returns true if there are more elements in the iterator * being managed by this instance which satisfy all the * {@link ActionCondition}s set for this instance. Returns * false if there are no more valid elements available. */ public boolean hasNext() { return hasNext(true); } /** * Returns the result of {@link #hasNext}. Exists to allow $loop.this.hasNext syntax. */ public boolean getHasNext() { return hasNext(false);//no need to pop, #foreach will always call hasNext() } // version that lets isLast check w/o popping this from the stack private boolean hasNext(boolean popWhenDone) { // we don't if we've stopped if (stopped) { return false; } // we're not stopped, so do we have a next cached? if (this.next != null) { return true; } // try to get a next that satisfies the conditions // if there isn't one, return false; if there is, return true return cacheNext(popWhenDone); } // Tries to get a next that satisfies the conditions. // Returns true if there is a next to get. private boolean cacheNext(boolean popWhenDone) { // ok, let's see if we can get a next if (!iterator.hasNext()) { if (popWhenDone) { // this iterator is done, pop it from the owner's stack owner.pop(); // and make sure we don't pop twice stop(); } return false; } // ok, the iterator has more, but do they work for us? this.next = iterator.next(); if (conditions != null) { for (ActionCondition condition : conditions) { if (condition.matches(this.next)) { switch (condition.action) { case EXCLUDE: // recurse on to the next one return cacheNext(popWhenDone); case STOP: stop(); return false; default: throw new IllegalStateException("ActionConditions should never have a null Action"); } } } } // ok, looks like we have a next that met all the conditions shiftSynced(); return true; } private void shiftSynced() { if (synced != null) { for (SyncedIterator parallel : synced.values()) { parallel.shift(); } } } /** * Returns {@code true} if this ManagedIterator has a sync'ed * iterator with the specified name. */ public boolean isSyncedWith(String name) { if (synced == null) { return false; } return synced.containsKey(name); } /** * Returns the parallel value from the specified sync'ed iterator. * If no sync'ed iterator exists with that name or that iterator * is finished, this will return {@code null}. */ public Object get(String name) { if (synced == null) { return null; } SyncedIterator parallel = synced.get(name); if (parallel == null) { return null; } return parallel.get(); } /** * Returns the number of elements returned by {@link #next()} so far. */ public int getCount() { return count; } /** * Returns the 0-based index of the current item. */ public int getIndex() { return count - 1; } /** * Returns the next element that meets the set {@link ActionCondition}s * (if any) in the iterator being managed. If there are none left, then * this will throw a {@link NoSuchElementException}. */ public Object next() { // if no next is cached... if (this.next == null) { // try to cache one if (!cacheNext(true)) { // naughty! calling next() without knowing if there is one! throw new NoSuchElementException("There are no more valid elements in this iterator"); } } // if we haven't returned any elements, first = true if (first == null) { first = Boolean.TRUE; } // or if we've only returned one, first = false else if (first.booleanValue()) { first = Boolean.FALSE; } // update the number of iterations made count++; // get the cached next value Object value = this.next; // clear the cache this.next = null; // return the no-longer-cached value return value; } /** * This operation is unsupported. */ public void remove() { // at this point, i don't see any use for this, so... throw new UnsupportedOperationException("remove is not currently supported"); } /** * Stops this iterator from doing any further iteration. */ public void stop() { this.stopped = true; this.next = null; } /** * Directs this instance to completely exclude * any elements equal to the specified Object. * @return This same {@link ManagedIterator} instance */ public ManagedIterator exclude(Object compare) { return condition(new ActionCondition(Action.EXCLUDE, new Equals(compare))); } /** * Directs this instance to stop iterating immediately prior to * any element equal to the specified Object. * @return This same {@link ManagedIterator} instance */ public ManagedIterator stop(Object compare) { return condition(new ActionCondition(Action.STOP, new Equals(compare))); } /** * Adds a new {@link ActionCondition} for this instance to check * against the elements in the iterator being managed. * @return This same {@link ManagedIterator} instance */ public ManagedIterator condition(ActionCondition condition) { if (condition == null) { return null; } if (conditions == null) { conditions = new ArrayList(); } conditions.add(condition); return this; } /** *

      Adds another iterator to be kept in sync with the one * being managed by this instance. The values of the parallel * iterator can be retrieved from the LoopTool under the * name s"synced" (e.g. $loop.synched or $loop.get('synced')) * and are automatically updated for each iteration by this instance. *

      NOTE: if you are sync'ing multiple iterators * with the same managed iterator, you must use * {@link #sync(Object,String)} or else your the later iterators * will simply replace the earlier ones under the default * 'synced' key.

      * * @return This same {@link ManagedIterator} instance * @see SyncedIterator * @see #get(String) */ public ManagedIterator sync(Object iterable) { return sync(iterable, "synced"); } /** * Adds another iterator to be kept in sync with the one * being managed by this instance. The values of the parallel * iterator can be retrieved from the LoopTool under the * name specified here (e.g. $loop.name or $loop.get('name')) * and are automatically updated for each iteration by this instance. * * @return This same {@link ManagedIterator} instance * @see SyncedIterator * @see #get(String) */ public ManagedIterator sync(Object iterable, String name) { Iterator parallel = LoopTool.getIterator(iterable); if (parallel == null) { return null; } if (synced == null) { synced = new HashMap(); } synced.put(name, new SyncedIterator(parallel)); return this; } @Override public String toString() { return ManagedIterator.class.getSimpleName()+':'+getName(); } } /** * Represents an automatic action taken by a {@link ManagedIterator} * when a {@link Condition} is satisfied by the subsequent element. */ public static enum Action { EXCLUDE, STOP; } /** * Composition class which associates an {@link Action} and {@link Condition} * for a {@link ManagedIterator}. */ public static class ActionCondition { protected Condition condition; protected Action action; public ActionCondition(Action action, Condition condition) { if (condition == null || action == null) { throw new IllegalArgumentException("Condition and Action must both not be null"); } this.condition = condition; this.action = action; } /** * Returns true if the specified value meets the set {@link Condition} */ public boolean matches(Object value) { return condition.test(value); } } /** * Represents a function into which a {@link ManagedIterator} can * pass it's next element to see if an {@link Action} should be taken. */ public static interface Condition { public boolean test(Object value); } /** * Base condition class for conditions (assumption here is that * conditions are all comparative. Not much else makes sense to me * for this context at this point. */ public static abstract class Comparison implements Condition { protected Object compare; public Comparison(Object compare) { if (compare == null) { throw new IllegalArgumentException("Condition must have something to compare to"); } this.compare = compare; } } /** * Simple condition that checks elements in the iterator * for equality to a specified Object. */ public static class Equals extends Comparison { public Equals(Object compare) { super(compare); } public boolean test(Object value) { if (value == null) { return false; } if (compare.equals(value)) { return true; } if (value.getClass().equals(compare.getClass())) { // no point in going on to string comparison // if the classes are the same return false; } // compare them as strings as a last resort return String.valueOf(value).equals(String.valueOf(compare)); } } /** * Simple wrapper to make it easy to keep an arbitray Iterator * in sync with a {@link ManagedIterator}. */ public static class SyncedIterator { private Iterator iterator; private Object current; public SyncedIterator(Iterator iterator) { if (iterator == null) { // do we really care? perhaps we should just keep quiet... throw new NullPointerException("Cannot synchronize a null Iterator"); } this.iterator = iterator; } /** * If the sync'ed iterator has any more values, * this sets the next() value as the current one. * If there are no more values, this sets the current * one to {@code null}. */ public void shift() { if (iterator.hasNext()) { current = iterator.next(); } else { current = null; } } /** * Returns the currently parallel value, if any. */ public Object get() { return current; } } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/generic/MarkupTool.java100644 0 0 31760 11360645210 26326 0ustar 0 0 package org.apache.velocity.tools.generic; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.velocity.tools.config.DefaultKey; import org.apache.velocity.tools.generic.SafeConfig; /** * NOTE: This tools is considered "alpha" quality due to lack of testing * and a generally unpolished API. Feel free to use but expect changes. * Also, this is not automatically provided via the default tools.xml file. * * *

      * A tool to make it easy to generate XML or HTML on the fly. It uses a CSS-type * syntax with a vaguely jQuery-ish API to help you generate the markup you need. *

      *

       * Example uses in a template:
       *   #set( $foospan = $markup.span.id($foo.id).body($foo) )
       *   $markup.tag('table tr.bar td').body("This is $foospan")
       *
       * Output:
       *   
       *     
       *       
       *     
       *   
      This is my first foo.
      * * * Example tools.xml config: * <tools> * <toolbox scope="application"> * <tool class="org.apache.velocity.tools.generic.alpha.MarkupTool"/> * </toolbox> * </tools> *

      * * @author Nathan Bubna * @since VelocityTools 2.0 * @version $Id$ */ @DefaultKey("mark") public class MarkupTool extends SafeConfig { public static final String DEFAULT_TAB = " "; public static final String DEFAULT_DELIMITER = " "; private String tab = DEFAULT_TAB; private String delim = DEFAULT_DELIMITER; public void setTab(String tab) { if (isConfigLocked()) { //TODO: log setTab failure } else { this.tab = tab; } } public String getTab() { return this.tab; } public Tag get(String tag) { return tag(tag); } public Tag tag(String definition) { String[] tags = split(definition); Tag last = null; for (int i=0; i < tags.length; i++) { Tag tag = parse(tags[i]); if (last != null) { last.append(tag); } last = tag; } return last; } protected String[] split(String me) { //TODO: fix escaped delimiters return me.split(delim); } private static enum Mode { NAME, ID, CLASS, ATTR } protected Tag parse(String definition) { StringBuilder store = new StringBuilder(); Tag tag = new Tag(this); Mode mode = Mode.NAME; for (int i=0; i < definition.length(); i++) { char c = definition.charAt(i); if (c == '#') { store = clear(mode, tag, store, true); mode = Mode.ID; } else if (c == '.') { store = clear(mode, tag, store, true); mode = Mode.CLASS; } else if (c == '[') { store = clear(mode, tag, store, true); mode = Mode.ATTR; } else if (c == ']') { store = clear(mode, tag, store, true); mode = Mode.NAME; } else { store.append(c); } } clear(mode, tag, store, false); return tag; } private StringBuilder clear(Mode mode, Tag tag, StringBuilder val, boolean emptyStore) { if (val.length() > 0) { String s = val.toString(); switch (mode) { case NAME: tag.name(s); break; case ID: tag.id(s); break; case CLASS: tag.addClass(s); break; case ATTR: if (s.indexOf('=') > 0) { String[] kv = s.split("="); tag.attr(kv[0], kv[1]); } else { tag.attr(s, null); } break; } if (emptyStore) { return new StringBuilder(); } return val; } else { // already is clean return val; } } public static class Tag { private MarkupTool tool; private Tag parent; private Object name; private Object id; private List classes; private Map attributes; private List children; public Tag(MarkupTool tool) { this.tool = tool; } public Tag name(Object name) { this.name = name; return this; } public Tag id(Object id) { this.id = id; return this; } public Tag addClass(Object c) { if (c == null) { return null; } if (classes == null) { classes = new ArrayList(); } classes.add(c); return this; } public Tag attr(Object k, Object v) { if (k == null) { return null; } if (attributes == null) { attributes = new HashMap(); } attributes.put(k, v); return this; } public Tag body(Object o) { if (children == null) { children = new ArrayList(); } else { children.clear(); } children.add(o); return this; } public Tag append(Object o) { if (children == null) { children = new ArrayList(); } children.add(o); if (o instanceof Tag) { ((Tag)o).parent(this); } return this; } public Tag prepend(Object o) { if (children == null) { children = new ArrayList(); children.add(o); } else { children.add(0, o); } if (o instanceof Tag) { ((Tag)o).parent(this); } return this; } public Tag wrap(String tag) { // make new tag Tag prnt = tool.tag(tag); // give root of new tag our parent prnt.root().parent(parent()); // make new tag our parent parent(prnt); return this; } public Tag orphan() { return parent(null); } public Tag parent(Tag parent) { this.parent = parent; return this; } public Tag parent() { return this.parent; } public Tag root() { if (isOrphan()) { return this; } return this.parent.root(); } public List children() { return children; } public boolean isOrphan() { return (parent == null); } public boolean isEmpty() { return (children == null || children().isEmpty()); } public boolean matches(Tag tag) { if (missed(name, tag.name) || missed(id, tag.id) || missed(classes, tag.classes)) { return false; } //TODO: match attributes return true; } protected boolean missed(Object target, Object arrow) { // no arrow, no miss if (arrow == null) { return false; } // otherwise, the arrow must hit the target return !arrow.equals(target); } protected boolean missed(List targets, List arrows) { // no arrows, no miss if (arrows == null) { return false; } // no targets, always miss if (targets == null) { return true; } for (Object o : arrows) { if (!targets.contains(o)) { return true; } } return false; } /************* rendering methods **************/ protected void render(String indent, StringBuilder s) { if (render_start(indent, s)) { render_body(indent, s); render_end(indent, s); } } protected boolean render_start(String indent, StringBuilder s) { if (indent != null) { s.append(indent); } s.append('<'); render_name(s); render_id(s); render_classes(s); render_attributes(s); if (isEmpty()) { s.append("/>"); return false; } else { s.append('>'); return true; } } protected void render_name(StringBuilder s) { s.append(name == null ? "div" : name); } protected void render_id(StringBuilder s) { if (id != null) { s.append(" id=\"").append(id).append('"'); } } protected void render_classes(StringBuilder s) { if (classes != null) { s.append(" class=\""); for (int i=0; i < classes.size(); i++) { s.append(classes.get(i)); if (i + 1 != classes.size()) { s.append(' '); } } s.append('"'); } } protected void render_attributes(StringBuilder s) { if (attributes != null) { for (Map.Entry entry : attributes.entrySet()) { s.append(' ').append(entry.getKey()).append("=\""); if (entry.getValue() != null) { s.append(entry.getValue()); } s.append('"'); } } } protected void render_body(String indent, StringBuilder s) { String kidIndent = indent + tool.getTab(); for (Object o : children) { if (o instanceof Tag) { ((Tag)o).render(kidIndent, s); } else { s.append(kidIndent); s.append(o); } } } protected void render_end(String indent, StringBuilder s) { if (indent != null) { s.append(indent); } s.append("'); } public String toString() { StringBuilder s = new StringBuilder(); root().render("\n", s); return s.toString(); } } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/generic/MathTool.java100644 0 0 57143 11110347753 25767 0ustar 0 0 package org.apache.velocity.tools.generic; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.util.Arrays; import java.util.Collection; import java.util.Iterator; import org.apache.commons.beanutils.PropertyUtils; import org.apache.velocity.tools.ConversionUtils; import org.apache.velocity.tools.config.DefaultKey; /** *

      Tool for performing math in Velocity.

      * *

      Some things should be noted here:

      *
        *
      • This class does not have methods that take * primitives. This is simply because Velocity * wraps all primitives for us automagically.
      • * *
      • No null pointer, number format, or divide by zero * exceptions are thrown here. This is because such exceptions * thrown in template halt rendering. It should be sufficient * debugging feedback that Velocity will render the reference * literally. (e.g. $math.div(1, 0) renders as '$math.div(1, 0)')
      • *
      *

       * Example tools.xml config:
       * <tools>
       *   <toolbox scope="application">
       *     <tool class="org.apache.velocity.tools.generic.MathTool"/>
       *   </toolbox>
       * </tools>
       * 

      * * @author Nathan Bubna * @author Leon Messerschmidt * @version $Revision: 696463 $ $Date: 2008-09-17 14:39:04 -0700 (Wed, 17 Sep 2008) $ */ @DefaultKey("math") public class MathTool extends FormatConfig { /* Old non-vararg methods (can be removed once we require Velocity 1.6) */ public Number add(Object num1, Object num2) { return add(new Object[] { num1, num2 }); } public Number sub(Object num1, Object num2) { return sub(new Object[] { num1, num2 }); } public Number mul(Object num1, Object num2) { return mul(new Object[] { num1, num2 }); } public Number div(Object num1, Object num2) { return div(new Object[] { num1, num2 }); } public Number max(Object num1, Object num2) { return max(new Object[] { num1, num2 }); } public Number min(Object num1, Object num2) { return min(new Object[] { num1, num2 }); } /** * @param nums the numbers to be added * @return the sum of the numbers or * null if they're invalid * @see #toNumber */ public Number add(Object... nums) { double value = 0; Number[] ns = new Number[nums.length]; for (Object num : nums) { Number n = toNumber(num); if (n == null) { return null; } value += n.doubleValue(); } return matchType(value, ns); } /** * @param nums the numbers to be subtracted * @return the difference of the numbers (subtracted in order) or * null if they're invalid * @see #toNumber */ public Number sub(Object... nums) { double value = 0; Number[] ns = new Number[nums.length]; for (int i=0; inull if they're invalid * @see #toNumber */ public Number mul(Object... nums) { double value = 1; Number[] ns = new Number[nums.length]; for (Object num : nums) { Number n = toNumber(num); if (n == null) { return null; } value *= n.doubleValue(); } return matchType(value, ns); } /** * @param nums the numbers to be divided * @return the quotient of the numbers or * null if they're invalid * or if any denominator equals zero * @see #toNumber */ public Number div(Object... nums) { double value = 0; Number[] ns = new Number[nums.length]; for (int i=0; inull if they're invalid * @see #toNumber */ public Number pow(Object num1, Object num2) { Number n1 = toNumber(num1); Number n2 = toNumber(num2); if (n1 == null || n2 == null) { return null; } double value = Math.pow(n1.doubleValue(), n2.doubleValue()); return matchType(n1, n2, value); } /** * Does integer division on the int values of the specified numbers. * *

      So, $math.idiv('5.1',3) will return '1', * and $math.idiv(6,'3.9') will return '2'.

      * * @param num1 the first number * @param num2 the second number * @return the result of performing integer division * on the operands. * @see #toInteger */ public Integer idiv(Object num1, Object num2) { Number n1 = toNumber(num1); Number n2 = toNumber(num2); if (n1 == null || n2 == null || n2.intValue() == 0) { return null; } int value = n1.intValue() / n2.intValue(); return Integer.valueOf(value); } /** * Does integer modulus on the int values of the specified numbers. * *

      So, $math.mod('5.1',3) will return '2', * and $math.mod(6,'3.9') will return '0'.

      * * @param num1 the first number * @param num2 the second number * @return the result of performing integer modulus * on the operands. * @see #toInteger */ public Integer mod(Object num1, Object num2) { Number n1 = toNumber(num1); Number n2 = toNumber(num2); if (n1 == null || n2 == null || n2.intValue() == 0) { return null; } int value = n1.intValue() % n2.intValue(); return Integer.valueOf(value); } /** * @param nums the numbers to be searched * @return the largest of the numbers or * null if they're invalid * @see #toNumber */ public Number max(Object... nums) { double value = Double.MIN_VALUE; Number[] ns = new Number[nums.length]; for (Object num : nums) { Number n = toNumber(num); if (n == null) { return null; } value = Math.max(value, n.doubleValue()); } return matchType(value, ns); } /** * @param nums the numbers to be searched * @return the smallest of the numbers or * null if they're invalid * @see #toNumber */ public Number min(Object... nums) { double value = Double.MAX_VALUE; Number[] ns = new Number[nums.length]; for (Object num : nums) { Number n = toNumber(num); if (n == null) { return null; } value = Math.min(value, n.doubleValue()); } return matchType(value, ns); } /** * @param num the number * @return the absolute value of the number or * null if it's invalid * @see #toDouble */ public Number abs(Object num) { Number n = toNumber(num); if (n == null) { return null; } double value = Math.abs(n.doubleValue()); return matchType(n, value); } /** * @param num the number * @return the smallest integer that is not * less than the given number */ public Integer ceil(Object num) { Number n = toNumber(num); if (n == null) { return null; } return Integer.valueOf((int)Math.ceil(n.doubleValue())); } /** * @param num the number * @return the integer portion of the number */ public Integer floor(Object num) { Number n = toNumber(num); if (n == null) { return null; } return Integer.valueOf((int)Math.floor(n.doubleValue())); } /** * Rounds a number to the nearest whole Integer * * @param num the number to round * @return the number rounded to the nearest whole Integer * or null if it's invalid * @see java.lang.Math#rint(double) */ public Integer round(Object num) { Number n = toNumber(num); if (n == null) { return null; } return Integer.valueOf((int)Math.rint(n.doubleValue())); } /** * Rounds a number to the specified number of decimal places. * This is particulary useful for simple display formatting. * If you want to round an number to the nearest integer, it * is better to use {@link #round}, as that will return * an {@link Integer} rather than a {@link Double}. * * @param decimals the number of decimal places * @param num the number to round * @return the value rounded to the specified number of * decimal places or null if it's invalid * @see #toNumber */ public Double roundTo(Object decimals, Object num) { Number i = toNumber(decimals); Number d = toNumber(num); if (i == null || d == null) { return null; } //ok, go ahead and do the rounding int places = i.intValue(); double value = d.doubleValue(); int delta = 10; for(int j=1;jnull if it's invalid */ public Integer toInteger(Object num) { Number n = toNumber(num); if (n == null) { return null; } return Integer.valueOf(n.intValue()); } /** * Converts an object with a numeric value into a Double * Valid formats are {@link Number} or a {@link String} * representation of a number * * @param num the number to be converted * @return a {@link Double} representation of the number * or null if it's invalid */ public Double toDouble(Object num) { Number n = toNumber(num); if (n == null) { return null; } return new Double(n.doubleValue()); } /** * Converts an object with a numeric value into a Number * Valid formats are {@link Number} or a {@link String} * representation of a number. Note that this does not * handle localized number formats. Use the {@link NumberTool} * to handle such conversions. * * @param num the number to be converted * @return a {@link Number} representation of the number * or null if it's invalid */ public Number toNumber(Object num) { return ConversionUtils.toNumber(num, getFormat(), getLocale()); } // --------------------------- protected methods ------------------ /** * @see #matchType(double,Number...) */ protected Number matchType(Number in, double out) { return matchType(out, new Number[] { in }); } /** * @see #matchType(double,Number...) */ protected Number matchType(Number in1, Number in2, double out) { return matchType(out, new Number[] { in1, in2 }); } /** * Takes the original argument(s) and returns the resulting value as * an instance of the best matching type (Integer, Long, or Double). * If either an argument or the result is not an integer (i.e. has no * decimal when rendered) the result will be returned as a Double. * If not and the result is < -2147483648 or > 2147483647, then a * Long will be returned. Otherwise, an Integer will be returned. */ protected Number matchType(double out, Number... in) { //NOTE: if we just checked class types, we could miss custom // extensions of java.lang.Number, and if we only checked // the mathematical value, $math.div('3.0', 1) would render // as '3'. To get the expected result, we check what we're // concerned about: the rendered string. // first check if the result is even a whole number boolean isIntegral = (Math.rint(out) == out); if (isIntegral) { for (Number n : in) { if (n == null) { break; } else if (hasFloatingPoint(n.toString())) { isIntegral = false; break; } } } if (!isIntegral) { return new Double(out); } else if (out > Integer.MAX_VALUE || out < Integer.MIN_VALUE) { return Long.valueOf((long)out); } else { return Integer.valueOf((int)out); } } protected boolean hasFloatingPoint(String value) { return value.indexOf('.') >= 0; } @Deprecated protected Number parseNumber(String value) { // check for the floating point if (!hasFloatingPoint(value)) { // check for large numbers long i = Long.valueOf(value).longValue(); if (i > Integer.MAX_VALUE || i < Integer.MIN_VALUE) { return Long.valueOf(i); } else { return Integer.valueOf((int)i); } } else { return new Double(value); } } // ------------------------- Aggregation methods ------------------ /** * Get the sum of the values from a list * * @param collection A collection containing Java beans * @param field A Java Bean field for the objects in collection that * will return a number. * @return The sum of the values in collection. */ public Number getTotal(Collection collection, String field) { if (collection == null || field == null) { return null; } double result = 0; // hold the first number and use it to match return type Number first = null; try { for (Iterator i = collection.iterator(); i.hasNext();) { Object property = PropertyUtils.getProperty(i.next(), field); Number value = toNumber(property); // skip over nulls (i.e. treat them as 0) if (value != null) { if (first == null) { first = value; } result += value.doubleValue(); } } return matchType(first, result); } catch (Exception e) { return null; } } /** * Get the average of the values from a list * * @param collection A collection containing Java beans * @param field A Java Bean field for the objects in collection that * will return a number. * @return The average of the values in collection. */ public Number getAverage(Collection collection, String field) { Number result = getTotal(collection, field); if (result == null) { return null; } double avg = result.doubleValue() / collection.size(); return matchType(result, avg); } /** * Get the sum of the values from a list * * @param array An array containing Java beans * @param field A Java Bean field for the objects in array that * will return a number. * @return The sum of the values in array. */ public Number getTotal(Object[] array, String field) { return getTotal(Arrays.asList(array), field); } /** * Get the sum of the values from a list * * @param array A collection containing Java beans * @param field A Java Bean field for the objects in array that * will return a number. * @return The sum of the values in array. */ public Number getAverage(Object[] array, String field) { return getAverage(Arrays.asList(array), field); } /** * Get the sum of the values * * @param collection A collection containing numeric values * @return The sum of the values in collection. */ public Number getTotal(Collection collection) { if (collection == null) { return null; } double result = 0; // grab the first number and use it to match return type Number first = null; for (Iterator i = collection.iterator(); i.hasNext();) { Number value = toNumber(i.next()); if (value == null) { //FIXME? or should we ignore this and keep adding? return null; } if (first == null) { first = value; } result += value.doubleValue(); } return matchType(first, result); } /** * Get the average of the values * * @param collection A collection containing number values * @return The average of the values in collection. */ public Number getAverage(Collection collection) { Number result = getTotal(collection); if (result == null) { return null; } double avg = result.doubleValue() / collection.size(); return matchType(result, avg); } /** * Get the sum of the values * * @param array An array containing number values * @return The sum of the values in array. */ public Number getTotal(Object... array) { return getTotal(Arrays.asList(array)); } /** * Get the average of the values * * @param array An array containing number values * @return The sum of the values in array. */ public Number getAverage(Object... array) { return getAverage(Arrays.asList(array)); } /** * Get the sum of the values * * @param values The list of double values to add up. * @return The sum of the arrays */ public Number getTotal(double... values) { if (values == null) { return null; } double result = 0; for (int i = 0; i < values.length; i++) { result += values[i]; } return new Double(result); } /** * Get the average of the values in an array of double values * * @param values The list of double values * @return The average of the array of values */ public Number getAverage(double... values) { Number total = getTotal(values); if (total == null) { return null; } return new Double(total.doubleValue() / values.length); } /** * Get the sum of the values * * @param values The list of long values to add up. * @return The sum of the arrays */ public Number getTotal(long... values) { if (values == null) { return null; } long result = 0; for (int i = 0; i < values.length; i++) { result += values[i]; } return Long.valueOf(result); } /** * Get the average of the values in an array of long values * * @param values The list of long values * @return The average of the array of values */ public Number getAverage(long... values) { Number total = getTotal(values); if (total == null) { return null; } double avg = total.doubleValue() / values.length; return matchType(total, avg); } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/generic/NumberTool.java100644 0 0 21705 11030275253 26315 0ustar 0 0 package org.apache.velocity.tools.generic; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.text.NumberFormat; import java.util.Locale; import org.apache.velocity.tools.ConversionUtils; import org.apache.velocity.tools.ToolContext; import org.apache.velocity.tools.config.DefaultKey; /** * Tool for working with {@link Number} in Velocity templates. * It is useful for accessing and * formatting arbitrary {@link Number} objects. Also * the tool can be used to retrieve {@link NumberFormat} instances * or make conversions to and from various number types. *

       * Example uses:
       *  $myNumber                            -> 13.55
       *  $number.format($myNumber)   -> 13.6
       *  $number.currency($myNumber) -> $13.55
       *  $number.integer($myNumber)  -> 13
       *
       * Example tools.xml config (if you want to use this with VelocityView):
       * <tools>
       *   <toolbox scope="application">
       *     <tool class="org.apache.velocity.tools.generic.MathTool"/>
       *   </toolbox>
       * </tools>
       * 

      * *

      This tool is entirely threadsafe, and has no instance members. * It may be used in any scope (request, session, or application). * As such, the methods are highly interconnected, and overriding * key methods provides an easy way to create subclasses that use * a non-default format or locale.

      * * @author Nathan Bubna * @author Mike Kienenberger * @since VelocityTools 1.2 * @version $Id: NumberTool.java 671008 2008-06-24 03:37:33Z nbubna $ */ @DefaultKey("number") public class NumberTool extends FormatConfig { @Deprecated public static final String DEFAULT_FORMAT_KEY = FORMAT_KEY; @Deprecated public static final String DEFAULT_LOCALE_KEY = ToolContext.LOCALE_KEY; // ------------------------- formatting methods --------------------------- /** * Converts the specified object to a number and formats it according to * the pattern or style returned by {@link #getFormat()}. * * @param obj the number object to be formatted * @return the specified number formatted as a string * @see #format(String format, Object obj, Locale locale) */ public String format(Object obj) { return format(getFormat(), obj); } /** * Convenience method equivalent to $number.format("currency", $foo). * @since VelocityTools 1.3 */ public String currency(Object obj) { return format("currency", obj); } /** * Convenience method equivalent to $number.format("integer", $foo). * @since VelocityTools 1.3 */ public String integer(Object obj) { return format("integer", obj); } /** * Convenience method equivalent to $number.format("number", $foo). * @since VelocityTools 1.3 */ public String number(Object obj) { return format("number", obj); } /** * Convenience method equivalent to $number.format("percent", $foo). * @since VelocityTools 1.3 */ public String percent(Object obj) { return format("percent", obj); } /** * Converts the specified object to a number and returns * a formatted string representing that number in the locale * returned by {@link #getLocale()}. * * @param format the formatting instructions * @param obj the number object to be formatted * @return a formatted string for this locale representing the specified * number or null if the parameters are invalid * @see #format(String format, Object obj, Locale locale) */ public String format(String format, Object obj) { return format(format, obj, getLocale()); } /** * Converts the specified object to a number and returns * a formatted string representing that number in the specified * {@link Locale}. * * @param format the custom or standard pattern to be used * @param obj the number object to be formatted * @param locale the {@link Locale} to be used when formatting * @return a formatted string representing the specified number or * null if the parameters are invalid */ public String format(String format, Object obj, Locale locale) { Number number = toNumber(obj); NumberFormat nf = getNumberFormat(format, locale); if (number == null || nf == null) { return null; } return nf.format(number); } // -------------------------- NumberFormat creation methods -------------- /** * Returns a {@link NumberFormat} instance for the specified * format and {@link Locale}. If the format specified is a standard * style pattern, then a number instance * will be returned with the number style set to the * specified style. If it is a custom format, then a customized * {@link NumberFormat} will be returned. * * @param format the custom or standard formatting pattern to be used * @param locale the {@link Locale} to be used * @return an instance of {@link NumberFormat} * @see NumberFormat */ public NumberFormat getNumberFormat(String format, Locale locale) { return ConversionUtils.getNumberFormat(format, locale); } /** * Returns a {@link NumberFormat} instance for the specified * number style and {@link Locale}. * * @param numberStyle the number style (number will be ignored if this is * less than zero or the number style is not recognized) * @param locale the {@link Locale} to be used * @return an instance of {@link NumberFormat} or null * if an instance cannot be constructed with the given * parameters */ @Deprecated protected NumberFormat getNumberFormat(int numberStyle, Locale locale) { return ConversionUtils.getNumberFormat(numberStyle, locale); } /** * Checks a string to see if it matches one of the standard * NumberFormat style patterns: * NUMBER, CURRENCY, PERCENT, INTEGER, or DEFAULT. * if it does it will return the integer constant for that pattern. * if not, it will return -1. * * @see NumberFormat * @param style the string to be checked * @return the int identifying the style pattern */ @Deprecated protected int getStyleAsInt(String style) { return ConversionUtils.getNumberStyleAsInt(style); } // ------------------------- number conversion methods --------------- /** * Converts an object to an instance of {@link Number} using the * format returned by {@link #getFormat()} and the {@link Locale} * returned by {@link #getLocale()} if the object is not already * an instance of Number. * * @param obj the number to convert * @return the object as a {@link Number} or null if no * conversion is possible */ public Number toNumber(Object obj) { return toNumber(getFormat(), obj, getLocale()); } /** * Converts an object to an instance of {@link Number} using the * specified format and the {@link Locale} returned by * {@link #getLocale()} if the object is not already an instance * of Number. * * @param format - the format the number is in * @param obj - the number to convert * @return the object as a {@link Number} or null if no * conversion is possible * @see #toNumber(String format, Object obj, Locale locale) */ public Number toNumber(String format, Object obj) { return toNumber(format, obj, getLocale()); } /** * Converts an object to an instance of {@link Number} using the * specified format and {@link Locale}if the object is not already * an instance of Number. * * @param format - the format the number is in * @param obj - the number to convert * @param locale - the {@link Locale} * @return the object as a {@link Number} or null if no * conversion is possible * @see NumberFormat#parse */ public Number toNumber(String format, Object obj, Locale locale) { return ConversionUtils.toNumber(obj, format, locale); } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/generic/RenderTool.java100644 0 0 30323 11030275253 26300 0ustar 0 0 package org.apache.velocity.tools.generic; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.io.StringWriter; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.Velocity; import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.context.Context; import org.apache.velocity.tools.Scope; import org.apache.velocity.tools.config.DefaultKey; /** * This tool exposes methods to evaluate the given * strings as VTL (Velocity Template Language) * using either a pre-configured context or one you * provide directly. *
       * Example of eval():
       *      Input
       *      -----
       *      #set( $list = [1,2,3] )
       *      #set( $object = '$list' )
       *      #set( $method = 'size()' )
       *      $render.eval("${object}.$method")
       *
       *      Output
       *      ------
       *      3
       *
       * Example of recurse():
       *      Input
       *      -----
       *      #macro( say_hi )hello world!#end
       *      #set( $foo = '#say_hi()' )
       *      #set( $bar = '$foo' )
       *      $render.recurse($bar)
       *
       *      Output
       *      ------
       *      hello world!
       *
       *
       * Toolbox configuration:
       * <tools>
       *   <toolbox scope="request">
       *     <tool class="org.apache.velocity.tools.generic.RenderTool">
       *       <property name="parseDepth" type="number" value="10"/>
       *     </tool>
       *   </toolbox>
       * </tools>
       * 
      * *

      Ok, so these examples are really lame. But, it seems like * someone out there is always asking how to do stuff like this * and we always tell them to write a tool. Now we can just tell * them to use this tool.

      * *

      This tool may be used in any scope, however, the context provided * for the {@link #eval(String)} and {@link #recurse(String)} methods * will only be current if the tool is request scoped. If application or * session scoped, then the context will be the same one set at the time * of the tool's first use. In such a case, each call to eval(String) or * recurse(String) will by default create a new Context that wraps the * configured one to prevent modifications to the configured Context * (concurrent or otherwise). If you wish to risk it and accrete changes * then you can relax the thread-safety by setting the 'forceThreadSafe' * property to 'false'.

      * *

      Of course none of the previous paragraph likely applies if you are * not using the core tool management facilities or if you stick to the * {@link #eval(Context,String)} and {@link #recurse(Context,String)} * methods. :)

      * *

      This tool by default will catch * and log any exceptions thrown during rendering and * instead return null in such cases. It also limits recursion, by default, * to 20 cycles, to prevent infinite loops. Both settings may be configured * to behave otherwise.

      * * @author Nathan Bubna * @version $Revision: 671010 $ $Date: 2008-06-23 20:40:41 -0700 (Mon, 23 Jun 2008) $ */ @DefaultKey("render") public class RenderTool extends SafeConfig { /** * The maximum number of loops allowed when recursing. * @since VelocityTools 1.2 */ public static final int DEFAULT_PARSE_DEPTH = 20; @Deprecated public static final String KEY_PARSE_DEPTH = "parse.depth"; @Deprecated public static final String KEY_CATCH_EXCEPTIONS = "catch.exceptions"; public static final String KEY_FORCE_THREAD_SAFE = "forceThreadSafe"; private static final String LOG_TAG = "RenderTool.eval()"; private VelocityEngine engine = null; private Context context; private int parseDepth = DEFAULT_PARSE_DEPTH; private boolean catchExceptions = true; private boolean forceThreadSafe = true; /** * Looks for deprecated parse depth and catch.exceptions properties, * as well as any 'forceThreadSafe' setting. */ protected void configure(ValueParser parser) { // look for deprecated parse.depth key Integer depth = parser.getInteger(KEY_PARSE_DEPTH); if (depth != null) { setParseDepth(depth); } // look for deprecated catch.exceptions key Boolean catchEm = parser.getBoolean(KEY_CATCH_EXCEPTIONS); if (catchEm != null) { setCatchExceptions(catchEm); } // check if they want thread-safety manually turned off this.forceThreadSafe = parser.getBoolean(KEY_FORCE_THREAD_SAFE, forceThreadSafe); // if we're request-scoped, then there's no point in forcing the issue if (Scope.REQUEST.equals(parser.getString("scope"))) { this.forceThreadSafe = false; } } /** * Allow user to specify a VelocityEngine to be used * in place of the Velocity singleton. */ public void setVelocityEngine(VelocityEngine ve) { this.engine = ve; } /** * Set the maximum number of loops allowed when recursing. * * @since VelocityTools 1.2 */ public void setParseDepth(int depth) { if (!isConfigLocked()) { this.parseDepth = depth; } else if (this.parseDepth != depth) { debug("RenderTool: Attempt was made to alter parse depth while config was locked."); } } /** * Sets the {@link Context} to be used by the {@link #eval(String)} * and {@link #recurse(String)} methods. */ public void setVelocityContext(Context context) { if (!isConfigLocked()) { if (context == null) { throw new NullPointerException("context must not be null"); } this.context = context; } else if (this.context != context) { debug("RenderTool: Attempt was made to set a new context while config was locked."); } } /** * Get the maximum number of loops allowed when recursing. * * @since VelocityTools 1.2 */ public int getParseDepth() { return this.parseDepth; } /** * Sets whether or not the render() and eval() methods should catch * exceptions during their execution or not. * @since VelocityTools 1.3 */ public void setCatchExceptions(boolean catchExceptions) { if (!isConfigLocked()) { this.catchExceptions = catchExceptions; } else if (this.catchExceptions != catchExceptions) { debug("RenderTool: Attempt was made to alter catchE while config was locked."); } } /** * Returns true if this render() and eval() methods will * catch exceptions thrown during rendering. * @since VelocityTools 1.3 */ public boolean getCatchExceptions() { return this.catchExceptions; } /** *

      Evaluates a String containing VTL using the context passed * to the {@link #setVelocityContext} method. If this tool is request * scoped, then this will be the current context and open to modification * by the rendered VTL. If application or session scoped, the context * will be a new wrapper around the configured context to protect it * from modification. * The results of the rendering are returned as a String. By default, * null will be returned when this throws an exception. * This evaluation is not recursive.

      * * @param vtl the code to be evaluated * @return the evaluated code as a String */ public String eval(String vtl) throws Exception { Context ctx = forceThreadSafe ? new VelocityContext(context) : context; return eval(ctx, vtl); } /** *

      Recursively evaluates a String containing VTL using the * current context, and returns the result as a String. It * will continue to re-evaluate the output of the last * evaluation until an evaluation returns the same code * that was fed into it.

      * * @see #eval(String) * @param vtl the code to be evaluated * @return the evaluated code as a String */ public String recurse(String vtl) throws Exception { Context ctx = forceThreadSafe ? new VelocityContext(context) : context; return recurse(ctx, vtl); } /** *

      Evaluates a String containing VTL using the current context, * and returns the result as a String. By default if this fails, then * null will be returned, though this tool can be configured * to let Exceptions pass through. This evaluation is not recursive.

      * * @param ctx the current Context * @param vtl the code to be evaluated * @return the evaluated code as a String */ public String eval(Context ctx, String vtl) throws Exception { if (this.catchExceptions) { try { return internalEval(ctx, vtl); } catch (Exception e) { debug(LOG_TAG+" failed due to "+e, e); return null; } } else { return internalEval(ctx, vtl); } } /* Internal implementation of the eval() method function. */ protected String internalEval(Context ctx, String vtl) throws Exception { if (vtl == null) { return null; } StringWriter sw = new StringWriter(); boolean success; if (engine == null) { success = Velocity.evaluate(ctx, sw, LOG_TAG, vtl); } else { success = engine.evaluate(ctx, sw, LOG_TAG, vtl); } if (success) { return sw.toString(); } /* or would it be preferable to return the original? */ return null; } /** *

      Recursively evaluates a String containing VTL using the * current context, and returns the result as a String. It * will continue to re-evaluate the output of the last * evaluation until an evaluation returns the same code * that was fed into it or the number of recursive loops * exceeds the set parse depth.

      * * @param ctx the current Context * @param vtl the code to be evaluated * @return the evaluated code as a String */ public String recurse(Context ctx, String vtl) throws Exception { return internalRecurse(ctx, vtl, 0); } protected String internalRecurse(Context ctx, String vtl, int count) throws Exception { String result = eval(ctx, vtl); if (result == null || result.equals(vtl)) { return result; } else { // if we haven't reached our parse depth... if (count < parseDepth) { // continue recursing return internalRecurse(ctx, result, count + 1); } else { // abort, log and return what we have so far debug("RenderTool.recurse() exceeded the maximum parse depth of " + parseDepth + "on the following template: "+vtl); return result; } } } // internal convenience methods private void debug(String message) { if (engine == null) { Velocity.getLog().debug(message); } else { engine.getLog().debug(message); } } private void debug(String message, Throwable t) { if (engine == null) { Velocity.getLog().debug(message, t); } else { engine.getLog().debug(message, t); } } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/generic/ResourceTool.java100644 0 0 34512 11115263032 26650 0ustar 0 0 package org.apache.velocity.tools.generic; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.text.MessageFormat; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; import java.util.Locale; import java.util.ResourceBundle; import org.apache.velocity.tools.ConversionUtils; import org.apache.velocity.tools.config.DefaultKey; /** *

      Tool for accessing ResourceBundles and formatting messages therein.

      *

       * Template example(s):
       *   $text.foo                      ->  bar
       *   $text.hello.world              ->  Hello World!
       *   $text.keys                     ->  [foo, hello.world, world]
       *   #set( $otherText = $text.bundle('otherBundle') )
       *   $otherText.foo                 ->  woogie
       *   $otherText.bar                 ->  The args are {0} and {1}.
       *   $otherText.bar.insert(4)       ->  The args are 4 and {1}.
       *   $otherText.bar.insert(4,true)  ->  The args are 4 and true.
       *
       * Toolbox configuration example:
       * <tools>
       *   <toolbox scope="request">
       *     <tool class="org.apache.velocity.tools.generic.ResourceTool"
       *              bundles="resources,com.foo.moreResources"
       *              locale="en_US"/>
       *   </toolbox>
       * </tools>
       * 

      * *

      This comes in very handy when internationalizing templates. * Note that the default resource bundle baseName is "resources", and * the default locale is either: *

        *
      • the result of HttpServletRequest.getLocale() (if used in request scope * of a VelocityView app)
      • *
      • the configured locale for this tool (as shown above)
      • *
      • the configured locale for the toolbox this tool is in
      • *
      • the configured locale for the toolbox factory managing this tool
      • *
      • the system locale, if none of the above
      • *
      . *

      *

      Also, be aware that very few performance considerations have been made * in this initial version. It should do fine, but if you have performance * issues, please report them to dev@velocity.apache.org, so we can make * improvements. *

      * * @author Nathan Bubna * @version $Revision: 722509 $ $Date: 2006-11-27 10:49:37 -0800 (Mon, 27 Nov 2006) $ * @since VelocityTools 1.3 */ @DefaultKey("text") public class ResourceTool extends LocaleConfig { public static final String BUNDLES_KEY = "bundles"; private String[] bundles = new String[] { "resources" }; private boolean deprecationSupportMode = false; protected final void setDefaultBundle(String bundle) { if (bundle == null) { throw new NullPointerException("Default bundle cannot be null"); } this.bundles = new String[] { bundle }; } protected final String getDefaultBundle() { return this.bundles[0]; } @Deprecated protected final void setDefaultLocale(Locale locale) { if (locale == null) { throw new NullPointerException("Default locale cannot be null"); } super.setLocale(locale); } @Deprecated protected final Locale getDefaultLocale() { return super.getLocale(); } @Deprecated public void setDeprecationSupportMode(boolean depMode) { this.deprecationSupportMode = depMode; } protected void configure(ValueParser parser) { String[] bundles = parser.getStrings(BUNDLES_KEY); if (bundles != null) { this.bundles = bundles; } super.configure(parser); } /** * Accepts objects and uses their string value as the key. */ public Key get(Object k) { String key = k == null ? null : String.valueOf(k); return get(key); } public Key get(String key) { return new Key(key, this.bundles, getLocale(), null); } public List getKeys() { return getKeys(null, this.bundles, getLocale()); } public Key bundle(String bundle) { return new Key(null, new String[] { bundle }, getLocale(), null); } public Key locale(Object locale) { return new Key(null, this.bundles, locale, null); } public Key insert(Object[] args) { return new Key(null, this.bundles, getLocale(), args); } public Key insert(List args) { return insert(args.toArray()); } public Key insert(Object arg) { return insert(new Object[] { arg }); } public Key insert(Object arg0, Object arg1) { return insert(new Object[] { arg0, arg1 }); } /** * Retrieves the {@link ResourceBundle} for the specified baseName * and locale, if such exists. If the baseName or locale is null * or if the locale argument cannot be converted to a {@link Locale}, * then this will return null. */ protected ResourceBundle getBundle(String baseName, Object loc) { Locale locale = (loc == null) ? getLocale() : toLocale(loc); if (baseName == null || locale == null) { return null; } return ResourceBundle.getBundle(baseName, locale); } /** * Returns the value for the specified key in the ResourceBundle for * the specified basename and locale. If no such resource can be * found, no errors are thrown and {@code null} is returned. * * @param key the key for the requested resource * @param baseName the base name of the resource bundle to search * @param loc the locale to use */ public Object get(Object key, String baseName, Object loc) { ResourceBundle bundle = getBundle(baseName, loc); if (key == null || bundle == null) { return null; } try { return bundle.getObject(String.valueOf(key)); } catch (Exception e) { return null; } } /** * Retrieve a resource for the specified key from the first of the * specified bundles in which a matching resource is found. * If no resource is found, no exception will be thrown and {@code null} * will be returned. * * @param k the key for the requested resource * @param bundles the resource bundles to search * @param l the locale to use */ public Object get(Object k, String[] bundles, Object l) { String key = k == null ? null : String.valueOf(k); for (int i=0; i < bundles.length; i++) { Object resource = get(key, bundles[i], l); if (resource != null) { return resource; } } return null; } /** * Returns a {@link List} of the key strings in the ResourceBundle * with the specified baseName and locale. If the specified prefix * is not null, then this will skip any keys that do not begin with * that prefix and trim the prefix and any subsequent '.' off of the * remaining ones. If the prefix is null, then no filtering or trimming * will be done. * * @param prefix the prefix for the requested keys * @param bundles the resource bundles to search * @param loc the locale to use */ public List getKeys(String prefix, String baseName, Object loc) { ResourceBundle bundle = getBundle(baseName, loc); if (bundle == null) { return null; } Enumeration keys = bundle.getKeys(); if (keys == null) { return null; } ArrayList list = new ArrayList(); while (keys.hasMoreElements()) { String key = keys.nextElement(); if (prefix == null) { list.add(key); } else if (key.startsWith(prefix)) { key = key.substring(prefix.length(), key.length()); if (key.charAt(0) == '.') { key = key.substring(1, key.length()); } list.add(key); } } return list; } /** * Returns a {@link List} of the key strings in the specified * ResourceBundles. If the specified prefix * is not null, then this will skip any keys that do not begin with * that prefix and trim the prefix and any subsequent '.' off of the * remaining ones. If the prefix is null, then no filtering or trimming * will be done. * * @param prefix the prefix for the requested keys * @param bundles the resource bundles to search * @param loc the locale to use * @see #getKeys(String,String,Object) */ public List getKeys(String prefix, String[] bundles, Object loc) { Locale locale = (loc == null) ? getLocale() : toLocale(loc); if (locale == null || bundles == null || bundles.length == 0) { return null; } List master = new ArrayList(); for (String bundle : bundles) { List sub = getKeys(prefix, bundle, locale); if (sub != null) { master.addAll(sub); } } return master; } private Locale toLocale(Object obj) { if (obj == null) { return null; } if (obj instanceof Locale) { return (Locale)obj; } String s = String.valueOf(obj); return ConversionUtils.toLocale(s); } /** * Renders the specified resource value and arguments as a String. * The resource is treated as a {@link MessageFormat} pattern which * is used for formatting along with any specified argument values. * If deprecationSupportMode is set to true, then this * will return the resource directly when there are no args (as it * did in 1.x versions). */ public String render(Object resource, Object[] args) { String value = String.valueOf(resource); if (deprecationSupportMode && args == null) { return value; } return MessageFormat.format(value, args); } /** * Internal class used to enable an elegant syntax for accessing * resources. */ public final class Key { // these are copied and/or altered when a mutator is called private final String[] bundles; private final String key; private final Object locale; private final Object[] args; // these are not copied when a mutator is called private boolean cached = false; private Object rawValue; public Key(String key, String[] bundles, Object locale, Object[] args) { this.key = key; this.bundles = bundles; this.locale = locale; this.args = args; } // ----- mutators (these return an altered duplicate) --- public Key get(Object k) { return get(String.valueOf(k)); } public Key get(String key) { String newKey; if (this.key == null) { newKey = key; } else { newKey = this.key + '.' + key; } return new Key(newKey, this.bundles, this.locale, this.args); } public Key bundle(String bundle) { String[] newBundles = new String[] { bundle }; return new Key(this.key, newBundles, this.locale, this.args); } public Key locale(Object locale) { return new Key(this.key, this.bundles, locale, this.args); } public Key insert(Object[] args) { Object[] newargs; if (this.args == null) { // we can just use the new ones newargs = args; } else { // create a new array to hold both the new and old args newargs = new Object[this.args.length + args.length]; // copy the old args into the newargs array System.arraycopy(this.args, 0, newargs, 0, this.args.length); // copy the args to be inserted into the newargs array System.arraycopy(args, 0, newargs, this.args.length, args.length); } return new Key(this.key, this.bundles, this.locale, newargs); } public Key insert(List args) { return insert(args.toArray()); } public Key insert(Object arg) { return insert(new Object[] { arg }); } public Key insert(Object arg0, Object arg1) { return insert(new Object[] { arg0, arg1 }); } // --- accessors (these do not return a new Key) --- public boolean getExists() { return (getRaw() != null); } public Object getRaw() { if (!this.cached) { this.rawValue = ResourceTool.this.get(this.key, this.bundles, this.locale); this.cached = true; } return this.rawValue; } public List getKeys() { return ResourceTool.this.getKeys(this.key, this.bundles, this.locale); } public String toString() { if (this.key == null) { return ""; } if (!getExists()) { return "???"+this.key+"???"; } return ResourceTool.this.render(this.rawValue, this.args); } } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/generic/SafeConfig.java100644 0 0 11420 11030275253 26224 0ustar 0 0 package org.apache.velocity.tools.generic; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.util.Map; /** *

      Implements common logic and constants for tools which automatically * locks down the {@code public void configure(Map params)} method after * it is called once. * This keeps application or session scoped tools thread-safe in templates, * which generally have access to the tool after configuration has happened. *

      * It also provides for a separate "safe mode" setting which tells * tools to block any functions that may pose a security threat. This, * of course, is set to {@code true} by default. *

      * Once "locked down", the {@link #configure(Map)} may still be called, * however it will do nothing (unless some subclass is foolish enough to * override it and not check if {@link #isConfigLocked} before changing * configurations. The proper method for subclasses to override is * {@link #configure(ValueParser)} which will only be called by * {@link #configure(Map)} when the {@link #isConfigLocked} is false * (i.e. the first time only). *

      * * @author Nathan Bubna * @since VelocityTools 2.0 */ public class SafeConfig { /** * The key used for specifying whether or not to prevent templates * from reconfiguring this tool. The default is true. */ public static final String LOCK_CONFIG_KEY = "lockConfig"; @Deprecated public static final String OLD_LOCK_CONFIG_KEY = "lock-config"; /** * Many tools interested in locking configure() also have other * things they wish to secure. This key controls that property. * The default value is true, of course. */ public static final String SAFE_MODE_KEY = "safeMode"; private boolean configLocked = false; private boolean safeMode = false; /** * Only allow subclass access to this. */ protected void setLockConfig(boolean lock) { this.configLocked = lock; } protected void setSafeMode(boolean safe) { this.safeMode = safe; } /** * Returns {@code true} if the {@link #configure(Map)} method * has been locked. */ public boolean isConfigLocked() { return this.configLocked; } /** * Returns {@code true} if this tool is in "safe mode". */ public boolean isSafeMode() { return this.safeMode; } /** * If {@link #isConfigLocked} returns {@code true}, then this method * does nothing; otherwise, if {@code false}, this will create a new * {@link ValueParser} from the specified Map of params and call * {@link #configure(ValueParser)} with it. Then this will check * the parameters itself to find out whether or not the configuration * for this tool should be put into safe mode or have its config locked. * The safe mode value should be a boolean under the key * {@link #SAFE_MODE_KEY} and the lock value should be a boolean * under the key {@link #LOCK_CONFIG_KEY}. */ public void configure(Map params) { if (!isConfigLocked()) { ValueParser values = new ValueParser(params); configure(values); setSafeMode(values.getBoolean(SAFE_MODE_KEY, true)); // check under the new key Boolean lock = values.getBoolean(LOCK_CONFIG_KEY); if (lock == null) { // now check the old key (for now) // by default, lock down this method after use // to prevent templates from re-configuring this instance lock = values.getBoolean(OLD_LOCK_CONFIG_KEY, Boolean.TRUE); } setLockConfig(lock.booleanValue()); } } /** * Does the actual configuration. This is protected, so * subclasses may share the same ValueParser and call configure * at any time, while preventing templates from doing so when * configure(Map) is locked. */ protected void configure(ValueParser values) { // base implementation does nothing } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/generic/SortTool.java100644 0 0 24721 10730012250 26005 0ustar 0 0 package org.apache.velocity.tools.generic; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; import org.apache.commons.beanutils.PropertyUtils; import org.apache.velocity.tools.config.DefaultKey; /** * SortTool allows a user to sort a collection (or array, iterator, etc) * on any arbitary set of properties exposed by the objects contained * within the collection. * *

      The sort tool is specifically designed to use within a #foreach * but you may find other uses for it.

      * *

      The sort tool can handle all of the collection types supported by * #foreach and the same constraints apply as well as the following. * Every object in the collection must support the set of properties * selected to sort on. Each property which is to be sorted on must * return one of the follow: *

        *
      • Primitive type: e.g. int, char, long etc
      • *
      • Standard Object: e.g. String, Integer, Long etc
      • *
      • Object which implements the Comparable interface.
      • *
      *

      * *

      During the sort operation all properties are compared by calling * compareTo() with the exception of Strings for which * compareToIgnoreCase() is called.

      * *

      The sort is performed by calling Collections.sort() after * marshalling the collection to sort into an appropriate collection type. * The original collection will not be re-ordered; a new list containing * the sorted elements will always be returned.

      * *

      The tool is used as follows: *

       * Single Property Sort
       * #foreach($obj in $sorter.sort($objects, "name"))
       *   $obj.name Ordinal= $obj.ordinal
       * #end
       * End
       *
       * Multiple Property Sort
       * #foreach($obj in $sorter.sort($objects, ["name", "ordinal"]))
       *   $obj.name, $obj.ordinal
       * #end
       * End
       * 
      * * The sort method takes two parameters a collection and a property name * or an array of property names. The property names and corresponding * methods must conform to java bean standards since commons-beanutils * is used to extract the property values.

      * *

      By default the sort tool sorts ascending, you can override this by * adding a sort type suffix to any property name.

      * *

      The supported suffixes are: *

       * For ascending
       * :asc
       * For descending
       * :desc
       *
       * Example
       * #foreach($obj in $sorter.sort($objects, ["name:asc", "ordinal:desc"]))
       *   $obj.name, $obj.ordinal
       * #end
       * 

      * *

      This will sort first by Name in ascending order and then by Ordinal * in descending order, of course you could have left the :asc off of the * 'Name' property as ascending is always the default.

      * *

       * Example tools.xml config (if you want to use this with VelocityView):
       * <tools>
       *   <toolbox scope="application">
       *     <tool class="org.apache.velocity.tools.generic.SortTool"/>
       *   </toolbox>
       * </tools>
       * 

      * * @author S. Brett Sutton * @author Nathan Bubna * @since VelocityTools 1.2 * @version $Id: SortTool.java 564672 2007-08-10 16:50:04Z nbubna $ */ @DefaultKey("sorter") public class SortTool { public Collection sort(Collection collection) { return sort(collection, (List)null); } public Collection sort(Object[] array) { return sort(array, (List)null); } public Collection sort(Map map) { return sort(map, (List)null); } /** * Sorts the collection on a single property. * * @param object the collection to be sorted. * @param property the property to sort on. */ public Collection sort(Object object, String property) { List properties = new ArrayList(1); properties.add(property); if (object instanceof Collection) { return sort((Collection)object, properties); } else if (object instanceof Object[]) { return sort((Object[])object, properties); } else if (object instanceof Map) { return sort((Map)object, properties); } // the object type is not supported return null; } public Collection sort(Collection collection, List properties) { List list = new ArrayList(collection.size()); list.addAll(collection); return internalSort(list, properties); } public Collection sort(Map map, List properties) { return sort(map.values(), properties); } public Collection sort(Object[] array, List properties) { return internalSort(Arrays.asList(array), properties); } protected Collection internalSort(List list, List properties) { try { if (properties == null) { Collections.sort(list); } else { Collections.sort(list, new PropertiesComparator(properties)); } return list; } catch (Exception e) { //TODO: log this return null; } } /** * Does all of the comparisons */ public static class PropertiesComparator implements Comparator, java.io.Serializable { private static final int TYPE_ASCENDING = 1; private static final int TYPE_DESCENDING = -1; public static final String TYPE_ASCENDING_SHORT = "asc"; public static final String TYPE_DESCENDING_SHORT = "desc"; List properties; int[] sortTypes; public PropertiesComparator(List props) { // copy the list so we can safely drop :asc and :desc suffixes this.properties = new ArrayList(props.size()); this.properties.addAll(props); // determine ascending/descending sortTypes = new int[properties.size()]; for (int i = 0; i < properties.size(); i++) { if (properties.get(i) == null) { throw new IllegalArgumentException("Property " + i + "is null, sort properties may not be null."); } // determine if the property contains a sort type // e.g "Name:asc" means sort by property Name ascending String prop = properties.get(i).toString(); int colonIndex = prop.indexOf(':'); if (colonIndex != -1) { String sortType = prop.substring(colonIndex + 1); properties.set(i, prop.substring(0, colonIndex)); if (TYPE_ASCENDING_SHORT.equalsIgnoreCase(sortType)) { sortTypes[i] = TYPE_ASCENDING; } else if (TYPE_DESCENDING_SHORT.equalsIgnoreCase(sortType)) { sortTypes[i] = TYPE_DESCENDING; } else { //FIXME: log this // invalide property sort type. use default instead. sortTypes[i] = TYPE_ASCENDING; } } else { // default sort type is ascending. sortTypes[i] = TYPE_ASCENDING; } } } public int compare(Object lhs, Object rhs) { for (int i = 0; i < properties.size(); i++) { int comparison = 0; String property = (String)properties.get(i); // properties must be comparable Comparable left = getComparable(lhs, property); Comparable right = getComparable(rhs, property); if (left == null && right != null) { // find out how right feels about left being null comparison = right.compareTo(null); // and reverse that (if it works) comparison *= -1; } else if (left instanceof String) { //TODO: make it optional whether or not case is ignored comparison = ((String)left).compareToIgnoreCase((String)right); } else if (left != null) { comparison = left.compareTo(right); } // return the first difference we find if (comparison != 0) { // multiplied by the sort direction, of course return comparison * sortTypes[i]; } } return 0; } } /** * Safely retrieves the comparable value for the specified property * from the specified object. Subclasses that wish to perform more * advanced, efficient, or just different property retrieval methods * should override this method to do so. */ protected static Comparable getComparable(Object object, String property) { try { return (Comparable)PropertyUtils.getProperty(object, property); } catch (Exception e) { throw new IllegalArgumentException("Could not retrieve comparable value for '" + property + "' from " + object + ": " + e); } } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/generic/ValueParser.java100644 0 0 43640 11361115526 26465 0ustar 0 0 package org.apache.velocity.tools.generic; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.util.Map; import java.util.Locale; import java.util.Set; import java.util.HashMap; import java.util.Collection; import org.apache.velocity.tools.config.DefaultKey; /** *

      Utility class for easy parsing of String values held in a Map.

      * *

      This comes in very handy when parsing parameters.

      * *

      When subkeys are allowed, getValue("foo") will also search for all keys * of the form "foo.bar" and return a ValueParser of the type "bar" -> value for all found values.

      * * TODO: someone doing java configuration ought to be able to put a source Map * in the tool properties, allowing this to be used like other tools * * @author Nathan Bubna * @version $Revision: 933536 $ $Date: 2010-04-13 03:09:52 -0700 (Tue, 13 Apr 2010) $ * @since VelocityTools 1.2 */ @DefaultKey("parser") public class ValueParser extends ConversionTool implements Map { private Map source = null; private boolean allowSubkeys = true; /* default to whatever, should be overridden by deprecationSupportMode default value anyway */ /* when using subkeys, cache at least the presence of any subkey, so that the rendering of templates not using subkeys will only look once for subkeys */ private Boolean hasSubkeys = null; /* whether the wrapped map should be read-only or not */ private boolean readOnly = true; /** * The key used for specifying whether to support subkeys */ public static final String ALLOWSUBKEYS_KEY = "allowSubkeys"; /** * The key used for specifying whether to be read-only */ public static final String READONLY_KEY = "readOnly"; public ValueParser() {} public ValueParser(Map source) { setSource(source); } protected void setSource(Map source) { this.source = source; } protected Map getSource() { return this.source; } /** * Are subkeys allowed ? * @return yes/no */ protected boolean getAllowSubkeys() { return allowSubkeys; } /** * allow or disallow subkeys * @param allow */ protected void setAllowSubkeys(boolean allow) { allowSubkeys = allow; } /** * Is the Map read-only? * @return yes/no */ protected boolean getReadOnly() { return readOnly; } /** * Set or unset read-only behaviour * @param ro */ protected void setReadOnly(boolean ro) { readOnly = ro; } /** * Does the actual configuration. This is protected, so * subclasses may share the same ValueParser and call configure * at any time, while preventing templates from doing so when * configure(Map) is locked. */ @Override protected void configure(ValueParser values) { super.configure(values); // if we're supporting 1.x behavior Boolean depMode = values.getBoolean("deprecationSupportMode"); if (depMode != null && depMode.booleanValue()) { // then don't allow subkeys setAllowSubkeys(false); } // except if explicitely asked for Boolean allow = values.getBoolean(ALLOWSUBKEYS_KEY); if(allow != null) { setAllowSubkeys(allow); } Boolean ro = values.getBoolean(READONLY_KEY); if(ro != null) { setReadOnly(ro); } } // ----------------- public parsing methods -------------------------- /** * Convenience method for checking whether a certain parameter exists. * * @param key the parameter's key * @return true if a parameter exists for the specified * key; otherwise, returns false. */ public boolean exists(String key) { return (getValue(key) != null); } /** * Convenience method for use in Velocity templates. * This allows for easy "dot" access to parameters. * * e.g. $params.foo instead of $params.getString('foo') * * @param key the parameter's key * @return parameter matching the specified key or * null if there is no matching * parameter */ public Object get(String key) { Object value = getValue(key); if (value == null && getSource() != null && getAllowSubkeys()) { value = getSubkey(key); } return value; } /** * Returns the value mapped to the specified key * in the {@link Map} returned by {@link #getSource()}. If there is * no source, then this will always return {@code null}. */ public Object getValue(String key) { if (getSource() == null) { return null; } return getSource().get(key); } /** * @param key the desired parameter's key * @param alternate The alternate value * @return parameter matching the specified key or the * specified alternate Object if there is no matching * parameter */ public Object getValue(String key, Object alternate) { Object value = getValue(key); if (value == null) { return alternate; } return value; } public Object[] getValues(String key) { Object value = getValue(key); if (value == null) { return null; } if (value instanceof String) { return parseStringList((String)value); } if (value instanceof Object[]) { return (Object[])value; } return new Object[] { value }; } /** * @param key the parameter's key * @return parameter matching the specified key or * null if there is no matching * parameter */ public String getString(String key) { return toString(getValue(key)); } /** * @param key the desired parameter's key * @param alternate The alternate value * @return parameter matching the specified key or the * specified alternate String if there is no matching * parameter */ public String getString(String key, String alternate) { String s = getString(key); return (s != null) ? s : alternate; } /** * @param key the desired parameter's key * @return a {@link Boolean} object for the specified key or * null if no matching parameter is found */ public Boolean getBoolean(String key) { return toBoolean(getValue(key)); } /** * @param key the desired parameter's key * @param alternate The alternate boolean value * @return boolean value for the specified key or the * alternate boolean is no value is found */ public boolean getBoolean(String key, boolean alternate) { Boolean bool = getBoolean(key); return (bool != null) ? bool.booleanValue() : alternate; } /** * @param key the desired parameter's key * @param alternate the alternate {@link Boolean} * @return a {@link Boolean} for the specified key or the specified * alternate if no matching parameter is found */ public Boolean getBoolean(String key, Boolean alternate) { Boolean bool = getBoolean(key); return (bool != null) ? bool : alternate; } /** * @param key the desired parameter's key * @return a {@link Integer} for the specified key or * null if no matching parameter is found */ public Integer getInteger(String key) { return toInteger(getValue(key)); } /** * @param key the desired parameter's key * @param alternate The alternate Integer * @return an Integer for the specified key or the specified * alternate if no matching parameter is found */ public Integer getInteger(String key, Integer alternate) { Integer num = getInteger(key); if (num == null) { return alternate; } return num; } /** * @param key the desired parameter's key * @return a {@link Double} for the specified key or * null if no matching parameter is found */ public Double getDouble(String key) { return toDouble(getValue(key)); } /** * @param key the desired parameter's key * @param alternate The alternate Double * @return an Double for the specified key or the specified * alternate if no matching parameter is found */ public Double getDouble(String key, Double alternate) { Double num = getDouble(key); if (num == null) { return alternate; } return num; } /** * @param key the desired parameter's key * @return a {@link Number} for the specified key or * null if no matching parameter is found */ public Number getNumber(String key) { return toNumber(getValue(key)); } /** * @param key the desired parameter's key * @return a {@link Locale} for the specified key or * null if no matching parameter is found */ public Locale getLocale(String key) { return toLocale(getValue(key)); } /** * @param key the desired parameter's key * @param alternate The alternate Number * @return a Number for the specified key or the specified * alternate if no matching parameter is found */ public Number getNumber(String key, Number alternate) { Number n = getNumber(key); return (n != null) ? n : alternate; } /** * @param key the desired parameter's key * @param alternate The alternate int value * @return the int value for the specified key or the specified * alternate value if no matching parameter is found */ public int getInt(String key, int alternate) { Number n = getNumber(key); return (n != null) ? n.intValue() : alternate; } /** * @param key the desired parameter's key * @param alternate The alternate double value * @return the double value for the specified key or the specified * alternate value if no matching parameter is found */ public double getDouble(String key, double alternate) { Number n = getNumber(key); return (n != null) ? n.doubleValue() : alternate; } /** * @param key the desired parameter's key * @param alternate The alternate Locale * @return a Locale for the specified key or the specified * alternate if no matching parameter is found */ public Locale getLocale(String key, Locale alternate) { Locale l = getLocale(key); return (l != null) ? l : alternate; } /** * @param key the key for the desired parameter * @return an array of String objects containing all of the values * associated with the given key, or null * if the no values are associated with the given key */ public String[] getStrings(String key) { return toStrings(getValues(key)); } /** * @param key the key for the desired parameter * @return an array of Boolean objects associated with the given key. */ public Boolean[] getBooleans(String key) { return toBooleans(getValues(key)); } /** * @param key the key for the desired parameter * @return an array of Number objects associated with the given key, * or null if Numbers are not associated with it. */ public Number[] getNumbers(String key) { return toNumbers(getValues(key)); } /** * @param key the key for the desired parameter * @return an array of int values associated with the given key, * or null if numbers are not associated with it. */ public int[] getInts(String key) { return toInts(getValues(key)); } /** * @param key the key for the desired parameter * @return an array of double values associated with the given key, * or null if numbers are not associated with it. */ public double[] getDoubles(String key) { return toDoubles(getValues(key)); } /** * @param key the key for the desired parameter * @return an array of Locale objects associated with the given key, * or null if Locales are not associated with it. */ public Locale[] getLocales(String key) { return toLocales(getValues(key)); } /** * Determines whether there are subkeys available in the source map. */ public boolean hasSubkeys() { if (getSource() == null) { return false; } if (hasSubkeys == null) { for (String key : getSource().keySet()) { int dot = key.indexOf('.'); if (dot > 0 && dot < key.length()) { hasSubkeys = Boolean.TRUE; break; } } if (hasSubkeys == null) { hasSubkeys = Boolean.FALSE; } } return hasSubkeys; } /** * subkey getter that returns a map -> value * for every "subkey.subkey2" found entry * * @param subkey subkey to search for * @return the map of found values */ protected ValueParser getSubkey(String subkey) { if (!hasSubkeys() || subkey == null || subkey.length() == 0) { return null; } Map values = null; subkey = subkey.concat("."); for (Map.Entry entry : getSource().entrySet()) { if (entry.getKey().startsWith(subkey) && entry.getKey().length() > subkey.length()) { if(values == null) { values = new HashMap(); } values.put(entry.getKey().substring(subkey.length()),entry.getValue()); } } if (values == null) { return null; } else { return new ValueParser(values); } } public int size() { return getSource().size(); } public boolean isEmpty() { return getSource().isEmpty(); } public boolean containsKey(Object key) { return getSource().containsKey(key); } public boolean containsValue(Object value) { return getSource().containsValue(value); } public Object get(Object key) { return get(String.valueOf(key)); } public Object put(String key, Object value) { if(readOnly) { throw new UnsupportedOperationException("Cannot put("+key+","+value+"); "+getClass().getName()+" is read-only"); } if(hasSubkeys != null && hasSubkeys.equals(Boolean.FALSE) && key.indexOf('.') != -1) { hasSubkeys = Boolean.TRUE; } return source.put(key,value); // TODO this tool should be made thread-safe (the request-scoped ParameterTool doesn't need it, but other uses could...) } public Object remove(Object key) { if(readOnly) { throw new UnsupportedOperationException("Cannot remove("+key+"); "+getClass().getName()+" is read-only"); } if(hasSubkeys != null && hasSubkeys.equals(Boolean.TRUE) && ((String)key).indexOf('.') != -1) { hasSubkeys = null; } return source.remove(key); } public void putAll(Map m) { if(readOnly) { throw new UnsupportedOperationException("Cannot putAll("+m+"); "+getClass().getName()+" is read-only"); } hasSubkeys = null; source.putAll(m); } public void clear() { if(readOnly) { throw new UnsupportedOperationException("Cannot clear(); "+getClass().getName()+" is read-only"); } hasSubkeys = Boolean.FALSE; source.clear(); } public Set keySet() { return getSource().keySet(); } public Collection values() { return getSource().values(); } public Set> entrySet() { return getSource().entrySet(); } public String toString() { StringBuilder builder = new StringBuilder(); builder.append('{'); boolean empty = true; for(Map.Entry entry:entrySet()) { if(!empty) { builder.append(", "); } empty = false; builder.append(entry.getKey()); builder.append('='); builder.append(String.valueOf(entry.getValue())); } builder.append('}'); return builder.toString(); } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/generic/XmlTool.java100644 0 0 42154 11202122666 25626 0ustar 0 0 package org.apache.velocity.tools.generic; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.io.StringWriter; import java.net.URL; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.dom4j.Attribute; import org.dom4j.Node; import org.dom4j.Element; import org.dom4j.Document; import org.dom4j.DocumentHelper; import org.dom4j.io.XMLWriter; import org.dom4j.io.SAXReader; import org.apache.velocity.runtime.log.Log; import org.apache.velocity.tools.ConversionUtils; import org.apache.velocity.tools.ToolContext; import org.apache.velocity.tools.config.DefaultKey; /** *

      Tool for reading/navigating XML files. This uses dom4j under the * covers to provide complete XPath support for traversing XML files.

      *

      Here's a short example:

       * XML file:
       *   <foo><bar>woogie</bar><a name="test"/></foo>
       *
       * Template:
       *   $foo.bar.text
       *   $foo.find('a')
       *   $foo.a.name
       *
       * Output:
       *   woogie
       *   <a name="test"/>
       *   test
       *
       * Configuration:
       * <tools>
       *   <toolbox scope="application">
       *     <tool class="org.apache.velocity.tools.generic.XmlTool"
       *              key="foo" file="doc.xml"/>
       *   </toolbox>
       * </tools>
       * 

      *

      Note that this tool is included in the default GenericTools configuration * under the key "xml", but unless you set safeMode="false" for it, you will * only be able to parse XML strings. Safe mode is on by default and blocks * access to the {@link #read(Object)} method.

      * * @author Nathan Bubna * @version $Revision: 749731 $ $Date: 2006-11-27 10:49:37 -0800 (Mon, 27 Nov 2006) $ * @since VelocityTools 2.0 */ @DefaultKey("xml") public class XmlTool extends SafeConfig { public static final String FILE_KEY = "file"; protected Log LOG; private List nodes; public XmlTool() {} public XmlTool(Node node) { this(Collections.singletonList(node)); } public XmlTool(List nodes) { this.nodes = nodes; } /** * Looks for the "file" parameter and automatically uses * {@link #read(String)} to parse the file and set the * resulting {@link Document} as the root node for this * instance. */ protected void configure(ValueParser parser) { this.LOG = (Log)parser.getValue(ToolContext.LOG_KEY); String file = parser.getString(FILE_KEY); if (file != null) { try { read(file); } catch (IllegalArgumentException iae) { throw iae; } catch (Exception e) { throw new RuntimeException("Could not read XML file at: "+file, e); } } } /** * Sets a singular root {@link Node} for this instance. */ protected void setRoot(Node node) { if (node instanceof Document) { node = ((Document)node).getRootElement(); } this.nodes = new ArrayList(1); this.nodes.add(node); } private void log(Object o, Throwable t) { if (LOG != null) { LOG.debug("XmlTool - "+o, t); } } /** * Creates a {@link URL} from the string and passes it to {@link #read(URL)}. */ protected void read(String file) throws Exception { URL url = ConversionUtils.toURL(file, this); if (url == null) { throw new IllegalArgumentException("Could not find file, classpath resource or standard URL for '"+file+"'."); } read(url); } /** * Reads, parses and creates a {@link Document} from the * given {@link URL} and uses it as the root {@link Node} for this instance. */ protected void read(URL url) throws Exception { SAXReader reader = new SAXReader(); setRoot(reader.read(url)); } /** * Parses the given XML string and uses the resulting {@link Document} * as the root {@link Node}. */ protected void parse(String xml) throws Exception { setRoot(DocumentHelper.parseText(xml)); } /** * If safe mode is explicitly turned off for this tool, then * this will accept either a {@link URL} or the string representation * thereof. If valid, it will return a new {@link XmlTool} instance * with that document as the root {@link Node}. If reading the URL * or parsing its content fails or if safe mode is on (the default), * this will return {@code null}. */ public XmlTool read(Object o) { if (isSafeMode() || o == null) { return null; } try { XmlTool xml = new XmlTool(); if (o instanceof URL) { xml.read((URL)o); } else { String file = String.valueOf(o); xml.read(file); } return xml; } catch (Exception e) { log("Failed to read XML from : "+o, e); return null; } } /** * This accepts XML in form. If the XML is valid, it will return a * new {@link XmlTool} instance with the resulting XML document * as the root {@link Node}. If parsing the content fails, * this will return {@code null}. */ public XmlTool parse(Object o) { if (o == null) { return null; } String s = String.valueOf(o); try { XmlTool xml = new XmlTool(); xml.parse(s); return xml; } catch (Exception e) { log("Failed to parse XML from : "+o, e); return null; } } /** * This will first attempt to find an attribute with the * specified name and return its value. If no such attribute * exists or its value is {@code null}, this will attempt to convert * the given value to a {@link Number} and get the result of * {@link #get(Number)}. If the number conversion fails, * then this will convert the object to a string. If that string * does not contain a '/', it appends the result of {@link #getPath()} * and a '/' to the front of it. Finally, it delegates the string to the * {@link #find(String)} method and returns the result of that. */ public Object get(Object o) { if (isEmpty() || o == null) { return null; } String attr = attr(o); if (attr != null) { return attr; } Number i = ConversionUtils.toNumber(o); if (i != null) { return get(i); } String s = String.valueOf(o); if (s.length() == 0) { return null; } if (s.indexOf('/') < 0) { s = getPath()+'/'+s; } return find(s); } /** * Asks {@link #get(Object)} for a "name" result. * If none, this will return the result of {@link #getNodeName()}. */ public Object getName() { // give attributes and child elements priority Object name = get("name"); if (name != null) { return name; } return getNodeName(); } /** * Returns the name of the root node. If the internal {@link Node} * list has more than one {@link Node}, it will only return the name * of the first node in the list. */ public String getNodeName() { if (isEmpty()) { return null; } return node().getName(); } /** * Returns the XPath that identifies the first/sole {@link Node} * represented by this instance. */ public String getPath() { if (isEmpty()) { return null; } return node().getPath(); } /** * Returns the value of the specified attribute for the first/sole * {@link Node} in the internal Node list for this instance, if that * Node is an {@link Element}. If it is a non-Element node type or * there is no value for that attribute in this element, then this * will return {@code null}. */ public String attr(Object o) { if (o == null) { return null; } String key = String.valueOf(o); Node node = node(); if (node instanceof Element) { return ((Element)node).attributeValue(key); } return null; } /** * Returns a {@link Map} of all attributes for the first/sole * {@link Node} held internally by this instance. If that Node is * not an {@link Element}, this will return null. */ public Map attributes() { Node node = node(); if (node instanceof Element) { Map attrs = new HashMap(); for (Iterator i = ((Element)node).attributeIterator(); i.hasNext();) { Attribute a = (Attribute)i.next(); attrs.put(a.getName(), a.getValue()); } return attrs; } return null; } /** * Returns {@code true} if there are no {@link Node}s internally held * by this instance. */ public boolean isEmpty() { return (nodes == null || nodes.isEmpty()); } /** * Returns the number of {@link Node}s internally held by this instance. */ public int size() { if (isEmpty()) { return 0; } return nodes.size(); } /** * Returns an {@link Iterator} that returns new {@link XmlTool} * instances for each {@link Node} held internally by this instance. */ public Iterator iterator() { if (isEmpty()) { return null; } return new NodeIterator(nodes.iterator()); } /** * Returns an {@link XmlTool} that wraps only the * first {@link Node} from this instance's internal Node list. */ public XmlTool getFirst() { if (size() == 1) { return this; } return new XmlTool(node()); } /** * Returns an {@link XmlTool} that wraps only the * last {@link Node} from this instance's internal Node list. */ public XmlTool getLast() { if (size() == 1) { return this; } return new XmlTool(nodes.get(size() - 1)); } /** * Returns an {@link XmlTool} that wraps the specified * {@link Node} from this instance's internal Node list. */ public XmlTool get(Number n) { if (n == null) { return null; } int i = n.intValue(); if (i < 0 || i > size() - 1) { return null; } return new XmlTool(nodes.get(i)); } /** * Returns the first/sole {@link Node} from this * instance's internal Node list, if any. */ public Node node() { if (isEmpty()) { return null; } return nodes.get(0); } /** * Converts the specified object to a String and calls * {@link #find(String)} with that. */ public XmlTool find(Object o) { if (o == null || isEmpty()) { return null; } return find(String.valueOf(o)); } /** * Performs an XPath selection on the current set of * {@link Node}s held by this instance and returns a new * {@link XmlTool} instance that wraps those results. * If the specified value is null or this instance does * not currently hold any nodes, then this will return * {@code null}. If the specified value, when converted * to a string, does not contain a '/' character, then * it has "//" prepended to it. This means that a call to * {@code $xml.find("a")} is equivalent to calling * {@code $xml.find("//a")}. The full range of XPath * selectors is supported here. */ public XmlTool find(String xpath) { if (xpath == null || xpath.length() == 0) { return null; } if (xpath.indexOf('/') < 0) { xpath = "//"+xpath; } List found = new ArrayList(); for (Node n : nodes) { found.addAll((List)n.selectNodes(xpath)); } if (found.isEmpty()) { return null; } return new XmlTool(found); } /** * Returns a new {@link XmlTool} instance that wraps * the parent {@link Element} of the first/sole {@link Node} * being wrapped by this instance. */ public XmlTool getParent() { if (isEmpty()) { return null; } Element parent = node().getParent(); if (parent == null) { return null; } return new XmlTool(parent); } /** * Returns a new {@link XmlTool} instance that wraps * the parent {@link Element}s of each of the {@link Node}s * being wrapped by this instance. This does not return * all ancestors, just the immediate parents. */ public XmlTool parents() { if (isEmpty()) { return null; } if (size() == 1) { return getParent(); } List parents = new ArrayList(size()); for (Node n : nodes) { Element parent = n.getParent(); if (parent != null && !parents.contains(parent)) { parents.add(parent); } } if (parents.isEmpty()) { return null; } return new XmlTool(parents); } /** * Returns a new {@link XmlTool} instance that wraps all the * child {@link Element}s of all the current internally held nodes * that are {@link Element}s themselves. */ public XmlTool children() { if (isEmpty()) { return null; } List kids = new ArrayList(); for (Node n : nodes) { if (n instanceof Element) { kids.addAll((List)((Element)n).elements()); } } return new XmlTool(kids); } /** * Returns the concatenated text content of all the internally held * nodes. Obviously, this is most useful when only one node is held. */ public String getText() { if (isEmpty()) { return null; } StringBuilder out = new StringBuilder(); for (Node n : nodes) { String text = n.getText(); if (text != null) { out.append(text); } } String result = out.toString().trim(); if (result.length() > 0) { return result; } return null; } /** * If this instance has no XML {@link Node}s, then this * returns the result of {@code super.toString()}. Otherwise, it * returns the XML (as a string) of all the internally held nodes * that are not {@link Attribute}s. For attributes, only the value * is used. */ public String toString() { if (isEmpty()) { return super.toString(); } StringBuilder out = new StringBuilder(); for (Node n : nodes) { if (n instanceof Attribute) { out.append(n.getText().trim()); } else { out.append(n.asXML()); } } return out.toString(); } /** * Iterator implementation that wraps a Node list iterator * to return new XmlTool instances for each item in the wrapped * iterator.s */ public static class NodeIterator implements Iterator { private Iterator i; public NodeIterator(Iterator i) { this.i = i; } public boolean hasNext() { return i.hasNext(); } public XmlTool next() { return new XmlTool(i.next()); } public void remove() { i.remove(); } } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/generic/log/CommonsLogLogSystem.java100644 0 0 7661 10730012250 30711 0ustar 0 0 package org.apache.velocity.tools.generic.log; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.velocity.runtime.RuntimeServices; import org.apache.velocity.runtime.log.LogSystem; /** * Redirects Velocity's LogSystem messages to commons-logging. * * @author Nathan Bubna * @since VelocityTools 1.1 * @version $Id: CommonsLogLogSystem.java 534721 2007-05-03 05:55:15Z nbubna $ */ /** * Redirects Velocity's LogSystem messages to commons-logging. * *

      Please use CommonsLogLogChute in Velocity Engine 1.6 as this will be * removed in VelocityTools releases subsequent to Velocity 1.6's release, * if not earlier. *

      * *

      To use, first set up commons-logging, then tell Velocity to use * this class for logging by adding the following to your velocity.properties: * * * runtime.log.logsystem.class = org.apache.velocity.tools.generic.log.CommonsLogLogSystem * *

      * *

      You may also set this property to specify what log/name Velocity's * messages should be logged to (example below is default). * * runtime.log.logsystem.commons.logging.name = org.apache.velocity * *

      * * @author Nathan Bubna * @deprecated Use CommonsLogLogChute in Velocity 1.6 instead. * @since VelocityTools 1.1 * @version $Id: CommonsLogLogSystem.java 534721 2007-05-03 05:55:15Z nbubna $ */ @Deprecated public class CommonsLogLogSystem implements LogSystem { /** Property key for specifying the name for the log instance */ public static final String LOGSYSTEM_COMMONS_LOG_NAME = "runtime.log.logsystem.commons.logging.name"; /** Default name for the commons-logging instance */ public static final String DEFAULT_LOG_NAME = "org.apache.velocity"; /** the commons-logging Log instance */ protected Log log; /********** LogSystem methods *************/ public void init(RuntimeServices rs) throws Exception { String name = (String)rs.getProperty(LOGSYSTEM_COMMONS_LOG_NAME); if (name == null) { name = DEFAULT_LOG_NAME; } log = LogFactory.getLog(name); logVelocityMessage(LogSystem.DEBUG_ID, "CommonsLogLogSystem name is '" + name + "'"); } /** * Send a log message from Velocity. */ public void logVelocityMessage(int level, String message) { switch (level) { case LogSystem.WARN_ID: log.warn(message); break; case LogSystem.INFO_ID: log.info(message); break; //NOTE: this is a hack to offer minor support for the // new trace level in Velocity 1.5 case -1: log.trace(message); break; case LogSystem.ERROR_ID: log.error(message); break; case LogSystem.DEBUG_ID: default: log.debug(message); break; } } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/generic/log/LogChuteCommonsLog.java100644 0 0 13362 11115263032 30514 0ustar 0 0 package org.apache.velocity.tools.generic.log; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import org.apache.velocity.app.Velocity; import org.apache.velocity.runtime.log.Log; /** * Redirects commons-logging messages to Velocity's configured LogChute. * *

      To use, specify this class in your commons-logging.properties: *

      
       * org.apache.commons.logging.Log=org.apache.velocity.tools.generic.log.LogChuteCommonsLog
       * 
      *

      * @since VelocityTools 2.0 * @version $Id: LogChuteCommonsLog.java 72115 2004-11-11 07:00:54Z nbubna $ */ public class LogChuteCommonsLog implements org.apache.commons.logging.Log { private static Log target = null; /** * Allow subclasses to statically access the static target. */ protected static Log getVelocityLog() { return target; } /** * Set a VelocityEngine to handle all the log messages. */ public static void setVelocityLog(Log target) { LogChuteCommonsLog.target = target; } // ******************** begin non-static stuff ******************* private String category; public LogChuteCommonsLog() { this(""); } public LogChuteCommonsLog(String category) { this.category = category + ": "; } protected Log getTarget() { if (target == null) { return Velocity.getLog(); } else { return target; } } /*************** Commons Log Interface ****************/ /** * Passes messages to Velocity's LogChute at "DEBUG" level. * (it's the lowest available. sorry.) */ public void trace(Object message) { getTarget().trace(category+message); } /** * Passes messages to Velocity's LogChute at "DEBUG" level. * (it's the lowest available. sorry.) */ public void trace(Object message, Throwable t) { getTarget().trace(category+message, t); } /** * Passes messages to Velocity's LogChute at "DEBUG" level. */ public void debug(Object message) { getTarget().debug(category+message); } /** * Passes messages to Velocity's LogChute at "DEBUG" level. */ public void debug(Object message, Throwable t) { getTarget().debug(category+message, t); } /** * Passes messages to Velocity's LogChute at "INFO" level. */ public void info(Object message) { getTarget().info(category+message); } /** * Passes messages to Velocity's LogChute at "INFO" level. */ public void info(Object message, Throwable t) { getTarget().info(category+message, t); } /** * Passes messages to Velocity's LogChute at "WARN" level. */ public void warn(Object message) { getTarget().warn(category+message); } /** * Passes messages to Velocity's LogChute at "WARN" level. */ public void warn(Object message, Throwable t) { getTarget().warn(category+message, t); } /** * Passes messages to Velocity's LogChute at "ERROR" level. */ public void error(Object message) { getTarget().error(category+message); } /** * Passes messages to Velocity's LogChute at "ERROR" level. */ public void error(Object message, Throwable t) { getTarget().error(category+message, t); } /** * Passes messages to Velocity's LogChute at "ERROR" level. * (it's the highest available. sorry.) */ public void fatal(Object message) { getTarget().error(category+message); } /** * Passes messages to Velocity's LogChute at "ERROR" level. * (it's the highest available. sorry.) */ public void fatal(Object message, Throwable t) { getTarget().error(category+message, t); } /** * Returns true if Velocity's LogChute returns true * for isTraceEnabled(). */ public boolean isTraceEnabled() { return getTarget().isTraceEnabled(); } /** * Returns true if Velocity's LogChute returns true * for isDebugEnabled(). */ public boolean isDebugEnabled() { return getTarget().isDebugEnabled(); } /** * Returns true if Velocity's LogChute returns true * for isInfoEnabled(). */ public boolean isInfoEnabled() { return getTarget().isInfoEnabled(); } /** * Returns true if Velocity's LogChute returns true * for isWarnEnabled(). */ public boolean isWarnEnabled() { return getTarget().isWarnEnabled(); } /** * Returns true if Velocity's LogChute returns true * for isErrorEnabled(). */ public boolean isErrorEnabled() { return getTarget().isErrorEnabled(); } /** * Returns true if isErrorEnabled() returns true, since * Velocity's LogChute doesn't support this level. */ public boolean isFatalEnabled() { return isErrorEnabled(); } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/generic/log/LogSystemCommonsLog.java100644 0 0 3256 10730012250 30705 0ustar 0 0 package org.apache.velocity.tools.generic.log; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import org.apache.velocity.app.VelocityEngine; /** * Redirects commons-logging messages to Velocity's LogSystem. * *

      This is basically an empty subclass of LogChuteCommmonsLog that exists * merely for backwards compatibility with VelocityTools 1.x. Please * use LogChuteCommonsLog directly, as this will likely be removed * in VelocityTools 2.1, if not earlier. *

      * * @deprecated Use LogChuteCommonsLog instead * @version $Id: LogSystemCommonsLog.java 534682 2007-05-03 01:50:54Z nbubna $ */ @Deprecated public class LogSystemCommonsLog extends LogChuteCommonsLog { /** * @deprecated Use LogChuteCommonsLog.setVelocityLog(Log target) instead */ public static void setVelocityEngine(VelocityEngine target) { setVelocityLog(target.getLog()); } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/generic/log/package.html100644 0 0 3573 10730012250 26401 0ustar 0 0 Contains classes created to serve as bridges between Commons-Logging and Velocity's LogSystem. These are useful for trying to direct Velocity's log output to another project's log setup or vice versa. See each class's javadoc for more information.

      Package Specification

      Related Documentation

      velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/generic/package.html100644 0 0 3442 10730012250 25613 0ustar 0 0 Contains a collection of reusable, general-purpose "tools" for Velocity. These tools are independent of the VelocityView classes and may be used in any context.

      Package Specification

      Related Documentation

      velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/generic/times.properties100644 0 0 3061 11115263032 26572 0ustar 0 0 # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. after=later before=earlier equal=same time zero=0 milliseconds current.after=away current.after.day=tomorrow current.before=ago current.before.day=yesterday current.equal=now millisecond=millisecond milliseconds=milliseconds second=second seconds=seconds minute=minute minutes=minutes hour=hour hours=hours day=day days=days week=week weeks=weeks month=month months=months year=year years=years # abbreviations after.abbr=later before.abbr=earlier equal.abbr=same zero.abbr=0 ms current.after.abbr=away current.before.abbr=ago current.equal.abbr=now millisecond.abbr=ms milliseconds.abbr=ms second.abbr=s seconds.abbr=s minute.abbr=min minutes.abbr=min hour.abbr=hr hours.abbr=hrs day.abbr=day days.abbr=days week.abbr=wk weeks.abbr=wks month.abbr=mo months.abbr=mos year.abbr=yr years.abbr=yrs velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/generic/tools.xml100644 0 0 4504 11202122666 25224 0ustar 0 0 velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/struts/ActionMessagesTool.java100644 0 0 21651 10730012242 27713 0ustar 0 0 package org.apache.velocity.tools.struts; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.apache.struts.action.ActionMessage; import org.apache.struts.action.ActionMessages; import org.apache.struts.util.MessageResources; import org.apache.velocity.tools.Scope; import org.apache.velocity.tools.config.DefaultKey; import org.apache.velocity.tools.config.ValidScope; /** *

      * This tool deals with Struts action messages. A few important aspects about action * messages are:

      *
        *
      • Action message strings are looked up in the message resources. Support * for internationalized messages is provided.
      • *
      • Action messages can have up to five replacement parameters.
      • *
      • Actions have an attribute property that describes the category of * message. This allows the view designer to place action messages precisely where they are * wanted. Several methods of this tool provide a parameter * property that allows to select a specific category of messages to operate * on. Without the property parameter, methods operate on all action messages.
      • *
      * *

      See the Struts User's Guide, section * Building View Components * for more information on this topic.

      * *

       * Template example(s):
       *   #if( $messages.exist() )
       *     #foreach( $e in $messages.all )
       *       $e <br>
       *     #end
       *   #end
       *
       * Toolbox configuration:
       * <tools>
       *   <toolbox scope="request">
       *     <tool class="org.apache.velocity.tools.struts.ActionMessagesTool"/>
       *   </toolbox>
       * </tools>
       * 

      * *

      This tool should only be used in the request scope.

      * * @author Gabe Sidler * @author Nathan Bubna * @since VelocityTools 1.1 * @version $Id: ActionMessagesTool.java 601976 2007-12-07 03:50:51Z nbubna $ */ @DefaultKey("messages") @ValidScope(Scope.REQUEST) public class ActionMessagesTool extends MessageResourcesTool { /** A reference to the queued action messages. */ protected ActionMessages actionMsgs; protected ActionMessages getActionMessages() { if (this.actionMsgs == null) { this.actionMsgs = StrutsUtils.getMessages(this.request); } return this.actionMsgs; } /*************************** Public Methods ***********************/ /** *

      Returns true if there are action messages queued, * otherwise false.

      */ public boolean exist() { if (getActionMessages() == null) { return false; } return !actionMsgs.isEmpty(); } /** *

      Returns true if there are action messages queued for the specified * category of messages, otherwise false.

      * * @param property the category of messages to check for */ public boolean exist(String property) { if (getActionMessages() == null) { return false; } return (actionMsgs.size(property) > 0); } /** * Returns the number of action messages queued. */ public int getSize() { if (getActionMessages() == null) { return 0; } return actionMsgs.size(); } /** * Returns the number of action messages queued for a particular property. * * @param property the category of messages to check for */ public int getSize(String property) { if (getActionMessages() == null) { return 0; } return actionMsgs.size(property); } /** *

      * This a convenience method and the equivalent of * $messages.get($messages.globalName). *

      *

      * Returns the set of localized action messages as an * list of strings for all action messages queued of the * global category or null if no messages * are queued for the specified category. If the message * resources don't contain an action message for a * particular message key, the key itself is used. *

      * * @return a list of all messages stored under the "global" property */ public List getGlobal() { return get(getGlobalName()); } /** * Returns the set of localized action messages as an * java.util.List of strings for all actionMsgs * queued or null if no messages are queued. * If the message resources don't contain a message for a * particular key, the key itself is used as the message. */ public List getAll() { return get(null); } /** * Returns a List of all queued action messages using * the specified message resource bundle. * * @param bundle the message resource bundle to use * @see #getAll() */ public List getAll(String bundle) { return get(null, bundle); } /** * Returns the set of localized action messages as an * java.util.List of strings for all actionMsgs * queued of the specified category or null * if no messages are queued for the specified category. If the * message resources don't contain a message for a particular * key, the key itself is used as the message. * * @param property the category of actionMsgs to operate on */ public List get(String property) { return get(property, null); } /** * Returns the set of localized action messages as a * java.util.List of strings for all action messages * queued of the specified category or null * if no action messages are queued for the specified category. If the * message resources don't contain an action message for a particular * action key, the key itself is used as action message. * * @param property the category of actionMsgs to operate on * @param bundle the message resource bundle to use */ public List get(String property, String bundle) { ActionMessages actionMsgs = getActionMessages(); if (actionMsgs == null || actionMsgs.isEmpty()) { return null; } Iterator msgs; if (property == null) { msgs = actionMsgs.get(); } else { msgs = actionMsgs.get(property); } if (!msgs.hasNext()) { return null; } MessageResources res = getResources(bundle); List list = new ArrayList(); while (msgs.hasNext()) { ActionMessage msg = (ActionMessage)msgs.next(); String message = null; if (res != null && msg.isResource()) { message = res.getMessage(getLocale(), msg.getKey(), msg.getValues()); if (message == null) { LOG.warn("ActionMessagesTool : Message for key " + msg.getKey() + " could not be found in message resources."); } } if (message == null) { // if the resource bundle wasn't found or // ActionMessage.isResource() returned false or the key // wasn't found in the resources, then use the key message = msg.getKey(); } list.add(message); } return list; } /** * Returns the default "GLOBAL" category name that can be used for * messages that are not associated with a particular property. */ public String getGlobalName() { return ActionMessages.GLOBAL_MESSAGE; } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/struts/ErrorsTool.java100644 0 0 13114 10730012242 26255 0ustar 0 0 package org.apache.velocity.tools.struts; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import org.apache.struts.action.ActionMessages; import org.apache.velocity.tools.Scope; import org.apache.velocity.tools.config.DefaultKey; import org.apache.velocity.tools.config.ValidScope; /** *

      * This tool deals with Struts error messages. Errors may stem from the validation * of a submitted form or from the processing of a request. If there are errors, * they are made available to the view to render. A few important aspects about errors * are:

      *
        *
      • Error message strings are looked up in the message resources. Support * for internationalized messages is provided.
      • *
      • Error messages can have up to five replacement parameters.
      • *
      • Errors have an attribute property that describes the category of * error. This allows the view designer to place error messages precisely where an * error occurred. For example, errors that apply to the entire page can be rendered * at the top of the page, errors that apply to a specific input field can be rendered * next to this input field. Several methods of this tool provide a parameter * property that allows to select a specific category of errors to operate * on. Without the property parameter, methods operate on all error messages.
      • *
      * *

      See the Struts User's Guide, section * Building View Components * for more information on this topic.

      * *

       * Template example(s):
       *   #if( $errors.exist() )
       *     <div class="errors">
       *     #foreach( $e in $errors.all )
       *       $e <br>
       *     #end
       *     </div>
       *   #end
       *
       * Toolbox configuration:
       * <tools>
       *   <toolbox scope="request">
       *     <tool class="org.apache.velocity.tools.struts.ErrorsTool"/>
       *   </toolbox>
       * </tools>
       * 

      * *

      This tool should only be used in the request scope.

      *

      Since VelocityTools 1.1, ErrorsTool extends ActionMessagesTool.

      * * @author Gabe Sidler * @author Nathan Bubna * @since VelocityTools 1.0 * @version $Id: ErrorsTool.java 601976 2007-12-07 03:50:51Z nbubna $ */ @DefaultKey("errors") @ValidScope(Scope.REQUEST) public class ErrorsTool extends ActionMessagesTool { protected ActionMessages getActionMessages() { if (this.actionMsgs == null) { this.actionMsgs = StrutsUtils.getErrors(this.request); } return this.actionMsgs; } /** *

      Renders the queued error messages as a list. This method expects * the message keys errors.header and errors.footer * in the message resources. The value of the former is rendered before * the list of error messages and the value of the latter is rendered * after the error messages.

      * * @return The formatted error messages. If no error messages are queued, * an empty string is returned. */ public String getMsgs() { return getMsgs(null, null); } /** *

      Renders the queued error messages of a particual category as a list. * This method expects the message keys errors.header and * errors.footer in the message resources. The value of the * former is rendered before the list of error messages and the value of * the latter is rendered after the error messages.

      * * @param property the category of errors to render * * @return The formatted error messages. If no error messages are queued, * an empty string is returned. */ public String getMsgs(String property) { return getMsgs(property, null); } /** *

      Renders the queued error messages of a particual category as a list. * This method expects the message keys errors.header and * errors.footer in the message resources. The value of the * former is rendered before the list of error messages and the value of * the latter is rendered after the error messages.

      * * @param property the category of errors to render * @param bundle the message resource bundle to use * * @return The formatted error messages. If no error messages are queued, * an empty string is returned. * @since VelocityTools 1.1 */ public String getMsgs(String property, String bundle) { return StrutsUtils.errorMarkup(property, bundle, request, request.getSession(false), application); } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/struts/FormTool.java100644 0 0 13255 10730012242 25712 0ustar 0 0 package org.apache.velocity.tools.struts; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import org.apache.struts.action.ActionForm; import org.apache.velocity.tools.view.ViewContext; import org.apache.velocity.tools.Scope; import org.apache.velocity.tools.config.DefaultKey; import org.apache.velocity.tools.config.ValidScope; /** *

      View tool to work with HTML forms in Struts.

      * *

      Struts has support to parse incoming HTTP requests and populate a Java bean * with the submitted request parameters. The same Java bean is used to populate * forms with initial values. Additionally, a hook allows the application developer * to include automatic form validation code.

      * *

      FormTool provides miscellaneous methods to work with forms and form bean in * the context of Struts applications.

      * *

       * Template example(s):
       *  <input type="hidden" name="$form.tokenName" value="$form.token">
       *  <input type="submit" name="$form.cancelName" value="Cancel">
       *
       * Toolbox configuration:
       * <tools>
       *   <toolbox scope="request">
       *     <tool class="org.apache.velocity.tools.struts.FormTool"/>
       *   </toolbox>
       * </tools>
       * 

      * *

      This tool may only be used in the request scope.

      * * @author Gabe Sidler * @since VelocityTools 1.0 * @version $Id: FormTool.java 601976 2007-12-07 03:50:51Z nbubna $ */ @DefaultKey("form") @ValidScope(Scope.REQUEST) public class FormTool { // --------------------------------------------- Properties --------------- /** * A reference to the HtttpServletRequest. */ protected HttpServletRequest request; /** * A reference to the HtttpSession. */ protected HttpSession session; // --------------------------------------------- Constructors ------------- @Deprecated public void init(Object obj) { if (obj instanceof ViewContext) { setRequest(((ViewContext)obj).getRequest()); } } /** * Initializes this tool. * * @param request the current {@link HttpServletRequest} * @throws IllegalArgumentException if the param is not a ViewContext */ public void setRequest(HttpServletRequest request) { if (request == null) { throw new NullPointerException("request should not be null"); } this.request = request; this.session = request.getSession(false); } // --------------------------------------------- View Helpers ------------- /** *

      Returns the form bean associated with this action mapping.

      * *

      This is a convenience method. The form bean is automatically * available in the Velocity context under the name defined in the * Struts configuration.

      * *

      If the form bean is used repeatedly, it is recommended to create a * local variable referencing the bean rather than calling getBean() * multiple times.

      * *
           * Example:
           * #set ($defaults = $form.bean)
           * <input type="text" name="username" value="$defaults.username">
           * 
      * * @return the {@link ActionForm} associated with this request or * null if there is no form bean associated with this mapping */ public ActionForm getBean() { return StrutsUtils.getActionForm(request, session); } /** *

      Returns the form bean name associated with this action mapping.

      * * @return the name of the ActionForm associated with this request or * null if there is no form bean associated with this mapping */ public String getName() { return StrutsUtils.getActionFormName(request, session); } /** *

      Returns the query parameter name under which a cancel button press * must be reported if form validation is to be skipped.

      * *

      This is the value of * org.apache.struts.taglib.html.Constants.CANCEL_PROPERTY

      */ public String getCancelName() { return org.apache.struts.taglib.html.Constants.CANCEL_PROPERTY; } /** * Returns the transaction control token for this session or * null if no token exists. */ public String getToken() { return StrutsUtils.getToken(session); } /** *

      Returns the query parameter name under which a transaction token * must be reported. This is the value of * org.apache.struts.taglib.html.Constants.TOKEN_KEY

      */ public String getTokenName() { return org.apache.struts.taglib.html.Constants.TOKEN_KEY; } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/struts/MessageResourcesTool.java100644 0 0 7330 10730012242 30243 0ustar 0 0 package org.apache.velocity.tools.struts; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.util.Locale; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.ServletContext; import org.apache.struts.util.MessageResources; import org.apache.velocity.runtime.log.Log; import org.apache.velocity.tools.view.ViewContext; /** *

      Abstract view tool that provides access to Struts' message resources.

      * * @author Nathan Bubna * @since VelocityTools 1.1 * @version $Id: MessageResourcesTool.java 595822 2007-11-16 21:07:51Z nbubna $ */ public abstract class MessageResourcesTool { protected Log LOG; protected ServletContext application; protected HttpServletRequest request; private Locale locale; private MessageResources resources; @Deprecated public void init(Object obj) { if (obj instanceof ViewContext) { ViewContext ctx = (ViewContext)obj; this.request = ctx.getRequest(); this.application = ctx.getServletContext(); this.LOG = ctx.getVelocityEngine().getLog(); } } /** * Initializes this tool. * * @param params the Map of configuration parameters * @throws IllegalArgumentException if the param is not a ViewContext */ public void configure(Map params) { this.request = (HttpServletRequest)params.get(ViewContext.REQUEST); this.application = (ServletContext)params.get(ViewContext.SERVLET_CONTEXT_KEY); this.LOG = (Log)params.get("log"); } /** * Retrieves the {@link Locale} for this request. * @since VelocityTools 2.0 */ protected Locale getLocale() { if (this.locale == null) { this.locale = StrutsUtils.getLocale(request, request.getSession(false)); } return this.locale; } /** * Retrieves the specified {@link MessageResources} bundle, or the * application's default MessageResources if no bundle is specified. * @since VelocityTools 1.1 */ protected MessageResources getResources(String bundle) { if (bundle == null) { if (this.resources == null) { this.resources = StrutsUtils.getMessageResources(request, application); if (this.resources == null) { LOG.error("MessageResourcesTool : Message resources are not available."); } } return resources; } MessageResources res = StrutsUtils.getMessageResources(request, application, bundle); if (res == null) { LOG.error("MessageResourcesTool : MessageResources bundle '" + bundle + "' is not available."); } return res; } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/struts/MessageTool.java100644 0 0 34506 10730012242 26375 0ustar 0 0 package org.apache.velocity.tools.struts; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.util.List; import java.util.Locale; import org.apache.struts.util.MessageResources; import org.apache.velocity.tools.Scope; import org.apache.velocity.tools.config.DefaultKey; import org.apache.velocity.tools.config.ValidScope; /** *

      * The MessageTool is used to render internationalized message strings. Source * of the strings are the message resource bundles of the Struts framework. The * following methods operate on these message resources. *

      * *

       * Template example(s):
       *   #if( $text.greeting.exists )
       *     $text.greeting
       *   #end
       *
       * Toolbox configuration:
       * <tools>
       *   <toolbox scope="request">
       *     <tool class="org.apache.velocity.tools.struts.MessageTool"/>
       *   </toolbox>
       * </tools>
       * 

      * *

      This tool should only be used in the request scope.

      * * @author Gabe Sidler * @since VelocityTools 1.0 * @version $Id: MessageTool.java 601976 2007-12-07 03:50:51Z nbubna $ */ @DefaultKey("text") @ValidScope(Scope.REQUEST) public class MessageTool extends MessageResourcesTool { /** * Looks up and returns the localized message for the specified key. * The user's locale is consulted to determine the language of the * message. * *

      Example use: $text.forms.profile.title

      * * @param key message key */ public TextKey get(String key) { return new TextKey(key, null, null, getLocale()); } /** * Looks up and returns the localized message for the specified key. * The user's locale is consulted to determine the language of the * message. * * @param key message key * @param bundle The bundle name to look for. * * @return the localized message for the specified key or * null if no such message exists * @since VelocityTools 1.1 */ public String get(String key, String bundle) { return get(key, bundle, (Object[])null); } /** * Looks up and returns the localized message for the specified key. * Replacement parameters passed with args are * inserted into the message. The user's locale is consulted to * determine the language of the message. * * @param key message key * @param args replacement parameters for this message * * @return the localized message for the specified key or * null if no such message exists */ public String get(String key, Object args[]) { return get(key, null, args); } /** * Looks up and returns the localized message for the specified key. * Replacement parameters passed with args are * inserted into the message. The user's locale is consulted to * determine the language of the message. * * @param key message key * @param bundle The bundle name to look for. * @param args replacement parameters for this message * @since VelocityTools 1.1 * @return the localized message for the specified key or * null if no such message exists */ public String get(String key, String bundle, Object args[]) { return this.get(key, bundle, args, getLocale()); } /** * Looks up and returns the localized message for the specified key. * Replacement parameters passed with args are * inserted into the message. * * @param key message key * @param bundle The bundle name to look for. * @param args replacement parameters for this message * @param locale The locale to use for this message. * * @return the localized message for the specified key or * null if no such message exists * @since VelocityTools 1.4 */ public String get(String key, String bundle, Object[] args, Locale locale) { MessageResources res = getResources(bundle); if (res == null) { return null; } // return the requested message if (args == null) { return res.getMessage(locale, key); } else { return res.getMessage(locale, key, args); } } /** * Same as {@link #get(String key, Object[] args)}, but takes a * java.util.List instead of an array. This is more * Velocity friendly. * * @param key message key * @param args replacement parameters for this message * * @return the localized message for the specified key or * null if no such message exists */ public String get(String key, List args) { return get(key, null, args); } /** * Same as {@link #get(String key, Object[] args)}, but takes a * java.util.List instead of an array. This is more * Velocity friendly. * * @param key message key * @param bundle The bundle name to look for. * @param args replacement parameters for this message * @since VelocityTools 1.1 * @return the localized message for the specified key or * null if no such message exists */ public String get(String key, String bundle, List args) { return get(key, bundle, args.toArray()); } /** * Looks up and returns the localized message for the specified key. * Replacement parameters passed with args are * inserted into the message. * * @param key message key * @param bundle The bundle name to look for. * @param args replacement parameters for this message * @param locale The locale to use for this message. * * @since VelocityTools 1.4 * @return the localized message for the specified key or * null if no such message exists */ public String get(String key, String bundle, List args, Locale locale) { return get(key, bundle, args.toArray(), locale); } /** * Checks if a message string for a specified message key exists * for the user's locale. * * @param key message key * * @return true if a message strings exists, * false otherwise */ public boolean exists(String key) { return exists(key, null); } /** * Checks if a message string for a specified message key exists * for the user's locale. * * @param key message key * @param bundle The bundle name to look for. * @since VelocityTools 1.1 * @return true if a message strings exists, * false otherwise */ public boolean exists(String key, String bundle) { MessageResources res = getResources(bundle); if (res == null) { return false; } // Return the requested message presence indicator return res.isPresent(getLocale(), key); } /** * Helper class to simplify tool usage when retrieving * no-arg messages from the default bundle that have periods * in their key. * *

      So instead of $text.get("forms.profile.title"),1 * you can just type $text.forms.profile.title. Also, * this lets you do things like: *

           *   #if( $text.forms.profile.exists )
           *      #set( $profiletext = $text.forms.profile )
           *      <h1>$profiletext.title</h1>
           *      <h3>$profiletext.subtitle</h3>
           *   #end
           * 
      *

      * * @since VelocityTools 1.2 */ public class TextKey { private final String key; private final String bundle; private final Object[] args; private final Locale locale; /** * @since VelocityTools 1.4 */ public TextKey(String key, String bundle, Object[] args, Locale locale) { this.key = key; this.bundle = bundle; this.args = args; this.locale = locale; } /** * Appends a period and the new key to the current * key and returns a new TextKey instance with the * combined result as its key. */ public TextKey get(String appendme) { StringBuilder sb = new StringBuilder(this.key); sb.append('.'); sb.append(appendme); return new TextKey(sb.toString(), this.bundle, this.args, this.locale); } /** * Returns a new TextKey with the specified resource bundle set. * @since VelocityTools 1.3 */ public TextKey bundle(String setme) { return new TextKey(this.key, setme, this.args, this.locale); } /** * Returns a new TextKey with the specified resource bundle set. * @since VelocityTools 1.4 */ public TextKey locale(Locale setme) { return new TextKey(this.key, this.bundle, this.args, setme); } /** * Returns a new TextKey with the specified argument * to be inserted into the text output. If arguments already * exist for this TextKey, the new arguments will be appended * to the old ones in the new TextKey that is returned. * * @since VelocityTools 1.3 */ public TextKey insert(Object addme) { return insert(new Object[] { addme }); } /** * Returns a new TextKey with the specified arguments * to be inserted into the text output. If arguments already * exist for this TextKey, the new arguments will be appended * to the old ones in the new TextKey that is returned. * * @since VelocityTools 1.3 */ public TextKey insert(Object addme, Object metoo) { return insert(new Object[] { addme, metoo }); } /** * Returns a new TextKey with the specified arguments * to be inserted into the text output. If arguments already * exist for this TextKey, the new arguments will be appended * to the old ones in the new TextKey that is returned. * * @since VelocityTools 1.3 */ public TextKey insert(Object addme, Object metoo, Object methree) { return insert(new Object[] { addme, metoo, methree }); } /** * Returns a new TextKey with the specified List of arguments * to be inserted into the text output. If arguments already * exist for this TextKey, the new arguments will be appended * to the old ones in the new TextKey that is returned. * * @since VelocityTools 1.3 */ public TextKey insert(List addme) { // convert the list to an array Object[] newargs = ((List)addme).toArray(); return insert(newargs); } /** * Returns a new TextKey with the specified array of arguments * to be inserted into the text output. If arguments already * exist for this TextKey, the new arguments will be appended * to the old ones in the new TextKey that is returned. * * @since VelocityTools 1.3 */ public TextKey insert(Object[] addme) { Object[] newargs; if (this.args == null) { // we can just use the ones we're adding newargs = addme; } else { // create the new array to hold both the new and old ones newargs = new Object[this.args.length + addme.length]; // copy the old args into the newargs array System.arraycopy(this.args, 0, newargs, 0, this.args.length); // copy the args to be inserted into the newargs array System.arraycopy(addme, 0, newargs, this.args.length, addme.length); } // return an new TextKey return new TextKey(this.key, this.bundle, newargs, this.locale); } /** * This will return a new TextKey that has no arguments to * be inserted into the text output. * * @since VelocityTools 1.3 */ public TextKey clearArgs() { return new TextKey(this.key, this.bundle, null, this.locale); } /** * Convenience method to allow $text.key.exists syntax. * @since VelocityTools 1.3 */ public boolean getExists() { return exists(); } /** * Checks for the existence of the key that we've built up. * @since VelocityTools 1.3 */ public boolean exists() { return MessageTool.this.exists(key, bundle); } /** * Renders the text output according to the collected key value, * bundle, and arguments. */ public String toString() { return MessageTool.this.get(key, bundle, args, locale); } } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/struts/SecureLinkTool.java100644 0 0 35457 11110347747 27101 0ustar 0 0 package org.apache.velocity.tools.struts; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.util.Iterator; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import org.apache.struts.action.SecurePlugInInterface; import org.apache.struts.config.ModuleConfig; import org.apache.struts.config.SecureActionConfig; import org.apache.velocity.tools.generic.ValueParser; import org.apache.velocity.tools.view.LinkTool; import org.apache.velocity.tools.view.ViewContext; /** * Tool to be able to use Struts SSL Extensions with Velocity. *

      It has the same interface as StrutsLinkTool and can function as a * substitute if Struts 1.x and SSL Ext are installed.

      * *

      The SecureLinkTool extends the standard * {@link LinkTool} and has the exact same interface as * {@link StrutsLinkTool} and the same function. It should * substitute the {@link StrutsLinkTool} in the toolbox if * SSL Ext is installed. * It's functionality is a subset of the functionality provided by the * sslext tag library for JSP.

      * *

      The SSL Ext. Struts extension package makes it possible to declare Struts actions * secure, non-secure, or neutral in the struts config like so:

      * *
       * <action path="/someSecurePath" type="some.important.Action">
       *     <set-property property="secure" value="true"/>
       *     <forward name="success" path="/somePage.vm" />
       * </action>
       * 
      * *

      If an action is declared secure the SecureLinkTool will render the relevant link * as https (if not already in ssl-mode). In the same way, if an action is declared * non-secure the SecureLinkTool will render the relevant link as http (if in ssl-mode). * If the action is declared as neutral (with a "secure" property of "any") then the * SecureLinkTool won't force a protocol change either way.
      If the custom * request processor is also used then a request will be redirected to the correct * protocol if an action URL is manually entered into the browser with the wrong protocol

      * *

      These are the steps needed to enable SSL Ext:

      *
        *
      • SSL connections need to be enabled on the webserver.
      • *
      • The Java Secure Socket Extension (JSSE) package needs to be in place (it's * integrated into the Java 2 SDK Standard Edition, v. 1.4 but optional for earlier * versions)
      • *
      • In your tools.xml, add the SecureLinkTool to replace (same key) or complement * (alternate key) the {@link StrutsLinkTool}
      • *
      • In struts-conf.xml the custom action-mapping class needs to be specified
      • *
      • In struts-conf.xml the custom controller class can optionally be specified * (if the redirect feature is wanted)
      • *
      • In struts-conf.xml the SecurePlugIn needs to be added
      • *
      • In struts-conf.xml, when using Tiles, the SecureTilesPlugin substitues both the * TilesPlugin and the SecurePlugIn and it also takes care of setting the correct * controller so there is no need to specify the custom controller.
      • *
      * * See SSL Ext.project home for more info. * *

      Usage: *

       * Template example:
       * <!-- Use just like a regular StrutsLinkTool -->
       * $link.action.nameOfAction
       * $link.action.nameOfForward
       *
       * If the action or forward is marked as secure, or not,
       * in your struts-config then the link will be rendered
       * with https or http accordingly.
       *
       * Toolbox configuration:
       * <tools>
       *   <toolbox scope="request">
       *     <tool class="org.apache.velocity.tools.struts.SecureLinkTool"/>
       *   </toolbox>
       * </tools>
       * 
      *

      * @since VelocityTools 1.1 * @author Marino A. Jonsson * @version $Revision: 707788 $ $Date: 2008-10-24 16:28:06 -0700 (Fri, 24 Oct 2008) $ */ public class SecureLinkTool extends LinkTool { protected ServletContext application; private static final String HTTP = "http"; private static final String HTTPS = "https"; private static final String STD_HTTP_PORT = "80"; private static final String STD_HTTPS_PORT = "443"; @Override protected void configure(ValueParser props) { super.configure(props); this.application = (ServletContext)props.getValue(ViewContext.SERVLET_CONTEXT_KEY); } /** *

      Returns a copy of the link with the given action name * converted into a server-relative URI reference. This method * does not check if the specified action really is defined. * This method will overwrite any previous URI reference settings * but will copy the query string.

      * * @param action an action path as defined in struts-config.xml * * @return a new instance of StrutsLinkTool */ public SecureLinkTool setAction(String action) { String link = StrutsUtils.getActionMappingURL(application, request, action); return (SecureLinkTool)absolute(computeURL(request, application, link)); } /** *

      Returns a copy of the link with the given global forward name * converted into a server-relative URI reference. If the parameter * does not map to an existing global forward name, null * is returned. This method will overwrite any previous URI reference * settings but will copy the query string.

      * * @param forward a global forward name as defined in struts-config.xml * * @return a new instance of StrutsLinkTool */ public SecureLinkTool setForward(String forward) { String url = StrutsUtils.getForwardURL(request, application, forward); if (url == null) { return null; } return (SecureLinkTool)absolute(url); } /** * Compute a hyperlink URL based on the specified action link. * The returned URL will have already been passed to * response.encodeURL() for adding a session identifier. * * @param request the current request. * @param app the current ServletContext. * @param link the action that is to be converted to a hyperlink URL * @return the computed hyperlink URL */ public String computeURL(HttpServletRequest request, ServletContext app, String link) { StringBuilder url = new StringBuilder(link); String contextPath = request.getContextPath(); SecurePlugInInterface securePlugin = (SecurePlugInInterface)app.getAttribute(SecurePlugInInterface.SECURE_PLUGIN); if (securePlugin.getSslExtEnable() && url.toString().startsWith(contextPath)) { // Initialize the scheme and ports we are using String usingScheme = request.getScheme(); String usingPort = String.valueOf(request.getServerPort()); // Get the servlet context relative link URL String linkString = url.toString().substring(contextPath.length()); // See if link references an action somewhere in our app SecureActionConfig secureConfig = getActionConfig(app, linkString); // If link is an action, find the desired port and scheme if (secureConfig != null && !SecureActionConfig.ANY.equalsIgnoreCase(secureConfig.getSecure())) { String desiredScheme = Boolean.valueOf(secureConfig.getSecure()).booleanValue() ? HTTPS : HTTP; String desiredPort = Boolean.valueOf(secureConfig.getSecure()).booleanValue() ? securePlugin.getHttpsPort() : securePlugin.getHttpPort(); // If scheme and port we are using do not match the ones we want if (!desiredScheme.equals(usingScheme) || !desiredPort.equals(usingPort)) { url.insert(0, startNewUrlString(request, desiredScheme, desiredPort)); // This is a hack to help us overcome the problem that some // older browsers do not share sessions between http & https // If this feature is diabled, session ID could still be added // the previous call to the RequestUtils.computeURL() method, // but only if needed due to cookies disabled, etc. if (securePlugin.getSslExtAddSession() && url.toString().indexOf(";jsessionid=") < 0) { // Add the session identifier url = new StringBuilder(toEncoded(url.toString(), request.getSession().getId())); } } } } return url.toString(); } /** * Finds the configuration definition for the specified action link * * @param app the current ServletContext. * @param linkString The action we are searching for, specified as a * link. (i.e. may include "..") * @return The SecureActionConfig object entry for this action, * or null if not found */ private static SecureActionConfig getActionConfig(ServletContext app, String linkString) { ModuleConfig moduleConfig = StrutsUtils.selectModule(linkString, app); // Strip off the module path, if any linkString = linkString.substring(moduleConfig.getPrefix().length()); // Use our servlet mapping, if one is specified //String servletMapping = (String)app.getAttribute(Globals.SERVLET_KEY); SecurePlugInInterface spi = (SecurePlugInInterface)app.getAttribute( SecurePlugInInterface.SECURE_PLUGIN); Iterator mappingItr = spi.getServletMappings().iterator(); while (mappingItr.hasNext()) { String servletMapping = (String)mappingItr.next(); int starIndex = servletMapping != null ? servletMapping.indexOf('*') : -1; if (starIndex == -1) { continue; } // No servlet mapping or no usable pattern defined, short circuit String prefix = servletMapping.substring(0, starIndex); String suffix = servletMapping.substring(starIndex + 1); // Strip off the jsessionid, if any int jsession = linkString.indexOf(";jsessionid="); if (jsession >= 0) { linkString = linkString.substring(0, jsession); } // Strip off the query string, if any // (differs from the SSL Ext. version - query string before anchor) int question = linkString.indexOf('?'); if (question >= 0) { linkString = linkString.substring(0, question); } // Strip off the anchor, if any int anchor = linkString.indexOf('#'); if (anchor >= 0) { linkString = linkString.substring(0, anchor); } // Unable to establish this link as an action, short circuit if (!(linkString.startsWith(prefix) && linkString.endsWith(suffix))) { continue; } // Chop off prefix and suffix linkString = linkString.substring(prefix.length()); linkString = linkString.substring(0, linkString.length() - suffix.length()); if (!linkString.startsWith("/")) { linkString = "/" + linkString; } SecureActionConfig secureConfig = (SecureActionConfig)moduleConfig. findActionConfig(linkString); return secureConfig; } return null; } /** * Builds the protocol, server name, and port portion of the new URL * @param request The current request * @param desiredScheme The scheme (http or https) to be used in the new URL * @param desiredPort The port number to be used in th enew URL * @return The new URL as a StringBuilder */ private static StringBuilder startNewUrlString(HttpServletRequest request, String desiredScheme, String desiredPort) { StringBuilder url = new StringBuilder(); String serverName = request.getServerName(); url.append(desiredScheme).append("://").append(serverName); if ((HTTP.equals(desiredScheme) && !STD_HTTP_PORT.equals(desiredPort)) || (HTTPS.equals(desiredScheme) && !STD_HTTPS_PORT.equals(desiredPort))) { url.append(":").append(desiredPort); } return url; } /** * Return the specified URL with the specified session identifier * suitably encoded. * * @param url URL to be encoded with the session id * @param sessionId Session id to be included in the encoded URL * @return the specified URL with the specified session identifier suitably encoded */ public String toEncoded(String url, String sessionId) { if (url == null || sessionId == null) { return (url); } String path = url; String query = ""; String anchor = ""; // (differs from the SSL Ext. version - anchor before query string) int pound = url.indexOf('#'); if (pound >= 0) { path = url.substring(0, pound); anchor = url.substring(pound); } int question = path.indexOf('?'); if (question >= 0) { query = path.substring(question); path = path.substring(0, question); } StringBuilder sb = new StringBuilder(path); // jsessionid can't be first. if (sb.length() > 0) { sb.append(";jsessionid="); sb.append(sessionId); } sb.append(query); sb.append(anchor); return sb.toString(); } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/struts/StrutsLinkTool.java100644 0 0 12074 11110347747 27145 0ustar 0 0 package org.apache.velocity.tools.struts; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import javax.servlet.ServletContext; import org.apache.velocity.tools.generic.ValueParser; import org.apache.velocity.tools.view.LinkTool; import org.apache.velocity.tools.view.ViewContext; /** *

      The StrutsLinkTool extends the standard {@link LinkTool} to add methods * for working with Struts' Actions and Forwards:

      *
        *
      • translate logical names (Struts forwards, actions ) to URI references, see * methods {@link #setAction} and {@link #setForward}
      • *
      * *

       * Template example(s):
       *   <a href="$link.action.update">update something</a>
       *   #set( $base = $link.forward.MyPage.anchor('view') )
       *   <a href="$base.param('select','this')">view this</a>
       *   <a href="$base.param('select','that')">view that</a>
       *
       * Toolbox configuration:
       * <tools>
       *   <toolbox scope="request">
       *     <tool class="org.apache.velocity.tools.struts.StrutsLinkTool"/>
       *   </toolbox>
       * </tools>
       * 

      * *

      This tool may only be used in the request scope.

      * * @author Gabe Sidler * @author Nathan Bubna * * @version $Id: StrutsLinkTool.java 707788 2008-10-24 23:28:06Z nbubna $ */ public class StrutsLinkTool extends LinkTool { protected ServletContext application; private String get; @Override protected void configure(ValueParser props) { super.configure(props); this.application = (ServletContext)props.getValue(ViewContext.SERVLET_CONTEXT_KEY); } /** *

      This exists to enable a simplified syntax for using this tool in a * template. Now, users can do $link.action.saveFoo instead of * $link.setAction('saveFoo') and * $link.forward.profile instead of * $link.setForward('profile'). Neat, eh? :)

      * @since VelocityTools 1.3 */ public StrutsLinkTool get(String getme) { StrutsLinkTool sub = null; if ("action".equalsIgnoreCase(this.get)) { sub = setAction(getme); } else if ("forward".equalsIgnoreCase(this.get)) { sub = setForward(getme); } else { sub = (StrutsLinkTool)this.duplicate(); } if (sub == null) { return null; } sub.get = getme; return sub; } /** *

      Returns a copy of the link with the given action name * converted into a server-relative URI reference. This method * does not check if the specified action really is defined. * This method will overwrite any previous URI reference settings * but will copy the query string.

      * * @param action an action path as defined in struts-config.xml * * @return a new instance of StrutsLinkTool */ public StrutsLinkTool setAction(String action) { String url = StrutsUtils.getActionMappingURL(application, request, action); if (url == null) { debug("StrutsLinkTool : In method setAction("+action+ "): Parameter does not map to a valid action."); return null; } return (StrutsLinkTool)absolute(url); } /** *

      Returns a copy of the link with the given global or local forward * name converted into a server-relative URI reference. If the parameter * does not map to an existing global forward name, null * is returned. This method will overwrite any previous URI reference * settings but will copy the query string.

      * * @param forward a forward name as defined in struts-config.xml * in either global-forwards or in the currently executing * action mapping. * * @return a new instance of StrutsLinkTool */ public StrutsLinkTool setForward(String forward) { String url = StrutsUtils.getForwardURL(request, application, forward); if (url == null) { debug("StrutsLinkTool : In method setForward(" + forward + "): Parameter does not map to a valid forward."); return null; } return (StrutsLinkTool)absolute(url); } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/struts/StrutsUtils.java100644 0 0 45132 11030275242 26502 0ustar 0 0 package org.apache.velocity.tools.struts; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.util.Locale; import java.util.Iterator; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import org.apache.struts.Globals; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionMessage; import org.apache.struts.action.ActionMessages; import org.apache.struts.config.ModuleConfig; import org.apache.struts.config.ForwardConfig; import org.apache.struts.config.ActionConfig; import org.apache.struts.util.MessageResources; import org.apache.struts.util.RequestUtils; import org.apache.struts.taglib.TagUtils; import org.apache.struts.util.ModuleUtils; /** *

      A utility class to expose the Struts shared * resources. All methods are static.

      * *

      This class is provided for use by Velocity view tools * that need access to Struts resources. By having all Struts- * specific code in this utility class, maintenance is simplified * and reuse fostered.

      * *

      It is the aim, that sooner or later the functionality in * this class is integrated into Struts itself. See * Bug #16814 * for more on that.

      * * @author Marino A. Jonsson * @author Nathan Bubna * @author Gabe Sidler * based on code by Ted Husted * * @version $Id: StrutsUtils.java 670093 2008-06-20 23:10:11Z nbubna $ */ public class StrutsUtils { public static final StrutsUtils INSTANCE = new StrutsUtils(); private StrutsUtils() {} public StrutsUtils getInstance() { return INSTANCE; } /****************** Struts ServletContext Resources ****************/ /** * Returns the message resources for this application or null * if not found. * * @param app the servlet context * @since VelocityTools 1.1 */ public static MessageResources getMessageResources(HttpServletRequest request, ServletContext app) { return getMessageResources(request, app, null); } /** * Returns the message resources with the specified bundle name for this application * or null if not found. * * @param app the servlet context * @param bundle The bundle name to look for. If this is null, the * default bundle name is used. * @since VelocityTools 1.1 */ public static MessageResources getMessageResources(HttpServletRequest request, ServletContext app, String bundle) { /* Identify the current module */ ModuleConfig moduleConfig = ModuleUtils.getInstance().getModuleConfig(request, app); if (bundle == null) { bundle = Globals.MESSAGES_KEY; } // First check request scope MessageResources resources = (MessageResources)request.getAttribute(bundle + moduleConfig.getPrefix()); if (resources == null) { resources = (MessageResources) app.getAttribute(bundle + moduleConfig.getPrefix()); } return resources; } /** * Select the module to which the specified request belongs, and * add return the corresponding ModuleConfig. * * @param urlPath The requested URL * @param app The ServletContext for this web application * @return The ModuleConfig for the given URL path * @since VelocityTools 1.1 */ public static ModuleConfig selectModule(String urlPath, ServletContext app) { /* Match against the list of sub-application prefixes */ String prefix = ModuleUtils.getInstance().getModuleName(urlPath, app); /* Expose the resources for this sub-application */ ModuleConfig config = (ModuleConfig) app.getAttribute(Globals.MODULE_KEY + prefix); return config; } /********************** Struts Session Resources ******************/ /** * Returns the java.util.Locale for the user. If a * locale object is not found in the user's session, the system * default locale is returned. * * @param request the servlet request * @param session the HTTP session */ public static Locale getLocale(HttpServletRequest request, HttpSession session) { Locale locale = null; if (session != null) { locale = (Locale)session.getAttribute(Globals.LOCALE_KEY); } if (locale == null) { locale = request.getLocale(); } return locale; } /** * Returns the transaction token stored in this session or * null if not used. * * @param session the HTTP session */ public static String getToken(HttpSession session) { if (session == null) { return null; } return (String)session.getAttribute(Globals.TRANSACTION_TOKEN_KEY); } /*********************** Struts Request Resources ****************/ /** * Returns the Struts errors for this request or null * if none exist. Since VelocityTools 1.2, this will also check * the session (if there is one) for errors if there are no errors * in the request. * * @param request the servlet request * @since VelocityTools 1.1 */ public static ActionMessages getErrors(HttpServletRequest request) { ActionMessages errors = (ActionMessages)request.getAttribute(Globals.ERROR_KEY); if (errors == null || errors.isEmpty()) { // then check the session HttpSession session = request.getSession(false); if (session != null) { errors = (ActionMessages)session.getAttribute(Globals.ERROR_KEY); } } return errors; } /** * Returns the Struts messages for this request or null * if none exist. Since VelocityTools 1.2, this will also check * the session (if there is one) for messages if there are no messages * in the request. * * @param request the servlet request * @since VelocityTools 1.1 */ public static ActionMessages getMessages(HttpServletRequest request) { ActionMessages messages = (ActionMessages)request.getAttribute(Globals.MESSAGE_KEY); if (messages == null || messages.isEmpty()) { // then check the session HttpSession session = request.getSession(false); if (session != null) { messages = (ActionMessages)session.getAttribute(Globals.MESSAGE_KEY); } } return messages; } /** * Returns the ActionForm bean associated with * this request of null if none exists. * * @param request the servlet request * @param session the HTTP session */ public static ActionForm getActionForm(HttpServletRequest request, HttpSession session) { /* Is there a mapping associated with this request? */ ActionConfig mapping = (ActionConfig)request.getAttribute(Globals.MAPPING_KEY); if (mapping == null) { return null; } /* Is there a form bean associated with this mapping? */ String attribute = mapping.getAttribute(); if (attribute == null) { return null; } /* Look up the existing form bean */ if ("request".equals(mapping.getScope())) { return (ActionForm)request.getAttribute(attribute); } if (session != null) { return (ActionForm)session.getAttribute(attribute); } return null; } /** * Returns the ActionForm name associated with * this request of null if none exists. * * @param request the servlet request * @param session the HTTP session */ public static String getActionFormName(HttpServletRequest request, HttpSession session) { /* Is there a mapping associated with this request? */ ActionConfig mapping = (ActionConfig)request.getAttribute(Globals.MAPPING_KEY); if (mapping == null) { return null; } return mapping.getAttribute(); } /*************************** Utilities *************************/ /** * Return the form action converted into an action mapping path. The * value of the action property is manipulated as follows in * computing the name of the requested mapping: *
        *
      • Any filename extension is removed (on the theory that extension * mapping is being used to select the controller servlet).
      • *
      • If the resulting value does not start with a slash, then a * slash is prepended.
      • *
      */ public static String getActionMappingName(String action) { String value = action; int question = action.indexOf('?'); if (question >= 0) { value = value.substring(0, question); } int slash = value.lastIndexOf('/'); int period = value.lastIndexOf('.'); if ((period >= 0) && (period > slash)) { value = value.substring(0, period); } return value.startsWith("/") ? value : ("/" + value); } /** * Returns the form action converted into a server-relative URI * reference. * * @param application the servlet context * @param request the servlet request * @param action the name of an action as per struts-config.xml */ public static String getActionMappingURL(ServletContext application, HttpServletRequest request, String action) { StringBuilder value = new StringBuilder(request.getContextPath()); ModuleConfig config = (ModuleConfig)request.getAttribute(Globals.MODULE_KEY); if (config != null) { value.append(config.getPrefix()); } /* Use our servlet mapping, if one is specified */ String servletMapping = (String)application.getAttribute(Globals.SERVLET_KEY); if (servletMapping != null) { String queryString = null; int question = action.indexOf('?'); if (question >= 0) { queryString = action.substring(question); } String actionMapping = TagUtils.getInstance().getActionMappingName(action); if (servletMapping.startsWith("*.")) { value.append(actionMapping); value.append(servletMapping.substring(1)); } else if (servletMapping.endsWith("/*")) { value.append(servletMapping.substring (0, servletMapping.length() - 2)); value.append(actionMapping); } if (queryString != null) { value.append(queryString); } } else { /* Otherwise, assume extension mapping is in use and extension is * already included in the action property */ if (!action.startsWith("/")) { value.append("/"); } value.append(action); } /* Return the completed value */ return value.toString(); } /** * Returns the action forward name converted into a server-relative URI * reference. * * @param app the servlet context * @param request the servlet request * @param forward the name of a forward as per struts-config.xml */ public static String getForwardURL(HttpServletRequest request, ServletContext app, String forward) { ModuleConfig moduleConfig = ModuleUtils.getInstance().getModuleConfig(request, app); //TODO? beware of null module config if ActionServlet isn't init'ed? ActionConfig actionConfig = (ActionConfig)request.getAttribute(Globals.MAPPING_KEY); // NOTE: ActionConfig.findForwardConfig only searches local forwards ForwardConfig fc = null; if(actionConfig != null) { fc = actionConfig.findForwardConfig(forward); } // No ActionConfig forward? // Find the ForwardConfig in the global-forwards. if(fc == null) { fc = moduleConfig.findForwardConfig(forward); // ok, give up if (fc == null) { return null; } } StringBuilder url = new StringBuilder(); if (fc.getPath().startsWith("/")) { url.append(request.getContextPath()); url.append(RequestUtils.forwardURL(request, fc, moduleConfig)); } else { url.append(fc.getPath()); } return url.toString(); } /** * Returns a formatted error message. The error message is assembled from * the following three pieces: First, value of message resource * "errors.header" is prepended. Then, the list of error messages is * rendered. Finally, the value of message resource "errors.footer" * is appended. * * @param property the category of errors to markup and return * @param request the servlet request * @param session the HTTP session * @param application the servlet context * * @return The formatted error message. If no error messages are queued, * an empty string is returned. */ public static String errorMarkup(String property, HttpServletRequest request, HttpSession session, ServletContext application) { return errorMarkup(property, null, request, session, application); } /** * Returns a formatted error message. The error message is assembled from * the following three pieces: First, value of message resource * "errors.header" is prepended. Then, the list of error messages is * rendered. Finally, the value of message resource "errors.footer" * is appended. * * @param property the category of errors to markup and return * @param bundle the message resource bundle to use * @param request the servlet request * @param session the HTTP session * @param application the servlet context * @since VelocityTools 1.1 * @return The formatted error message. If no error messages are queued, * an empty string is returned. */ public static String errorMarkup(String property, String bundle, HttpServletRequest request, HttpSession session, ServletContext application) { ActionMessages errors = getErrors(request); if (errors == null) { return ""; } /* fetch the error messages */ Iterator reports = null; if (property == null) { reports = errors.get(); } else { reports = errors.get(property); } if (!reports.hasNext()) { return ""; } /* Render the error messages appropriately if errors have been queued */ StringBuilder results = new StringBuilder(); String header = null; String footer = null; String prefix = null; String suffix = null; Locale locale = getLocale(request, session); MessageResources resources = getMessageResources(request, application, bundle); if (resources != null) { header = resources.getMessage(locale, "errors.header"); footer = resources.getMessage(locale, "errors.footer"); prefix = resources.getMessage(locale, "errors.prefix"); suffix = resources.getMessage(locale, "errors.suffix"); } if (header == null) { header = "errors.header"; } if (footer == null) { footer = "errors.footer"; } /* prefix or suffix are optional, be quiet if they're missing */ if (prefix == null) { prefix = ""; } if (suffix == null) { suffix = ""; } results.append(header); results.append("\r\n"); String message; while (reports.hasNext()) { message = null; ActionMessage report = (ActionMessage)reports.next(); if (resources != null && report.isResource()) { message = resources.getMessage(locale, report.getKey(), report.getValues()); } results.append(prefix); if (message != null) { results.append(message); } else { results.append(report.getKey()); } results.append(suffix); results.append("\r\n"); } results.append(footer); results.append("\r\n"); /* return result */ return results.toString(); } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/struts/TilesTool.java100644 0 0 42646 10730012242 26075 0ustar 0 0 package org.apache.velocity.tools.struts; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.util.Iterator; import java.util.Map; import java.util.Stack; import javax.servlet.http.HttpSession; import org.apache.struts.tiles.AttributeDefinition; import org.apache.struts.tiles.ComponentContext; import org.apache.struts.tiles.ComponentDefinition; import org.apache.struts.tiles.Controller; import org.apache.struts.tiles.DefinitionAttribute; import org.apache.struts.tiles.DefinitionNameAttribute; import org.apache.struts.tiles.DefinitionsFactoryException; import org.apache.struts.tiles.DirectStringAttribute; import org.apache.struts.tiles.TilesUtil; import org.apache.velocity.context.Context; import org.apache.velocity.tools.Scope; import org.apache.velocity.tools.config.DefaultKey; import org.apache.velocity.tools.config.ValidScope; import org.apache.velocity.tools.view.ImportSupport; import org.apache.velocity.tools.view.ViewContext; /** *

      The TilesTool is used to interact with the Struts-Tiles framework that is part * of Struts 1.

      *

       * Template example(s):
       *  <!-- insert a tile -->
       *  $tiles.myTileDefinition
       *
       *  <!-- get named attribute value from the current tiles-context -->
       *  $tiles.getAttribute("myTileAttribute")
       *
       *  <!-- import all attributes of the current tiles-context into the velocity-context. -->
       *  $tiles.importAttributes()
       *
       * Toolbox configuration:
       * <tools>
       *   <toolbox scope="request">
       *     <tool class="org.apache.velocity.tools.struts.TilesTool"/>
       *   </toolbox>
       * </tools>
       * 

      * *

      This tool may only be used in the request scope.

      * * @author Marino A. Jonsson * @since VelocityTools 1.1 * @version $Revision: 601976 $ $Date: 2007-12-06 19:50:51 -0800 (Thu, 06 Dec 2007) $ */ @DefaultKey("tiles") @ValidScope(Scope.REQUEST) public class TilesTool extends ImportSupport { static final String PAGE_SCOPE = "page"; static final String REQUEST_SCOPE = "request"; static final String SESSION_SCOPE = "session"; static final String APPLICATION_SCOPE = "application"; protected Context velocityContext; /** * A stack to hold ComponentContexts while nested tile-definitions * are rendered. */ protected Stack contextStack; /** * Indicates if there is a MethodExceptionEventHandler present */ protected boolean catchExceptions = true; /******************************* Constructors ****************************/ @Deprecated public void init(Object obj) { if (obj instanceof ViewContext) { ViewContext ctx = (ViewContext)obj; setVelocityContext(ctx.getVelocityContext()); setRequest(ctx.getRequest()); setResponse(ctx.getResponse()); setServletContext(ctx.getServletContext()); setLog(ctx.getVelocityEngine().getLog()); } } /** * Initializes this tool. * * @param context the current {@link Context} * @throws IllegalArgumentException if the param is not a {@link Context} */ public void setVelocityContext(Context context) { if (context == null) { throw new NullPointerException("velocity context should not be null"); } this.velocityContext = context; } public void setCatchExceptions(boolean catchExceptions) { this.catchExceptions = catchExceptions; } /***************************** View Helpers ******************************/ /** * A generic tiles insert function. * *

      This is functionally equivalent to * <tiles:insert attribute="foo" />.

      * * @param obj Can be any of the following: * AttributeDefinition, * tile-definition name, * tile-attribute name, * regular uri. * (checked in that order) * @return the rendered template or value as a String * @throws Exception on failure */ public String get(Object obj) throws Exception { try { Object value = getCurrentContext().getAttribute(obj.toString()); if (value != null) { return processObjectValue(value); } return processAsDefinitionOrURL(obj.toString()); } catch (Exception e) { LOG.error("TilesTool : Exeption while rendering Tile " + obj, e); /* delegate exception handling to an EventHandler if present. */ if (!this.catchExceptions) { throw e; } return null; } } /** * Fetches a named attribute-value from the current tiles-context. * *

      This is functionally equivalent to * <tiles:getAsString name="foo" />.

      * * @param name the name of the tiles-attribute to fetch * @return attribute value for the named attribute */ public Object getAttribute(String name) { Object value = getCurrentContext().getAttribute(name); if (value == null) { LOG.warn("TilesTool : Tile attribute '" + name + "' wasn't found in context."); } return value; } /** * Imports the named attribute-value from the current tiles-context into the * current Velocity context. * *

      This is functionally equivalent to * <tiles:importAttribute name="foo" /> * * @param name the name of the tiles-attribute to import */ public void importAttribute(String name) { this.importAttribute(name, PAGE_SCOPE); } /** * Imports the named attribute-value from the current tiles-context into the * named context ("page", "request", "session", or "application"). * *

      This is functionally equivalent to * <tiles:importAttribute name="foo" scope="scopeValue" /> * * @param name the name of the tiles-attribute to import * @param scope the named context scope to put the attribute into. */ public void importAttribute(String name, String scope) { Object value = getCurrentContext().getAttribute(name); if (value == null) { LOG.warn("TilesTool : Tile attribute '" + name + "' wasn't found in context."); } if (scope.equals(PAGE_SCOPE)) { velocityContext.put(name, value); } else if (scope.equals(REQUEST_SCOPE)) { request.setAttribute(name, value); } else if (scope.equals(SESSION_SCOPE)) { request.getSession().setAttribute(name, value); } else if (scope.equals(APPLICATION_SCOPE)) { application.setAttribute(name, value); } } /** * Imports all attributes in the current tiles-context into the * current velocity-context. * *

      This is functionally equivalent to * <tiles:importAttribute />.

      */ public void importAttributes() { this.importAttributes(PAGE_SCOPE); } /** * Imports all attributes in the current tiles-context into the named * context ("page", "request", "session", or "application"). * *

      This is functionally equivalent to * <tiles:importAttribute scope="scopeValue" />.

      * * @param scope the named context scope to put the attributes into. */ public void importAttributes(String scope) { ComponentContext context = getCurrentContext(); Iterator names = context.getAttributeNames(); if (scope.equals(PAGE_SCOPE)) { while (names.hasNext()) { String name = (String)names.next(); velocityContext.put(name, context.getAttribute(name)); } } else if (scope.equals(REQUEST_SCOPE)) { while (names.hasNext()) { String name = (String)names.next(); request.setAttribute(name, context.getAttribute(name)); } } else if (scope.equals(SESSION_SCOPE)) { HttpSession session = request.getSession(); while (names.hasNext()) { String name = (String)names.next(); session.setAttribute(name, context.getAttribute(name)); } } else if (scope.equals(APPLICATION_SCOPE)) { while (names.hasNext()) { String name = (String)names.next(); application.setAttribute(name, context.getAttribute(name)); } } } /************************** Protected Methods ****************************/ /** * Process an object retrieved as a bean or attribute. * * @param value - Object can be a typed attribute, a String, or anything * else. If typed attribute, use associated type. Otherwise, apply * toString() on object, and use returned string as a name. * @throws Exception - Throws by underlying nested call to * processDefinitionName() * @return the fully processed value as String */ protected String processObjectValue(Object value) throws Exception { /* First, check if value is one of the Typed Attribute */ if (value instanceof AttributeDefinition) { /* We have a type => return appropriate IncludeType */ return processTypedAttribute((AttributeDefinition)value); } else if (value instanceof ComponentDefinition) { return processDefinition((ComponentDefinition)value); } /* Value must denote a valid String */ return processAsDefinitionOrURL(value.toString()); } /** * Process typed attribute according to its type. * * @param value Typed attribute to process. * @return the fully processed attribute value as String. * @throws Exception - Throws by underlying nested call to processDefinitionName() */ protected String processTypedAttribute(AttributeDefinition value) throws Exception { if (value instanceof DirectStringAttribute) { return (String)value.getValue(); } else if (value instanceof DefinitionAttribute) { return processDefinition((ComponentDefinition)value.getValue()); } else if (value instanceof DefinitionNameAttribute) { return processAsDefinitionOrURL((String)value.getValue()); } /* else if( value instanceof PathAttribute ) */ return doInsert((String)value.getValue(), null, null); } /** * Try to process name as a definition, or as an URL if not found. * * @param name Name to process. * @return the fully processed definition or URL * @throws Exception */ protected String processAsDefinitionOrURL(String name) throws Exception { try { ComponentDefinition definition = TilesUtil.getDefinition(name, this.request, this.application); if (definition != null) { return processDefinition(definition); } } catch (DefinitionsFactoryException ex) { /* silently failed, because we can choose to not define a factory. */ } /* no definition found, try as url */ return processUrl(name); } /** * End of Process for definition. * * @param definition Definition to process. * @return the fully processed definition. * @throws Exception from InstantiationException Can't create requested controller */ protected String processDefinition(ComponentDefinition definition) throws Exception { Controller controller = null; try { controller = definition.getOrCreateController(); String role = definition.getRole(); String page = definition.getTemplate(); return doInsert(definition.getAttributes(), page, role, controller); } catch (InstantiationException ex) { throw new Exception(ex.getMessage()); } } /** * Processes an url * * @param url the URI to process. * @return the rendered template as String. * @throws Exception */ protected String processUrl(String url) throws Exception { return doInsert(url, null, null); } /** * Use this if there is no nested tile. * * @param page the page to process. * @param role possible user-role * @param controller possible tiles-controller * @return the rendered template as String. * @throws Exception */ protected String doInsert(String page, String role, Controller controller) throws Exception { if (role != null && !this.request.isUserInRole(role)) { return null; } ComponentContext subCompContext = new ComponentContext(); return doInsert(subCompContext, page, role, controller); } /** * Use this if there is a nested tile. * * @param attributes attributes for the sub-context * @param page the page to process. * @param role possible user-role * @param controller possible tiles-controller * @return the rendered template as String. * @throws Exception */ protected String doInsert(Map attributes, String page, String role, Controller controller) throws Exception { if (role != null && !this.request.isUserInRole(role)) { return null; } ComponentContext subCompContext = new ComponentContext(attributes); return doInsert(subCompContext, page, role, controller); } /** * An extension of the other two doInsert functions * * @param subCompContext the sub-context to set in scope when the * template is rendered. * @param page the page to process. * @param role possible user-role * @param controller possible tiles-controller * @return the rendered template as String. * @throws Exception */ protected String doInsert(ComponentContext subCompContext, String page, String role, Controller controller) throws Exception { pushTilesContext(); try { ComponentContext.setContext(subCompContext, this.request); /* Call controller if any */ if (controller != null) { controller.execute(subCompContext, this.request, this.response, this.application); } /* pass things off to ImportSupport */ return this.acquireString(page); } finally { popTilesContext(); } } /** * Retrieve the current tiles component context. * This is pretty much just a convenience method. */ protected ComponentContext getCurrentContext() { return ComponentContext.getContext(this.request); } /** *

      pushes the current tiles context onto the context-stack. * preserving the context is necessary so that a sub-context can be * put into request scope and lower level tiles can be rendered

      */ protected void pushTilesContext() { if (this.contextStack == null) { this.contextStack = new Stack(); } contextStack.push(getCurrentContext()); } /** * Pops the tiles sub-context off the context-stack after the lower level * tiles have been rendered. */ protected void popTilesContext() { ComponentContext context = (ComponentContext)this.contextStack.pop(); ComponentContext.setContext(context, this.request); } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/struts/ValidatorTool.java100644 0 0 66110 10730012242 26732 0ustar 0 0 package org.apache.velocity.tools.struts; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import org.apache.commons.validator.Field; import org.apache.commons.validator.Form; import org.apache.commons.validator.ValidatorAction; import org.apache.commons.validator.ValidatorResources; import org.apache.commons.validator.Var; import org.apache.struts.Globals; import org.apache.struts.config.ActionConfig; import org.apache.struts.config.ModuleConfig; import org.apache.struts.util.MessageResources; import org.apache.struts.util.ModuleUtils; import org.apache.struts.validator.Resources; import org.apache.struts.validator.ValidatorPlugIn; import org.apache.velocity.tools.Scope; import org.apache.velocity.tools.config.DefaultKey; import org.apache.velocity.tools.config.ValidScope; import org.apache.velocity.tools.view.ViewContext; import org.apache.velocity.tools.view.ViewToolContext; /** *

      View tool that works with Struts Validator to * produce client side javascript validation for your forms.

      *

      Usage: *

       * Template example:
       *
       * $validator.getJavascript("nameOfYourForm")
       *
       * Toolbox configuration:
       * <tools>
       *   <toolbox scope="request">
       *     <tool class="org.apache.velocity.tools.struts.ValidatorTool"/>
       *   </toolbox>
       * </tools>
       * 
      *

      *

      This is an adaptation of the JavascriptValidatorTag * from the Struts 1.1 validator library.

      * * @author David Winterfeldt * @author David Graham * @author Marino A. Jonsson * @author Nathan Bubna * @since VelocityTools 1.1 * @version $Revision: 595822 $ $Date: 2007-11-16 13:07:51 -0800 (Fri, 16 Nov 2007) $ */ @DefaultKey("validator") @ValidScope(Scope.REQUEST) public class ValidatorTool { /** A reference to the ViewContext */ protected ViewContext context; /** A reference to the ServletContext */ protected ServletContext app; /** A reference to the HttpServletRequest. */ protected HttpServletRequest request; /** A reference to the HttpSession. */ protected HttpSession session; /** A reference to the ValidatorResources. */ protected ValidatorResources resources; private static final String HTML_BEGIN_COMMENT = "\n \n"; private boolean xhtml = false; private boolean htmlComment = true; private boolean cdata = true; private String formName = null; private String methodName = null; private String src = null; private int page = 0; /** * formName is used for both Javascript and non-javascript validations. * For the javascript validations, there is the possibility that we will * be rewriting the formName (if it is a ValidatorActionForm instead of just * a ValidatorForm) so we need another variable to hold the formName just for * javascript usage. */ protected String jsFormName = null; /** * A Comparator to use when sorting ValidatorAction objects. */ private static final Comparator actionComparator = new Comparator() { public int compare(Object o1, Object o2) { ValidatorAction va1 = (ValidatorAction) o1; ValidatorAction va2 = (ValidatorAction) o2; if ((va1.getDepends() == null || va1.getDepends().length() == 0) && (va2.getDepends() == null || va2.getDepends().length() == 0)) { return 0; } else if ( (va1.getDepends() != null && va1.getDepends().length() > 0) && (va2.getDepends() == null || va2.getDepends().length() == 0)) { return 1; } else if ( (va1.getDepends() == null || va1.getDepends().length() == 0) && (va2.getDepends() != null && va2.getDepends().length() > 0)) { return -1; } else { return va1.getDependencyList().size() - va2.getDependencyList().size(); } } }; @Deprecated public void init(Object obj) { if (obj instanceof ViewContext) { this.context = (ViewContext)obj; this.request = context.getRequest(); this.session = request.getSession(false); this.app = context.getServletContext(); } } /** * Initializes this tool. * * @param params the Map of configuration parameters * @throws IllegalArgumentException if the param is not a ViewContext */ public void configure(Map params) { this.context = (ViewContext)params.get(ViewToolContext.CONTEXT_KEY); this.request = (HttpServletRequest)params.get(ViewContext.REQUEST); this.session = request.getSession(false); this.app = (ServletContext)params.get(ViewContext.SERVLET_CONTEXT_KEY); Boolean b = (Boolean)params.get("XHTML"); if (b != null) { this.xhtml = b.booleanValue(); } /* Is there a mapping associated with this request? */ ActionConfig config = (ActionConfig)request.getAttribute(Globals.MAPPING_KEY); if (config != null) { /* Is there a form bean associated with this mapping? */ this.formName = config.getAttribute(); } ModuleConfig mconfig = ModuleUtils.getInstance().getModuleConfig(request, app); this.resources = (ValidatorResources)app.getAttribute(ValidatorPlugIn. VALIDATOR_KEY + mconfig.getPrefix()); } /****************** get/set accessors ***************/ /** * Gets the current page number of a multi-part form. * Only field validations with a matching page number * will be generated that match the current page number. * Only valid when the formName attribute is set. * * @return the current page number of a multi-part form */ public int getPage() { return page; } /** * Sets the current page number of a multi-part form. * Only field validations with a matching page number * will be generated that match the current page number. * * @param page the current page number of a multi-part form */ public void setPage(int page) { this.page = page; } /** * Gets the method name that will be used for the Javascript * validation method name if it has a value. This overrides * the auto-generated method name based on the key (form name) * passed in. * * @return the method name that will be used for the Javascript validation method */ public String getMethod() { return methodName; } /** * Sets the method name that will be used for the Javascript * validation method name if it has a value. This overrides * the auto-generated method name based on the key (form name) * passed in. * * @param methodName the method name that will be used for the Javascript validation method name */ public void setMethod(String methodName) { this.methodName = methodName; } /** * Gets whether or not to delimit the * JavaScript with html comments. If this is set to 'true', which * is the default, html comments will surround the JavaScript. * * @return true if the JavaScript should be delimited with html comments */ public boolean getHtmlComment() { return this.htmlComment; } /** * Sets whether or not to delimit the * JavaScript with html comments. If this is set to 'true', which * is the default, html comments will surround the JavaScript. * * @param htmlComment whether or not to delimit the JavaScript with html comments */ public void setHtmlComment(boolean htmlComment) { this.htmlComment = htmlComment; } /** * Gets the src attribute's value when defining * the html script element. * * @return the src attribute's value */ public String getSrc() { return src; } /** * Sets the src attribute's value (used to include * an external script resource) when defining * the html script element. The src attribute is only recognized * when the formName attribute is specified. * * @param src the src attribute's value */ public void setSrc(String src) { this.src = src; } /** * Returns the cdata setting "true" or "false". * * @return boolean - "true" if JavaScript will be hidden in a CDATA section */ public boolean getCdata() { return cdata; } /** * Sets the cdata status. * @param cdata The cdata to set */ public void setCdata(boolean cdata) { this.cdata = cdata; } /****************** methods that aren't just accessors ***************/ /** * Render both dynamic and static JavaScript to perform * validations based on the form name attribute of the action * mapping associated with the current request (if such exists). * * @return the javascript for the current form * @throws Exception */ public String getJavascript() throws Exception { return getJavascript(this.formName); } /** * Render both dynamic and static JavaScript to perform * validations based on the supplied form name. * * @param formName the key (form name) * @return the Javascript for the specified form * @throws Exception */ public String getJavascript(String formName) throws Exception { this.formName = formName; return getJavascript(formName, true); } /** * Render just the dynamic JavaScript to perform validations based * on the form name attribute of the action mapping associated * with the current request (if such exists). Useful i.e. if the static * parts are located in a seperate .js file. * * @return the javascript for the current form * @throws Exception */ public String getDynamicJavascript() throws Exception { return getDynamicJavascript(this.formName); } /** * Render just the static JavaScript methods. Useful i.e. if the static * parts should be located in a seperate .js file. * * @return all static Javascript methods * @throws Exception */ public String getStaticJavascript() throws Exception { StringBuilder results = new StringBuilder(); results.append(getStartElement()); if (this.htmlComment) { results.append(HTML_BEGIN_COMMENT); } results.append(getJavascriptStaticMethods(resources)); results.append(getJavascriptEnd()); return results.toString(); } /** * Render just the dynamic JavaScript to perform validations based * on the supplied form name. Useful i.e. if the static * parts are located in a seperate .js file. * * @param formName the key (form name) * @return the dynamic Javascript for the specified form * @throws Exception */ public String getDynamicJavascript(String formName) throws Exception { this.formName = formName; return getJavascript(formName, false); } /** * Render both dynamic and static JavaScript to perform * validations based on the supplied form name. * * @param formName the key (form name) * @param getStatic indicates if the static methods should be rendered * @return the Javascript for the specified form * @throws Exception */ protected String getJavascript(String formName, boolean getStatic) throws Exception { StringBuilder results = new StringBuilder(); Locale locale = StrutsUtils.getLocale(request, session); Form form = resources.getForm(locale, formName); if (form != null) { results.append(getDynamicJavascript(resources, locale, form)); } if(getStatic) { results.append(getJavascriptStaticMethods(resources)); } if (form != null) { results.append(getJavascriptEnd()); } return results.toString(); } /** * Generates the dynamic JavaScript for the form. * * @param resources the validator resources * @param locale the locale for the current request * @param form the form to generate javascript for * @return the dynamic javascript */ protected String getDynamicJavascript(ValidatorResources resources, Locale locale, Form form) { StringBuilder results = new StringBuilder(); MessageResources messages = StrutsUtils.getMessageResources(request, app); List actions = createActionList(resources, form); final String methods = createMethods(actions); String formName = form.getName(); jsFormName = formName; if(jsFormName.charAt(0) == '/') { String mappingName = StrutsUtils.getActionMappingName(jsFormName); ModuleConfig mconfig = ModuleUtils.getInstance().getModuleConfig(request, app); ActionConfig mapping = (ActionConfig) mconfig.findActionConfig(mappingName); if (mapping == null) { throw new NullPointerException("Cannot retrieve mapping for action " + mappingName); } jsFormName = mapping.getAttribute(); } results.append(getJavascriptBegin(methods)); for (Iterator i = actions.iterator(); i.hasNext();) { ValidatorAction va = (ValidatorAction)i.next(); int jscriptVar = 0; String functionName = null; if (va.getJsFunctionName() != null && va.getJsFunctionName().length() > 0) { functionName = va.getJsFunctionName(); } else { functionName = va.getName(); } results.append(" function "); results.append(jsFormName); results.append("_"); results.append(functionName); results.append(" () { \n"); for (Iterator x = form.getFields().iterator(); x.hasNext();) { Field field = (Field)x.next(); // Skip indexed fields for now until there is // a good way to handle error messages (and the length // of the list (could retrieve from scope?)) if (field.isIndexed() || field.getPage() != page || !field.isDependency(va.getName())) { continue; } String message = Resources.getMessage(app, request, messages, locale, va, field); message = (message != null) ? message : ""; //jscriptVar = this.getNextVar(jscriptVar); results.append(" this.a"); results.append(jscriptVar++); results.append(" = new Array(\""); results.append(field.getKey()); // TODO: escape? results.append("\", \""); results.append(escapeJavascript(message)); results.append("\", new Function (\"varName\", \""); Map vars = (Map)field.getVars(); // Loop through the field's variables. for (Map.Entry entry : vars.entrySet()) { String varName = entry.getKey(); // TODO: escape? Var var = entry.getValue(); String varValue = Resources.getVarValue(var, app, request, false); String jsType = var.getJsType(); // skip requiredif variables field, fieldIndexed, fieldTest, fieldValue if (varName.startsWith("field")) { continue; } // these are appended no matter what jsType is results.append("this."); results.append(varName); String escapedVarValue = escapeJavascript(varValue); if (Var.JSTYPE_INT.equalsIgnoreCase(jsType)) { results.append("="); results.append(escapedVarValue); results.append("; "); } else if (Var.JSTYPE_REGEXP.equalsIgnoreCase(jsType)) { results.append("=/"); results.append(escapedVarValue); results.append("/; "); } else if (Var.JSTYPE_STRING.equalsIgnoreCase(jsType)) { results.append("='"); results.append(escapedVarValue); results.append("'; "); } // So everyone using the latest format // doesn't need to change their xml files immediately. else if ("mask".equalsIgnoreCase(varName)) { results.append("=/"); results.append(escapedVarValue); results.append("/; "); } else { results.append("='"); results.append(escapedVarValue); results.append("'; "); } } results.append(" return this[varName];\"));\n"); } results.append(" } \n\n"); } return results.toString(); } /** *

      Backslash-escapes the following characters from the input string: * ", ', \, \r, \n.

      * *

      This method escapes characters that will result in an invalid * Javascript statement within the validator Javascript.

      * * @param str The string to escape. * @return The string s with each instance of a double quote, * single quote, backslash, carriage-return, or line feed escaped * with a leading backslash. * @since VelocityTools 1.2 */ protected String escapeJavascript(String str) { if (str == null) { return null; } int length = str.length(); if (length == 0) { return str; } // guess at how many chars we'll be adding... StringBuilder out = new StringBuilder(length + 4); // run through the string escaping sensitive chars for (int i=0; i < length; i++) { char c = str.charAt(i); if (c == '"' || c == '\'' || c == '\\' || c == '\n' || c == '\r') { out.append('\\'); } out.append(c); } return out.toString(); } /** * Creates the JavaScript methods list from the given actions. * @param actions A List of ValidatorAction objects. * @return JavaScript methods. */ protected String createMethods(List actions) { String methodOperator = " && "; StringBuilder methods = null; for (Iterator i = actions.iterator(); i.hasNext();) { ValidatorAction va = (ValidatorAction)i.next(); if (methods == null) { methods = new StringBuilder(va.getMethod()); } else { methods.append(methodOperator); methods.append(va.getMethod()); } methods.append("(form)"); } return methods.toString(); } /** * Get List of actions for the given Form. * * @param resources the validator resources * @param form the form for which the actions are requested * @return A sorted List of ValidatorAction objects. */ protected List createActionList(ValidatorResources resources, Form form) { List actionMethods = new ArrayList(); // Get List of actions for this Form for (Iterator i = form.getFields().iterator(); i.hasNext();) { Field field = (Field)i.next(); for (Iterator x = field.getDependencyList().iterator(); x.hasNext();) { Object o = x.next(); if (o != null && !actionMethods.contains(o)) { actionMethods.add(o); } } } List actions = new ArrayList(); // Create list of ValidatorActions based on actionMethods for (Iterator i = actionMethods.iterator(); i.hasNext();) { String depends = (String) i.next(); ValidatorAction va = resources.getValidatorAction(depends); // throw nicer NPE for easier debugging if (va == null) { throw new NullPointerException( "Depends string \"" + depends + "\" was not found in validator-rules.xml."); } String javascript = va.getJavascript(); if (javascript != null && javascript.length() > 0) { actions.add(va); } else { i.remove(); } } Collections.sort(actions, actionComparator); return actions; } /** * Returns the opening script element and some initial javascript. * * @param methods javascript validation methods * @return the opening script element and some initial javascript */ protected String getJavascriptBegin(String methods) { StringBuilder sb = new StringBuilder(); String name = jsFormName.replace('/', '_'); // remove any '/' characters name = jsFormName.substring(0, 1).toUpperCase() + jsFormName.substring(1, jsFormName.length()); sb.append(this.getStartElement()); if (this.xhtml && this.cdata) { sb.append(" 0) { sb.append(javascript); sb.append("\n"); } } } return sb.toString(); } /** * Returns the closing script element. * * @return the closing script element */ protected String getJavascriptEnd() { StringBuilder sb = new StringBuilder(); sb.append("\n"); if (!this.xhtml && this.htmlComment) { sb.append(HTML_END_COMMENT); } if (this.xhtml && this.cdata) { sb.append("]]>\r\n"); } sb.append("\n\n"); return sb.toString(); } /** * Constructs the beginning ")); DEFAULT_TYPES = Collections.unmodifiableList(types); } private Map groups = null; private List types = DEFAULT_TYPES; private Map> dependencies; private Log LOG; private String context = ""; private void debug(String msg, Object... args) { if (LOG.isDebugEnabled()) { LOG.debug(String.format("UiDependencyTool: "+msg, args)); } } protected static final void trace(Log log, String msg, Object... args) { if (log.isTraceEnabled()) { log.trace(String.format("UiDependencyTool: "+msg, args)); } } public void configure(Map params) { ServletContext app = (ServletContext)params.get(ViewContext.SERVLET_CONTEXT_KEY); LOG = (Log)params.get(ToolContext.LOG_KEY); HttpServletRequest request = (HttpServletRequest)params.get(ViewContext.REQUEST); context = request.getContextPath(); String file = (String)params.get(SOURCE_FILE_KEY); if (file == null) { file = DEFAULT_SOURCE_FILE; } else { debug("Loading file: %s", file); } synchronized (app) { // first, see if we've already read this file groups = (Map)app.getAttribute(GROUPS_KEY_SPACE+file); if (groups == null) { groups = new LinkedHashMap(); // only require file presence, if one is specified read(file, (file != DEFAULT_SOURCE_FILE)); app.setAttribute(GROUPS_KEY_SPACE+file, groups); if (types != DEFAULT_TYPES) { app.setAttribute(TYPES_KEY_SPACE+file, types); } } else { // load any custom types too List alt = (List)app.getAttribute(TYPES_KEY_SPACE+file); if (alt != null) { types = alt; } } } } /** * Adds all the files required for the specified group, then returns * this instance. If the group name is null or no such group exists, * this will return null to indicate the error. */ public UiDependencyTool on(String name) { Map> groupDeps = getGroupDependencies(name); if (groupDeps == null) { return null; } else { addDependencies(groupDeps); return this; } } /** * Adds the specified file to this instance's list of dependencies * of the specified type, then returns this instance. If either the * type or file are null, this will return null to indicate the error. */ public UiDependencyTool on(String type, String file) { if (type == null || file == null) { return null; } else { addFile(type, file); return this; } } /** * Formats and prints all the current dependencies of this tool, * using a new line in between the printed/formatted files. */ public String print() { return printAll("\n"); } /** * If the parameter value is a known type, then this will * format and print all of this instance's current dependencies of the * specified type, using a new line in between the printed/formatted files. * If the parameter value is NOT a known type, then this will treat it * as a delimiter and print all of this instance's dependencies of all * types, using the specified value as the delimiter in between the * printed/formatted files. * @see #print(String,String) * @see #printAll(String) */ public String print(String typeOrDelim) { if (getType(typeOrDelim) == null) { // then it's a delimiter return printAll(typeOrDelim); } else { // then it's obviously a type return print(typeOrDelim, "\n"); } } /** * Formats and prints all of this instance's current dependencies of the * specified type, using the specified delimiter in between the * printed/formatted files. */ public String print(String type, String delim) { List files = getDependencies(type); if (files == null) { return null; } String format = getFormat(type); StringBuilder out = new StringBuilder(); for (String file : files) { out.append(format(format, file)); out.append(delim); } return out.toString(); } /** * Formats and prints all the current dependencies of this tool, * using the specified delimiter in between the printed/formatted files. */ public String printAll(String delim) { if (dependencies == null) { return null; } StringBuilder out = new StringBuilder(); for (Type type : types) { if (out.length() > 0) { out.append(delim); } List files = dependencies.get(type.name); if (files != null) { for (int i=0; i < files.size(); i++) { if (i > 0) { out.append(delim); } out.append(format(type.format, files.get(i))); } } } return out.toString(); } /** * Sets a custom {context} variable for the formats to use. */ public UiDependencyTool context(String path) { this.context = path; return this; } /** * Retrieves the configured format string for the specified file type. */ public String getFormat(String type) { Type t = getType(type); if (t == null) { return null; } return t.format; } /** * Sets the format string for the specified file type. */ public void setFormat(String type, String format) { if (format == null || type == null) { throw new NullPointerException("Type name and format must not be null"); } // do NOT alter the defaults, just copy them if (types == DEFAULT_TYPES) { types = new ArrayList(); for (Type t : DEFAULT_TYPES) { types.add(new Type(t.name, t.format)); } } Type t = getType(type); if (t == null) { types.add(new Type(type, format)); } else { t.format = format; } } /** * Returns the current dependencies of this instance, organized * as an ordered map of file types to lists of the required files * of that type. */ public Map> getDependencies() { return dependencies; } /** * Returns the {@link List} of files for the specified file type, if any. */ public List getDependencies(String type) { if (dependencies == null) { return null; } return dependencies.get(type); } /** * Returns the dependencies of the specified group, organized * as an ordered map of file types to lists of the required files * of that type. */ public Map> getGroupDependencies(String name) { Group group = getGroup(name); if (group == null) { return null; } return group.getDependencies(this); } /** * Returns an empty String to avoid polluting the template output after a * successful call to {@link #on(String)} or {@link #on(String,String)}. */ @Override public String toString() { return ""; } /** * Reads group info out of the specified file and into this instance. * If the file cannot be found and required is true, then this will throw * an IllegalArgumentException. Otherwise, it will simply do nothing. Any * checked exceptions during the actual reading of the file are caught and * wrapped as {@link RuntimeException}s. */ protected void read(String file, boolean required) { debug("UiDependencyTool: Reading file from %s", file); URL url = toURL(file); if (url == null) { String msg = "UiDependencyTool: Could not read file from '"+file+"'"; if (required) { LOG.error(msg); throw new IllegalArgumentException(msg); } else { LOG.debug(msg); } } else { Digester digester = createDigester(); try { digester.parse(url.openStream()); } catch (SAXException saxe) { LOG.error("UiDependencyTool: Failed to parse '"+file+"'", saxe); throw new RuntimeException("While parsing the InputStream", saxe); } catch (IOException ioe) { LOG.error("UiDependencyTool: Failed to read '"+file+"'", ioe); throw new RuntimeException("While handling the InputStream", ioe); } } } /** * Creates the {@link Digester} used by {@link #read} to create * the group info for this instance out of the specified XML file. */ protected Digester createDigester() { Digester digester = new Digester(); digester.setValidating(false); digester.setUseContextClassLoader(true); digester.addRule("ui/type", new TypeRule()); digester.addRule("ui/group", new GroupRule()); digester.addRule("ui/group/file", new FileRule()); digester.addRule("ui/group/needs", new NeedsRule()); digester.push(this); return digester; } /** * Applies the format string to the given value. Currently, * this simply replaces '{file}' with the value. If you * want to handle more complicated formats, override this method. */ protected String format(String format, String value) { if (format == null) { return value; } return format.replace("{file}", value).replace("{context}", this.context); } /** * NOTE: This method may change or disappear w/o warning; don't depend * on it unless you're willing to update your code whenever this changes. */ protected Group getGroup(String name) { if (groups == null) { return null; } return groups.get(name); } /** * NOTE: This method may change or disappear w/o warning; don't depend * on it unless you're willing to update your code whenever this changes. */ protected Group makeGroup(String name) { trace(LOG, "Creating group '%s'", name); Group group = new Group(name, LOG); groups.put(name, group); return group; } /** * Adds the specified files organized by type to this instance's * current dependencies. */ protected void addDependencies(Map> fbt) { if (this.dependencies == null) { dependencies = new LinkedHashMap>(fbt.size()); } for (Map.Entry> entry : fbt.entrySet()) { String type = entry.getKey(); if (getType(type) == null) { LOG.error("UiDependencyTool: Type '"+type+"' is unknown and will not be printed unless defined."); } List existing = dependencies.get(type); if (existing == null) { existing = new ArrayList(entry.getValue().size()); dependencies.put(type, existing); } for (String file : entry.getValue()) { if (!existing.contains(file)) { trace(LOG, "Adding %s: %s", type, file); existing.add(file); } } } } /** * Adds a file to this instance's dependencies under the specified type. */ protected void addFile(String type, String file) { List files = null; if (dependencies == null) { dependencies = new LinkedHashMap>(types.size()); } else { files = dependencies.get(type); } if (files == null) { files = new ArrayList(); dependencies.put(type, files); } if (!files.contains(file)) { trace(LOG, "Adding %s: %s", type, file); files.add(file); } } /** * For internal use only. Use/override get/setFormat instead. */ private Type getType(String type) { for (Type t : types) { if (t.name.equals(type)) { return t; } } return null; } //TODO: replace this method with ConversionUtils.toURL(file, this) // once VelocityTools 2.0-beta3 or 2.0 final is released. private URL toURL(String file) { try { return ClassUtils.getResource(file, this); } catch (Exception e) { return null; } } /** * NOTE: This class may change or disappear w/o warning; don't depend * on it unless you're willing to update your code whenever this changes. */ protected static class Group { private volatile boolean resolved = true; private String name; private Map typeCounts = new LinkedHashMap(); private Map> dependencies = new LinkedHashMap>(); private List groups; private Log LOG; public Group(String name, Log log) { this.name = name; this.LOG = log; } private void trace(String msg, Object... args) { if (LOG.isTraceEnabled()) { UiDependencyTool.trace(LOG, "Group "+name+": "+msg, args); } } public void addFile(String type, String value) { List files = dependencies.get(type); if (files == null) { files = new ArrayList(); dependencies.put(type, files); } if (!files.contains(value)) { trace("Adding %s: %s", type, value); files.add(value); } } public void addGroup(String group) { if (this.groups == null) { this.resolved = false; this.groups = new ArrayList(); } if (!this.groups.contains(group)) { trace("Adding group %s", group, name); this.groups.add(group); } } public Map> getDependencies(UiDependencyTool parent) { resolve(parent); return this.dependencies; } protected void resolve(UiDependencyTool parent) { if (!resolved) { // mark first to keep circular from becoming infinite resolved = true; trace("resolving..."); for (String name : groups) { Group group = parent.getGroup(name); if (group == null) { throw new NullPointerException("No group named '"+name+"'"); } Map> dependencies = group.getDependencies(parent); for (Map.Entry> type : dependencies.entrySet()) { for (String value : type.getValue()) { addFileFromGroup(type.getKey(), value); } } } trace(" is resolved."); } } private void addFileFromGroup(String type, String value) { List files = dependencies.get(type); if (files == null) { files = new ArrayList(); files.add(value); trace("adding %s '%s' first", type, value); dependencies.put(type, files); typeCounts.put(type, 1); } else if (!files.contains(value)) { Integer count = typeCounts.get(type); if (count == null) { count = 0; } files.add(count, value); trace("adding %s '%s' at %s", type, value, count); typeCounts.put(type, ++count); } } } /** * NOTE: This class may change or disappear w/o warning; don't depend * on it unless you're willing to update your code whenever this changes. */ protected static class TypeRule extends Rule { private UiDependencyTool parent; public void begin(String ns, String el, Attributes attributes) throws Exception { parent = (UiDependencyTool)digester.peek(); for (int i=0; i < attributes.getLength(); i++) { String name = attributes.getLocalName(i); if ("".equals(name)) { name = attributes.getQName(i); } if ("name".equals(name)) { digester.push(attributes.getValue(i)); } } } public void body(String ns, String el, String typeFormat) throws Exception { String typeName = (String)digester.pop(); parent.setFormat(typeName, typeFormat); } } /** * NOTE: This class may change or disappear w/o warning; don't depend * on it unless you're willing to update your code whenever this changes. */ protected static class GroupRule extends Rule { private UiDependencyTool parent; public void begin(String ns, String el, Attributes attributes) throws Exception { parent = (UiDependencyTool)digester.peek(); for (int i=0; i < attributes.getLength(); i++) { String name = attributes.getLocalName(i); if ("".equals(name)) { name = attributes.getQName(i); } if ("name".equals(name)) { digester.push(parent.makeGroup(attributes.getValue(i))); } } } public void end(String ns, String el) throws Exception { digester.pop(); } } /** * NOTE: This class may change or disappear w/o warning; don't depend * on it unless you're willing to update your code whenever this changes. */ protected static class FileRule extends Rule { public void begin(String ns, String el, Attributes attributes) throws Exception { for (int i=0; i < attributes.getLength(); i++) { String name = attributes.getLocalName(i); if ("".equals(name)) { name = attributes.getQName(i); } if ("type".equals(name)) { digester.push(attributes.getValue(i)); } } } public void body(String ns, String el, String value) throws Exception { String type = (String)digester.pop(); Group group = (Group)digester.peek(); group.addFile(type, value); } } /** * NOTE: This class may change or disappear w/o warning; don't depend * on it unless you're willing to update your code whenever this changes. */ protected static class NeedsRule extends Rule { public void body(String ns, String el, String otherGroup) throws Exception { Group group = (Group)digester.peek(); group.addGroup(otherGroup); } } private static final class Type { protected String name; protected String format; Type(String n, String f) { name = n; format = f; } } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/view/VelocityLayoutServlet.java100644 0 0 23066 11360645210 30130 0ustar 0 0 package org.apache.velocity.tools.view; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.io.IOException; import java.io.StringWriter; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.velocity.Template; import org.apache.velocity.context.Context; import org.apache.velocity.exception.MethodInvocationException; /** * Extension of the VelocityViewServlet to perform "two-pass" * layout rendering and allow for a customized error screen. * * @author Nathan Bubna * @version $Id: VelocityLayoutServlet.java 823236 2009-10-08 17:24:48Z nbubna $ */ public class VelocityLayoutServlet extends VelocityViewServlet { /** serial version id */ private static final long serialVersionUID = -4521817395157483487L; /** * The velocity.properties key for specifying the * servlet's error template. */ public static final String PROPERTY_ERROR_TEMPLATE = "tools.view.servlet.error.template"; /** * The velocity.properties key for specifying the * relative directory holding layout templates. */ public static final String PROPERTY_LAYOUT_DIR = "tools.view.servlet.layout.directory"; /** * The velocity.properties key for specifying the * servlet's default layout template's filename. */ public static final String PROPERTY_DEFAULT_LAYOUT = "tools.view.servlet.layout.default.template"; /** * The default error template's filename. */ public static final String DEFAULT_ERROR_TEMPLATE = "Error.vm"; /** * The default layout directory */ public static final String DEFAULT_LAYOUT_DIR = "layout/"; /** * The default filename for the servlet's default layout */ public static final String DEFAULT_DEFAULT_LAYOUT = "Default.vm"; /** * The context key that will hold the content of the screen. * * This key ($screen_content) must be present in the layout * template for the current screen to be rendered. */ public static final String KEY_SCREEN_CONTENT = "screen_content"; /** * The context/parameter key used to specify an alternate * layout to be used for a request instead of the default layout. */ public static final String KEY_LAYOUT = "layout"; /** * The context key that holds the {@link Throwable} that * broke the rendering of the requested screen. */ public static final String KEY_ERROR_CAUSE = "error_cause"; /** * The context key that holds the stack trace of the error that * broke the rendering of the requested screen. */ public static final String KEY_ERROR_STACKTRACE = "stack_trace"; /** * The context key that holds the {@link MethodInvocationException} * that broke the rendering of the requested screen. * * If this value is placed in the context, then $error_cause * will hold the error that this invocation exception is wrapping. */ public static final String KEY_ERROR_INVOCATION_EXCEPTION = "invocation_exception"; protected String errorTemplate; protected String layoutDir; protected String defaultLayout; /** * Initializes Velocity, the view servlet and checks for changes to * the initial layout configuration. * * @param config servlet configuration parameters */ public void init(ServletConfig config) throws ServletException { // first do VVS' init() super.init(config); // check for default template path overrides errorTemplate = getVelocityProperty(PROPERTY_ERROR_TEMPLATE, DEFAULT_ERROR_TEMPLATE); layoutDir = getVelocityProperty(PROPERTY_LAYOUT_DIR, DEFAULT_LAYOUT_DIR); defaultLayout = getVelocityProperty(PROPERTY_DEFAULT_LAYOUT, DEFAULT_DEFAULT_LAYOUT); // preventive error checking! directory must end in / if (!layoutDir.endsWith("/")) { layoutDir += '/'; } // log the current settings getLog().info("VelocityLayoutServlet: Error screen is '"+errorTemplate+"'"); getLog().info("VelocityLayoutServlet: Layout directory is '"+layoutDir+"'"); getLog().info("VelocityLayoutServlet: Default layout template is '"+defaultLayout+"'"); // for efficiency's sake, make defaultLayout a full path now defaultLayout = layoutDir + defaultLayout; } /** * Overrides VelocityViewServlet to check the request for * an alternate layout * * @param ctx context for this request * @param request client request */ protected void fillContext(Context ctx, HttpServletRequest request) { String layout = findLayout(request); if (layout != null) { // let the template know what its new layout is ctx.put(KEY_LAYOUT, layout); } } /** * Searches for a non-default layout to be used for this request. * This implementation checks the request parameters and attributes. */ protected String findLayout(HttpServletRequest request) { // check if an alternate layout has been specified // by way of the request parameters String layout = request.getParameter(KEY_LAYOUT); // also look in the request attributes if (layout == null) { layout = (String)request.getAttribute(KEY_LAYOUT); } return layout; } /** * Overrides VelocityViewServlet.mergeTemplate to do a two-pass * render for handling layouts */ protected void mergeTemplate(Template template, Context context, HttpServletResponse response) throws IOException { // // this section is based on Tim Colson's "two pass render" // // Render the screen content StringWriter sw = new StringWriter(); template.merge(context, sw); // Add the resulting content to the context context.put(KEY_SCREEN_CONTENT, sw.toString()); // Check for an alternate layout // // we check after merging the screen template so the screen // can overrule any layout set in the request parameters // by doing #set( $layout = "MyLayout.vm" ) Object obj = context.get(KEY_LAYOUT); String layout = (obj == null) ? null : obj.toString(); if (layout == null) { // no alternate, use default layout = defaultLayout; } else { // make it a full(er) path layout = layoutDir + layout; } try { //load the layout template template = getTemplate(layout); } catch (Exception e) { getLog().error("Can't load layout \"" + layout + "\"", e); // if it was an alternate layout we couldn't get... if (!layout.equals(defaultLayout)) { // try to get the default layout // if this also fails, let the exception go template = getTemplate(defaultLayout); } } // Render the layout template into the response super.mergeTemplate(template, context, response); } /** * Overrides VelocityViewServlet to display user's custom error template */ protected void error(HttpServletRequest request, HttpServletResponse response, Throwable e) { try { // get a velocity context Context ctx = createContext(request, response); Throwable cause = e; // if it's an MIE, i want the real cause and stack trace! if (cause instanceof MethodInvocationException) { // put the invocation exception in the context ctx.put(KEY_ERROR_INVOCATION_EXCEPTION, e); // get the real cause cause = ((MethodInvocationException)e).getWrappedThrowable(); } // add the cause to the context ctx.put(KEY_ERROR_CAUSE, cause); // grab the cause's stack trace and put it in the context StringWriter sw = new StringWriter(); cause.printStackTrace(new java.io.PrintWriter(sw)); ctx.put(KEY_ERROR_STACKTRACE, sw.toString()); // retrieve and render the error template Template et = getTemplate(errorTemplate); mergeTemplate(et, ctx, response); } catch (Exception e2) { // d'oh! log this getLog().error("Error during error template rendering", e2); // then punt the original to a higher authority super.error(request, response, e); } } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/view/VelocityView.java100644 0 0 101247 11360645210 26236 0ustar 0 0 package org.apache.velocity.tools.view; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.io.InputStream; import java.io.IOException; import java.io.Writer; import java.util.List; import javax.servlet.FilterConfig; import javax.servlet.ServletConfig; import javax.servlet.ServletContext; import javax.servlet.ServletRequest; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.apache.commons.collections.ExtendedProperties; import org.apache.velocity.Template; import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.context.Context; import org.apache.velocity.exception.ResourceNotFoundException; import org.apache.velocity.io.VelocityWriter; import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.runtime.log.Log; import org.apache.velocity.tools.generic.log.LogChuteCommonsLog; import org.apache.velocity.tools.ClassUtils; import org.apache.velocity.tools.Scope; import org.apache.velocity.tools.Toolbox; import org.apache.velocity.tools.ToolboxFactory; import org.apache.velocity.tools.config.ConfigurationCleaner; import org.apache.velocity.tools.config.ConfigurationUtils; import org.apache.velocity.tools.config.FactoryConfiguration; import org.apache.velocity.tools.view.ViewToolContext; import org.apache.velocity.tools.view.context.ChainedContext; import org.apache.velocity.util.SimplePool; /** *

      The class provides the following features:

      *
        *
      • renders Velocity templates
      • *
      • provides support for an auto-loaded, configurable toolbox
      • *
      • provides transparent access to the servlet request attributes, * servlet session attributes and servlet context attributes by * auto-searching them
      • *
      • logs to the logging facility of the servlet API
      • *
      * *

      VelocityView supports the following configuration parameters * in web.xml:

      *
      *
      org.apache.velocity.tools
      *
      Path and name of the toolbox configuration file. The path must be * relative to the web application root directory. If this parameter is * not found, the servlet will check for a toolbox file at * '/WEB-INF/tools.xml'.
      *
      org.apache.velocity.properties
      *
      Path and name of the Velocity configuration file. The path must be * relative to the web application root directory. If this parameter * is not present, Velocity will check for a properties file at * '/WEB-INF/velocity.properties'. If no file is found there, then * Velocity is initialized with the settings in the classpath at * 'org.apache.velocity.tools.view.velocity.properties'.
      *
      * * @author Dave Bryson * @author Jon S. Stevens * @author Gabe Sidler * @author Geir Magnusson Jr. * @author Kent Johnson * @author Daniel Rall * @author Nathan Bubna * * @version $Id: VelocityView.java 511959 2007-02-26 19:24:39Z nbubna $ */ public class VelocityView extends ViewToolManager { /** The HTTP content type context key. */ public static final String CONTENT_TYPE_KEY = "default.contentType"; /** * Key used to access the ServletContext in * the Velocity application attributes. */ public static final String SERVLET_CONTEXT_KEY = ServletContext.class.getName(); /** The default content type for the response */ public static final String DEFAULT_CONTENT_TYPE = "text/html"; /** Default encoding for the output stream */ public static final String DEFAULT_OUTPUT_ENCODING = "ISO-8859-1"; /** * Key used to access the toolbox configuration file path from the * Servlet or webapp init parameters ("org.apache.velocity.tools") * or to access a live {@link FactoryConfiguration} previously * placed in the ServletContext attributes. */ public static final String TOOLS_KEY = ServletUtils.CONFIGURATION_KEY; @Deprecated public static final String DEPRECATED_TOOLS_KEY = "org.apache.velocity.toolbox"; /** * Default toolbox configuration file path. If no alternate value for * this is specified, the servlet will look here. */ public static final String USER_TOOLS_PATH = "/WEB-INF/tools.xml"; @Deprecated public static final String DEPRECATED_USER_TOOLS_PATH = "/WEB-INF/toolbox.xml"; /** * Default Runtime properties. */ public static final String DEFAULT_PROPERTIES_PATH = "/org/apache/velocity/tools/view/velocity.properties"; /** * This is the string that is looked for when getInitParameter is * called ("org.apache.velocity.properties"). */ public static final String PROPERTIES_KEY = "org.apache.velocity.properties"; /** * Default velocity properties file path. If no alternate value for * this is specified, the servlet will look here. */ public static final String USER_PROPERTIES_PATH = "/WEB-INF/velocity.properties"; /** * Controls loading of available default tool configurations * provided by VelocityTools. The default behavior is conditional; * if {@link #DEPRECATION_SUPPORT_MODE_KEY} has not been set to * {@code false} and there is an old {@code toolbox.xml} configuration * present, then the defaults will not be loaded unless you explicitly * set this property to {@code true} in your init params. If there * is no {@code toolbox.xml} and/or the deprecation support is turned off, * then the default tools will be loaded automatically unless you * explicitly set this property to {@code false} in your init params. */ public static final String LOAD_DEFAULTS_KEY = "org.apache.velocity.tools.loadDefaults"; /** * Controls removal of tools or data with invalid configurations * before initialization is finished. * The default is false; set to {@code true} to turn this feature on. */ public static final String CLEAN_CONFIGURATION_KEY = "org.apache.velocity.tools.cleanConfiguration"; /** * Controls whether or not templates can overwrite tool and servlet API * variables in the local context. The default is true; set to {@code false} * to prevent overwriting of any tool variables. */ public static final String USER_OVERWRITE_KEY = "org.apache.velocity.tools.userCanOverwriteTools"; /** * Controls support for deprecated tools and configuration. * The default is {@code true}; set to {@code false} to turn off * support for deprecated tools and configuration. */ public static final String DEPRECATION_SUPPORT_MODE_KEY = "org.apache.velocity.tools.deprecationSupportMode"; private static SimplePool writerPool = new SimplePool(40); private String defaultContentType = DEFAULT_CONTENT_TYPE; private boolean deprecationSupportMode = true; public VelocityView(ServletConfig config) { this(new JeeServletConfig(config)); } public VelocityView(FilterConfig config) { this(new JeeFilterConfig(config)); } public VelocityView(ServletContext context) { this(new JeeContextConfig(context)); } public VelocityView(JeeConfig config) { // suppress auto-config, as we have our own config lookup order here super(config.getServletContext(), false, false); init(config); } @Deprecated protected final void setDeprecationSupportMode(boolean support) { if (deprecationSupportMode != support) { this.deprecationSupportMode = support; debug("deprecationSupportMode is now %s", (support ? "on" : "off")); } } /** * Overrides super class to ensure engine is not set to null. */ @Override public void setVelocityEngine(VelocityEngine engine) { if (engine == null) { throw new NullPointerException("VelocityEngine cannot be null"); } super.setVelocityEngine(engine); } /** * Returns the configured default Content-Type. */ public String getDefaultContentType() { return this.defaultContentType; } /** * Sets the configured default Content-Type. */ public void setDefaultContentType(String type) { if (!defaultContentType.equals(type)) { this.defaultContentType = type; debug("Default Content-Type was changed to %s", type); } } /** * Simplifies process of getting a property from VelocityEngine, * because the VelocityEngine interface sucks compared to the singleton's. * Use of this method assumes that {@link #init(JeeConfig,VelocityEngine)} * has already been called. */ protected String getProperty(String key, String alternate) { String prop = (String)velocity.getProperty(key); if (prop == null || prop.length() == 0) { return alternate; } return prop; } /** *

      Initializes ToolboxFactory, VelocityEngine, and sets default * encoding for processing requests.

      * *

      NOTE: If no charset is specified in the default.contentType * property (in your velocity.properties) and you have specified * an output.encoding property, then that will be used as the * charset for the default content-type of pages served by this * servlet.

      * * @param config servlet configuation */ protected void init(JeeConfig config) { // create an engine if none is set yet // (servletContext and factory should already be set by now if (this.velocity == null) { this.velocity = new VelocityEngine(); } // default is true for these, so just watch for false String depMode = config.findInitParameter(DEPRECATION_SUPPORT_MODE_KEY); if (depMode != null && depMode.equalsIgnoreCase("false")) { setDeprecationSupportMode(false); } String allowOverwrite = config.findInitParameter(USER_OVERWRITE_KEY); if (allowOverwrite != null && allowOverwrite.equalsIgnoreCase("false")) { setUserCanOverwriteTools(false); } // configure and initialize the VelocityEngine init(config, velocity); // configure the ToolboxFactory configure(config, factory); // set encoding & content-type setEncoding(config); } /** * Initializes the Velocity runtime, first calling * loadConfiguration(JeeConfig) to get a * org.apache.commons.collections.ExtendedProperties * of configuration information * and then calling velocityEngine.init(). Override this * to do anything to the environment before the * initialization of the singleton takes place, or to * initialize the singleton in other ways. * * @param config servlet configuration parameters */ protected void init(JeeConfig config, final VelocityEngine velocity) { // register this engine to be the default handler of log messages // if the user points commons-logging to the LogSystemCommonsLog LogChuteCommonsLog.setVelocityLog(getLog()); // put the servlet context into Velocity's application attributes, // where the WebappResourceLoader can find them velocity.setApplicationAttribute(SERVLET_CONTEXT_KEY, this.servletContext); // configure the engine itself configure(config, velocity); // now all is ready - init Velocity try { velocity.init(); } catch(Exception e) { String msg = "Could not initialize VelocityEngine"; getLog().error(msg, e); e.printStackTrace(); throw new RuntimeException(msg + ": "+e, e); } } protected void configure(final JeeConfig config, final VelocityEngine velocity) { // first get the default properties, and bail if we don't find them ExtendedProperties defaultProperties = getProperties(DEFAULT_PROPERTIES_PATH, true); // if using Velocity engine prior to 1.6.x, remove WebappUberspector // (this hack will disappear once tools require Velocity 1.6.x+) try { Class.forName("org.apache.velocity.tools.view.WebappUberspector"); } catch(Throwable t) { // remove WebappUberspector from the list of introspectors List introspectors = defaultProperties.getList(VelocityEngine.UBERSPECT_CLASSNAME); introspectors.remove("org.apache.velocity.tools.view.WebappUberspector"); defaultProperties.setProperty(VelocityEngine.UBERSPECT_CLASSNAME,introspectors); } velocity.setExtendedProperties(defaultProperties); // check for application-wide user props in the context init params String appPropsPath = servletContext.getInitParameter(PROPERTIES_KEY); setProps(velocity, appPropsPath, true); // check for servlet-wide user props in the config init params at the // conventional location, and be silent if they're missing setProps(velocity, USER_PROPERTIES_PATH, false); // check for a custom location for servlet-wide user props String servletPropsPath = config.getInitParameter(PROPERTIES_KEY); setProps(velocity, servletPropsPath, true); } private boolean setProps(VelocityEngine velocity, String path, boolean require) { if (path == null) { // only bother with this if a path was given return false; } // this will throw an exception if require is true and there // are no properties at the path. if require is false, this // will return null when there's no properties at the path ExtendedProperties props = getProperties(path, require); if (props == null) { return false; } debug("Configuring Velocity with properties at: %s", path); // these props will override those already set velocity.setExtendedProperties(props); // notify that new props were set return true; } /** * Here's the configuration lookup/loading order: *
        *
      1. If deprecationSupportMode is true: *
          *
        1. Config file optionally specified by {@code org.apache.velocity.toolbox} init-param (servlet or servletContext)
        2. *
        3. If none, config file optionally at {@code /WEB-INF/toolbox.xml} (deprecated conventional location)
        4. *
        *
      2. *
      3. If no old toolbox or loadDefaults is true, {@link ConfigurationUtils#getDefaultTools()}
      4. *
      5. {@link ConfigurationUtils#getAutoLoaded}(false)
      6. *
      7. Config file optionally specified by servletContext {@code org.apache.velocity.tools} init-param
      8. *
      9. Config file optionally at {@code /WEB-INF/tools.xml} (new conventional location)
      10. *
      11. Config file optionally specified by servlet {@code org.apache.velocity.tools} init-param
      12. *
      * Remember that as these configurations are added on top of each other, * the newer values will always override the older ones. Also, once they * are all loaded, this method can "clean" your configuration of all invalid * tool, toolbox or data configurations if you set the * {@code org.apache.velocity.tools.cleanConfiguration} init-param to true in * either your servlet or servletContext init-params. */ protected void configure(final JeeConfig config, final ToolboxFactory factory) { FactoryConfiguration factoryConfig = new FactoryConfiguration("VelocityView.configure(config,factory)"); boolean hasOldToolbox = false; if (this.deprecationSupportMode) { FactoryConfiguration oldToolbox = getDeprecatedConfig(config); if (oldToolbox != null) { hasOldToolbox = true; factoryConfig.addConfiguration(oldToolbox); } } // only load the default tools if they have explicitly said to // or if they are not using an old toolbox and have said nothing String loadDefaults = config.findInitParameter(LOAD_DEFAULTS_KEY); if ((!hasOldToolbox && loadDefaults == null) || "true".equalsIgnoreCase(loadDefaults)) { // add all available default tools getLog().trace("Loading default tools configuration..."); factoryConfig.addConfiguration(ConfigurationUtils.getDefaultTools()); } else { // let the user know that the defaults were suppressed debug("Default tools configuration has been suppressed%s", (hasOldToolbox ? " to avoid conflicts with older application's context and toolbox definition." : ".")); } // this gets the auto loaded config from the classpath // this doesn't include defaults since they're handled already // and it could theoretically pick up an auto-loaded config from the // filesystem, but that is highly unlikely to happen in a webapp env FactoryConfiguration autoLoaded = ConfigurationUtils.getAutoLoaded(false); factoryConfig.addConfiguration(autoLoaded); // check for application-wide user config in the context init params String appToolsPath = servletContext.getInitParameter(TOOLS_KEY); setConfig(factoryConfig, appToolsPath, true); // check for user configuration at the conventional location, // and be silent if they're missing setConfig(factoryConfig, USER_TOOLS_PATH, false); // check for a custom location for servlet-wide user props String servletToolsPath = config.getInitParameter(TOOLS_KEY); setConfig(factoryConfig, servletToolsPath, true); // check for "injected" configuration in application attributes FactoryConfiguration injected = ServletUtils.getConfiguration(servletContext); if (injected != null) { debug("Adding configuration instance in servletContext attributes as '%s'", TOOLS_KEY); factoryConfig.addConfiguration(injected); } // see if we should only keep valid tools, data, and properties String cleanConfig = config.findInitParameter(CLEAN_CONFIGURATION_KEY); if ("true".equals(cleanConfig)) { // remove invalid tools, data, and properties from the configuration ConfigurationCleaner cleaner = new ConfigurationCleaner(); cleaner.setLog(getLog()); cleaner.clean(factoryConfig); } // apply this configuration to the specified factory debug("Configuring factory with: %s", factoryConfig); configure(factoryConfig); } /** * First tries to find a path to a toolbox under the deprecated * {@code org.apache.velocity.toolbox} key. * If found, it tries to load the configuration there and will blow up * if there is no config file there. * If not found, it looks for a config file at /WEB-INF/toolbox.xml * (the deprecated default location) and tries to load it if found. */ @Deprecated protected FactoryConfiguration getDeprecatedConfig(JeeConfig config) { FactoryConfiguration toolbox = null; // look for specified path under the deprecated toolbox key String oldPath = config.findInitParameter(DEPRECATED_TOOLS_KEY); if (oldPath != null) { // ok, they said the toolbox.xml should be there // so this should blow up if it is not toolbox = getConfiguration(oldPath, true); } else { // check for deprecated user configuration at the old conventional // location. be silent if missing, log deprecation warning otherwise oldPath = DEPRECATED_USER_TOOLS_PATH; toolbox = getConfiguration(oldPath); } if (toolbox != null) { debug("Loaded deprecated configuration from: %s", oldPath); getLog().warn("Please upgrade to new \"/WEB-INF/tools.xml\" format and conventional location."+ " Support for \"/WEB-INF/toolbox.xml\" format and conventional file name will "+ "be removed in a future version."); } return toolbox; } private boolean setConfig(FactoryConfiguration factory, String path, boolean require) { if (path == null) { // only bother with this if a path was given return false; } // this will throw an exception if require is true and there // is no tool config at the path. if require is false, this // will return null when there's no tool config at the path FactoryConfiguration config = getConfiguration(path, require); if (config == null) { return false; } debug("Loaded configuration from: %s", path); factory.addConfiguration(config); // notify that new config was added return true; } protected InputStream getInputStream(String path, boolean required) { // first, search the classpath InputStream inputStream = ServletUtils.getInputStream(path, this.servletContext); // if we didn't find one if (inputStream == null) { String msg = "Did not find resource at: "+path; if (required) { getLog().error(msg); throw new ResourceNotFoundException(msg); } debug(msg); return null; } return inputStream; } protected ExtendedProperties getProperties(String path) { return getProperties(path, false); } protected ExtendedProperties getProperties(String path, boolean required) { if (getLog().isTraceEnabled()) { getLog().trace("Searching for properties at: "+path); } InputStream inputStream = getInputStream(path, required); if (inputStream == null) { return null; } ExtendedProperties properties = new ExtendedProperties(); try { properties.load(inputStream); } catch (IOException ioe) { String msg = "Failed to load properties at: "+path; getLog().error(msg, ioe); if (required) { throw new RuntimeException(msg, ioe); } } finally { try { if (inputStream != null) { inputStream.close(); } } catch (IOException ioe) { getLog().error("Failed to close input stream for "+path, ioe); } } return properties; } protected FactoryConfiguration getConfiguration(String path) { return getConfiguration(path, false); } protected FactoryConfiguration getConfiguration(String path, boolean required) { if (getLog().isTraceEnabled()) { getLog().trace("Searching for configuration at: "+path); } FactoryConfiguration config = null; try { config = ServletUtils.getConfiguration(path, this.servletContext, this.deprecationSupportMode); if (config == null) { String msg = "Did not find resource at: "+path; if (required) { getLog().error(msg); throw new ResourceNotFoundException(msg); } else { debug(msg); } } } catch (ResourceNotFoundException rnfe) { // no need to re-log this throw rnfe; } catch (RuntimeException re) { if (required) { getLog().error(re.getMessage(), re); throw re; } getLog().debug(re.getMessage(), re); } return config; } protected void setEncoding(JeeConfig config) { // we can get these now that velocity is initialized this.defaultContentType = getProperty(CONTENT_TYPE_KEY, DEFAULT_CONTENT_TYPE); String encoding = getProperty(RuntimeConstants.OUTPUT_ENCODING, DEFAULT_OUTPUT_ENCODING); // For non Latin-1 encodings, ensure that the charset is // included in the Content-Type header. if (!DEFAULT_OUTPUT_ENCODING.equalsIgnoreCase(encoding)) { int index = defaultContentType.lastIndexOf("charset"); if (index < 0) { // the charset specifier is not yet present in header. // append character encoding to default content-type this.defaultContentType += "; charset=" + encoding; } else { // The user may have configuration issues. getLog().info("Charset was already " + "specified in the Content-Type property. " + "Output encoding property will be ignored."); } } debug("Default Content-Type is: %s", defaultContentType); } /******************* REQUEST PROCESSING ****************************/ /** * * * @param request HttpServletRequest object containing client request * @param response HttpServletResponse object for the response * @return the {@link Context} prepared and used to perform the rendering * to allow proper cleanup afterward */ public Context render(HttpServletRequest request, HttpServletResponse response) throws IOException { // then get a context Context context = createContext(request, response); // get the template Template template = getTemplate(request, response); // merge the template and context into the response merge(template, context, response.getWriter()); return context; } public Context render(HttpServletRequest request, Writer out) throws IOException { // then get a context Context context = createContext(request, null); // get the template Template template = getTemplate(request); // merge the template and context into the writer merge(template, context, out); return context; } /** *

      Creates and returns an initialized Velocity context.

      * * A new context of class {@link ViewToolContext} is created and * initialized. * * @param request servlet request from client * @param response servlet reponse to client */ @Override public ViewToolContext createContext(HttpServletRequest request, HttpServletResponse response) { ViewToolContext ctx; if (this.deprecationSupportMode) { ctx = new ChainedContext(velocity, request, response, servletContext); } else { ctx = new ViewToolContext(velocity, request, response, servletContext); } prepareContext(ctx, request); return ctx; } /** *

      Gets the requested template.

      * * @param request client request * @return Velocity Template object or null */ public Template getTemplate(HttpServletRequest request) { return getTemplate(request, null); } public Template getTemplate(HttpServletRequest request, HttpServletResponse response) { String path = ServletUtils.getPath(request); if (response == null) { return getTemplate(path); } else { return getTemplate(path, response.getCharacterEncoding()); } } /** * Retrieves the requested template. * * @param name The file name of the template to retrieve relative to the * template root. * @return The requested template. * @throws ResourceNotFoundException if template not found * from any available source. * @throws ParseErrorException if template cannot be parsed due * to syntax (or other) error. */ public Template getTemplate(String name) { return getTemplate(name, null); } /** * Retrieves the requested template with the specified character encoding. * * @param name The file name of the template to retrieve relative to the * template root. * @param encoding the character encoding of the template * @return The requested template. * @throws ResourceNotFoundException if template not found * from any available source. * @throws ParseErrorException if template cannot be parsed due * to syntax (or other) error. */ public Template getTemplate(String name, String encoding) { try { if (encoding == null) { return velocity.getTemplate(name); } else { return velocity.getTemplate(name, encoding); } } catch (RuntimeException e) // FIXME This is useless with Velocity 1.7 { throw e; } catch (Exception e) // FIXME This is useless with Velocity 1.7 { throw new RuntimeException(e); } } /** * Merges the template with the context. Only override this if you really, really * really need to. (And don't call us with questions if it breaks :) * * @param template template being rendered * @param context Context created by the {@link #createContext} * @param writer into which the content is rendered */ public void merge(Template template, Context context, Writer writer) throws IOException { VelocityWriter vw = null; try { vw = (VelocityWriter)writerPool.get(); if (vw == null) { vw = new VelocityWriter(writer, 4 * 1024, true); } else { vw.recycle(writer); } performMerge(template, context, vw); // flush writer but don't close to allow us to play nicely with others. vw.flush(); } finally { if (vw != null) { try { /* This hack sets the VelocityWriter's internal ref to the * PrintWriter to null to keep memory free while * the writer is pooled. See bug report #18951 */ vw.recycle(null); writerPool.put(vw); } catch (Exception e) { getLog().error("Trouble releasing VelocityWriter: " + e.getMessage(), e); } } } } /** * This is here so developers may override it and gain access to the * Writer which the template will be merged into. See * VELTOOLS-7 * for discussion of this. * * @param template template object returned by the handleRequest() method * @param context Context created by the {@link #createContext} * @param writer a VelocityWriter that the template is merged into */ protected void performMerge(Template template, Context context, Writer writer) throws IOException { template.merge(context, writer); } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/view/VelocityViewFilter.java100644 0 0 16657 11110347752 27401 0ustar 0 0 package org.apache.velocity.tools.view; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.velocity.context.Context; import org.apache.velocity.tools.Toolbox; import org.apache.velocity.tools.view.VelocityView; import org.apache.velocity.tools.view.ViewToolContext; /** *

      A filter to ensure VelocityTools {@link Toolbox}es are * available in the request/session/application scopes. This * can simplify the process of integration with other frameworks.

      * *

      VelocityViewFilter supports the following configuration parameters * in web.xml:

      *
      *
      org.apache.velocity.tools
      *
      Path and name of the toolbox configuration file. The path must be * relative to the web application root directory. If this parameter is * not found, the servlet will check for a toolbox file at * '/WEB-INF/tools.xml'.
      *
      org.apache.velocity.properties
      *
      Path and name of the Velocity configuration file. The path must be * relative to the web application root directory. If this parameter * is not present, Velocity will check for a properties file at * '/WEB-INF/velocity.properties'. If no file is found there, then * Velocity is initialized with the settings in the classpath at * 'org.apache.velocity.tools.view.velocity.properties'.
      *
      org.apache.velocity.tools.loadDefaults
      *
      By default, this is {@code true}. If set to {@code false}, then * the default toolbox configuration will not be added to your (if any) * custom configuration. NOTE: The default configuration will also be * suppressed if you are using a deprecated toolbox.xml format and do not * explicitly set this to {@code true}.
      *
      org.apache.velocity.tools.cleanConfiguration
      *
      By default, this is {@code false}. If set to {@code true}, then * then the final toolbox configuration (the combination of any custom * one(s) provided by yourself and/or the default configuration(s)) * will have all invalid tools, properties, and/or data removed prior to * configuring the ToolboxFactory for this servlet by a * {@link org.apache.velocity.tools.config.ConfigurationCleaner}
      *
      org.apache.velocity.tools.shared.config
      *
      By default, this is {@code true}. If set to {@code false}, then * the {@link VelocityView} used by this filter will not be shared * with other VelocityViewFilters, {@link VelocityViewServlet}s or * {@link org.apache.velocity.tools.view.jsp.VelocityViewTag}s in the * application.
      *
      org.apache.velocity.tools.context.key
      *
      If you set a value for this property, this filter will create * and prepare a {@link ViewToolContext} for each request, and then * place it into the request attributes under the key you set. This * is primarily for those who have this filter NOT share a config * (i.e. non-shared VelocityView) and thus will find it easier to * retrieve a working context from the request attributes than it * would be to get the VelocityView for this filter and have it * create the context for them. Most users will have no trouble * getting a shared VelocityView and creating the context themselves.
      *
      * * @version $Id: VelocityViewFilter.java 611011 2008-01-11 01:32:59Z nbubna $ */ public class VelocityViewFilter implements Filter { public static final String CONTEXT_KEY = "org.apache.velocity.tools.context.key"; private VelocityView view; private FilterConfig config; private String contextKey = null; /** *

      Initializes VelocityView used to process requests. * Called by the servlet container on loading.

      * * @param config filter configuation */ public void init(FilterConfig config) throws ServletException { this.config = config; // init the VelocityView (if it hasn't been already) getVelocityView(); // look for a context key contextKey = findInitParameter(CONTEXT_KEY); } protected FilterConfig getFilterConfig() { return this.config; } protected VelocityView getVelocityView() { if (this.view == null) { this.view = ServletUtils.getVelocityView(getFilterConfig()); assert (view != null); } return this.view; } protected String getContextKey() { return this.contextKey; } /** * Looks up an init parameter with the specified key in either the * FilterConfig or, failing that, in the ServletContext. */ protected String findInitParameter(String key) { FilterConfig conf = getFilterConfig(); String param = conf.getInitParameter(key); if (param == null || param.length() == 0) { param = conf.getServletContext().getInitParameter(key); } return param; } /** * Simply prepares the request (and/or session) toolbox(es) * for other filters, servlets or whatnot to use. If a context key * has been provided in the init-params of the filter or webapp, * then this will also create a {@link ViewToolContext} and put * it in the request attributes under that key. */ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws java.io.IOException, ServletException { // can/should we create the context for the request? if (contextKey != null && request instanceof HttpServletRequest) { Context context = createContext((HttpServletRequest)request, (HttpServletResponse)response); request.setAttribute(contextKey, context); } else { // just publish the toolboxes getVelocityView().publishToolboxes(request); } // move down the chain chain.doFilter(request, response); } protected Context createContext(HttpServletRequest request, HttpServletResponse response) { return getVelocityView().createContext(request, response); } public void destroy() { // do anything else? this.view = null; this.config = null; this.contextKey = null; } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/view/VelocityViewServlet.java100644 0 0 36607 11360645210 27572 0ustar 0 0 package org.apache.velocity.tools.view; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; import java.io.Writer; import javax.servlet.ServletConfig; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang.StringEscapeUtils; import org.apache.velocity.Template; import org.apache.velocity.context.Context; import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.exception.ResourceNotFoundException; import org.apache.velocity.runtime.log.Log; /** *

      A servlet to process Velocity templates. This is comparable to the * the JspServlet for JSP-based applications.

      * *

      The servlet provides the following features:

      *
        *
      • renders Velocity templates
      • *
      • provides support for an auto-loaded, configurable toolbox
      • *
      • provides transparent access to the servlet request attributes, * servlet session attributes and servlet context attributes by * auto-searching them
      • *
      • logs to the logging facility of the servlet API
      • *
      * *

      VelocityViewServlet supports the following configuration parameters * in web.xml:

      *
      *
      org.apache.velocity.tools
      *
      Path and name of the toolbox configuration file. The path must be * relative to the web application root directory. If this parameter is * not found, the servlet will check for a toolbox file at * '/WEB-INF/tools.xml'.
      *
      org.apache.velocity.properties
      *
      Path and name of the Velocity configuration file. The path must be * relative to the web application root directory. If this parameter * is not present, Velocity will check for a properties file at * '/WEB-INF/velocity.properties'. If no file is found there, then * Velocity is initialized with the settings in the classpath at * 'org.apache.velocity.tools.view.velocity.properties'.
      *
      org.apache.velocity.tools.shared.config
      *
      By default, this is {@code true}. If set to {@code false}, then * the {@link VelocityView} used by this servlet will not be shared * with {@link VelocityViewFilter}s, other VelocityViewServlets or * {@link org.apache.velocity.tools.view.jsp.VelocityViewTag}s in the * application.
      *
      org.apache.velocity.tools.loadDefaults
      *
      By default, this is {@code true}. If set to {@code false}, then * the default toolbox configuration will not be added to your (if any) * custom configuration. NOTE: The default configuration will also be * suppressed if you are using a deprecated toolbox.xml format and do not * explicitly set this to {@code true}.
      *
      org.apache.velocity.tools.cleanConfiguration
      *
      By default, this is {@code false}. If set to {@code true}, then * then the final toolbox configuration (the combination of any custom * one(s) provided by yourself and/or the default configuration(s)) * will have all invalid tools, properties, and/or data removed prior to * configuring the ToolboxFactory for this servlet by a * {@link org.apache.velocity.tools.config.ConfigurationCleaner}
      *
      org.apache.velocity.tools.bufferOutput
      *
      By default, the processed templates are merged directly into * the {@link HttpServletResponse}'s writer. If this parameter is * set to {@code true}, then the output of the merge process will be * buffered before being fed to the response. This allows the {@link #error} * method to be overridden to return a "500 Internal Server Error" or * at least not return any of the failed request content. Essentially, * setting this to {@code true} degrades performance in order to enable * a more "correct" error response"
      * *
      * * @version $Id: VelocityViewServlet.java 791530 2009-07-06 16:06:52Z nbubna $ */ public class VelocityViewServlet extends HttpServlet { public static final String BUFFER_OUTPUT_PARAM = "org.apache.velocity.tools.bufferOutput"; private static final long serialVersionUID = -3329444102562079189L; private transient VelocityView view; private boolean bufferOutput = false; /** *

      Initializes servlet and VelocityView used to process requests. * Called by the servlet container on loading.

      * * @param config servlet configuation */ public void init(ServletConfig config) throws ServletException { super.init(config); // init the VelocityView (if it hasn't been already) getVelocityView(); String buffer = findInitParameter(config, BUFFER_OUTPUT_PARAM); if (buffer != null && buffer.equals("true")) { this.bufferOutput = true; getLog().debug("VelocityViewServlet will buffer mergeTemplate output."); } } /** * Looks up an init parameter with the specified key in either the * ServletConfig or, failing that, in the ServletContext. */ protected String findInitParameter(ServletConfig config, String key) { // check the servlet config String param = config.getInitParameter(key); if (param == null || param.length() == 0) { // check the servlet context ServletContext servletContext = config.getServletContext(); param = servletContext.getInitParameter(key); } return param; } protected VelocityView getVelocityView() { if (this.view == null) { setVelocityView(ServletUtils.getVelocityView(getServletConfig())); assert (this.view != null); } return this.view; } protected void setVelocityView(VelocityView view) { this.view = view; } protected String getVelocityProperty(String name, String alternate) { return getVelocityView().getProperty(name, alternate); } protected Log getLog() { return getVelocityView().getLog(); } /** * Handles GET - calls doRequest() */ public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doRequest(request, response); } /** * Handle a POST request - calls doRequest() */ public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doRequest(request, response); } /** * Handles with both GET and POST requests * * @param request HttpServletRequest object containing client request * @param response HttpServletResponse object for the response */ protected void doRequest(HttpServletRequest request, HttpServletResponse response) throws IOException { Context context = null; try { // then get a context context = createContext(request, response); // call standard extension point fillContext(context, request); setContentType(request, response); // get the template Template template = handleRequest(request, response, context); // merge the template and context into the response mergeTemplate(template, context, response); } catch (IOException e) { error(request, response, e); throw e; } catch (ResourceNotFoundException e) { manageResourceNotFound(request, response, e); } catch (RuntimeException e) { error(request, response, e); throw e; } finally { requestCleanup(request, response, context); } } /** *

      This was a common extension point, but now it is usually * simpler to override {@link #fillContext} to add custom things * to the {@link Context} or override a {@link #getTemplate} * method to change how {@link Template}s are retrieved. * This is only recommended for more complicated use-cases.

      * * @param request client request * @param response client response * @param ctx VelocityContext to fill * @return Velocity Template object or null */ protected Template handleRequest(HttpServletRequest request, HttpServletResponse response, Context ctx) { return getTemplate(request, response); } protected Context createContext(HttpServletRequest request, HttpServletResponse response) { return getVelocityView().createContext(request, response); } protected void fillContext(Context context, HttpServletRequest request) { // this implementation does nothing } /** * Sets the content type of the response. This is available to be overriden * by a derived class. * *

      The default implementation is : * * response.setContentType(getVelocityView().getDefaultContentType()); * * where defaultContentType is set to the value of the default.contentType * property, or "text/html" if that was not set for the {@link VelocityView}. *

      * * @param request servlet request from client * @param response servlet reponse to client */ protected void setContentType(HttpServletRequest request, HttpServletResponse response) { response.setContentType(getVelocityView().getDefaultContentType()); } protected Template getTemplate(HttpServletRequest request, HttpServletResponse response) { return getVelocityView().getTemplate(request, response); } protected Template getTemplate(String name) { return getVelocityView().getTemplate(name); } protected void mergeTemplate(Template template, Context context, HttpServletResponse response) throws IOException { Writer writer; if (this.bufferOutput) { writer = new StringWriter(); } else { writer = response.getWriter(); } getVelocityView().merge(template, context, writer); if (this.bufferOutput) { response.getWriter().write(writer.toString()); } } /** * Invoked when there is an error thrown in any part of doRequest() processing. *

      * Default will send a simple HTML response indicating there was a problem. * * @param request original HttpServletRequest from servlet container. * @param response HttpServletResponse object from servlet container. * @param e Exception that was thrown by some other part of process. */ protected void error(HttpServletRequest request, HttpServletResponse response, Throwable e) { if (!response.isCommitted()) { return; } try { String path = ServletUtils.getPath(request); getLog().error("Error processing a template for path '" + path + "'", e); StringBuilder html = new StringBuilder(); html.append("\n"); html.append("Error\n"); html.append("\n"); html.append("

      VelocityView : Error processing a template for path '"); html.append(path); html.append("'

      \n"); Throwable cause = e; String why = cause.getMessage(); if (why != null && why.length() > 0) { html.append(StringEscapeUtils.escapeHtml(why)); html.append("\n
      \n"); } //TODO: add line/column/template info for parse errors et al // if it's an MIE, i want the real stack trace! if (cause instanceof MethodInvocationException) { // get the real cause cause = ((MethodInvocationException)cause).getWrappedThrowable(); } StringWriter sw = new StringWriter(); cause.printStackTrace(new PrintWriter(sw)); html.append("
      \n");
                  html.append(StringEscapeUtils.escapeHtml(sw.toString()));
                  html.append("
      \n"); html.append("\n"); html.append(""); response.getWriter().write(html.toString()); } catch (Exception e2) { // clearly something is quite wrong. // let's log the new exception then give up and // throw a runtime exception that wraps the first one String msg = "Exception while printing error screen"; getLog().error(msg, e2); throw new RuntimeException(msg, e); } } /** * Manages the {@link ResourceNotFoundException} to send an HTTP 404 result * when needed. * * @param request The request object. * @param response The response object. * @param e The exception to check. * @throws IOException If something goes wrong when sending the HTTP error. */ protected void manageResourceNotFound(HttpServletRequest request, HttpServletResponse response, ResourceNotFoundException e) throws IOException { String path = ServletUtils.getPath(request); if (getLog().isDebugEnabled()) { getLog().debug("Resource not found for path '" + path + "'", e); } String message = e.getMessage(); if (!response.isCommitted() && path != null && message != null && message.contains("'" + path + "'")) { response.sendError(HttpServletResponse.SC_NOT_FOUND, path); } else { error(request, response, e); throw e; } } /** * Cleanup routine called at the end of the request processing sequence * allows a derived class to do resource cleanup or other end of * process cycle tasks. This default implementation does nothing. * * @param request servlet request from client * @param response servlet response * @param context Context that was merged with the requested template */ protected void requestCleanup(HttpServletRequest request, HttpServletResponse response, Context context) { } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/view/ViewContext.java100644 0 0 6357 11030275251 26030 0ustar 0 0 package org.apache.velocity.tools.view; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.ServletContext; import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.context.Context; /** *

      This interface provides view tools in a servlet environment * access to relevant context information, like servlet request, servlet * context and the velocity context.

      *

      The standard implementation is {@link ViewToolContext}.

      * * @author Gabe Sidler * @author Geir Magnusson Jr. * @author Nathan Bubna * @version $Id: ViewContext.java 651469 2008-04-25 00:46:13Z nbubna $ */ public interface ViewContext { /** Key used for the HTTP request object. */ public static final String REQUEST = "request"; /** Key used for the HTTP response object. */ public static final String RESPONSE = "response"; /** Key used for the HTTP session object. */ public static final String SESSION = "session"; /** Key used for the servlet context object in templates. */ public static final String APPLICATION = "application"; /** Key used for the servlet context object in tool properties. */ public static final String SERVLET_CONTEXT_KEY = "servletContext"; /** Default key used to store toolboxes in request/session/application attributes. */ public static final String DEFAULT_TOOLBOX_KEY = VelocityView.DEFAULT_TOOLBOX_KEY; /** *

      Returns the instance of {@link HttpServletRequest} for this request.

      */ public HttpServletRequest getRequest(); /** *

      Returns the instance of {@link HttpServletResponse} for this request.

      */ public HttpServletResponse getResponse(); /** *

      Returns the instance of {@link ServletContext} for this request.

      */ public ServletContext getServletContext(); /** *

      Searches for the named attribute in request, session (if valid), * and application scope(s) in order and returns the value associated * or null.

      * * @since VelocityTools 1.1 */ public Object getAttribute(String key); /** *

      Returns a reference to the current Velocity context.

      */ public Context getVelocityContext(); /** *

      Returns the current VelocityEngine instance.

      */ public VelocityEngine getVelocityEngine(); } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/view/ViewContextTool.java100644 0 0 6410 11202122665 26655 0ustar 0 0 package org.apache.velocity.tools.view; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.util.Enumeration; import java.util.Set; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import javax.servlet.ServletContext; import org.apache.velocity.tools.generic.ContextTool; import org.apache.velocity.tools.generic.ValueParser; import org.apache.velocity.tools.view.ViewContext; /** *

      Extension of {@link ContextTool} that includes keys and values * from the {@link HttpServletRequest}, {@link HttpSession} and * {@link ServletContext}.

      *

       * Template example(s):
       *  #foreach( $key in $context.keys )
       *    $key = $context.get($key)
       *  #end
       *
       * Toolbox configuration:
       * <tools>
       *   <toolbox scope="request">
       *     <tool class="org.apache.velocity.tools.view.ViewContextTool"/>
       *   </toolbox>
       * </tools>
       * 

      * *

      This class is only designed for use as a request-scope VelocityView tool.

      * * @author Nathan Bubna * @since VelocityTools 2.0 * @version $Id: ViewContextTool.java 385122 2006-03-11 18:37:42Z nbubna $ */ public class ViewContextTool extends ContextTool { protected HttpServletRequest request; protected HttpSession session; protected ServletContext application; @Override protected void configure(ValueParser parser) { // do ContextTool config first super.configure(parser); this.request = (HttpServletRequest)parser.getValue(ViewContext.REQUEST); this.session = request.getSession(false); this.application = (ServletContext)parser.getValue(ViewContext.SERVLET_CONTEXT_KEY); } @Override protected void fillKeyset(Set keys) { // start with the standard ContextTool's keys super.fillKeyset(keys); // get request attribute keys Enumeration e = request.getAttributeNames(); while (e.hasMoreElements()) { keys.add(e.nextElement()); } // get session attribute keys if we have a session if (session != null) { e = session.getAttributeNames(); while (e.hasMoreElements()) { keys.add(e.nextElement()); } } // get request attribute keys e = application.getAttributeNames(); while (e.hasMoreElements()) { keys.add(e.nextElement()); } } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/view/ViewToolContext.java100644 0 0 23060 11360645210 26676 0ustar 0 0 package org.apache.velocity.tools.view; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.util.HashMap; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import javax.servlet.ServletContext; import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.context.Context; import org.apache.velocity.tools.ToolContext; import org.apache.velocity.tools.Toolbox; /** *

      {@link ToolContext} implementation specific to the servlet environment.

      * *

      It provides the following special features:

      *
        *
      • puts the request, response, session, and servlet context objects * into the Velocity context for direct access, and keeps them * read-only
      • *
      • supports a read-only toolbox of view tools
      • *
      • auto-searches servlet request attributes, session attributes and * servlet context attribues for objects
      • *
      * *

      The {@link #get(String key)} method implements the following search order * for objects:

      *
        *
      1. tool in a request scoped toolbox
      2. *
      3. tool in a session scoped toolbox
      4. *
      5. tool in a application scoped toolbox
      6. *
      7. request, response, session, or servlet context
      8. *
      9. object in the local map of objects (traditional use)
      10. *
      11. request attributes, session attributes, servlet context attributes
      12. *
      * *

      The purpose of this class is to make it easy for web designer to work * with Java servlet based web applications. They do not need to be concerned * with the concepts of request, session or application attributes and the * lifetime of objects in these scopes.

      * *

      Note that the put() method always puts objects into the local map * and does not allow tools or servlet classes to be overridden. *

      * * @author Geir Magnusson Jr. * @author Gabe Sidler * @author Nathan Bubna * * @version $Id: ViewContext.java 514727 2007-03-05 16:49:03Z nbubna $ */ public class ViewToolContext extends ToolContext implements ViewContext { private final HttpServletRequest request; private final HttpServletResponse response; private final ServletContext application; private final VelocityEngine velocity; private String toolboxKey = DEFAULT_TOOLBOX_KEY; public ViewToolContext(VelocityEngine velocity, HttpServletRequest request, HttpServletResponse response, ServletContext application) { super(velocity); this.velocity = velocity; this.request = request; this.response = response; this.application = application; // automagically set common tool properties putToolProperties(); } protected void setToolboxKey(String key) { this.toolboxKey = key; } protected void putToolProperties() { putToolProperty(REQUEST, getRequest()); if (getRequest() != null) { putToolProperty(LOCALE_KEY, getRequest().getLocale()); } putToolProperty(RESPONSE, getResponse()); putToolProperty(SESSION, getSession()); putToolProperty(SERVLET_CONTEXT_KEY, getServletContext()); putToolProperty(PATH_KEY, ServletUtils.getPath(getRequest())); } protected List getToolboxes() { // this means once we find any toolbox, // then we stop looking. adding boxes to // the request/session/application attributes // later will not work. once one is in, any // later additions must be via addToolbox(Toolbox) // or addToolboxesUnderKey(String toolboxKey) if (super.getToolboxes().isEmpty()) { addToolboxesUnderKey(this.toolboxKey); } return super.getToolboxes(); } protected void addToolboxesUnderKey(String toolboxKey) { Toolbox reqTools = (Toolbox)getRequest().getAttribute(toolboxKey); if (reqTools != null) { addToolbox(reqTools); } if (getSession() != null) { Toolbox sessTools = (Toolbox)getSession().getAttribute(toolboxKey); if (sessTools != null) { addToolbox(sessTools); } } Toolbox appTools = (Toolbox)getServletContext().getAttribute(toolboxKey); if (appTools != null) { addToolbox(appTools); } } /** *

      Looks up and returns the object with the specified key.

      *

      See the class documentation for more details.

      * * @see #setUserCanOverwriteTools * @see #getUserVar * @see #getToolVar * @param key the key of the object requested * @return the requested object or null if not found */ @Override public Object get(String key) { boolean overwrite = getUserCanOverwriteTools(); Object o = overwrite ? getUserVar(key) : getToolVar(key); if (o == null) { o = overwrite ? getToolVar(key) : getUserVar(key); } return o; } /** * Finds "user" set values, either in the local context * or in the scoped attributes if none is in the local context. * @see #internalGet * @see #getAttribute */ protected Object getUserVar(String key) { Object o = internalGet(key); if (o != null) { return o; } return getAttribute(key); } /** * Finds the automatically provided values, either configured * tools or servlet API objects (request, response, etc). * @see #findTool * @see #getServletApi */ protected Object getToolVar(String key) { Object o = findTool(key); if (o != null) { return o; } return getServletApi(key); } /** * Returns the current matching servlet request, response, session, * or servlet context instance, or null if the key matches none of those * keys. */ protected Object getServletApi(String key) { if (key.equals(REQUEST)) { return request; } else if(key.equals(RESPONSE)) { return response; } else if (key.equals(SESSION)) { return getSession(); } else if (key.equals(APPLICATION)) { return application; } return null; } /** *

      Searches for the named attribute in request, session (if valid), * and application scope(s) in order and returns the value associated * or null.

      * * @since VelocityTools 1.1 */ public Object getAttribute(String key) { Object o = request.getAttribute(key); if (o == null) { if (getSession() != null) { try { o = getSession().getAttribute(key); } catch (IllegalStateException ise) { // Handle invalidated session state o = null; } } if (o == null) { o = application.getAttribute(key); } } return o; } /** *

      Returns the current servlet request.

      */ public HttpServletRequest getRequest() { return request; } /** *

      Returns the current servlet response.

      */ public HttpServletResponse getResponse() { return response; } /** *

      Returns the current session, if any.

      */ public HttpSession getSession() { return getRequest().getSession(false); } /** *

      Returns the servlet context.

      */ public ServletContext getServletContext() { return application; } /** *

      Returns a reference to the Velocity context (this object).

      */ public Context getVelocityContext() { return this; } /** *

      Returns a reference to the VelocityEngine.

      */ public VelocityEngine getVelocityEngine() { return velocity; } /** * Indicates whether the specified key is in the context. * * @param key The key to look for. * @return Whether the key is in the context. */ public boolean containsKey(String key) { return super.containsKey(key) || getAttribute(key) != null || key.equals(REQUEST) && request != null || key.equals(RESPONSE) && response != null || key.equals(SESSION) && getSession() != null || key.equals(APPLICATION) && application != null; } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/view/ViewToolInfo.java100644 0 0 17134 10730012246 26147 0ustar 0 0 package org.apache.velocity.tools.view; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * ToolInfo implementation for view tools. New instances * are returned for every call to getInstance(obj), and tools * that have an init(Object) method are initialized with the * given object before being returned. And tools that have a * configure(Map) method will be configured before being returned * if there are parameters specified for the tool. * * @author Nathan Bubna * @author Henning P. Schmiedehausen * @version $Id: ViewToolInfo.java 564045 2007-08-08 23:25:20Z nbubna $ * @deprecated Use {@link org.apache.velocity.tools.ToolInfo} */ @Deprecated public class ViewToolInfo implements ToolInfo { protected static final Log LOG = LogFactory.getLog(ViewToolInfo.class); private String key; private Class clazz; private Map parameters; private Method init = null; private Method configure = null; public ViewToolInfo() {} //TODO: if classloading becomes needed elsewhere, move this to a utils class /** * Return the Class object for the specified fully qualified * class name, from this web application's class loader. If no * class loader is set for the current thread, then the class loader * that loaded this class will be used. * * @param name Fully qualified class name to be loaded * @return Class object * @exception ClassNotFoundException if the class cannot be found * @since VelocityTools 1.1 */ protected Class getApplicationClass(String name) throws ClassNotFoundException { ClassLoader loader = Thread.currentThread().getContextClassLoader(); if (loader == null) { loader = ViewToolInfo.class.getClassLoader(); } return loader.loadClass(name); } /*********************** Mutators *************************/ public void setKey(String key) { this.key = key; } /** * If an instance of the tool cannot be created from * the classname passed to this method, it will throw an exception. * * @param classname the fully qualified java.lang.Class name of the tool */ public void setClassname(String classname) throws Exception { if (classname != null && classname.length() != 0) { this.clazz = getApplicationClass(classname); // create an instance to make sure we can clazz.newInstance(); try { // try to get an init(Object) method this.init = clazz.getMethod("init", new Class[]{ Object.class }); } catch (NoSuchMethodException nsme) { // ignore } try { // check for a configure(Map) method this.configure = clazz.getMethod("configure", new Class[]{ Map.class }); } catch (NoSuchMethodException nsme) { // ignore } } else { this.clazz = null; } } /** * Set parameter map for this tool. * * @since VelocityTools 1.1 */ public void setParameters(Map parameters) { this.parameters = parameters; } /** * Set/add new parameter for this tool. * * @since VelocityTools 1.1 */ public void setParameter(String name, String value) { if (parameters == null) { parameters = new HashMap(); } parameters.put(name, value); } /*********************** Accessors *************************/ public String getKey() { return key; } public String getClassname() { return clazz != null ? clazz.getName() : null; } /** * Get parameters for this tool. * @since VelocityTools 1.1 */ public Map getParameters() { return parameters; } /** * Returns a new instance of the tool. If the tool * has an init(Object) method, the new instance * will be initialized using the given data. If parameters * have been specified and the tool has a configure(Map) * method, the tool will be passed the parameters also. */ public Object getInstance(Object initData) { if (clazz == null) { LOG.error("Tool "+this.key+" has no Class definition!"); return null; } /* Get the tool instance */ Object tool = null; try { tool = clazz.newInstance(); } /* we shouldn't get exceptions here because we already * got an instance of this class during setClassname(). * but to be safe, let's catch the declared ones and give * notice of them, and let other exceptions slip by. */ catch (IllegalAccessException e) { LOG.error("Exception while instantiating instance of \"" + getClassname() + "\"", e); } catch (InstantiationException e) { LOG.error("Exception while instantiating instance of \"" + getClassname() + "\"", e); } /* if the tool is configurable and we have parameters... */ if (configure != null && parameters != null) { try { // call the configure method on the instance configure.invoke(tool, new Object[]{ parameters }); } catch (IllegalAccessException iae) { LOG.error("Exception when calling configure(Map) on "+tool, iae); } catch (InvocationTargetException ite) { LOG.error("Exception when calling configure(Map) on "+tool, ite); } } /* if the tool is initializable... */ if (init != null) { try { // call the init method on the instance init.invoke(tool, new Object[]{ initData }); } catch (IllegalAccessException iae) { LOG.error("Exception when calling init(Object) on "+tool, iae); } catch (InvocationTargetException ite) { LOG.error("Exception when calling init(Object) on "+tool, ite); } } return tool; } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/view/ViewToolManager.java100644 0 0 25375 11202122665 26636 0ustar 0 0 package org.apache.velocity.tools.view; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.util.Map; import javax.servlet.ServletContext; import javax.servlet.ServletRequest; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import javax.servlet.http.HttpServletResponse; import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.tools.Scope; import org.apache.velocity.tools.Toolbox; import org.apache.velocity.tools.ToolboxFactory; import org.apache.velocity.tools.ToolContext; import org.apache.velocity.tools.ToolManager; import org.apache.velocity.tools.config.ConfigurationUtils; import org.apache.velocity.tools.config.FactoryConfiguration; import org.apache.velocity.tools.view.ServletUtils; import org.apache.velocity.tools.view.ViewContext; import org.apache.velocity.tools.view.ViewToolContext; /** * Manages tools for web applications. This simplifies the process * of getting a tool-populated Velocity context for merging with templates. * It allows for both direct configuration by passing in a {@link FactoryConfiguration} * or having one in the ServletContext attributes under * {@link ServletUtils#CONFIGURATION_KEY}, as well as configuration * via a tools.xml or tools.properties file in * either the classpath or the local file system. * * @author Nathan Bubna * @version $Id: ToolManager.java 511959 2007-02-26 19:24:39Z nbubna $ */ public class ViewToolManager extends ToolManager { public static final String CREATE_SESSION_PROPERTY = "createSession"; public static final String PUBLISH_TOOLBOXES_PROPERTY = "publishToolboxes"; public static final String DEFAULT_TOOLBOX_KEY = Toolbox.KEY; protected ServletContext servletContext; private boolean createSession = true; private boolean publishToolboxes = true; private boolean appToolsPublished = false; private String toolboxKey = DEFAULT_TOOLBOX_KEY; /** * Constructs an instance already configured to use the * {@link ConfigurationUtils#getAutoLoaded()()} configuration * and any configuration specified via a "org.apache.velocity.tools" * system property. */ public ViewToolManager(ServletContext app) { this(app, true, true); } public ViewToolManager(ServletContext app, boolean includeDefaults) { this(app, true, includeDefaults); } public ViewToolManager(ServletContext app, boolean autoConfig, boolean includeDefaults) { super(autoConfig, includeDefaults); if (app == null) { throw new NullPointerException("ServletContext is required"); } this.servletContext = app; } @Override public void autoConfigure(boolean includeDefaults) { super.autoConfigure(includeDefaults); // check for a configuration in application attributes FactoryConfiguration injected = ServletUtils.getConfiguration(servletContext); if (injected != null) { configure(injected); } } /** * Sets whether or not the creation of a new {@link ViewToolContext} * should make the various scoped {@link Toolbox} instances available * publically via the HttpServletRequest/HttpSession/ServletContext * attributes or simply add the Toolbox instances directly to the * context. It is important to note that if this is set to false, * session-scoped tools will NOT be stored in the session, but instead * be recreated for each request. * @see #publishToolboxes * @see #setToolboxKey */ public void setPublishToolboxes(boolean publish) { if (publish != this.publishToolboxes) { debug("Publish toolboxes setting was changed to %s", publish); this.publishToolboxes = publish; } } public boolean getPublishToolboxes() { return this.publishToolboxes; } /** * Sets a new attribute key to be used for publishing each {@link Toolbox}. * @see #setPublishToolboxes * @see #publishToolboxes */ public void setToolboxKey(String key) { if (key == null) { throw new NullPointerException("toolboxKey cannot be null"); } if (!key.equals(toolboxKey)) { this.toolboxKey = key; unpublishApplicationTools(); debug("Toolbox key was changed to %s", key); } } public String getToolboxKey() { return this.toolboxKey; } /** * Sets whether or not a new HttpSession should be created * when there are session scoped tools to be stored in the session, * but no session has been created yet. * @see #publishToolboxes */ public void setCreateSession(boolean create) { if (create != this.createSession) { debug("Create session setting was changed to %s", create); this.createSession = create; } } public boolean getCreateSession() { return this.createSession; } /** * Checks the internal {@link ToolboxFactory} for any changes to * the createSession or publishToolboxes settings. */ protected void updateGlobalProperties() { // check for a createSession setting Boolean create = (Boolean)this.factory.getGlobalProperty(CREATE_SESSION_PROPERTY); if (create != null) { setCreateSession(create); } // check for a publishToolboxes setting Boolean publish = (Boolean)this.factory.getGlobalProperty(PUBLISH_TOOLBOXES_PROPERTY); if (publish != null) { setPublishToolboxes(publish); } } /** * Removes any published {@link Scope#APPLICATION} Toolbox. */ protected void unpublishApplicationTools() { if (appToolsPublished) { // clear the published application toolbox servletContext.removeAttribute(this.toolboxKey); appToolsPublished = false; } } @Override public void configure(FactoryConfiguration config) { super.configure(config); // reset things as best we can unpublishApplicationTools(); updateGlobalProperties(); } @Override protected FactoryConfiguration findConfig(String path) { return ServletUtils.getConfiguration(path, servletContext, false); } @Override protected void addToolboxes(ToolContext context) { super.addToolboxes(context); if (hasSessionTools()) { context.addToolbox(getSessionToolbox()); } } @Override public ToolContext createContext(Map toolProps) { ToolContext context = super.createContext(toolProps); context.putToolProperty(ViewContext.SERVLET_CONTEXT_KEY, servletContext); debug("Non-ViewToolContext was requested from ViewToolManager."); return context; } public ViewToolContext createContext(HttpServletRequest request, HttpServletResponse response) { ViewToolContext context = new ViewToolContext(getVelocityEngine(), request, response, servletContext); prepareContext(context, request); return context; } public void prepareContext(ViewToolContext context, HttpServletRequest request) { context.setToolboxKey(this.toolboxKey); if (this.publishToolboxes) { // put the toolboxes where the ViewToolContext // and others can find them publishToolboxes(request); // these would otherwise be done in super.prepareContext VelocityEngine engine = getVelocityEngine(); if (engine != null) { context.putVelocityEngine(engine); } context.setUserCanOverwriteTools(getUserCanOverwriteTools()); } else { // super class takes care of engine // and adds toolboxes directly prepareContext(context); } } protected boolean hasSessionTools() { return hasTools(Scope.SESSION); } protected Toolbox getSessionToolbox() { return createToolbox(Scope.SESSION); } /** * Places the {@link Scope#REQUEST} {@link Toolbox} (if any) * into the {@link ServletRequest} attributes using * {@link Toolbox#KEY} as the key. */ public void publishToolboxes(ServletRequest request) { publishToolbox(request); } private void publishToolbox(ServletRequest request) { if (hasRequestTools() && request.getAttribute(this.toolboxKey) == null) { request.setAttribute(this.toolboxKey, getRequestToolbox()); } } /** * Places the {@link Scope#REQUEST} {@link Toolbox} (if any) * into the {@link HttpServletRequest} attributes using * {@link Toolbox#KEY} as the key, places the {@link Scope#SESSION} * Toolbox (if any) into the attributes of the {@link HttpSession} (if any) * then ensures that the {@link Scope#APPLICATION} Toolbox (if any) * has been placed in the {@link ServletContext} attributes. */ public void publishToolboxes(HttpServletRequest request) { publishToolbox(request); if (hasSessionTools()) { HttpSession session = request.getSession(this.createSession); if (session != null) { // allow only one thread per session synchronized(ServletUtils.getMutex(session, "session.mutex", this)) { if (session.getAttribute(this.toolboxKey) == null) { session.setAttribute(this.toolboxKey, getSessionToolbox()); } } } } if (!appToolsPublished && hasApplicationTools()) { servletContext.setAttribute(this.toolboxKey, getApplicationToolbox()); } } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/view/WebappResourceLoader.java100644 0 0 23154 11110347752 27645 0ustar 0 0 package org.apache.velocity.tools.view; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.io.File; import java.io.InputStream; import java.util.HashMap; import javax.servlet.ServletContext; import org.apache.commons.collections.ExtendedProperties; import org.apache.velocity.exception.ResourceNotFoundException; import org.apache.velocity.runtime.resource.Resource; import org.apache.velocity.runtime.resource.loader.ResourceLoader; /** * Resource loader that uses the ServletContext of a webapp to * load Velocity templates. (it's much easier to use with servlets than * the standard FileResourceLoader, in particular the use of war files * is transparent). * * The default search path is '/' (relative to the webapp root), but * you can change this behaviour by specifying one or more paths * by mean of as many webapp.resource.loader.path properties as needed * in the velocity.properties file. * * All paths must be relative to the root of the webapp. * * To enable caching and cache refreshing the webapp.resource.loader.cache and * webapp.resource.loader.modificationCheckInterval properties need to be * set in the velocity.properties file ... auto-reloading of global macros * requires the webapp.resource.loader.cache property to be set to 'false'. * * @author Geir Magnusson Jr. * @author Nathan Bubna * @author Claude Brisson * @version $Id: WebappResourceLoader.java 712011 2008-11-06 23:35:43Z nbubna $ */ public class WebappResourceLoader extends ResourceLoader { /** The root paths for templates (relative to webapp's root). */ protected String[] paths = null; protected HashMap templatePaths = null; protected ServletContext servletContext = null; /** * This is abstract in the base class, so we need it. *
      * NOTE: this expects that the ServletContext has already * been placed in the runtime's application attributes * under its full class name (i.e. "javax.servlet.ServletContext"). * * @param configuration the {@link ExtendedProperties} associated with * this resource loader. */ public void init(ExtendedProperties configuration) { log.trace("WebappResourceLoader: initialization starting."); /* get configured paths */ paths = configuration.getStringArray("path"); if (paths == null || paths.length == 0) { paths = new String[1]; paths[0] = "/"; } else { /* make sure the paths end with a '/' */ for (int i=0; i < paths.length; i++) { if (!paths[i].endsWith("/")) { paths[i] += '/'; } log.info("WebappResourceLoader: added template path - '" + paths[i] + "'"); } } /* get the ServletContext */ Object obj = rsvc.getApplicationAttribute(ServletContext.class.getName()); if (obj instanceof ServletContext) { servletContext = (ServletContext)obj; } else { log.error("WebappResourceLoader: unable to retrieve ServletContext"); } /* init the template paths map */ templatePaths = new HashMap(); log.trace("WebappResourceLoader: initialization complete."); } /** * Get an InputStream so that the Runtime can build a * template with it. * * @param name name of template to get * @return InputStream containing the template * @throws ResourceNotFoundException if template not found * in classpath. */ public synchronized InputStream getResourceStream(String name) throws ResourceNotFoundException { InputStream result = null; if (name == null || name.length() == 0) { throw new ResourceNotFoundException("WebappResourceLoader: No template name provided"); } /* since the paths always ends in '/', * make sure the name never starts with one */ while (name.startsWith("/")) { name = name.substring(1); } Exception exception = null; for (int i = 0; i < paths.length; i++) { String path = paths[i] + name; try { result = servletContext.getResourceAsStream(path); /* save the path and exit the loop if we found the template */ if (result != null) { templatePaths.put(name, paths[i]); break; } } catch (NullPointerException npe) { /* no servletContext was set, whine about it! */ throw npe; } catch (Exception e) { /* only save the first one for later throwing */ if (exception == null) { if (log.isDebugEnabled()) { log.debug("WebappResourceLoader: Could not load "+path, e); } exception = e; } } } /* if we never found the template */ if (result == null) { String msg = "WebappResourceLoader: Resource '" + name + "' not found."; /* convert to a general Velocity ResourceNotFoundException */ if (exception == null) { throw new ResourceNotFoundException(msg); } else { msg += " Due to: " + exception; throw new ResourceNotFoundException(msg, exception); } } return result; } private File getCachedFile(String rootPath, String fileName) { // we do this when we cache a resource, // so do it again to ensure a match while (fileName.startsWith("/")) { fileName = fileName.substring(1); } String savedPath = (String)templatePaths.get(fileName); return new File(rootPath + savedPath, fileName); } /** * Checks to see if a resource has been deleted, moved or modified. * * @param resource Resource The resource to check for modification * @return boolean True if the resource has been modified */ public boolean isSourceModified(Resource resource) { String rootPath = servletContext.getRealPath("/"); if (rootPath == null) { // rootPath is null if the servlet container cannot translate the // virtual path to a real path for any reason (such as when the // content is being made available from a .war archive) return false; } // first, try getting the previously found file String fileName = resource.getName(); File cachedFile = getCachedFile(rootPath, fileName); if (!cachedFile.exists()) { /* then the source has been moved and/or deleted */ return true; } /* check to see if the file can now be found elsewhere * before it is found in the previously saved path */ File currentFile = null; for (int i = 0; i < paths.length; i++) { currentFile = new File(rootPath + paths[i], fileName); if (currentFile.canRead()) { /* stop at the first resource found * (just like in getResourceStream()) */ break; } } /* if the current is the cached and it is readable */ if (cachedFile.equals(currentFile) && cachedFile.canRead()) { /* then (and only then) do we compare the last modified values */ return (cachedFile.lastModified() != resource.getLastModified()); } else { /* we found a new file for the resource * or the resource is no longer readable. */ return true; } } /** * Checks to see when a resource was last modified * * @param resource Resource the resource to check * @return long The time when the resource was last modified or 0 if the file can't be read */ public long getLastModified(Resource resource) { String rootPath = servletContext.getRealPath("/"); if (rootPath == null) { // rootPath is null if the servlet container cannot translate the // virtual path to a real path for any reason (such as when the // content is being made available from a .war archive) return 0; } File cachedFile = getCachedFile(rootPath, resource.getName()); if (cachedFile.canRead()) { return cachedFile.lastModified(); } else { return 0; } } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/view/WebappUberspector.java100644 0 0 20037 11202122665 27215 0ustar 0 0 package org.apache.velocity.tools.view; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import org.apache.velocity.util.introspection.AbstractChainableUberspector; import org.apache.velocity.util.introspection.Info; import org.apache.velocity.util.introspection.Introspector; import org.apache.velocity.util.introspection.VelMethod; import org.apache.velocity.util.introspection.VelPropertyGet; import org.apache.velocity.util.introspection.VelPropertySet; import org.apache.velocity.runtime.parser.node.AbstractExecutor; import org.apache.velocity.runtime.parser.node.SetExecutor; import org.apache.velocity.runtime.log.Log; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import javax.servlet.ServletContext; import java.lang.reflect.InvocationTargetException; /** *

      This custom uberspector allows getAttribute() and setAttribute() as standard * getters and setters for the "request","session" and "application" keys. *

      It allows VTL statements like: *

       * #set($session.foo = 'youpi')
       * session parameter 'foo' has value: $session.foo
       * 
      *

      *

      This uberspector requires Velocity 1.6+ ; to use it, you must specify org.apache.velocity.tools.view.WebappUberspector * as the last uberspector to the runtime.introspector.uberspect property in you velocity.properties file.

      * *

      For instance:

      * *

      runtime.introspector.uberspect = org.apache.velocity.util.introspection.UberspectImpl,org.apache.velocity.tools.view.WebappUberspector

      * * @author Claude Brisson * @version $Id: WebappUberspector.java $ */ public class WebappUberspector extends AbstractChainableUberspector { /** * Property getter * @param obj * @param identifier * @param i * @return A Velocity Getter Method. * @throws Exception */ public VelPropertyGet getPropertyGet(Object obj, String identifier, Info i) throws Exception { VelPropertyGet ret = super.getPropertyGet(obj,identifier,i); if(ret == null) { Class claz = obj.getClass(); if(obj instanceof HttpServletRequest || obj instanceof HttpSession || obj instanceof ServletContext) { AbstractExecutor executor = new GetAttributeExecutor(log, introspector, claz, identifier); ret = executor.isAlive() ? new VelGetterImpl(executor) : null; } } return ret; } /** * init method */ @Override public void init() { try { super.init(); } catch (RuntimeException re) { throw re; } catch (Exception e) { throw new RuntimeException(e); } // we need our own introspector since the inner one is hidden by the Uberspect interface introspector = new Introspector(log); } /** * Property setter * @param obj * @param identifier * @param arg * @param i * @return A Velocity Setter method. * @throws Exception */ public VelPropertySet getPropertySet(Object obj, String identifier, Object arg, Info i) throws Exception { VelPropertySet ret = super.getPropertySet(obj,identifier,arg,i); if(ret == null) { Class claz = obj.getClass(); if(obj instanceof HttpServletRequest || obj instanceof HttpSession || obj instanceof ServletContext) { SetExecutor executor = new SetAttributeExecutor(log, introspector, claz, arg, identifier); ret = executor.isAlive() ? new VelSetterImpl(executor) : null; } } return ret; } /** * Executor for getAttribute(name) method. */ public class GetAttributeExecutor extends AbstractExecutor { private final Introspector introspector; // This is still threadsafe because this object is only read except in the C'tor. private Object [] params; /** * @param log * @param introspector * @param clazz * @param property */ public GetAttributeExecutor(final Log log, final Introspector introspector, final Class clazz, final String property) { this.log = log; this.introspector = introspector; this.params = new Object[] { property }; discover(clazz); } protected void discover(final Class clazz) { try { setMethod(introspector.getMethod(clazz, "getAttribute", params)); } /** * pass through application level runtime exceptions */ catch( RuntimeException e ) { throw e; } catch(Exception e) { log.error("While looking for getAttribute('" + params[0] + "') method:", e); } } /** * @see org.apache.velocity.runtime.parser.node.AbstractExecutor#execute(java.lang.Object) */ public Object execute(final Object o) throws IllegalAccessException, InvocationTargetException { return isAlive() ? getMethod().invoke(o, params) : null; } } /** * Executor for setAttribute(name,value) method */ public class SetAttributeExecutor extends SetExecutor { private final Introspector introspector; private final String property; /** * @param log * @param introspector * @param clazz * @param arg * @param property */ public SetAttributeExecutor(final Log log, final Introspector introspector, final Class clazz, final Object arg, final String property) { this.log = log; this.introspector = introspector; this.property = property; discover(clazz, arg); } /** * @param clazz * @param arg */ protected void discover(final Class clazz, final Object arg) { Object [] params = new Object[] { property, arg }; try { setMethod(introspector.getMethod(clazz, "setAttribute", params)); } /** * pass through application level runtime exceptions */ catch( RuntimeException e ) { throw e; } catch(Exception e) { log.error("While looking for put('" + params[0] + "') method:", e); } } /** * @see org.apache.velocity.runtime.parser.node.SetExecutor#execute(java.lang.Object, java.lang.Object) */ public Object execute(final Object o, final Object value) throws IllegalAccessException, InvocationTargetException { Object [] params; if (isAlive()) { params = new Object [] { property, value }; return getMethod().invoke(o, params); } return null; } } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/view/XMLToolboxManager.java100644 0 0 16634 11030275251 27072 0ustar 0 0 package org.apache.velocity.tools.view; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.apache.commons.digester.Digester; import org.apache.commons.digester.RuleSet; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * A ToolboxManager for loading a toolbox from xml. * *

      A toolbox manager is responsible for automatically filling the Velocity * context with a set of view tools. This class provides the following * features:

      *
        *
      • configurable through an XML-based configuration file
      • *
      • assembles a set of view tools (the toolbox) on request
      • *
      • supports any class with a public constructor without parameters * to be used as a view tool
      • *
      • supports adding primitive data values to the context(String,Number,Boolean)
      • *
      * * *

      Configuration

      *

      The toolbox manager is configured through an XML-based configuration * file. The configuration file is passed to the {@link #load(java.io.InputStream input)} * method. The format is shown in the following example:

      *
       * <?xml version="1.0"?>
       * <toolbox>
       *   <tool>
       *      <key>date</key>
       *      <class>org.apache.velocity.tools.generic.DateTool</class>
       *   </tool>
       *   <data type="Number">
       *      <key>luckynumber</key>
       *      <value>1.37</value>
       *   </data>
       *   <data type="String">
       *      <key>greeting</key>
       *      <value>Hello World!</value>
       *   </data>
       * </toolbox>
       * 
      * * * @author Nathan Bubna * @author Geir Magnusson Jr. * @author Henning P. Schmiedehausen * @version $Id: XMLToolboxManager.java 651470 2008-04-25 00:47:52Z nbubna $ * @deprecated Use {@link org.apache.velocity.tools.config.XmlFactoryConfiguration} */ @Deprecated public class XMLToolboxManager implements ToolboxManager { protected static final Log LOG = LogFactory.getLog(XMLToolboxManager.class); private List toolinfo; private Map data; private static RuleSet ruleSet = new ToolboxRuleSet(); /** * Default constructor */ public XMLToolboxManager() { toolinfo = new ArrayList(); data = new HashMap(); LOG.warn("XMLToolboxManager has been deprecated. Please use "+ "org.apache.velocity.tools.ToolboxFactory instead."); } // ------------------------------- ToolboxManager interface ------------ public void addTool(ToolInfo info) { if (validateToolInfo(info)) { toolinfo.add(info); if (LOG.isDebugEnabled()) { LOG.debug("Added "+info.getClassname()+" to the toolbox as "+info.getKey()); } } } public void addData(ToolInfo info) { if (validateToolInfo(info)) { data.put(info.getKey(), info.getInstance(null)); if (LOG.isDebugEnabled()) { LOG.debug("Added '"+info.getInstance(null)+"' to the toolbox as "+info.getKey()); } } } /** * Checks whether an object described by a ToolInfo passes * some basic sanity checks. * * @param info A ToolInfo object * * @return true if the ToolInfo is valid */ protected boolean validateToolInfo(ToolInfo info) { if (info == null) { LOG.error("ToolInfo is null!"); return false; } if (info.getKey() == null || info.getKey().length() == 0) { LOG.error("Tool has no key defined!"); return false; } if (info.getClassname() == null) { LOG.error("Tool " + info.getKey() + " has no Class definition!"); return false; } return true; } public Map getToolbox(Object initData) { Map toolbox = new HashMap(data); Iterator i = toolinfo.iterator(); while(i.hasNext()) { ToolInfo info = (ToolInfo)i.next(); toolbox.put(info.getKey(), info.getInstance(initData)); } return toolbox; } // ------------------------------- toolbox loading methods ------------ /** *

      Reads an XML document from the specified file path * and sets up the toolbox from that. If the file does not * exist, an {@link IllegalArgumentException} will be thrown.

      * * @param path the path to the file to be read from * @since VelocityTools 1.3 */ public void load(String path) throws Exception { if (path == null) { throw new IllegalArgumentException("Path value cannot be null"); } File file = new File(path); if (!file.exists()) { throw new IllegalArgumentException("Could not find toolbox config file at: "+path); } // ok, load the file load(new FileInputStream(file)); } /** *

      Reads an XML document from an {@link InputStream} * and sets up the toolbox from that.

      * * @param input the InputStream to read from */ public void load(InputStream input) throws Exception { LOG.trace("Loading toolbox..."); Digester digester = new Digester(); digester.setValidating(false); digester.setUseContextClassLoader(true); digester.push(this); digester.addRuleSet(getRuleSet()); digester.parse(input); LOG.trace("Toolbox loaded."); } /** *

      Retrieves the rule set Digester should use to parse and load * the toolbox for this manager.

      * *

      The DTD corresponding to the default ToolboxRuleSet is: *

           *  <?xml version="1.0"?>
           *  <!ELEMENT toolbox (tool*,data*,#PCDATA)>
           *  <!ELEMENT tool    (key,class,parameter*,#PCDATA)>
           *  <!ELEMENT data    (key,value)>
           *      <!ATTLIST data type (string|number|boolean) "string">
           *  <!ELEMENT key     (#CDATA)>
           *  <!ELEMENT class   (#CDATA)>
           *  <!ELEMENT parameter (EMPTY)>
           *      <!ATTLIST parameter name CDATA #REQUIRED>
           *      <!ATTLIST parameter value CDATA #REQUIRED>
           *  <!ELEMENT value   (#CDATA)>
           * 

      * * @since VelocityTools 1.1 */ protected RuleSet getRuleSet() { return ruleSet; } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/view/context/ChainedContext.java100644 0 0 6611 11030275247 30133 0ustar 0 0 package org.apache.velocity.tools.view.context; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.util.HashMap; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.ServletContext; import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.context.Context; import org.apache.velocity.tools.view.ViewToolContext; import org.apache.velocity.tools.view.context.ViewContext; /** * @deprecated Use {@link ViewToolContext} instead * @version $Id: ChainedContext.java 608694 2008-01-04 00:53:32Z nbubna $ */ @Deprecated public class ChainedContext extends ViewToolContext implements ViewContext { private Map oldToolbox; public ChainedContext(VelocityEngine velocity, HttpServletRequest request, HttpServletResponse response, ServletContext application) { super(velocity, request, response, application); } public ChainedContext(Context ctx, VelocityEngine velocity, HttpServletRequest request, HttpServletResponse response, ServletContext application) { this(velocity, request, response, application); if (ctx != null) { // copy all values from the context into this for (Object key : ctx.getKeys()) { String skey = String.valueOf(key); put(skey, ctx.get(skey)); } } } /** * Sets a "toolbox" in the style of VelocityTools 1.x. * @deprecated */ public void setToolbox(Map box) { this.oldToolbox = box; } /** *

      Returns the tools for this context

      * @since VelocityTools 1.3 * @return any tools passed in via setToolbox() plus the results * of {@link ViewToolContext#getToolbox()}. */ public Map getToolbox() { if (this.oldToolbox != null) { Map box = new HashMap(this.oldToolbox); box.putAll(super.getToolbox()); return box; } return super.getToolbox(); } protected Object internalGet( String key ) { Object o = null; /* search the toolbox */ if (oldToolbox != null) { o = oldToolbox.get(key); if (o != null) { return o; } } /* try the local hashtable */ return super.internalGet(key); } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/view/context/ViewContext.java100644 0 0 2276 10730012246 27507 0ustar 0 0 package org.apache.velocity.tools.view.context; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ /** * @deprecated Use {@link org.apache.velocity.tools.view.ViewContext} * @version $Id: ViewContext.java 511959 2007-02-26 19:24:39Z nbubna $ */ @Deprecated public interface ViewContext extends org.apache.velocity.tools.view.ViewContext { /** @deprecated */ public static final String XHTML = "XHTML"; } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/view/context/package.html100644 0 0 1753 11030275247 26653 0ustar 0 0

      All classes in this package have been deprecated.

      velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/view/i18n/MultiViewsTool.java100644 0 0 3201 11202122665 27260 0ustar 0 0 package org.apache.velocity.tools.view.i18n; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.util.Locale; import org.apache.velocity.tools.view.IncludeTool; import org.apache.velocity.tools.view.ViewToolContext; /** * Use {@link org.apache.velocity.tools.view.IncludeTool}. */ @Deprecated public class MultiViewsTool extends IncludeTool { @Deprecated public void init(Object obj) { if (obj instanceof ViewToolContext) { configure((ViewToolContext)obj); } } @Deprecated public String findLocalizedResource(String name, Locale locale) { return find(name, locale); } @Deprecated public String findLocalizedResource(String name) { return find(name); } @Deprecated public String findLocalizedResource(String name, String language) { return find(name, language); } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/view/jsp/JspToolContext.java100644 0 0 4721 10730012246 27274 0ustar 0 0 package org.apache.velocity.tools.view.jsp; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.jsp.PageContext; import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.tools.view.ViewToolContext; /** *

      Velocity context implementation specific to the JSP environment.

      * * @author Nathan Bubna * @version $Id: ViewContext.java 514727 2007-03-05 16:49:03Z nbubna $ */ public class JspToolContext extends ViewToolContext { public static final String PAGE_CONTEXT_KEY = "pageContext"; private final PageContext pageContext; public JspToolContext(VelocityEngine velocity, PageContext pageContext) { super(velocity, (HttpServletRequest)pageContext.getRequest(), (HttpServletResponse)pageContext.getResponse(), pageContext.getServletContext()); this.pageContext = pageContext; } protected void putToolProperties() { putToolProperty(PAGE_CONTEXT_KEY, getPageContext()); super.putToolProperties(); } public PageContext getPageContext() { return this.pageContext; } protected Object getServletApi(String key) { if (key.equals(PAGE_CONTEXT_KEY)) { return getPageContext(); } return super.getServletApi(key); } public Object getAttribute(String key) { Object o = getPageContext().getAttribute(key); if (o == null) { o = super.getAttribute(key); } return o; } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/view/jsp/VelocityViewTag.java100644 0 0 24401 11202554465 27450 0ustar 0 0 package org.apache.velocity.tools.view.jsp; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.io.StringWriter; import java.io.Writer; import javax.servlet.http.HttpServletRequest; import javax.servlet.jsp.JspException; import javax.servlet.jsp.PageContext; import javax.servlet.jsp.tagext.BodyTagSupport; import org.apache.velocity.Template; import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.runtime.resource.loader.StringResourceLoader; import org.apache.velocity.runtime.resource.util.StringResourceRepository; import org.apache.velocity.tools.view.ServletUtils; import org.apache.velocity.tools.view.ViewToolContext; import org.apache.velocity.tools.view.VelocityView; /** *

      This tag enables use of Velocity and VelocityTools within JSP files and tags. * This makes it trivial to render embedded VTL (Velocity Template Language) * or include a separate Velocity template within a JSP using the current * page context. This also automatically provides the typical * {@link VelocityView} toolbox support, much like the VelocityViewServlet * and VelocityLayoutServlets have. In fact, this will by default share * the {@link VelocityView} instance used with those servlets. This allows * for consistent configuration and shared resources (better performance). *

      * * @author Nathan Bubna * @version $Id: VelocityViewTag.java,v 1.1 2001/08/14 00:07:39 geirm Exp $ * @since VelocityTools 2.0 */ public class VelocityViewTag extends BodyTagSupport { public static final String DEFAULT_BODY_CONTENT_KEY = "bodyContent"; private static final long serialVersionUID = -3329444102562079189L; protected transient VelocityView view; protected transient ViewToolContext context; protected transient StringResourceRepository repository; protected String var; protected String scope; protected String template; protected String bodyContentKey = DEFAULT_BODY_CONTENT_KEY; private boolean cache = false; /** * Release any per-invocation resources, resetting any resources or state * that should be cleared between successive invocations of * {@link javax.servlet.jsp.tagext.Tag#doEndTag()} and * {@link javax.servlet.jsp.tagext.Tag#doStartTag()}. */ protected void reset() { super.setId(null); var = null; scope = null; template = null; bodyContentKey = DEFAULT_BODY_CONTENT_KEY; cache = false; } public void setId(String id) { if (id == null) { throw new NullPointerException("id cannot be null"); } super.setId(id); // assume they want this cached cache = true; } protected String getLogId() { String id = super.getId(); if (id == null) { id = getClass().getSimpleName(); } return id; } public void setVar(String var) { this.var = var; } public String getVar() { return this.var; } public void setScope(String scope) { this.scope = scope; } public String getScope() { return this.scope; } public void setTemplate(String template) { this.template = template; } public String getTemplate() { return this.template; } public void setBodyContentKey(String key) { this.bodyContentKey = DEFAULT_BODY_CONTENT_KEY; } public String getBodyContentKey() { return this.bodyContentKey; } public void setCache(String s) { this.cache = "true".equalsIgnoreCase(s); } public String getCache() { return String.valueOf(this.cache); } public VelocityView getVelocityView() { return this.view; } public void setVelocityView(VelocityView view) { this.view = view; } public ViewToolContext getViewToolContext() { return this.context; } public void setViewToolContext(ViewToolContext context) { this.context = context; } public StringResourceRepository getRepository() { if (this.repository == null) { setRepository(StringResourceLoader.getRepository()); } return this.repository; } public void setRepository(StringResourceRepository repo) { this.repository = repo; } public int doStartTag() throws JspException { initializeView(); return EVAL_BODY_BUFFERED; } public int doEndTag() throws JspException { if (hasContent()) { try { // check for a var attribute String varname = getVar(); if (varname == null) { // if none, render into the pageout renderContent(this.pageContext.getOut()); } else { // if we have a var, render into a string StringWriter out = new StringWriter(); renderContent(out); // and insert the string into the specified scope // if none specified, default is PAGE_SCOPE this.pageContext.setAttribute(varname, out.toString(), toScopeInt(getScope())); } } catch (Exception e) { throw new JspException("Failed to render " + getClass() + ": "+getLogId(), e); } } return EVAL_PAGE; } protected void initializeView() { // get the VelocityView for this app VelocityView view = ServletUtils.getVelocityView(this.pageContext.getServletConfig()); // now make a Context ViewToolContext context = new JspToolContext(view.getVelocityEngine(), this.pageContext); view.prepareContext(context, (HttpServletRequest)this.pageContext.getRequest()); setVelocityView(view); setViewToolContext(context); } protected boolean hasContent() { return (getBodyContent() != null || getTemplate() != null); } protected void renderContent(Writer out) throws Exception { if (getTemplate() != null) { VelocityView view = getVelocityView(); ViewToolContext context = getViewToolContext(); // get the actual Template Template template = view.getTemplate(getTemplate()); if (getBodyContent() != null) { context.put(getBodyContentKey(), getRenderedBody()); } // render the template into the writer template.merge(context, out); } else { // render the body into the writer renderBody(out); } } protected String getRenderedBody() throws Exception { // render the body into a string StringWriter out = new StringWriter(); renderBody(out); return out.toString(); } protected boolean isCached() { return getRepository().getStringResource(getId()) != null; } protected void renderBody(Writer out) throws Exception { String name = getId(); // if it hasn't been cached, try that if (cache && !isCached()) { String template = getBodyContent().getString(); // if no id was set, use the template as the id if (name == null) { name = template; } cache(name, template); } // if it can't be cached, eval it if (!cache) { evalBody(out); } else { // load template from cache Template template = getVelocityView().getTemplate(name); template.merge(getViewToolContext(), out); } } protected void evalBody(Writer out) throws Exception { VelocityEngine engine = getVelocityView().getVelocityEngine(); engine.evaluate(getViewToolContext(), out, getLogId(), getBodyContent().getReader()); } protected static int toScopeInt(String scope) { if (scope == null) { return PageContext.PAGE_SCOPE; } if (scope.equalsIgnoreCase("request")) { return PageContext.REQUEST_SCOPE; } if (scope.equalsIgnoreCase("session")) { return PageContext.SESSION_SCOPE; } if (scope.equalsIgnoreCase("application")) { return PageContext.APPLICATION_SCOPE; } if (scope.equalsIgnoreCase("page")) { return PageContext.PAGE_SCOPE; } throw new IllegalArgumentException("Unknown scope: "+scope); } protected void cache(String name, String template) { try { getRepository().putStringResource(name, template); } catch (Exception cnfe) { getVelocityView().getLog() .error("Could not cache body in a StringResourceRepository", cnfe); cache = false; } } /** * Release any per-instance resources, releasing any resources or state * before this tag instance is disposed. * * @see javax.servlet.jsp.tagext.Tag#release() */ @Override public void release() { super.release(); reset(); } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/view/package.html100644 0 0 3410 11030275251 25152 0ustar 0 0 Contains tools and supporting infrastructure for using those tools in a servlet environment as well as general use classes to support use of Velocity as (or in) the view layer of web applications.

      Package Specification

      Related Documentation

      velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/view/servlet/ServletLogger.java100644 0 0 3743 11030275245 30020 0ustar 0 0 package org.apache.velocity.tools.view.servlet; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import org.apache.velocity.runtime.RuntimeServices; import org.apache.velocity.runtime.log.LogSystem; import org.apache.velocity.tools.view.ServletLogChute; /** *

      This is basically an empty subclass of {@link ServletLogChute} that exists * merely for backwards compatibility with VelocityTools 1.x. Please * use {@link ServletLogChute} directly, as this will likely be removed * in VelocityTools 2.1, if not earlier. *

      * * @author Geir Magnusson Jr. * @deprecated Use {@link ServletLogChute} instead * @version $Revision: 651470 $ $Date: 2007-02-26 11:24:39 -0800 (Mon, 26 Feb 2007) $ */ @Deprecated public class ServletLogger extends ServletLogChute implements LogSystem { @Override public void init(RuntimeServices rs) throws Exception { super.init(rs); log(LogSystem.WARN_ID, "ServletLogger has been deprecated. Use " + super.getClass().getName() + " instead."); } /** * Send a log message from Velocity. */ public void logVelocityMessage(int level, String message) { log(level, message); } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/view/servlet/ServletToolInfo.java100644 0 0 10002 10730012242 30324 0ustar 0 0 package org.apache.velocity.tools.view.servlet; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import org.apache.velocity.tools.view.ViewToolInfo; /** *

      ToolInfo implementation that holds scope information for tools * used in a servlet environment. The ServletToolboxManager uses * this to allow tool definitions to specify the scope/lifecycle * of individual view tools.

      * *

      Example of toolbox.xml definitions for servlet tools:

       *  <tool>
       *    <key>link</key>
       *    <scope>request</scope>
       *    <class>org.apache.velocity.tools.struts.StrutsLinkTool</class>
       *  </tool>
       *  <tool>
       *    <key>math</key>
       *    <scope>application</scope>
       *    <class>org.apache.velocity.tools.generic.MathTool</class>
       *  </tool>
       *  <tool>
       *    <key>user</key>
       *    <scope>session</scope>
       *    <class>com.mycompany.tools.MyUserTool</class>
       *  </tool>
       *  

      * * @author Nathan Bubna * @deprecated Use {@link org.apache.velocity.tools.ToolInfo} * @version $Id: ServletToolInfo.java 564438 2007-08-10 00:15:18Z nbubna $ */ @Deprecated public class ServletToolInfo extends ViewToolInfo { private String scope; private boolean exactPath; private String path; public void setScope(String scope) { this.scope = scope; } /** * @return the scope of the tool */ public String getScope() { return scope; } /** * @param path the full or partial request path restriction of the tool * @since VelocityTools 1.3 */ public void setRequestPath(String path) { // make sure all paths begin with slash if (!path.startsWith("/")) { path = "/" + path; } if (path.equals("/*")) { // match all paths this.path = null; } else if(path.endsWith("*")) { // match some paths exactPath = false; this.path = path.substring(0, path.length() - 1); } else { // match one path exactPath = true; this.path = path; } } /** * @return request path restriction for this tool * @since VelocityTools 1.3 */ public String getRequestPath() { return this.path; } /** * @param requestedPath the path of the current servlet request * @return true if the path of the specified * request path matches the request path of this tool. * If there is no request path restriction for this tool, * it will always return true. * @since VelocityTools 1.3 */ public boolean allowsRequestPath(String requestedPath) { if (this.path == null) { return true; } if (exactPath) { return this.path.equals(requestedPath); } else if (requestedPath != null) { return requestedPath.startsWith(this.path); } return false; } } ././@LongLink100644 0 0 147 11365341753 10265 Lustar 0 0 velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/view/servlet/ServletToolboxManager.javavelocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/view/servlet/ServletToolboxManager.ja100644 0 0 36653 11030275246 31222 0ustar 0 0 package org.apache.velocity.tools.view.servlet; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.io.InputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import javax.servlet.ServletContext; import javax.servlet.http.HttpSession; import org.apache.commons.digester.RuleSet; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.velocity.tools.view.ToolInfo; import org.apache.velocity.tools.view.XMLToolboxManager; import org.apache.velocity.tools.view.context.ViewContext; import org.apache.velocity.tools.view.ServletUtils; /** *

      A toolbox manager for the servlet environment.

      * *

      A toolbox manager is responsible for automatically filling the Velocity * context with a set of view tools. This class provides the following * features:

      *
        *
      • configurable through an XML-based configuration file
      • *
      • assembles a set of view tools (the toolbox) on request
      • *
      • handles different tool scopes (request, session, application)
      • *
      • supports any class with a public constructor without parameters * to be used as a view tool
      • *
      • supports adding primitive data values to the context(String,Number,Boolean)
      • *
      * * *

      Configuration

      *

      The toolbox manager is configured through an XML-based configuration * file. The configuration file is passed to the {@link #load(java.io.InputStream input)} * method. The format is shown in the following example:

      *
       * <?xml version="1.0"?>
       *
       * <toolbox>
       *   <tool>
       *      <key>link</key>
       *      <scope>request</scope>
       *      <class>org.apache.velocity.tools.view.tools.LinkTool</class>
       *   </tool>
       *   <tool>
       *      <key>date</key>
       *      <scope>application</scope>
       *      <class>org.apache.velocity.tools.generic.DateTool</class>
       *   </tool>
       *   <data type="number">
       *      <key>luckynumber</key>
       *      <value>1.37</value>
       *   </data>
       *   <data type="string">
       *      <key>greeting</key>
       *      <value>Hello World!</value>
       *   </data>
       *   <xhtml>true</xhtml>
       * </toolbox>
       * 
      *

      The recommended location for the configuration file is the WEB-INF directory of the * web application.

      * * @author Gabriel Sidler * @author Nathan Bubna * @author Geir Magnusson Jr. * @author Henning P. Schmiedehausen * @version $Id: ServletToolboxManager.java 651470 2008-04-25 00:47:52Z nbubna $ * @deprecated Use {@link org.apache.velocity.tools.config.XmlFactoryConfiguration} */ @Deprecated public class ServletToolboxManager extends XMLToolboxManager { // --------------------------------------------------- Properties --------- public static final String SESSION_TOOLS_KEY = ServletToolboxManager.class.getName() + ":session-tools"; protected static final Log LOG = LogFactory.getLog(ServletToolboxManager.class); private ServletContext servletContext; private Map appTools; private ArrayList sessionToolInfo; private ArrayList requestToolInfo; private boolean createSession; private static HashMap managersMap = new HashMap(); private static RuleSet servletRuleSet = new ServletToolboxRuleSet(); // --------------------------------------------------- Constructor -------- /** * Use getInstance(ServletContext,String) instead * to ensure there is exactly one ServletToolboxManager * per xml toolbox configuration file. */ private ServletToolboxManager(ServletContext servletContext) { this.servletContext = servletContext; appTools = new HashMap(); sessionToolInfo = new ArrayList(); requestToolInfo = new ArrayList(); createSession = true; LOG.warn("ServletToolboxManager has been deprecated. Please use "+ "org.apache.velocity.tools.ToolboxFactory instead."); } // -------------------------------------------- Public Methods ------------ /** * ServletToolboxManager factory method. * This method will ensure there is exactly one ServletToolboxManager * per xml toolbox configuration file. */ public static synchronized ServletToolboxManager getInstance(ServletContext servletContext, String toolboxFile) { // little fix up if (!toolboxFile.startsWith("/")) { toolboxFile = "/" + toolboxFile; } // get the unique key for this toolbox file in this servlet context String uniqueKey = servletContext.hashCode() + ':' + toolboxFile; // check if an instance already exists ServletToolboxManager toolboxManager = (ServletToolboxManager)managersMap.get(uniqueKey); if (toolboxManager == null) { // if not, build one InputStream is = null; try { // get the bits is = servletContext.getResourceAsStream(toolboxFile); if (is != null) { LOG.info("Using config file '" + toolboxFile + "'"); toolboxManager = new ServletToolboxManager(servletContext); toolboxManager.load(is); // remember it managersMap.put(uniqueKey, toolboxManager); LOG.debug("Toolbox setup complete."); } else { LOG.debug("No toolbox was found at '" + toolboxFile + "'"); } } catch(Exception e) { LOG.error("Problem loading toolbox '" + toolboxFile + "'", e); } finally { try { if (is != null) { is.close(); } } catch(Exception ee) {} } } return toolboxManager; } /** *

      Sets whether or not to create a new session when none exists for the * current request and session-scoped tools have been defined for this * toolbox.

      * *

      If true, then a call to {@link #getToolbox(Object)} will * create a new session if none currently exists for this request and * the toolbox has one or more session-scoped tools designed.

      * *

      If false, then a call to getToolbox(Object) will never * create a new session for the current request. * This effectively means that no session-scoped tools will be added to * the ToolboxContext for a request that does not have a session object. *

      * * The default value is true. */ public void setCreateSession(boolean b) { createSession = b; LOG.debug("create-session is set to " + b); } /** *

      Sets an application attribute to tell velocimacros and tools * (especially the LinkTool) whether they should output XHTML or HTML.

      * * @see ViewContext#XHTML * @since VelocityTools 1.1 */ public void setXhtml(Boolean value) { servletContext.setAttribute(ViewContext.XHTML, value); LOG.info(ViewContext.XHTML + " is set to " + value); } // ------------------------------ XMLToolboxManager Overrides ------------- /** *

      Retrieves the rule set Digester should use to parse and load * the toolbox for this manager.

      * *

      The DTD corresponding to the ServletToolboxRuleSet is: *

           *  <?xml version="1.0"?>
           *  <!ELEMENT toolbox (create-session?,xhtml?,tool*,data*,#PCDATA)>
           *  <!ELEMENT create-session (#CDATA)>
           *  <!ELEMENT xhtml          (#CDATA)>
           *  <!ELEMENT tool           (key,scope?,class,parameter*,#PCDATA)>
           *  <!ELEMENT data           (key,value)>
           *      <!ATTLIST data type (string|number|boolean) "string">
           *  <!ELEMENT key            (#CDATA)>
           *  <!ELEMENT scope          (#CDATA)>
           *  <!ELEMENT class          (#CDATA)>
           *  <!ELEMENT parameter (EMPTY)>
           *      <!ATTLIST parameter name CDATA #REQUIRED>
           *      <!ATTLIST parameter value CDATA #REQUIRED>
           *  <!ELEMENT value          (#CDATA)>
           * 

      * * @since VelocityTools 1.1 */ protected RuleSet getRuleSet() { return servletRuleSet; } /** * Ensures that application-scoped tools do not have request path * restrictions set for them, as those will not be enforced. * * @param info a ToolInfo object * @return true if the ToolInfo is valid * @since VelocityTools 1.3 */ protected boolean validateToolInfo(ToolInfo info) { if (!super.validateToolInfo(info)) { return false; } if (info instanceof ServletToolInfo) { ServletToolInfo sti = (ServletToolInfo)info; if (sti.getRequestPath() != null && !ViewContext.REQUEST.equalsIgnoreCase(sti.getScope())) { LOG.error(sti.getKey() + " must be a request-scoped tool to have a request path restriction!"); return false; } } return true; } /** * Overrides XMLToolboxManager to separate tools by scope. * For this to work, we obviously override getToolbox(Object) as well. */ public void addTool(ToolInfo info) { if (validateToolInfo(info)) { if (info instanceof ServletToolInfo) { ServletToolInfo sti = (ServletToolInfo)info; if (ViewContext.REQUEST.equalsIgnoreCase(sti.getScope())) { requestToolInfo.add(sti); return; } else if (ViewContext.SESSION.equalsIgnoreCase(sti.getScope())) { sessionToolInfo.add(sti); return; } else if (ViewContext.APPLICATION.equalsIgnoreCase(sti.getScope())) { /* add application scoped tools to appTools and * initialize them with the ServletContext */ appTools.put(sti.getKey(), sti.getInstance(servletContext)); return; } else { LOG.warn("Unknown scope '" + sti.getScope() + "' - " + sti.getKey() + " will be request scoped."); //default is request scope requestToolInfo.add(info); } } else { //default is request scope requestToolInfo.add(info); } } } /** * Overrides XMLToolboxManager to put data into appTools map */ public void addData(ToolInfo info) { if (validateToolInfo(info)) { appTools.put(info.getKey(), info.getInstance(null)); } } /** * Overrides XMLToolboxManager to handle the separate * scopes. * * Application scope tools were initialized when the toolbox was loaded. * Session scope tools are initialized once per session and stored in a * map in the session attributes. * Request scope tools are initialized on every request. * * @param initData the {@link ViewContext} for the current servlet request */ public Map getToolbox(Object initData) { //we know the initData is a ViewContext ViewContext ctx = (ViewContext)initData; String requestPath = ServletUtils.getPath(ctx.getRequest()); //create the toolbox map with the application tools in it Map toolbox = new HashMap(appTools); if (!sessionToolInfo.isEmpty()) { HttpSession session = ctx.getRequest().getSession(createSession); if (session != null) { // allow only one thread per session at a time synchronized(getMutex(session)) { // get the session tools Map stmap = (Map)session.getAttribute(SESSION_TOOLS_KEY); if (stmap == null) { // init and store session tools map stmap = new HashMap(sessionToolInfo.size()); Iterator i = sessionToolInfo.iterator(); while(i.hasNext()) { ServletToolInfo sti = (ServletToolInfo)i.next(); stmap.put(sti.getKey(), sti.getInstance(ctx)); } session.setAttribute(SESSION_TOOLS_KEY, stmap); } // add them to the toolbox toolbox.putAll(stmap); } } } //add and initialize request tools Iterator i = requestToolInfo.iterator(); while(i.hasNext()) { ToolInfo info = (ToolInfo)i.next(); if (info instanceof ServletToolInfo) { ServletToolInfo sti = (ServletToolInfo)info; if (!sti.allowsRequestPath(requestPath)) { continue; } } toolbox.put(info.getKey(), info.getInstance(ctx)); } return toolbox; } /** * Returns a mutex (lock object) unique to the specified session * to allow for reliable synchronization on the session. */ protected Object getMutex(HttpSession session) { // yes, this uses double-checked locking, but it is safe here // since partial initialization of the lock is not an issue Object lock = session.getAttribute("session.mutex"); if (lock == null) { // one thread per toolbox manager at a time synchronized(this) { // in case another thread already came thru lock = session.getAttribute("session.mutex"); if (lock == null) { // use a Boolean because it is serializable and small lock = new Boolean(true); session.setAttribute("session.mutex", lock); } } } return lock; } } ././@LongLink100644 0 0 147 11365341753 10265 Lustar 0 0 velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/view/servlet/ServletToolboxRuleSet.javavelocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/view/servlet/ServletToolboxRuleSet.ja100644 0 0 11146 10730012242 31210 0ustar 0 0 package org.apache.velocity.tools.view.servlet; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import org.apache.commons.digester.Digester; import org.apache.commons.digester.Rule; import org.apache.velocity.tools.view.ToolboxRuleSet; /** *

      The set of Digester rules required to parse a toolbox * configuration file (toolbox.xml) for the * ServletToolboxManager class.

      * * @since VelocityTools 1.1 * @author Nathan Bubna * @version $Id: ServletToolboxRuleSet.java 534682 2007-05-03 01:50:54Z nbubna $ * @deprecated Use {@link org.apache.velocity.tools.config.XmlFactoryConfigurationRuleSet}. */ @Deprecated public class ServletToolboxRuleSet extends ToolboxRuleSet { /** * Overrides {@link ToolboxRuleSet} to add create-session rule. * *

      These rules assume that an instance of * org.apache.velocity.tools.view.ServletToolboxManager is * pushed onto the evaluation stack before parsing begins.

      * * @param digester Digester instance to which the new Rule instances * should be added. */ public void addRuleInstances(Digester digester) { digester.addRule("toolbox/create-session", new CreateSessionRule()); digester.addRule("toolbox/xhtml", new XhtmlRule()); super.addRuleInstances(digester); } /** * Overrides {@link ToolboxRuleSet} to add rule for scope element. */ protected void addToolRules(Digester digester) { super.addToolRules(digester); digester.addBeanPropertySetter("toolbox/tool/scope", "scope"); digester.addBeanPropertySetter("toolbox/tool/request-path", "requestPath"); } /** * Overrides {@link ToolboxRuleSet} to use ServletToolInfo class. */ protected Class getToolInfoClass() { return ServletToolInfo.class; } /****************************** Custom Rules *****************************/ /** * Abstract rule for configuring boolean options on the parent * object/element of the matching element. */ protected abstract class BooleanConfigRule extends Rule { public void body(String ns, String name, String text) throws Exception { Object parent = digester.peek(); if ("yes".equalsIgnoreCase(text)) { setBoolean(parent, Boolean.TRUE); } else { setBoolean(parent, Boolean.valueOf(text)); } } /** * Takes the parent object and boolean value in order to * call the appropriate method on the parent for the * implementing rule. * * @param parent the parent object/element in the digester's stack * @param value the boolean value contained in the current element */ public abstract void setBoolean(Object parent, Boolean value) throws Exception; } /** * Rule that sets setCreateSession() for the top object * on the stack, which must be a * org.apache.velocity.tools.ServletToolboxManager. */ protected final class CreateSessionRule extends BooleanConfigRule { public void setBoolean(Object obj, Boolean b) throws Exception { ((ServletToolboxManager)obj).setCreateSession(b.booleanValue()); } } /** * Rule that sets setXhtml() for the top object * on the stack, which must be a * org.apache.velocity.tools.ServletToolboxManager. */ protected final class XhtmlRule extends BooleanConfigRule { public void setBoolean(Object obj, Boolean b) throws Exception { ((ServletToolboxManager)obj).setXhtml(b); } } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/view/servlet/ServletUtils.java100644 0 0 2157 10730012242 27667 0ustar 0 0 package org.apache.velocity.tools.view.servlet; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ /** * @deprecated Use {@link org.apache.velocity.tools.view.ServletUtils} * @version $Id: ServletUtils.java 471244 2006-11-04 18:34:38Z henning $ */ @Deprecated public class ServletUtils extends org.apache.velocity.tools.view.ServletUtils {} ././@LongLink100644 0 0 147 11365341753 10265 Lustar 0 0 velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/view/servlet/VelocityLayoutServlet.javavelocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/view/servlet/VelocityLayoutServlet.ja100644 0 0 3707 11110347752 31250 0ustar 0 0 package org.apache.velocity.tools.view.servlet; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import javax.servlet.ServletConfig; import javax.servlet.ServletException; import org.apache.velocity.tools.view.VelocityView; /** * @author Nathan Bubna * @deprecated This has moved to {@link org.apache.velocity.tools.view.VelocityLayoutServlet} * @version $Id: VelocityLayoutServlet.java 511959 2007-02-26 19:24:39Z nbubna $ */ @Deprecated public class VelocityLayoutServlet extends org.apache.velocity.tools.view.VelocityLayoutServlet { private transient VelocityView view; @Override public void init(ServletConfig config) throws ServletException { super.init(config); getLog().debug(this.getClass().getName() + " has been deprecated. Use " + super.getClass().getName() + " instead."); } /** * Overrides parent to ensure each VVS instance has * it's own separate configuration, just like in Tools 1.x. */ @Override protected VelocityView getVelocityView() { if (this.view == null) { this.view = new VelocityView(getServletConfig()); } return this.view; } } ././@LongLink100644 0 0 145 11365341753 10263 Lustar 0 0 velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/view/servlet/VelocityViewServlet.javavelocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/view/servlet/VelocityViewServlet.java100644 0 0 4441 11110347752 31230 0ustar 0 0 package org.apache.velocity.tools.view.servlet; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import org.apache.velocity.tools.view.VelocityView; import javax.servlet.ServletConfig; import javax.servlet.ServletException; /** * @deprecated This class has moved to {@link org.apache.velocity.tools.view.VelocityViewServlet} * @version $Id: VelocityViewServlet.java 511959 2007-02-26 19:24:39Z nbubna $ */ @Deprecated public class VelocityViewServlet extends org.apache.velocity.tools.view.VelocityViewServlet { /** * @deprecated toolbox key is now managed by {@link VelocityView} */ protected static final String TOOLBOX_KEY = VelocityView.DEPRECATED_TOOLS_KEY; /** * @deprecated Default path is now managed by {@link VelocityView} */ protected static final String DEFAULT_TOOLBOX_PATH = VelocityView.DEPRECATED_USER_TOOLS_PATH; private transient VelocityView view; @Override public void init(ServletConfig config) throws ServletException { super.init(config); getLog().debug(this.getClass().getName() + " has been deprecated. Use " + super.getClass().getName() + " instead."); } /** * Overrides parent to ensure each VVS instance has * it's own separate configuration, just like in Tools 1.x. */ @Override protected VelocityView getVelocityView() { if (this.view == null) { this.view = new VelocityView(getServletConfig()); } return this.view; } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/view/servlet/WebappLoader.java100644 0 0 3214 11030275246 27573 0ustar 0 0 package org.apache.velocity.tools.view.servlet; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import org.apache.velocity.tools.view.WebappResourceLoader; import org.apache.commons.collections.ExtendedProperties; /** *

      This is basically an empty subclass of {@link WebappResourceLoader} that exists * merely for backwards compatibility with VelocityTools 1.x. Please * use {@link WebappResourceLoader} directly, as this may be removed * in VelocityTools 2.1. *

      * @deprecated Use {@link WebappResourceLoader} instead. * @version $Id: WebappLoader.java 511959 2007-02-26 19:24:39Z nbubna $ */ @Deprecated public class WebappLoader extends WebappResourceLoader { public void init(ExtendedProperties configuration) { log.warn("WebappLoader is deprecated. Use "+ WebappResourceLoader.class.getName()+" instead."); super.init(configuration); } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/view/servlet/package.html100644 0 0 1744 11030275246 26652 0ustar 0 0 All classes in this package have been deprecated. velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/view/tools.xml100644 0 0 3425 11202122665 24562 0ustar 0 0 velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/view/tools/AbstractPagerTool.java100644 0 0 2422 10730012244 30253 0ustar 0 0 package org.apache.velocity.tools.view.tools; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import org.apache.velocity.tools.view.ViewContext; /** * Use {@link org.apache.velocity.tools.view.PagerTool} */ @Deprecated public abstract class AbstractPagerTool extends org.apache.velocity.tools.view.PagerTool { @Deprecated public void init(Object obj) { if (obj instanceof ViewContext) { setRequest(((ViewContext)obj).getRequest()); } } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/view/tools/AbstractSearchTool.java100644 0 0 3175 10730012244 30430 0ustar 0 0 package org.apache.velocity.tools.view.tools; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.util.List; import org.apache.velocity.tools.view.ViewContext; /** * Use {@link org.apache.velocity.tools.view.tools.AbstractSearchTool} */ @Deprecated public abstract class AbstractSearchTool extends org.apache.velocity.tools.view.AbstractSearchTool { @Deprecated public void init(Object obj) { if (obj instanceof ViewContext) { setRequest(((ViewContext)obj).getRequest()); } } /** * @deprecated Use {@link AbstractPagerTool#hasItems()} */ public boolean hasResults() { return hasItems(); } /** * @deprecated Use {@link AbstractPagerTool#getItems()}. */ public List getResults() { return getItems(); } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/view/tools/BrowserSnifferTool.java100644 0 0 2347 10730012244 30477 0ustar 0 0 package org.apache.velocity.tools.view.tools; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import org.apache.velocity.tools.view.ViewContext; /** * Use {@link org.apache.velocity.tools.view.BrowserTool} */ @Deprecated public class BrowserSnifferTool extends org.apache.velocity.tools.view.BrowserTool { @Deprecated public void init(Object obj) { if (obj instanceof ViewContext) { setRequest(((ViewContext)obj).getRequest()); } } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/view/tools/ContextTool.java100644 0 0 3733 11030275246 27172 0ustar 0 0 package org.apache.velocity.tools.view.tools; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.util.Map; import org.apache.velocity.tools.view.ViewContext; import org.apache.velocity.tools.view.ViewContextTool; /** * Use {@link org.apache.velocity.tools.view.ViewContextTool} */ @Deprecated public class ContextTool extends ViewContextTool { @Deprecated public static final String OLD_SAFE_MODE_KEY = "safe-mode"; @Deprecated public void init(Object obj) { if (obj instanceof ViewContext) { ViewContext ctx = (ViewContext)obj; this.context = ctx.getVelocityContext(); this.request = ctx.getRequest(); this.session = request.getSession(false); this.application = ctx.getServletContext(); } } @Override public void configure(Map params) { if (params != null) { // if we find a param under the old key Object oldSafeMode = params.get(OLD_SAFE_MODE_KEY); if (oldSafeMode != null) { // copy it under the new one params.put(SAFE_MODE_KEY, oldSafeMode); } super.configure(params); } } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/view/tools/CookieTool.java100644 0 0 2523 10730012244 26744 0ustar 0 0 package org.apache.velocity.tools.view.tools; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import org.apache.velocity.tools.view.ViewContext; /** * Use {@link org.apache.velocity.tools.view.CookieTool} */ @Deprecated public class CookieTool extends org.apache.velocity.tools.view.CookieTool { @Deprecated public void init(Object obj) { if (obj instanceof ViewContext) { ViewContext ctx = (ViewContext)obj; setRequest(ctx.getRequest()); setResponse(ctx.getResponse()); } } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/view/tools/ImportTool.java100644 0 0 2704 10730012244 27006 0ustar 0 0 package org.apache.velocity.tools.view.tools; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import org.apache.velocity.tools.view.ViewContext; /** * Use {@link org.apache.velocity.tools.view.tools.ImportTool} */ @Deprecated public class ImportTool extends org.apache.velocity.tools.view.ImportTool { @Deprecated public void init(Object obj) { if (obj instanceof ViewContext) { ViewContext ctx = (ViewContext)obj; setRequest(ctx.getRequest()); setResponse(ctx.getResponse()); setServletContext(ctx.getServletContext()); setLog(ctx.getVelocityEngine().getLog()); } } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/view/tools/LinkTool.java100644 0 0 17651 11202122665 26464 0ustar 0 0 package org.apache.velocity.tools.view.tools; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.util.HashSet; import java.util.Map; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.velocity.tools.generic.ValueParser; import org.apache.velocity.tools.view.context.ViewContext; /** * @deprecated Use {@link org.apache.velocity.tools.view.LinkTool} */ @Deprecated public class LinkTool extends org.apache.velocity.tools.view.LinkTool { @Deprecated public static final String SELF_ABSOLUTE_KEY = "self-absolute"; @Deprecated public static final String SELF_INCLUDE_PARAMETERS_KEY = "self-include-parameters"; @Deprecated public static final String AUTO_IGNORE_PARAMETERS_KEY = "auto-ignore-parameters"; @Deprecated protected ServletContext application; private HashSet parametersToIgnore; private boolean autoIgnore = true; @Override protected void configure(ValueParser parser) { Boolean selfAbsolute = parser.getBoolean(SELF_ABSOLUTE_KEY); if (selfAbsolute != null) { setForceRelative(!selfAbsolute.booleanValue()); } Boolean selfParams = parser.getBoolean(SELF_INCLUDE_PARAMETERS_KEY); if (selfParams != null) { setIncludeRequestParams(selfParams.booleanValue()); } Boolean autoIgnoreParams = parser.getBoolean(AUTO_IGNORE_PARAMETERS_KEY); if (autoIgnoreParams != null) { setAutoIgnoreParameters(autoIgnoreParams.booleanValue()); } super.configure(parser); } @Deprecated public void init(Object obj) { if (obj instanceof ViewContext) { ViewContext ctx = (ViewContext)obj; setRequest(ctx.getRequest()); setResponse(ctx.getResponse()); this.application = ctx.getServletContext(); if (ctx.getVelocityEngine() != null) { this.LOG = ctx.getVelocityEngine().getLog(); } } } // --------------------------------------- Protected Methods ------------- @Deprecated public void setXhtml(boolean useXhtml) { setXHTML(useXhtml); } /** * @deprecated use {@link #setForceRelative} as reversed * replacement */ @Deprecated public void setSelfAbsolute(boolean selfAbsolute) { setForceRelative(!selfAbsolute); } /** * @deprecated use {@link #setIncludeRequestParams} instead */ @Deprecated public void setSelfIncludeParameters(boolean selfParams) { setIncludeRequestParams(selfParams); } @Deprecated public void setAutoIgnoreParameters(boolean autoIgnore) { this.autoIgnore = autoIgnore; } @Deprecated public void setRequest(HttpServletRequest request) { this.request = request; setFromRequest(request); } @Deprecated public void setResponse(HttpServletResponse response) { this.response = response; if (response != null) { setCharacterEncoding(response.getCharacterEncoding()); } } // --------------------------------------------- Template Methods ----------- /** * @deprecated use {@link #anchor(Object)} instead */ @Deprecated public LinkTool setAnchor(String anchor) { return (LinkTool)anchor(anchor); } /** * @deprecated use {@link #relative(Object)} */ @Deprecated public LinkTool setRelative(String uri) { return (LinkTool)relative(uri); } /** * @deprecated use {@link #absolute(Object)} */ @Deprecated public LinkTool setAbsolute(String uri) { return (LinkTool)absolute(uri); } /** * @deprecated use {@link #uri(Object)} */ @Deprecated public LinkTool setURI(String uri) { return (LinkTool)uri(uri); } /** * @deprecated use {@link #getPath} */ @Deprecated public String getURI() { return path; } /** * @deprecated use {@link #append(Object,Object)} */ @Deprecated public LinkTool addQueryData(String key, Object value) { return (LinkTool)append(key, value); } /** * @deprecated use {@link #params(Object)} */ @Deprecated public LinkTool addQueryData(Map parameters) { return (LinkTool)params(parameters); } /** * @deprecated use {@link #getQuery} */ @Deprecated public String getQueryData() { return getQuery(); } /** * @deprecated use {@link #encode(Object)} */ @Deprecated public String encodeURL(String url) { return encode(url); } /** * If you do use this, then you must use {@link #addAllParameters()} * and not the replacements for it, or these will not be honored. * * @deprecated use {@link #addRequestParams(String...)} * or {@link #addRequestParamsExcept(String...)} * or {@link #addMissingRequestParams(String...)} */ @Deprecated public LinkTool addIgnore(String parameterName) { LinkTool copy = (LinkTool)duplicate(); if (copy.parametersToIgnore == null) { copy.parametersToIgnore = new HashSet(1); } copy.parametersToIgnore.add(parameterName); return copy; } /** * @deprecated use {@link #addRequestParams(String...)} * or {@link #addRequestParamsExcept(String...)} * or {@link #addMissingRequestParams(String...)} */ @Deprecated public LinkTool addAllParameters() { if (this.parametersToIgnore != null) { String[] ignoreThese = new String[parametersToIgnore.size()]; return (LinkTool)addRequestParamsExcept(parametersToIgnore.toArray(ignoreThese)); } else if (autoIgnore) { return (LinkTool)addMissingRequestParams(); } else { return (LinkTool)addRequestParams(); } } @Override public void setParam(Object key, Object value, boolean append) { super.setParam(key, value, append); if (autoIgnore) { if (parametersToIgnore == null) { parametersToIgnore = new HashSet(1); } parametersToIgnore.add(String.valueOf(key)); } } @Override public void setParams(Object obj, boolean append) { super.setParams(obj, append); if (autoIgnore && obj instanceof Map) { Map params = (Map)obj; if (!params.isEmpty()) { if (parametersToIgnore == null) { parametersToIgnore = new HashSet(params.size()); } for (Object e : ((Map)obj).entrySet()) { Map.Entry entry = (Map.Entry)e; String key = String.valueOf(entry.getKey()); parametersToIgnore.add(key); } } } } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/view/tools/ParameterParser.java100644 0 0 3177 10730012244 30000 0ustar 0 0 package org.apache.velocity.tools.view.tools; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import javax.servlet.ServletRequest; import org.apache.velocity.tools.view.ViewContext; /** * Use {@link org.apache.velocity.tools.view.ParameterTool} */ @Deprecated public class ParameterParser extends org.apache.velocity.tools.view.ParameterTool { /** * Constructs a new instance */ public ParameterParser() {} /** * Constructs a new instance using the specified request. * * @param request the {@link ServletRequest} to be parsed */ public ParameterParser(ServletRequest request) { setRequest(request); } @Deprecated public void init(Object obj) { if (obj instanceof ViewContext) { setRequest(((ViewContext)obj).getRequest()); } } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/view/tools/ViewRenderTool.java100644 0 0 2321 11030275246 27610 0ustar 0 0 package org.apache.velocity.tools.view.tools; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import org.apache.velocity.context.Context; /** * Use {@link org.apache.velocity.tools.generic.RenderTool} */ @Deprecated public class ViewRenderTool extends org.apache.velocity.tools.generic.RenderTool { @Deprecated public void init(Object obj) { if (obj instanceof Context) { setVelocityContext((Context)obj); } } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/view/tools/ViewResourceTool.java100644 0 0 2575 11030275246 30173 0ustar 0 0 package org.apache.velocity.tools.view.tools; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import org.apache.velocity.tools.view.ViewContext; /** * Use {@link org.apache.velocity.tools.generic.ResourceTool} */ @Deprecated public class ViewResourceTool extends org.apache.velocity.tools.generic.ResourceTool { public ViewResourceTool() { // force depMode for this deprecated version setDeprecationSupportMode(true); } @Deprecated public void init(Object obj) { if (obj instanceof ViewContext) { setLocale(((ViewContext)obj).getRequest().getLocale()); } } } velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/view/tools/package.html100644 0 0 2036 11030275246 26321 0ustar 0 0 All classes in this package have been deprecated and moved to org.apache.velocity.tools.view. velocity-tools-2.0-src/src/main/java/org/apache/velocity/tools/view/velocity.properties100644 0 0 3110 11207274140 26644 0ustar 0 0 # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # default to servletlogger, which logs to the servlet engines log runtime.log.logsystem.class = org.apache.velocity.runtime.log.ServletLogChute,org.apache.velocity.tools.view.ServletLogChute # by default, load resources with webapp resource loader and string resource loader (in that order) resource.loader = webapp,string webapp.resource.loader.class = org.apache.velocity.tools.view.WebappResourceLoader string.resource.loader.class = org.apache.velocity.runtime.resource.loader.StringResourceLoader # allows getting and setting $request, $session and $application attributes using Velocity syntax, # like in #set($session.foo = 'bar'), instead of $session.setAttribute('foo','bar') runtime.introspector.uberspect = org.apache.velocity.util.introspection.UberspectImpl,org.apache.velocity.tools.view.WebappUberspector velocity-tools-2.0-src/src/test/java/file.xml100644 0 0 1546 11115263031 16412 0ustar 0 0 woogie wiggie velocity-tools-2.0-src/src/test/java/org/apache/velocity/tools/generic/AlternatorToolTests.java100644 0 0 10275 11202122664 30254 0ustar 0 0 package org.apache.velocity.tools.generic; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import org.junit.*; import static org.junit.Assert.*; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.velocity.tools.generic.Alternator; /** *

      Tests for AlternatorTool

      * * @author Nathan Bubna * @since VelocityTools 2.0 * @version $Id$ */ public class AlternatorToolTests { public @Test void ctorAlternatorTool() throws Exception { try { new AlternatorTool(); } catch (Exception e) { fail("Constructor 'AlternatorTool()' failed due to: " + e); } } public @Test void methodConfigure_Map() throws Exception { AlternatorTool tool = new AlternatorTool(); Map conf = new HashMap(); conf.put(AlternatorTool.AUTO_ALTERNATE_DEFAULT_KEY, false); tool.configure(conf); assertFalse(tool.getAutoAlternateDefault()); } public @Test void methodsGetSetAutoAlternateDefault() throws Exception { AlternatorTool tool = new AlternatorTool(); assertTrue(tool.getAutoAlternateDefault()); tool.setAutoAlternateDefault(false); assertFalse(tool.getAutoAlternateDefault()); tool.setAutoAlternateDefault(true); assertTrue(tool.getAutoAlternateDefault()); } public @Test void methodMake_ObjectVarArgs() throws Exception { AlternatorTool tool = new AlternatorTool(); assertNull(tool.make()); Alternator result = tool.make(new Object[] { true }); assertTrue((Boolean)result.getNext()); assertTrue((Boolean)result.getNext()); result = tool.make("hi", true, false, 0); assertEquals("hi", result.getNext()); assertTrue((Boolean)result.getNext()); assertFalse((Boolean)result.getNext()); assertEquals(0, result.getNext()); assertEquals("hi", result.getNext()); result = tool.make(new Object[] { "red", "blue" }); result.shift(); assertEquals("blue", result.toString()); } public @Test void methodMake_booleanObjectVarArgs() throws Exception { AlternatorTool tool = new AlternatorTool(); Alternator result = tool.make(false, new Object[] { "red", "blue" }); assertEquals("red", result.toString()); assertEquals("red", result.toString()); result.shift(); assertEquals("blue", result.toString()); } public @Test void methodAuto_ObjectVarArgs() throws Exception { AlternatorTool tool = new AlternatorTool(); Alternator result = tool.auto(-1,0,null,1); assertEquals("-1", result.toString()); assertEquals(0, result.getCurrent()); assertEquals("0", result.toString()); assertEquals(null, result.toString()); assertEquals("1", result.toString()); assertEquals("-1", result.toString()); } public @Test void methodManual_ObjectVarArgs() throws Exception { AlternatorTool tool = new AlternatorTool(); Alternator result = tool.manual(new Object[] { true, false }); assertTrue((Boolean)result.getCurrent()); assertEquals("true", result.toString()); assertTrue((Boolean)result.getNext()); assertEquals("false", result.toString()); assertFalse((Boolean)result.getNext()); assertEquals("true", result.toString()); } } velocity-tools-2.0-src/src/test/java/org/apache/velocity/tools/generic/ClassToolTests.java100644 0 0 25571 11202122664 27213 0ustar 0 0 package org.apache.velocity.tools.generic; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import org.junit.*; import static org.junit.Assert.*; import java.lang.annotation.Annotation; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.velocity.runtime.log.Log; import org.apache.velocity.tools.config.DefaultKey; import org.apache.velocity.tools.config.SkipSetters; import org.apache.velocity.tools.generic.ValueParser; import org.apache.velocity.tools.view.AbstractSearchTool; /** *

      Tests for {@link ClassTool}

      * * @author Nathan Bubna * @since VelocityTools 2.0 * @version $Id$ */ public class ClassToolTests { public @Test void ctorClassTool() throws Exception { try { new ClassTool(); } catch (Exception e) { fail("Default constructor failed"); } } public @Test void ctorClassTool_ClassToolClass() throws Exception { // null parent should fail try { new ClassTool(null, ClassTool.class); fail("Constructor 'ClassTool(null, Class)' worked but shouldn't have."); } catch (Exception e) { } ClassTool parent = new ClassTool(); // null class should fail try { new ClassTool(parent, null); fail("Constructor 'ClassTool(ClassTool, null)' worked but shouldn't have."); } catch (Exception e) { } // this one should work try { new ClassTool(parent, ClassToolTests.class); } catch (Exception e) { fail("Constructor 'ClassTool(ClassTool, Class)' failed due to: " + e); } } public @Test void methodConfigure_Map() throws Exception { ClassTool classTool = new ClassTool(); assertEquals(Object.class, classTool.getType()); // change the inspected type to Map Map conf = new HashMap(); conf.put(ClassTool.INSPECT_KEY, "java.util.Map"); classTool.configure(conf); assertEquals(Map.class, classTool.getType()); //TODO: test other configuration settings } public @Test void methodGetAnnotations() throws Exception { ClassTool classTool = new ClassTool(); // default type is java.lang.Object assertTrue(classTool.getAnnotations().isEmpty()); classTool.setType(MyDeprecated.class); assertEquals(1, classTool.getAnnotations().size()); classTool.setType(ValueParser.class); assertEquals(2, classTool.getAnnotations().size()); Class type0 = classTool.getAnnotations().get(0).annotationType(); Class type1 = classTool.getAnnotations().get(1).annotationType(); assertTrue(type0 != type1); assertTrue(type0 == DefaultKey.class || type1 == DefaultKey.class); assertTrue(type0 == SkipSetters.class || type1 == SkipSetters.class); } public @Test void methodGetConstructors() throws Exception { ClassTool classTool = new ClassTool(); List result = classTool.getConstructors(); assertNotNull(result); assertFalse(result.isEmpty()); //TODO: test contents of list? } //TODO: add ConstructorSub tests public @Test void methodGetFields() throws Exception { ClassTool classTool = new ClassTool(); // default type is java.lang.Object List result = classTool.getFields(); assertNotNull(result); assertTrue(result.isEmpty()); //TODO: test a class that does have fields } //TODO: add FieldSub tests public @Test void methodGetMethods() throws Exception { ClassTool classTool = new ClassTool(); // default type is java.lang.Object List result = classTool.getMethods(); assertNotNull(result); assertFalse(result.isEmpty()); //TODO: test contents of list? } //TODO: add MethodSub tests public @Test void methodGetTypes() throws Exception { ClassTool classTool = new ClassTool(); // default type is java.lang.Object Set result = classTool.getTypes(); assertNotNull(result); assertFalse(result.isEmpty()); //TODO: test contents of set? } public @Test void methodGetFullName() throws Exception { ClassTool classTool = new ClassTool(); String result = classTool.getFullName(); assertEquals(result, "java.lang.Object"); } public @Test void methodGetName() throws Exception { ClassTool classTool = new ClassTool(); // default type is java.lang.Object String result = classTool.getName(); assertEquals(classTool.getName(), "Object"); } public @Test void methodGetPackage() throws Exception { ClassTool classTool = new ClassTool(); // default type is java.lang.Object assertEquals(classTool.getPackage(), "java.lang"); } public @Test void methodGetType() throws Exception { ClassTool classTool = new ClassTool(); // default type is java.lang.Object Class result = classTool.getType(); assertEquals(result, Object.class); classTool.setType(ClassTool.class); result = classTool.getType(); assertEquals(result, ClassTool.class); } public @Test void methodGetSuper() throws Exception { ClassTool classTool = new ClassTool(); // default type is java.lang.Object which has no super assertNull(classTool.getSuper()); classTool.setType(ClassTool.class); assertEquals(classTool.getSuper().getType(), SafeConfig.class); } public @Test void methodInspect_Class() throws Exception { ClassTool classTool = new ClassTool(); ClassTool result = classTool.inspect(ClassTool.class); assertEquals(result.getType(), ClassTool.class); } public @Test void methodInspect_Object() throws Exception { ClassTool classTool = new ClassTool(); ClassTool result = classTool.inspect(classTool); assertEquals(result.getType(), ClassTool.class); } public @Test void methodInspect_String() throws Exception { ClassTool classTool = new ClassTool(); assertNull(classTool.inspect((String)null)); assertNull(classTool.inspect("")); assertNull(classTool.inspect("bad")); assertEquals(Map.class, classTool.inspect("java.util.Map").getType()); } public @Test void methodIsAbstract() throws Exception { ClassTool classTool = new ClassTool(); // default type is java.lang.Object assertFalse(classTool.isAbstract()); classTool.setType(AbstractSearchTool.class); assertTrue(classTool.isAbstract()); } public @Test void methodIsDeprecated() throws Exception { ClassTool classTool = new ClassTool(); // default type is java.lang.Object assertFalse(classTool.isDeprecated()); classTool.setType(MyDeprecated.class); assertTrue(classTool.isDeprecated()); } @Deprecated protected static class MyDeprecated { // do nothing } public @Test void methodIsFinal() throws Exception { ClassTool classTool = new ClassTool(); // default type is java.lang.Object assertFalse(classTool.isFinal()); classTool.setType(String.class); assertTrue(classTool.isFinal()); } public @Test void methodIsInterface() throws Exception { ClassTool classTool = new ClassTool(); // default type is java.lang.Object assertFalse(classTool.isInterface()); classTool.setType(Map.class); assertTrue(classTool.isInterface()); } public @Test void methodIsPrivate() throws Exception { ClassTool classTool = new ClassTool(); // default type is java.lang.Object assertFalse(classTool.isPrivate()); classTool.setType(PrivateStrictStatic.class); assertTrue(classTool.isPrivate()); } public @Test void methodIsProtected() throws Exception { ClassTool classTool = new ClassTool(); // default type is java.lang.Object assertFalse(classTool.isProtected()); classTool.setType(ProtectedNoDefaultCtor.class); assertTrue(classTool.isProtected()); } public @Test void methodIsPublic() throws Exception { ClassTool classTool = new ClassTool(); // default type is java.lang.Object assertTrue(classTool.isPublic()); classTool.setType(PrivateStrictStatic.class); assertFalse(classTool.isPublic()); } public @Test void methodIsStatic() throws Exception { ClassTool classTool = new ClassTool(); // default type is java.lang.Object assertFalse(classTool.isStatic()); classTool.setType(PrivateStrictStatic.class); assertTrue(classTool.isStatic()); } /* CB - commented because on some JVM (ex: 1.6.0_02-b05 linux) the strictfp modifier is lost at runtime on Classes public @Test void methodIsStrict() throws Exception { ClassTool classTool = new ClassTool(); // default type is java.lang.Object assertFalse(classTool.isStrict()); classTool.setType(PrivateStrictStatic.class); assertTrue(classTool.isStrict()); } */ public @Test void methodSetClass_Class() throws Exception { ClassTool classTool = new ClassTool(); assertEquals(Object.class, classTool.getType()); classTool.setType(ClassTool.class); assertEquals(ClassTool.class, classTool.getType()); } public @Test void methodSupportsNewInstance() throws Exception { ClassTool classTool = new ClassTool(); // default type class is java.lang.Object assertEquals(classTool.supportsNewInstance(), true); classTool.setType(ProtectedNoDefaultCtor.class); assertEquals(classTool.supportsNewInstance(), false); } private static strictfp class PrivateStrictStatic {} protected static class ProtectedNoDefaultCtor { public ProtectedNoDefaultCtor(String foo) { } } } velocity-tools-2.0-src/src/test/java/org/apache/velocity/tools/generic/DisplayToolTests.java100644 0 0 43233 11202122664 27546 0ustar 0 0 package org.apache.velocity.tools.generic; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import org.junit.*; import static org.junit.Assert.*; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.velocity.tools.generic.ValueParser; /** *

      Tests for DisplayTool

      * * @author Nathan Bubna * @since VelocityTools 2.0 * @version $Id$ */ public class DisplayToolTests { public @Test void methodAlt_Object() throws Exception { DisplayTool display = new DisplayTool(); assertSame(display.alt(null), display.getDefaultAlternate()); Object notnull = new Object(); assertSame(display.alt(notnull), notnull); } public @Test void methodAlt_ObjectObject() throws Exception { DisplayTool display = new DisplayTool(); Object notnull = new Object(); Object result = display.alt(null, notnull); assertSame(result, notnull); result = display.alt(notnull, "foo"); assertSame(result, notnull); } public @Test void methodCapitalize_Object() throws Exception { DisplayTool display = new DisplayTool(); assertEquals("FOO", display.capitalize("fOO")); assertEquals("Foo", display.capitalize("Foo")); assertEquals("Foo", display.capitalize("foo")); assertEquals("F", display.capitalize("f")); assertEquals("", display.capitalize("")); assertEquals(null, display.capitalize(null)); } public @Test void methodCell_Object() throws Exception { DisplayTool display = new DisplayTool(); display.setCellLength(4); assertEquals(null, display.cell(null)); assertEquals("foo ", display.cell("foo")); assertEquals("f...", display.cell("foobar")); assertEquals("foob", display.cell("foob")); } public @Test void methodCell_ObjectString() throws Exception { DisplayTool display = new DisplayTool(); display.setCellLength(5); assertEquals("test>", display.cell("testing", ">")); } public @Test void methodCell_Objectint() throws Exception { DisplayTool display = new DisplayTool(); assertEquals("testing", display.cell("testing", 7)); assertEquals("testing ", display.cell("testing", 8)); assertEquals("tes...", display.cell("testing", 6)); } public @Test void methodCell_ObjectintString() throws Exception { DisplayTool display = new DisplayTool(); assertEquals("f", display.cell("foo", 1, null)); assertEquals("f", display.cell("foo", 1, "bar")); assertEquals("fbar", display.cell("foobar", 4, "bar")); assertEquals(null, display.cell("foo", 0, "bar")); assertEquals(null, display.cell("foo", -1, "bar")); } public @Test void methodConfigure_Map() throws Exception { DisplayTool display = new DisplayTool(); // change the inspected type to Map Map conf = new HashMap(); conf.put(DisplayTool.LIST_DELIM_KEY, ";"); conf.put(DisplayTool.LIST_FINAL_DELIM_KEY, " und "); conf.put(DisplayTool.TRUNCATE_LENGTH_KEY, "5"); conf.put(DisplayTool.TRUNCATE_SUFFIX_KEY, ">"); conf.put(DisplayTool.TRUNCATE_AT_WORD_KEY, "true"); conf.put(DisplayTool.CELL_LENGTH_KEY, "4"); conf.put(DisplayTool.CELL_SUFFIX_KEY, "~"); conf.put(DisplayTool.DEFAULT_ALTERNATE_KEY, "n/a"); conf.put(DisplayTool.ALLOWED_TAGS_KEY, "img,br"); display.configure(conf); assertEquals(";", display.getListDelimiter()); assertEquals(" und ", display.getListFinalDelimiter()); assertEquals(5, display.getTruncateLength()); assertEquals(">", display.getTruncateSuffix()); assertEquals(true, display.getTruncateAtWord()); assertEquals("~", display.getCellSuffix()); assertEquals(4, display.getCellLength()); assertEquals("n/a", display.getDefaultAlternate()); String[] tags = display.getAllowedTags(); assertNotNull(tags); assertEquals("img", tags[0]); assertEquals("br", tags[1]); // ensure that configure is locked now conf.put(DisplayTool.LIST_DELIM_KEY, " & "); display.configure(conf); assertEquals(";", display.getListDelimiter()); } public @Test void methodMeasure_String() throws Exception { DisplayTool display = new DisplayTool(); assertNull(display.measure(null)); DisplayTool.Measurements dims = display.measure(""); assertNotNull(dims); assertEquals(1, dims.getHeight()); assertEquals(0, dims.getWidth()); dims = display.measure("twelve chars"); assertEquals(12, dims.getWidth()); assertEquals(1, dims.getHeight()); dims = display.measure("one\ntwo\nthree"); assertEquals(5, dims.getWidth()); assertEquals(3, dims.getHeight()); } public @Test void methodMessage_StringObjectVarArgs() throws Exception { DisplayTool display = new DisplayTool(); assertNull(display.message(null)); assertEquals("foo", display.message("foo")); assertEquals("foo", display.message("foo", (Object[])null)); assertEquals("foo", display.message("foo", new Object[] {})); assertEquals("foo", display.message("foo", new ArrayList())); assertEquals("foo", display.message("foo", 1)); assertEquals("foo bar", display.message("foo {0}", "bar")); assertEquals("foo 2 bar", display.message("foo {1} {0}", "bar", 2)); } public @Test void methodPrintf_StringObjectVarArgs() throws Exception { DisplayTool display = new DisplayTool(); assertNull(display.printf(null)); assertEquals("foo", display.printf("foo")); assertEquals("foo", display.printf("foo", (Object[])null)); assertEquals("foo", display.printf("foo", new Object[] {})); assertEquals("foo", display.printf("foo", new ArrayList())); assertEquals("foo", display.printf("foo", 1)); assertEquals("foo bar", display.printf("foo %s", "bar")); assertEquals("foo 2 bar", display.printf("foo %2$d %1$s", "bar", 2)); } public @Test void methodList_Object() throws Exception { DisplayTool display = new DisplayTool(); int[] nums = new int[] { 1, 2, 3 }; assertEquals("1, 2 and 3", display.list(nums)); display.setListDelimiter(" & "); assertEquals("1 & 2 and 3", display.list(nums)); display.setListFinalDelimiter(" & "); assertEquals("1 & 2 & 3", display.list(nums)); } public @Test void methodList_ObjectString() throws Exception { DisplayTool display = new DisplayTool(); List nums = new ArrayList(); nums.add(1); nums.add(2); nums.add(3); assertEquals(null, display.list(null, null)); assertEquals("1null2null3", display.list(nums, null)); assertEquals("1, 2, 3", display.list(nums, ", ")); } public @Test void methodList_ObjectStringString() throws Exception { DisplayTool display = new DisplayTool(); int[] nums = new int[] { 1, 2, 3 }; assertEquals(null, display.list(null, null, null)); assertEquals("1null2null3", display.list(nums, null, null)); assertEquals("1 & 2null3", display.list(nums, " & ", null)); assertEquals("1null2 & 3", display.list(nums, null, " & ")); assertEquals("123", display.list(nums, "", "")); assertEquals("1; 2 und 3", display.list(nums, "; ", " und ")); } public @Test void methodList_ObjectStringStringString() throws Exception { TestBean bean1 = new TestBean(1, "one"); TestBean bean2 = new TestBean(2, "two"); TestBean bean3 = new TestBean(3, "three"); TestBean[] beanArray = new TestBean[] { bean1, bean2, bean3 }; List beanList = new ArrayList(); beanList.addAll(Arrays.asList(beanArray)); DisplayTool display = new DisplayTool(); assertEquals(null, display.list(null, null, null, null)); assertEquals("1null2null3", display.list(beanArray, null, null, "num")); assertEquals("123", display.list(beanList, "", "", "num")); assertEquals("one, two or three", display.list(beanList, ", ", " or ", "str")); } public @Test void methodSetAllowedTags_StringArray() throws Exception { DisplayTool display = new DisplayTool(); assertNull(display.getAllowedTags()); String[] tags = new String[] { "img" }; display.setAllowedTags(tags); assertEquals(tags, display.getAllowedTags()); } public @Test void methodSetCellLength_int() throws Exception { DisplayTool display = new DisplayTool(); display.setCellLength(10); assertEquals(10, display.getCellLength()); } public @Test void methodSetCellSuffix_String() throws Exception { DisplayTool display = new DisplayTool(); display.setCellSuffix("foo"); assertEquals("foo", display.getCellSuffix()); } public @Test void methodSetDefaultAlternate_String() throws Exception { DisplayTool display = new DisplayTool(); display.setDefaultAlternate("foo"); assertEquals("foo", display.getDefaultAlternate()); } public @Test void methodSetListDelimiter_String() throws Exception { DisplayTool display = new DisplayTool(); display.setListDelimiter("foo"); assertEquals("foo", display.getListDelimiter()); } public @Test void methodSetListFinalDelimiter_String() throws Exception { DisplayTool display = new DisplayTool(); display.setListFinalDelimiter("foo"); assertEquals("foo", display.getListFinalDelimiter()); } public @Test void methodSetTruncateLength_int() throws Exception { DisplayTool display = new DisplayTool(); display.setTruncateLength(5); assertEquals(5, display.getTruncateLength()); } public @Test void methodSetTruncateSuffix_String() throws Exception { DisplayTool display = new DisplayTool(); display.setTruncateSuffix("foo"); assertEquals("foo", display.getTruncateSuffix()); } public @Test void methodSetTruncateAtWord_String() throws Exception { DisplayTool display = new DisplayTool(); assertEquals(false, display.getTruncateAtWord()); display.setTruncateAtWord(true); assertEquals(true, display.getTruncateAtWord()); } public @Test void methodSpace_int() throws Exception { DisplayTool display = new DisplayTool(); assertEquals(null, display.space(-1)); assertEquals("", display.space(0)); assertEquals(" ", display.space(1)); assertEquals(" ", display.space(5)); } public @Test void methodTruncate_Object() throws Exception { DisplayTool display = new DisplayTool(); display.setTruncateLength(4); assertEquals(null, display.truncate(null)); assertEquals("f...", display.truncate("foobar")); assertEquals("foob", display.truncate("foob")); assertEquals("foo", display.truncate("foo")); } public @Test void methodTruncate_ObjectString() throws Exception { DisplayTool display = new DisplayTool(); display.setTruncateLength(4); assertEquals(null, display.truncate(null, ">")); assertEquals("foo>", display.truncate("foobar", ">")); assertEquals("foob", display.truncate("foobar", null)); assertEquals("foob", display.truncate("foobar", "woogie")); assertEquals("foo", display.truncate("foo", ">")); } public @Test void methodTruncate_Objectint() throws Exception { DisplayTool display = new DisplayTool(); assertEquals(null, display.truncate(null, 1)); assertEquals(null, display.truncate("foobar", -1)); assertEquals(null, display.truncate("foobar", 0)); assertEquals("f", display.truncate("foobar", 1)); assertEquals("fo", display.truncate("foobar", 2)); assertEquals("foo", display.truncate("foobar", 3)); assertEquals("f...", display.truncate("foobar", 4)); assertEquals("fo...", display.truncate("foobar", 5)); assertEquals("foobar", display.truncate("foobar", 6)); assertEquals("foobar", display.truncate("foobar", 7)); } public @Test void methodTruncate_ObjectintString() throws Exception { DisplayTool display = new DisplayTool(); assertEquals(null, display.truncate(null, 0, null)); assertEquals(null, display.truncate("foo", 0, null)); assertEquals("f", display.truncate("foo", 1, null)); assertEquals("foob", display.truncate("foobar", 4, null)); assertEquals("foo>", display.truncate("foobar", 4, ">")); } public @Test void methodTruncate_ObjectintStringboolean() throws Exception { DisplayTool display = new DisplayTool(); assertEquals(null, display.truncate(null, 0, null, true)); assertEquals(null, display.truncate("foo", 0, null, false)); assertEquals("f", display.truncate("foo", 1, null, true)); assertEquals("long stri>", display.truncate("long string", 10, ">", false)); assertEquals("long>", display.truncate("long string", 10, ">", true)); } public @Test void methodUncapitalize_Object() throws Exception { DisplayTool display = new DisplayTool(); assertEquals(null, display.uncapitalize(null)); assertEquals("", display.uncapitalize("")); assertEquals("test", display.uncapitalize("test")); assertEquals("test", display.uncapitalize("Test")); assertEquals("tEST", display.uncapitalize("TEST")); } public @Test void methodBr_Object() throws Exception { DisplayTool display = new DisplayTool(); assertEquals(null, display.br(null)); assertEquals("", display.br("")); assertEquals("
      \n", display.br("\n")); assertEquals("line1
      \n LINE2", display.br("line1 \n LINE2")); } public @Test void methodStripTags_Object() throws Exception { DisplayTool display = new DisplayTool(); String html = "

      paragraph link

      " + "

      header1

      header2

      " + "


      bold"; assertEquals(null, display.stripTags(null)); assertEquals("", display.stripTags("")); assertEquals("paragraph link header1 header2 bold", display.stripTags(html)); } public @Test void methodStripTags_ObjectStringVarArgs() throws Exception { DisplayTool display = new DisplayTool(); String html = "

      paragraph link

      " + "

      header1

      header2

      " + "


      bold"; assertEquals(null, display.stripTags(null, (String[])null)); assertEquals("", display.stripTags("","","")); assertEquals("paragraph link

      header1

      header2

      bold", display.stripTags(html, "h1", "h2")); assertEquals("paragraph link header1 header2 bold", display.stripTags(html, "a")); assertEquals("paragraph link header1 header2


      bold", display.stripTags(html, "b", "", null, "br")); } public @Test void methodPlural_intString() throws Exception { DisplayTool display = new DisplayTool(); assertEquals(null, display.plural(1,null)); assertEquals("", display.plural(2,"")); assertEquals("items", display.plural(0,"item")); assertEquals("item", display.plural(-1,"item")); assertEquals("555s", display.plural(2,"555")); assertEquals("TOYS", display.plural(2,"TOY")); assertEquals("ladies", display.plural(2,"lady")); assertEquals("foxes", display.plural(2,"fox")); assertEquals("churches", display.plural(2,"church")); } public @Test void methodPlural_intStringString() throws Exception { DisplayTool display = new DisplayTool(); assertEquals(null, display.plural(1,null,null)); assertEquals("", display.plural(2,"empty","")); assertEquals("men", display.plural(0,"man","men")); assertEquals("mouse", display.plural(-1,"mouse", "mice")); } public class TestBean { private int num; private String str; public TestBean(int num, String str) { this.num = num; this.str = str; } public int getNum() { return num; } public void setNum(int num) { this.num = num; } public String getStr() { return str; } public void setStr(String str) { this.str = str; } } }velocity-tools-2.0-src/src/test/java/org/apache/velocity/tools/generic/LinkToolTests.java100644 0 0 76602 11202122664 27044 0ustar 0 0 package org.apache.velocity.tools.generic; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import org.junit.*; import static org.junit.Assert.*; import java.net.URI; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; import org.apache.velocity.runtime.log.Log; import org.apache.velocity.tools.generic.ValueParser; /** *

      Tests for generic version of LinkTool

      * * @author Nathan Bubna * @since VelocityTools 2.0 * @version $Id$ */ public class LinkToolTests { public static final Map DEFAULT_PROPS = new HashMap(); static { // don't lock configure() for testing DEFAULT_PROPS.put(LinkTool.SAFE_MODE_KEY, false); DEFAULT_PROPS.put(LinkTool.LOCK_CONFIG_KEY, false); } /** * Returns a new instance configured with the * default testing properties. */ public LinkTool newInstance() { LinkTool link = new LinkTool(); link.configure(DEFAULT_PROPS); return link; } public LinkTool newInstance(String uri) { return newInstance(LinkTool.URI_KEY, uri); } /** * Returns a new instance configured with the * default testing properties and the specified * non-default property. */ public LinkTool newInstance(String key, Object value) { LinkTool link = new LinkTool(); Map props = new HashMap(DEFAULT_PROPS); props.put(key, value); link.configure(props); return link; } public @Test void ctorLinkTool() throws Exception { try { new LinkTool(); } catch (Exception e) { fail("Constructor 'LinkTool()' failed due to: " + e); } } public @Test void methodConfigure_ValueParser() throws Exception { LinkTool link = newInstance("mailto:nbubna@apache.org"); assertEquals("mailto", link.getScheme()); assertEquals("mailto:nbubna@apache.org", link.toString()); assertTrue(link.getUri().isOpaque()); assertTrue(link.isAbsolute()); } public @Test void methodDuplicate() throws Exception { LinkTool link = newInstance("http://apache.org/foo.html"); LinkTool result = link.duplicate(); assertFalse(link == result); assertSame(link.getScheme(), result.getScheme()); assertSame(link.getUser(), result.getUser()); assertSame(link.getHost(), result.getHost()); assertSame(link.getPath(), result.getPath()); assertSame(link.query, result.query); assertSame(link.getAnchor(), result.getAnchor()); assertSame(link.getSelf(), result.getSelf()); } public @Test void methodDuplicate_boolean() throws Exception { LinkTool link = newInstance("http://apache.org/foo.html?foo=bar"); LinkTool result = link.duplicate(true); assertFalse(link == result); assertSame(link.getPath(), result.getPath()); assertFalse(link.query == result.query); assertEquals(link.getQuery(), result.getQuery()); assertSame(link.getSelf(), result.getSelf()); assertSame(result.query, result.duplicate(false).query); } public @Test void methodEncode_Object() throws Exception { LinkTool link = newInstance(); assertEquals("this+has+spaces", link.encode("this has spaces")); assertEquals("%40%2F+", link.encode("@/ ")); } public @Test void methodDecode_Object() throws Exception { LinkTool link = newInstance(); assertEquals("this has spaces", link.decode("this+has+spaces")); assertEquals("@/ ", link.decode("%40%2F+")); } public @Test void methodSetScheme_Object() throws Exception { LinkTool link = newInstance(LinkTool.SCHEME_KEY, LinkTool.DEFAULT_SCHEME); assertEquals(LinkTool.DEFAULT_SCHEME, link.getScheme()); link.setScheme(null); assertEquals(null, link.getScheme()); link.setScheme("foo:"); assertEquals("foo", link.getScheme()); } public @Test void methodScheme_Object() throws Exception { LinkTool link = newInstance(); LinkTool result = link.scheme(null); assertEquals(null, result.getScheme()); link = newInstance("https://apache.org"); assertEquals(null, link.getPath()); assertEquals("https://apache.org", link.toString()); assertEquals(LinkTool.SECURE_SCHEME, link.getScheme()); assertTrue(link.isSecure()); result = link.scheme(LinkTool.DEFAULT_SCHEME); assertEquals("http://apache.org", result.toString()); assertFalse(result.isSecure()); } public @Test void methodGetScheme() throws Exception { LinkTool link = newInstance(); assertEquals(null, link.getScheme()); assertEquals("mailto", link.scheme("mailto").getScheme()); } public @Test void methodSecure() throws Exception { LinkTool link = newInstance(); assertFalse(link.isSecure()); LinkTool result = link.secure(); assertTrue(result.isSecure()); } public @Test void methodInsecure() throws Exception { LinkTool link = newInstance("https://apache.org"); assertTrue(link.isSecure()); LinkTool result = link.insecure(); assertFalse(result.isSecure()); } public @Test void methodIsAbsolute() throws Exception { LinkTool link = newInstance(); assertFalse(link.isAbsolute()); LinkTool result = link.absolute("http://apache.org"); assertTrue(result.isAbsolute()); } public @Test void methodSetUserInfo_Object() throws Exception { LinkTool link = newInstance(LinkTool.USER_KEY, "nbubna"); assertEquals("nbubna", link.getUser()); link.setUserInfo(null); assertEquals(null, link.getUser()); // no encoding should happen here link.setUserInfo("@#$ /@!"); assertEquals("@#$ /@!", link.getUser()); } public @Test void methodGetUser() throws Exception { LinkTool link = newInstance(); assertEquals(null, link.getUser()); link = newInstance("http://nbubna@apache.org"); assertEquals("nbubna", link.getUser()); } public @Test void methodUser_Object() throws Exception { LinkTool link = newInstance("http://nbubna@apache.org"); assertEquals(null, link.user(null).getUser()); assertEquals("nbubna", link.user("nbubna").getUser()); assertEquals("@#$ /!", link.user("@#$ /!").getUser()); assertEquals("http://%40%23$%20%2F!@apache.org", link.user("@#$ /!").toString()); } public @Test void methodGetHost() throws Exception { LinkTool link = newInstance("http://apache.org"); assertEquals("apache.org", link.getHost()); link.setFromURI("http://velocity.apache.org/tools/devel/"); assertEquals("velocity.apache.org", link.getHost()); } public @Test void methodHost_Object() throws Exception { LinkTool link = newInstance(); assertEquals("apache.org", link.host("apache.org").getHost()); link = newInstance("https://nbubna@www.apache.org"); assertEquals("https://nbubna@people.apache.org", link.host("people.apache.org").toString()); } public @Test void methodSetHost_Object() throws Exception { LinkTool link = newInstance(); link.setHost("foo.com"); assertEquals("foo.com", link.getHost()); } public @Test void methodGetPort() throws Exception { LinkTool link = newInstance(); assertNull(link.getPort()); link = newInstance(LinkTool.PORT_KEY, 42); assertEquals(42, link.getPort()); } public @Test void methodPort_Object() throws Exception { LinkTool link = newInstance(); assertNull(link.port(null).getPort()); assertNull(link.port(":asd").getPort()); assertEquals(1, link.port(1).getPort()); assertEquals(42, link.port("42").getPort()); } public @Test void methodSetPort_Object() throws Exception { LinkTool link = newInstance(); link.setPort(42); assertEquals(42, link.getPort()); } public @Test void methodGetPath() throws Exception { LinkTool link = newInstance(); assertNull(link.getPath()); link = newInstance("http://velocity.apache.org/tools/devel"); assertEquals("/tools/devel", link.getPath()); } public @Test void methodSetPath_Object() throws Exception { LinkTool link = newInstance(); assertNull(link.getPath()); link.setPath("foo"); assertEquals("/foo", link.getPath()); link.setPath("/foo"); assertEquals("/foo", link.getPath()); link.setPath("/foo/"); assertEquals("/foo/", link.getPath()); link.setPath("/foo/"); assertEquals("/foo/", link.getPath()); } public @Test void methodPath_Object() throws Exception { LinkTool link = newInstance(); assertNull(link.getPath()); assertEquals("/bar", link.path("bar").getPath()); assertEquals("/bar", link.path("/bar").getPath()); assertEquals("/bar/", link.path("bar/").getPath()); assertEquals("/bar/", link.path("/bar/").getPath()); link = newInstance("http://foo.com/this/that.vm"); assertEquals("http://foo.com/this/that.vm", link.toString()); assertEquals("http://foo.com/bar.vm", link.path("bar.vm").toString()); } public @Test void methodCombinePath_StringString() throws Exception { LinkTool link = newInstance(); String none = null; String empty = ""; String test = "test"; String starts = "/this"; String ends = "that/"; String both = "/these/"; assertNull(link.combinePath(none, none)); assertSame(empty, link.combinePath(none, empty)); assertSame(empty, link.combinePath(empty, none)); assertEquals("/test", link.combinePath(empty, test)); assertEquals("test/", link.combinePath(test, empty)); assertEquals("/this/this", link.combinePath(starts, starts)); assertEquals("that/that/", link.combinePath(ends, ends)); assertEquals("/this/that/", link.combinePath(starts, ends)); assertEquals("that/this", link.combinePath(ends, starts)); assertEquals("/these/these/", link.combinePath(both, both)); } public @Test void methodAppendPath_Object() throws Exception { LinkTool link = newInstance(LinkTool.PATH_KEY, "/foo"); assertEquals("/foo", link.getPath()); link.appendPath("bar"); assertEquals("/foo/bar", link.getPath()); link.appendPath("/bar"); assertEquals("/foo/bar/bar", link.getPath()); link.setPath("/foo/"); link.appendPath("bar/"); assertEquals("/foo/bar/", link.getPath()); link.appendPath("/bar"); assertEquals("/foo/bar/bar", link.getPath()); } public @Test void methodAppend_Object() throws Exception { LinkTool link = newInstance(LinkTool.PATH_KEY, "/foo"); assertEquals("/foo", link.append(null).getPath()); link.setPath(null); assertNull(link.getPath()); link = link.append("bar"); assertEquals("/bar", link.getPath()); assertEquals("/bar/foo", link.append("foo").getPath()); } public @Test void methodGetDirectory() throws Exception { LinkTool link = newInstance("http://foo.com/ctx/request.vm?this=that#anc"); assertEquals("/ctx/", link.getDirectory()); link = newInstance("http://foo.com"); assertNull(link.getDirectory()); link = newInstance("http://foo.com/bar"); assertEquals("/", link.getDirectory()); link = newInstance("http://foo.com/bar/foo/bar/foo"); assertEquals("/bar/foo/bar/", link.getDirectory()); } public @Test void methodGetFile() throws Exception { LinkTool link = newInstance("http://foo.com/ctx/request.vm?this=that#anc"); assertEquals("request.vm", link.getFile()); link = newInstance("http://foo.com/foo/bar/request.vm?this=that#anc"); assertEquals("request.vm", link.getFile()); link = newInstance("http://foo.com/bar/"); assertEquals("", link.getFile()); } public @Test void methodGetRoot() throws Exception { LinkTool link = newInstance("http://foo.com/ctx/request.vm?this=that#anc"); assertEquals("http://foo.com", link.getRoot()); link.setHost("apache.org"); assertEquals("https://apache.org", link.secure().getRoot()); } public @Test void methodDirectory() throws Exception { LinkTool link = newInstance("http://foo.com/ctx/request.vm?this=that#anc"); assertEquals("http://foo.com/ctx/", link.directory().toString()); link = newInstance("http://foo.com"); assertEquals("http://foo.com", link.directory().toString()); } public @Test void methodRoot() throws Exception { LinkTool link = newInstance("http://foo.com/ctx/request.vm?this=that#anc"); assertEquals("http://foo.com", link.root().toString()); link = newInstance("http://foo.com"); assertEquals("http://foo.com", link.root().toString()); link = newInstance("dev@velocity.apache.org"); assertNull(link.root()); } public @Test void methodSetForceRelative_boolean() throws Exception { LinkTool link = newInstance("http://apache.org/bar"); assertEquals("http://apache.org/bar", link.toString()); link.setForceRelative(true); assertEquals("/bar", link.toString()); } public @Test void methodRelative_Object() throws Exception { LinkTool link = newInstance("/ctx/request.vm?this=that#anc"); assertEquals("/ctx/request.vm", link.getPath()); assertEquals("/ctx/", link.getDirectory()); assertEquals("this=that", link.getQuery()); assertEquals("anc", link.getAnchor()); assertEquals("/ctx/request.vm?this=that#anc", link.toString()); assertEquals("/ctx/?this=that#anc", link.relative(null).toString()); assertEquals("/ctx/other.vm?this=that#anc", link.relative("other.vm").toString()); link = newInstance("http://foo.com/bar/"); assertEquals("/bar/woogie.vm", link.relative("woogie.vm").toString()); link = newInstance("/bar/"); assertEquals("/bar/foo/woogie.vm", link.relative("foo/woogie.vm").toString()); assertEquals("/bar/yo", link.relative("yo").toString()); } public @Test void methodIsRelative() throws Exception { LinkTool link = newInstance("/ctx/request.vm?this=that#anc"); assertTrue(link.isRelative()); link = newInstance("http://foo.com/bar.vm?q=woogie"); assertFalse(link.isRelative()); assertTrue(link.relative().isRelative()); link = newInstance("http://apache.org").relative("foo.vm"); assertTrue(link.isRelative()); } public @Test void methodAbsolute_Object() throws Exception { LinkTool link = newInstance(); LinkTool result = link.absolute(null); result = link.absolute("http://apache.org"); assertEquals(link.uri("http://apache.org"), result); assertTrue(result.isAbsolute()); assertEquals("http://apache.org", result.toString()); assertEquals(LinkTool.DEFAULT_SCHEME, result.getScheme()); assertEquals("apache.org", result.getHost()); assertFalse(link.isAbsolute()); result = link.absolute("/test/foo.vm"); assertTrue(result.isAbsolute()); assertEquals("/test/foo.vm", result.getPath()); assertEquals(null, result.getHost()); assertEquals("http:/test/foo.vm", result.toString()); result = result.host("apache.org"); assertEquals("http://apache.org/test/foo.vm", result.toString()); result = result.absolute("bar.vm"); assertEquals("http://apache.org/test/bar.vm", result.toString()); result = result.absolute("/woogie.vm"); assertEquals("http://apache.org/woogie.vm", result.toString()); } public @Test void methodGetBaseRef() throws Exception { LinkTool link = newInstance("http://foo.com/ctx/request.vm?this=that#anc"); assertEquals("http://foo.com/ctx/request.vm", link.getBaseRef()); assertEquals(null, newInstance().getBaseRef()); } public @Test void methodGetUri() throws Exception { LinkTool link = newInstance(LinkTool.SAFE_MODE_KEY, true); link.setFromURI("http://velocity.apache.org"); assertNull(link.getUri()); link = newInstance(); assertNull(link.getUri()); link = link.secure().user("nbubna").host("people.apache.org"); assertNotNull(link.getUri()); assertEquals("nbubna", link.getUri().getUserInfo()); } public @Test void methodSetFromURI_Object() throws Exception { LinkTool link = newInstance(); assertNull(link.toString()); link.setFromURI("*%&$^%#$*&^!"); assertNull(link.toString()); link.setFromURI("http://velocity.apache.org"); assertNotNull(link.toString()); assertEquals("velocity.apache.org", link.getHost()); } public @Test void methodToURI_Object() throws Exception { LinkTool link = newInstance(); URI uri = new URI("http://apache.org"); assertSame(uri, link.toURI(uri)); assertNull(link.toURI("*%&$^%#$*&^!")); assertNotNull(link.toURI("http://velocity.apache.org")); assertNotNull(link.toURI(new Object() { public String toString() { return "http://google.com"; } })); } public @Test void methodCreateURI() throws Exception { LinkTool link = newInstance(); assertNull(link.createURI()); link.setFromURI("http://velocity.apache.org"); assertNotNull(link.createURI()); link.setPort("foo"); assertNull(link.createURI()); link.setPort(null); assertTrue(link.setFromURI("mailto:nbubna@apache.org")); assertTrue(link.isOpaque()); assertNotNull(link.createURI()); assertTrue(link.createURI().isOpaque()); assertEquals(link.createURI(), link.createURI()); assertFalse(link.createURI() == link.createURI()); } public @Test void methodUri_Object() throws Exception { LinkTool link = newInstance(); assertEquals(null, link.uri(null).toString()); assertEquals("http://apache.org?a=b#c", link.uri("http://apache.org?a=b#c").toString()); link.setFromURI("https://nbubna@people.apache.org"); assertEquals("people.apache.org", link.getHost()); assertEquals("https://nbubna@people.apache.org", link.uri(link.createURI()).toString()); URI uri = new URI("mailto:nbubna@apache.org"); assertEquals("mailto:nbubna@apache.org", link.uri(uri).toString()); } public @Test void methodSetAppendParams_boolean() throws Exception { LinkTool link = newInstance("/bar?a=b"); LinkTool result = link.param("a","c"); assertEquals("a=b&a=c", result.getQuery()); link.setAppendParams(false); result = link.param("a", "d"); assertEquals("a=d", result.getQuery()); } public @Test void methodSetQuery_Object() throws Exception { LinkTool link = newInstance("/bar?a=b"); assertNotNull(link.getQuery()); assertEquals("a=b", link.getQuery()); link.setQuery("c=d&e=f"); assertEquals("c=d&e=f", link.getQuery()); link.setXHTML(false); link.setQuery("x=1&y=2"); assertEquals("x=1&y=2", link.getQuery()); link.setQuery(null); assertEquals(null, link.getQuery()); } public @Test void methodNormalizeQuery_String() throws Exception { LinkTool link = new LinkTool(); assertEquals("a=b", link.normalizeQuery("a=b")); assertEquals("a=b&b=c", link.normalizeQuery("a=b&b=c")); assertEquals("a=b&b=c", link.normalizeQuery("a=b&b=c")); assertEquals("a=b&b=c&t=f", link.normalizeQuery("a=b&b=c&t=f")); } public @Test void methodGetQuery() throws Exception { LinkTool link = newInstance(); assertEquals(null, link.getQuery()); assertEquals("this=that", link.query("this=that").getQuery()); } public @Test void methodQuery_Object() throws Exception { LinkTool link = newInstance("https://gmail.com"); assertEquals("https://gmail.com", link.query(null).toString()); assertEquals("https://gmail.com?v=2", link.query("v=2").toString()); link = newInstance("http://go.com?foo=bar"); assertEquals("foo=wog", link.query("foo=wog").getQuery()); assertEquals("http://go.com", link.query(null).toString()); } // this method also tests setXHTML public @Test void methodCombineQuery_StringString() throws Exception { LinkTool link = newInstance(); String none = null; String empty = ""; String test = "test=1"; String test2 = "a=b"; assertSame(none, link.combineQuery(none, none)); assertSame(none, link.combineQuery(none, empty)); assertSame(test, link.combineQuery(test, none)); assertEquals("test=1", link.combineQuery(test, empty)); assertEquals("test=1&a=b", link.combineQuery(test, test2)); link.setXHTML(false); assertEquals("a=b&test=1", link.combineQuery(test2, test)); } public @Test void methodAppendQuery_Object() throws Exception { LinkTool link = newInstance("/foo?bar=woogie"); link.appendQuery("x=1"); assertEquals("bar=woogie&x=1", link.getQuery()); link.appendQuery("y=2"); assertEquals("bar=woogie&x=1&y=2", link.getQuery()); link.setQuery(null); assertEquals(null, link.getQuery()); link.appendQuery("z=3"); assertEquals("z=3", link.getQuery()); } public @Test void methodToQuery_Map() throws Exception { LinkTool link = new LinkTool(); Map test = new LinkedHashMap(); test.put("a", "b"); assertEquals("a=b", link.toQuery(test)); test.put("b", "c"); assertEquals("a=b&b=c", link.toQuery(test)); Boolean[] array = new Boolean[] { Boolean.TRUE, Boolean.FALSE }; test.put("b", array); assertEquals("a=b&b=true&b=false", link.toQuery(test)); } public @Test void methodToQuery_ObjectObject() throws Exception { LinkTool link = newInstance(); assertEquals("null=", link.toQuery(null, null)); assertEquals("a+b=c", link.toQuery("a b", "c")); assertEquals("x=1", link.toQuery('x', 1)); assertEquals("true=false", link.toQuery(true, false)); assertEquals("path=%2Ffoo+bar%2Fnew", link.toQuery("path", "/foo bar/new")); // try all URI reserved chars assertEquals("x=%2C%3B%3A%24%26%2B%3D%3F%2F%5B%5D%40", link.toQuery('x', ",;:$&+=?/[]@")); } public @Test void methodSetParam_ObjectObjectboolean() throws Exception { LinkTool link = newInstance(); assertNull(link.query); link.setParam("a","b", true); assertNotNull(link.query); assertEquals("a=b", link.getQuery()); link.setParam("a", "c", true); assertEquals("a=b&a=c", link.getQuery()); link.setParam("a", "foo", false); assertEquals("a=foo", link.getQuery()); } public @Test void methodSetParams_Objectboolean() throws Exception { LinkTool link = newInstance(); assertNull(link.query); link.setParams("a=b", true); assertNotNull(link.query); assertEquals("a=b", link.getQuery()); link.setParams("a=c&a=d", true); assertEquals("a=b&a=c&a=d", link.getQuery()); Map test = new LinkedHashMap(); test.put("a", "foo"); link.setParams(test, false); assertEquals("a=foo", link.getQuery()); } public @Test void methodParams_Object() throws Exception { LinkTool link = newInstance(); Map test = new LinkedHashMap(); test.put("a", "foo"); assertEquals("a=foo", link.params(test).getQuery()); assertEquals("a=b&b=c", link.params("a=b&b=c").getQuery()); link = newInstance("/foo?q=a&a=q"); assertEquals("/foo", link.params(false).toString()); assertEquals("/foo?q=a&a=q", link.params(true).toString()); } public @Test void methodParam_ObjectObject() throws Exception { LinkTool link = newInstance(); assertEquals("null=", link.param(null, null).getQuery()); assertEquals("x=1", link.param("x",1).getQuery()); assertEquals("x=1&y=2", link.param("x",1).param("y",2).getQuery()); link = newInstance("/hee/haa.vm?a=b"); assertEquals("/hee/haa.vm?a=b&b=true", link.param('b', true).toString()); } public @Test void methodAppend_ObjectObject() throws Exception { LinkTool link = newInstance(); link.setAppendParams(false); //using append(key,val) should override assertEquals("x=1", link.append("x",1).getQuery()); assertEquals("x=1&x=2", link.append("x",1).append("x",2).getQuery()); } public @Test void methodSet_ObjectObject() throws Exception { LinkTool link = newInstance(); link.setAppendParams(true); //using set(key,val) should override assertEquals("x=1", link.set("x",1).getQuery()); assertEquals("x=2", link.set("x",1).set("x",2).getQuery()); } public @Test void methodRemove_Object() throws Exception { LinkTool link = newInstance("/foo?q=bar"); assertEquals("q=bar", link.getQuery()); assertEquals("", link.remove("q").getQuery()); assertEquals("q=bar", link.set("x",1).remove("x").getQuery()); } public @Test void methodRemoveParam_Object() throws Exception { LinkTool link = newInstance(); assertNull(link.removeParam("a")); link.setParam("a","b",true); assertEquals("a=b", link.getQuery()); assertEquals("b", link.removeParam("a")); assertNull(link.removeParam("a")); } public @Test void methodHandleParamsBoolean_boolean() throws Exception { LinkTool link = newInstance(); assertNull(link.query); link.setParam("a","b",true); Map q = link.query; link.handleParamsBoolean(true); assertSame(q, link.query); assertEquals("a=b", link.getQuery()); link.handleParamsBoolean(false); assertNull(link.query); } public @Test void methodParams_Map() throws Exception { LinkTool link = newInstance("http://go.com"); Map params = new LinkedHashMap(); params.put("this", "that"); params.put('x', 1); params.put(true, false); assertEquals("http://go.com?this=that&x=1&true=false", link.params(params).toString()); assertEquals("http://go.com", link.params(null).toString()); assertEquals("http://go.com", link.params(new HashMap()).toString()); } public @Test void methodParseQuery_String() throws Exception { LinkTool link = newInstance(); Map result = link.parseQuery("a=b&x=1"); assertEquals("b", result.get("a")); assertEquals("1", result.get("x")); link.setXHTML(false); result = link.parseQuery("true=false&false=true&black=white"); assertEquals("false", result.get("true")); assertEquals("true", result.get("false")); assertEquals("white", result.get("black")); } public @Test void methodGetParams() throws Exception { LinkTool link = newInstance("/foo?a=b&x=true"); Map result = link.getParams(); assertEquals("b", result.get("a")); assertEquals("true", result.get("x")); Map newresult = link.param('y',false).getParams(); assertFalse(result.equals(newresult)); assertEquals("b", newresult.get("a")); assertEquals(Boolean.FALSE, newresult.get("y")); } public @Test void methodSetFragment_Object() throws Exception { LinkTool link = newInstance(); link.setFragment("foo"); assertEquals("#foo", link.toString()); link.setFragment(null); assertEquals(null, link.toString()); link = newInstance("/foo#bar"); link.setFragment("woo gie"); assertEquals("/foo#woo%20gie", link.toString()); } public @Test void methodGetAnchor() throws Exception { LinkTool link = newInstance(); assertEquals(null, link.getAnchor()); link.setFragment("foo"); assertEquals("foo", link.getAnchor()); link = newInstance("http://go.com#espn"); assertEquals("espn", link.getAnchor()); link = newInstance(LinkTool.FRAGMENT_KEY, "foo"); assertEquals("foo", link.getAnchor()); } public @Test void methodAnchor_Object() throws Exception { LinkTool link = newInstance(); // here are possible string values to test: String none = null; String empty = ""; String space = "a b"; String test = "test"; assertEquals(null, link.anchor(none).getAnchor()); assertEquals(null, link.anchor(empty).getAnchor()); assertEquals(test, link.anchor(test).getAnchor()); assertEquals("a b", link.anchor(space).getAnchor()); link = newInstance("http://go.com#foo"); assertEquals("http://go.com#true", link.anchor(true).toString()); assertEquals("http://go.com#a%20b", link.anchor(space).toString()); } public @Test void methodGetSelf() throws Exception { LinkTool link = newInstance(); assertSame(link, link.getSelf()); assertSame(link, link.uri("http://go.com").getSelf()); assertSame(link, link.path("foo").param(1,true).anchor('a').getSelf()); } public @Test void methodToString() throws Exception { LinkTool link = newInstance(); assertEquals(null, link.toString()); assertEquals(null, link.secure().toString()); assertEquals("http://go.com", link.host("go.com").toString()); assertEquals(null, link.port(42).toString()); assertEquals("/foo", link.path("foo").toString()); assertEquals("?a=1", link.param('a',1).toString()); assertEquals("#42", link.anchor(42).toString()); } public @Test void methodNoDoubleEncode() throws Exception { LinkTool link = newInstance().relative("/foo"); assertEquals("/foo", link.toString()); link = link.param("q","a:b c"); assertEquals("/foo?q=a%3Ab+c", link.toString()); link = link.anchor("a(b, c)"); assertEquals("/foo?q=a%3Ab+c#a(b,%20c)", link.toString()); link = link.param("evil","%25%24%").anchor(null); assertEquals("/foo?q=a%3Ab+c&evil=%2525%2524%25", link.toString()); } } velocity-tools-2.0-src/src/test/java/org/apache/velocity/tools/generic/LoopToolTests.java100644 0 0 32224 11202122664 27050 0ustar 0 0 package org.apache.velocity.tools.generic; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import org.junit.*; import static org.junit.Assert.*; import java.util.*; /** *

      Tests for LoopTool

      * * @author Nathan Bubna * @since VelocityTools 2.0 * @version $Id$ */ public class LoopToolTests { public static final String[] ARRAY = { "foo", "bar", "woogie" }; public @Test void ctorLoopTool() throws Exception { try { new LoopTool(); } catch (Exception e) { fail("Constructor 'LoopTool()' failed due to: " + e); } } public @Test void methodSkip_int() throws Exception { LoopTool loop = new LoopTool(); Iterator i = loop.watch(ARRAY); // skip nothing loop.skip(0); assertEquals(i.next(), ARRAY[0]); // skip one (should be on 2 now) loop.skip(1); assertEquals(i.next(), ARRAY[2]); // end this loop.pop(); // start over to skip 2 i = loop.watch(ARRAY); loop.skip(2); assertEquals(i.next(), ARRAY[2]); } public @Test void methodSkip_intString() throws Exception { LoopTool loop = new LoopTool(); Iterator i = loop.watch(ARRAY, "i"); Iterator j = loop.watch(ARRAY, "j"); Iterator k = loop.watch(ARRAY, "k"); // these should not do anything loop.skip(1, null); loop.skip(1, ""); loop.skip(1, "test"); // these should work loop.skip(1, "i"); loop.skip(1, "j"); loop.skip(1, "k"); assertEquals(i.next(), ARRAY[1]); assertEquals(j.next(), ARRAY[1]); assertEquals(k.next(), ARRAY[1]); } public @Test void methodStop() throws Exception { LoopTool loop = new LoopTool(); Iterator i = loop.watch(ARRAY); assertTrue(i.hasNext()); loop.stop(); assertFalse(i.hasNext()); } public @Test void methodStopAll() throws Exception { LoopTool loop = new LoopTool(); Iterator i = loop.watch(ARRAY); Iterator j = loop.watch(ARRAY); Iterator k = loop.watch(j); assertTrue(i.hasNext() && j.hasNext() && k.hasNext()); loop.stopAll(); assertFalse(i.hasNext() || j.hasNext() || k.hasNext()); } public @Test void methodStopTo_String() throws Exception { LoopTool loop = new LoopTool(); Iterator i = loop.watch(ARRAY, "i"); Iterator j = loop.watch(ARRAY, "j"); Iterator k = loop.watch(ARRAY, "k"); assertTrue(i.hasNext() && j.hasNext() && k.hasNext()); // these shouldn't stop anything loop.stopTo(null); assertTrue(i.hasNext() && j.hasNext() && k.hasNext()); loop.stopTo(""); assertTrue(i.hasNext() && j.hasNext() && k.hasNext()); loop.stopTo("test"); assertTrue(i.hasNext() && j.hasNext() && k.hasNext()); // this should only stop j and k loop.stopTo("j"); assertTrue(i.hasNext()); assertFalse(j.hasNext() || k.hasNext()); } public @Test void methodStop_String() throws Exception { LoopTool loop = new LoopTool(); Iterator i = loop.watch(ARRAY, "i"); Iterator j = loop.watch(ARRAY, "j"); Iterator k = loop.watch(ARRAY, "k"); assertTrue(i.hasNext() && j.hasNext() && k.hasNext()); // these shouldn't stop anything loop.stop(null); assertTrue(i.hasNext() && j.hasNext() && k.hasNext()); loop.stop(""); assertTrue(i.hasNext() && j.hasNext() && k.hasNext()); loop.stop("test"); assertTrue(i.hasNext() && j.hasNext() && k.hasNext()); // this should only stop j loop.stop("j"); assertTrue(i.hasNext() && k.hasNext()); assertFalse(j.hasNext()); } public @Test void methodWatch_Object() throws Exception { LoopTool loop = new LoopTool(); // try to watch unwatchable things Iterator i = loop.watch(null); assertNull(i); assertNull(loop.watch(new Object())); // watch an array assertNotNull(loop.watch(ARRAY)); // watch an iterator assertNotNull(loop.watch(loop.watch(ARRAY))); //TODO: watch enumeration // watch collection assertNotNull(loop.watch(LIST)); // watch map assertNotNull(loop.watch(new HashMap())); // watch iterable assertNotNull(loop.watch(new MyIterable())); // watch object w/iterator method assertNotNull(loop.watch(new HasIteratorMethod())); } static final Collection LIST = Arrays.asList(ARRAY); public static class HasIteratorMethod { public Iterator iterator() { return LoopToolTests.LIST.iterator(); } } public static class MyIterable extends HasIteratorMethod implements Iterable { } public @Test void methodWatch_ObjectString() throws Exception { LoopTool loop = new LoopTool(); // null names are invalid Iterator i = loop.watch(ARRAY, null); assertNull(i); // empty names are ok assertNotNull(loop.watch(ARRAY, "")); // so are real ones assertNotNull(loop.watch(ARRAY, "name")); } public @Test void methodIsFirst() throws Exception { LoopTool loop = new LoopTool(); Iterator i = loop.watch(ARRAY); assertTrue(loop.isFirst()); i.next(); assertTrue(loop.isFirst()); i.next(); assertFalse(loop.isFirst()); } public @Test void methodIsFirst_String() throws Exception { LoopTool loop = new LoopTool(); Iterator i = loop.watch(ARRAY, "i"); assertTrue(loop.isFirst()); i.next(); Iterator j = loop.watch(ARRAY, "j"); assertTrue(loop.isFirst()); assertTrue(loop.isFirst("i")); assertTrue(loop.isFirst("j")); // check short syntax too assertTrue((Boolean)loop.get("first_i")); assertTrue((Boolean)loop.get("first_j")); i.next(); assertFalse(loop.isFirst("i")); assertFalse((Boolean)loop.get("first_i")); j.next(); assertTrue(loop.isFirst()); assertTrue(loop.isFirst("j")); assertTrue((Boolean)loop.get("first_j")); j.next(); assertFalse(loop.isFirst("j")); assertFalse((Boolean)loop.get("first_j")); } public @Test void methodIsLast() throws Exception { LoopTool loop = new LoopTool(); Iterator i = loop.watch(ARRAY); assertFalse(loop.isLast()); i.next(); assertFalse(loop.isLast()); i.next(); assertFalse(loop.isLast()); i.next(); assertTrue(loop.isLast()); } public @Test void methodIsLast_String() throws Exception { LoopTool loop = new LoopTool(); Iterator i = loop.watch(ARRAY, "i"); assertFalse(loop.isLast()); i.next(); i.next(); i.next(); assertTrue(loop.isLast()); Iterator j = loop.watch(ARRAY, "j"); assertFalse(loop.isLast()); assertTrue(loop.isLast("i")); assertFalse(loop.isLast("j")); // check short syntax too assertTrue((Boolean)loop.get("last_i")); assertFalse((Boolean)loop.get("last_j")); j.next(); j.next(); j.next(); assertTrue(loop.isLast()); assertTrue(loop.isLast("j")); assertTrue((Boolean)loop.get("last_j")); } public @Test void methodGet() throws Exception { LoopTool loop = new LoopTool(); // sync an array with itself Iterator i = loop.watch(ARRAY).sync(ARRAY, "twin"); while (i.hasNext()) { // make sure they match assertEquals(i.next(), loop.get("twin")); } // sync a shorter array with a longer one to be // sure the values turn to null once they're gone int[] little = { 10, 20, 30 }; Integer[] big = { 1, 2, 3, 4, 5 }; i = loop.watch(big).sync(little, "little"); while (i.hasNext()) { Integer val = (Integer)i.next(); if (val < 4) { assertEquals(val * 10, loop.get("little")); } else { assertNull(loop.get("little")); } } } public @Test void methodGet_StringString() throws Exception { LoopTool loop = new LoopTool(); int[] other = { 1, 2, 3 }; // sync arrays with nested loops using default names // the way we iterate over both i and j together below // is, of course, impossible in a template, but it // makes writing a reasonable test for this method a lot // easier. //NOTE: this reliese on the default name for synced iterators // being "synced", for i being "loop0", and for j being "loop1" Iterator i = loop.watch(ARRAY).sync(other); Iterator j = loop.watch(other).sync(ARRAY); while (i.hasNext() && j.hasNext()) { // i and loop.synced (aka loop.get("loop1","synced")) should match assertEquals(i.next(), loop.get("synced")); // j and loop.get("loop0","synced") should match assertEquals(j.next(), loop.get("loop0", "synced")); } } public @Test void methodGetCountOrGetIndex() throws Exception { LoopTool loop = new LoopTool(); Iterator i = loop.watch(ARRAY); assertEquals(0, loop.getCount()); assertNull(loop.getIndex()); i.next(); assertEquals(1, loop.getCount()); assertEquals(0, loop.getIndex()); i.next(); assertEquals(2, loop.getCount()); assertEquals(1, loop.getIndex()); i.next(); assertEquals(3, loop.getCount()); assertEquals(2, loop.getIndex()); loop.pop(); // test that skipped iterations are still included i = loop.watch(ARRAY); loop.skip(2); assertEquals(2, loop.getCount()); assertEquals(1, loop.getIndex()); } public @Test void methodGetCountOrGetIndex_String() throws Exception { LoopTool loop = new LoopTool(); Iterator i = loop.watch(ARRAY, "i"); assertEquals(0, loop.getCount("i")); assertNull(loop.getIndex("i")); i.next(); assertEquals(1, loop.getCount("i")); assertEquals(0, loop.getIndex("i")); Iterator j = loop.watch(ARRAY, "j"); loop.skip(2); assertEquals(2, loop.getCount("j")); assertEquals(1, loop.getIndex("j")); assertEquals(1, loop.getCount("i")); assertEquals(0, loop.getIndex("i")); // check short syntax too assertEquals(2, loop.get("count_j")); assertEquals(1, loop.get("index_j")); assertEquals(1, loop.get("count_i")); assertEquals(0, loop.get("index_i")); } public @Test void aliasMethods() throws Exception { LoopTool loop = new LoopTool(); Iterator i = loop.watch(ARRAY); assertEquals(loop.isFirst(), loop.getFirst()); assertEquals(loop.isLast(), loop.getLast()); i.next(); assertEquals(loop.isFirst(), loop.getFirst()); assertEquals(loop.isLast(), loop.getLast()); i.next(); assertEquals(loop.isFirst(), loop.getFirst()); assertEquals(loop.isLast(), loop.getLast()); i.next(); assertEquals(loop.isFirst(), loop.getFirst()); assertEquals(loop.isLast(), loop.getLast()); } public @Test void watchAndExclude() throws Exception { LoopTool loop = new LoopTool(); Iterator i = loop.watch(ARRAY).exclude("bar"); assertEquals(i.next(), "foo"); assertEquals(i.next(), "woogie"); assertTrue(loop.isLast()); assertFalse(i.hasNext()); } public @Test void watchAndStop() throws Exception { LoopTool loop = new LoopTool(); Iterator i = loop.watch(ARRAY).stop("bar"); assertEquals(i.next(), "foo"); assertTrue(loop.isLast()); assertFalse(i.hasNext()); } public @Test void method_getDepth() throws Exception { LoopTool loop = new LoopTool(); assertEquals(0, loop.getDepth()); loop.watch(ARRAY); assertEquals(1, loop.getDepth()); loop.watch(ARRAY); assertEquals(2, loop.getDepth()); loop.pop(); assertEquals(1, loop.getDepth()); loop.pop(); assertEquals(0, loop.getDepth()); } } velocity-tools-2.0-src/src/test/java/org/apache/velocity/tools/generic/XmlToolTests.java100644 0 0 22042 11202122664 26674 0ustar 0 0 package org.apache.velocity.tools.generic; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import org.junit.*; import static org.junit.Assert.*; import java.net.URL; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.apache.velocity.tools.generic.ValueParser; import org.dom4j.Node; /** *

      Tests for XmlTool

      * * @author Nathan Bubna * @since VelocityTools 2.0 * @version $Id$ */ public class XmlToolTests { private static final String XML_FILE = "@test.file.dir@/file.xml"; private static final String XML_STRING = "\n \n woogie\n wiggie\n"; public @Test void ctorXmlTool() throws Exception { try { new XmlTool(); } catch (Exception e) { fail("Constructor 'XmlTool()' failed due to: " + e); } } private XmlTool stringBased() throws Exception { XmlTool xml = new XmlTool(); xml.parse(XML_STRING); return xml; } private XmlTool fileBased() throws Exception { XmlTool xml = new XmlTool(); xml.read(XML_FILE); return xml; } public @Test void testStringFileEquals() throws Exception { String string = stringBased().toString(); String file = fileBased().toString(); //System.out.println("string:\n"+string+"\nfile:\n"+file); assertEquals(string, file); } public @Test void methodAttr_Object() throws Exception { XmlTool xml = stringBased(); assertNull(xml.attr("href")); xml = xml.find("bar"); assertNotNull(xml.attr("name")); assertEquals("a", xml.attr("name")); } public @Test void methodAttributes() throws Exception { XmlTool xml = stringBased(); Map result = xml.attributes(); assertTrue(result.isEmpty()); xml = xml.find("bar"); result = xml.attributes(); assertNotNull(result); assertEquals(1, result.size()); assertEquals("a", result.get("name")); } public @Test void methodChildren() throws Exception { XmlTool xml = stringBased(); assertEquals(1, xml.size()); XmlTool result = xml.children(); assertEquals(3, result.size()); } public @Test void methodGetParent() throws Exception { XmlTool xml = stringBased().find("bar"); assertNotNull(xml); XmlTool foo = xml.getParent(); assertNotNull(foo); assertEquals(1, foo.size()); assertNull(foo.getParent()); } public @Test void methodParents() throws Exception { XmlTool foo = stringBased(); XmlTool xml = foo.find("bar"); assertEquals(foo.toString(), xml.parents().toString()); xml = foo.children(); assertEquals(3, xml.size()); foo = xml.parents(); assertEquals(1, foo.size()); } public @Test void methodConfigure_ValueParser() throws Exception { XmlTool xml = new XmlTool(); Map params = new HashMap(); assertEquals("file", XmlTool.FILE_KEY); params.put(XmlTool.FILE_KEY, XML_FILE); xml.configure(params); assertEquals(1, xml.size()); assertEquals("foo", xml.getName()); } public @Test void methodFind_Object() throws Exception { XmlTool xml = stringBased(); XmlTool result = xml.find((Object)null); assertNull(result); assertEquals(xml.find("bar").toString(), xml.find("//bar").toString()); //TODO: test more xpath expressions? //TODO: test expressions with no results } public @Test void methodGetFirst() throws Exception { XmlTool xml = stringBased(); assertSame(xml, xml.getFirst()); xml = xml.children(); assertEquals(3, xml.size()); xml = xml.getFirst(); assertEquals(1, xml.size()); assertEquals("a", xml.getName()); } public @Test void methodGetLast() throws Exception { XmlTool xml = stringBased(); assertSame(xml, xml.getLast()); xml = xml.children(); assertEquals(3, xml.size()); xml = xml.getLast(); assertEquals(1, xml.size()); assertEquals("baz", xml.getName()); assertEquals("wiggie", xml.getText()); } public @Test void methodGetName() throws Exception { XmlTool xml = stringBased(); assertEquals(1, xml.size()); assertEquals("foo", xml.getName()); xml = xml.find("bar"); assertEquals("a", xml.getName()); } public @Test void methodGetNodeName() throws Exception { XmlTool xml = stringBased(); assertEquals("foo", xml.getNodeName()); xml = xml.find("baz"); assertEquals("baz", xml.getNodeName()); } public @Test void methodGetText() throws Exception { XmlTool xml = stringBased(); //TODO: prepare the instance for testing String result = xml.getText(); assertEquals((String)null, result); } public @Test void methodGet_Number() throws Exception { XmlTool xml = stringBased(); assertEquals(xml.toString(), xml.get(0).toString()); xml = xml.children(); assertEquals("bar", xml.get(0).getNodeName()); assertEquals("baz", xml.get(1).getName()); assertEquals("baz", xml.get(2).getName()); assertNull(xml.get(3)); assertNull(xml.get(-1)); } public @Test void methodGet_Object() throws Exception { XmlTool xml = stringBased(); assertNull(xml.get(null)); assertNull(xml.get("")); assertNull(xml.get("null")); Object result = xml.get("bar"); assertNotNull(result); assertTrue(result instanceof XmlTool); xml = (XmlTool)result; result = null; assertNull(result); result = xml.get("0"); assertNotNull(result); assertEquals(result.toString(), xml.toString()); result = null; assertNull(result); result = xml.get("name"); assertNotNull(result); assertEquals("a", result); } public @Test void methodIsEmpty() throws Exception { XmlTool xml = new XmlTool(); assertTrue(xml.isEmpty()); xml.parse(XML_STRING); assertFalse(xml.isEmpty()); } public @Test void methodIterator() throws Exception { XmlTool xml = new XmlTool(); assertNull(xml.iterator()); xml.parse(XML_STRING); Iterator i = xml.iterator(); assertNotNull(i); XmlTool foo = i.next(); assertNotNull(foo); assertEquals(foo.toString(), xml.toString()); xml = xml.children(); i = xml.iterator(); assertEquals("a", i.next().attr("name")); assertEquals("baz", i.next().getName()); assertEquals("wiggie", i.next().getText()); assertFalse(i.hasNext()); } public @Test void methodNode() throws Exception { XmlTool xml = new XmlTool(); assertNull(xml.node()); xml.parse(XML_STRING); Node n = xml.node(); assertNotNull(n); } public @Test void methodParse_Object() throws Exception { XmlTool xml = new XmlTool(); assertNull(xml.parse((Object)null)); assertNull(xml.parse((Object)">")); assertTrue(xml.toString().endsWith("")); XmlTool bar = xml.find("bar"); assertEquals("", bar.toString()); XmlTool baz = (XmlTool)xml.get("baz"); assertEquals("woogiewiggie", baz.toString()); } } velocity-tools-2.0-src/src/test/java/org/apache/velocity/tools/test/FilteredLogChuteCommonsLog.java100644 0 0 3401 10730012240 30754 0ustar 0 0 package org.apache.velocity.tools.test; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import org.apache.velocity.tools.generic.log.LogChuteCommonsLog; /** * This logging adapter filters out trace and debug messages that don't come from the velocity package * (provided its given name contains a class name) * * @author Claude Brisson * @version $Id:$ */ public class FilteredLogChuteCommonsLog extends LogChuteCommonsLog { private boolean filter = false; public FilteredLogChuteCommonsLog(String name) { filter = !name.startsWith("org.apache.velocity"); } public void trace(Object message) { if(!filter) super.trace(message); } public void trace(Object message, Throwable t) { if(!filter) super.trace(message,t); } public void debug(Object message) { if(!filter) super.debug(message); } public void debug(Object message, Throwable t) { if(!filter) super.debug(message,t); } } velocity-tools-2.0-src/src/test/java/org/apache/velocity/tools/test/JettyLogger.java100644 0 0 7766 10730012240 26046 0ustar 0 0 /* * Copyright 2003 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.velocity.tools.test; import java.io.PrintWriter; import java.io.IOException; import org.mortbay.log.Logger; import org.mortbay.util.DateCache; /** Basic Jetty logger for our showcase webapp * * @author Claude Brisson */ public class JettyLogger implements Logger { private boolean debug = false; private String name = null; private DateCache _dateCache=new DateCache("yyyy-MM-dd HH:mm:ss.SSS"); private static PrintWriter out = null; static { try { String logfile = System.getProperty("jetty.log.file","/tmp/error.log"); out = new PrintWriter(logfile); } catch(IOException ioe) { System.out.println(ioe.getMessage()); } } public JettyLogger() { this(null); } public JettyLogger(String name) { this.name = name==null? "" : name; } /* * org.mortbay.log.Logger interface */ public boolean isDebugEnabled() { return debug; } public void setDebugEnabled(boolean enabled) { debug = enabled; } public void info(String msg,Object arg0, Object arg1) { if (out == null) return; /* a bit of filtering in debug mode */ if (debug && (msg.startsWith("loaded class") || msg.startsWith("loaded interface"))) { return; } logString(_dateCache.now() + " " + name + " " + format(msg,arg0,arg1)); } public void debug(String msg,Throwable th) { if (debug) { if (out == null) return; /* a bit of filtering in debug mode */ if (debug && (msg.startsWith("loaded class") || msg.startsWith("loaded interface"))) { return; } logString(_dateCache.now()+" "+msg); logStackTrace(th); } } public void debug(String msg,Object arg0, Object arg1) { if (debug) { if (out == null) return; /* a bit of filtering in debug mode */ if (debug && (msg.startsWith("loaded class") || msg.startsWith("loaded interface"))) { return; } logString(_dateCache.now()+" "+format(msg,arg0,arg1)); } } public void warn(String msg,Object arg0, Object arg1) { if (out == null) return; logString(_dateCache.now()+" "+format(msg,arg0,arg1)); } public void warn(String msg, Throwable th) { if (out == null) return; logString(_dateCache.now()+" "+msg); logStackTrace(th); } public Logger getLogger(String name) { if ((name==null && this.name==null) || (name!=null && name.equals(this.name))) return this; return new JettyLogger(name); } /* * private helpers */ private synchronized void logString(String msg) { out.println(msg); out.flush(); } private synchronized void logStackTrace(Throwable th) { th.printStackTrace(out); out.flush(); } private String format(String msg, Object arg0, Object arg1) { int i0=msg.indexOf("{}"); int i1=i0<0?-1:msg.indexOf("{}",i0+2); if (arg1!=null && i1>=0) msg=msg.substring(0,i1)+arg1+msg.substring(i1+2); if (arg0!=null && i0>=0) msg=msg.substring(0,i0)+arg0+msg.substring(i0+2); return msg; } } velocity-tools-2.0-src/src/test/java/org/apache/velocity/tools/test/blackbox/CookieToolTests.java100644 0 0 12552 11202122663 30501 0ustar 0 0 package org.apache.velocity.tools.test.blackbox; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.lang.reflect.Proxy; import java.lang.reflect.InvocationHandler; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import org.apache.velocity.tools.view.CookieTool; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import static org.junit.Assert.*; import org.junit.Test; /** *

      CookieTool tests.

      * * @author Nathan Bubna * @version $Id$ */ public class CookieToolTests { private CookieTool newCookieTool(InvocationHandler handler) { Object proxy = Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class[] { HttpServletRequest.class, HttpServletResponse.class }, handler); HttpServletRequest request = (HttpServletRequest)proxy; HttpServletResponse response = (HttpServletResponse)proxy; CookieTool cookies = new CookieTool(); cookies.setRequest(request); cookies.setResponse(response); return cookies; } private CookieTool newCookieTool(Map cookies) { return newCookieTool(new ServletAdaptor(cookies)); } private CookieTool newCookieTool(String name, Object value) { Map cookies = new LinkedHashMap(); cookies.put(name, value); return newCookieTool(cookies); } public @Test void testCreate_StringString() { CookieTool cookies = newCookieTool(new LinkedHashMap()); Cookie c = cookies.create("a", "b"); assertNotNull(c); assertEquals("a", c.getName()); assertEquals("b", c.getValue()); assertEquals(-1, c.getMaxAge()); } public @Test void testCreate_StringStringObject() { CookieTool cookies = newCookieTool(new LinkedHashMap()); Cookie c = cookies.create("a", "b", 10); assertNotNull(c); assertEquals("a", c.getName()); assertEquals("b", c.getValue()); assertEquals(10, c.getMaxAge()); c = cookies.create("a", "b", "500"); assertNotNull(c); assertEquals(500, c.getMaxAge()); c = cookies.create("a", "b", "asd"); assertNull(c); } public @Test void testGet_String() { CookieTool cookies = newCookieTool("a", "b"); assertEquals("b", cookies.get("a").toString()); } public @Test void testGetAll() { CookieTool cookies = newCookieTool("a", "b"); assertEquals("[b]", cookies.getAll().toString()); Map jar = new LinkedHashMap(); jar.put("a", "b"); jar.put("foo", "bar"); cookies = newCookieTool(jar); List all = cookies.getAll(); assertEquals(2, all.size()); assertEquals("[b, bar]", all.toString()); assertEquals("a", all.get(0).getName()); assertEquals("foo", all.get(1).getName()); } public @Test void testToString() { CookieTool cookies = newCookieTool("a", "b"); assertEquals("[a=b]", cookies.toString()); Map jar = new LinkedHashMap(); jar.put("a", "b"); jar.put("foo", "bar"); cookies = newCookieTool(jar); assertEquals("[a=b, foo=bar]", cookies.toString()); } public @Test void testAdd_StringString() { Map jar = new LinkedHashMap(); jar.put("a", "b"); ServletAdaptor proxy = new ServletAdaptor(jar); CookieTool cookies = newCookieTool(proxy); assertEquals("", cookies.add("a","b")); cookies = newCookieTool(proxy); assertNotNull(cookies.get("a")); assertEquals("b", cookies.get("a").getValue()); } public @Test void testAdd_StringStringObject() { Map jar = new LinkedHashMap(); jar.put("a", "b"); ServletAdaptor proxy = new ServletAdaptor(jar); CookieTool cookies = newCookieTool(proxy); assertEquals("", cookies.add("a","b", 10)); cookies = newCookieTool(proxy); Cookie c = cookies.get("a"); assertNotNull(c); assertEquals("b", c.getValue()); assertEquals(10, c.getMaxAge()); } public @Test void testDelete_String() { Map jar = new LinkedHashMap(); jar.put("a", "b"); ServletAdaptor proxy = new ServletAdaptor(jar); CookieTool cookies = newCookieTool(proxy); assertEquals("b", cookies.get("a").toString()); cookies.delete("a"); cookies = newCookieTool(proxy); assertNull(cookies.get("a")); } } velocity-tools-2.0-src/src/test/java/org/apache/velocity/tools/test/blackbox/LinkToolTests.java100644 0 0 13027 11110347746 30174 0ustar 0 0 package org.apache.velocity.tools.test.blackbox; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.lang.reflect.Proxy; import java.lang.reflect.InvocationHandler; import java.util.HashMap; import java.util.Map; import org.apache.velocity.tools.view.tools.LinkTool; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.junit.Assert; import org.junit.Test; /** *

      LinkTool tests.

      * * @author Christopher Schultz * @version $Id$ */ public class LinkToolTests { private LinkTool newLinkTool(InvocationHandler handler) { Object proxy = Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class[] { HttpServletRequest.class, HttpServletResponse.class }, handler); HttpServletRequest request = (HttpServletRequest)proxy; HttpServletResponse response = (HttpServletResponse)proxy; LinkTool link = new LinkTool(); link.setRequest(request); link.setResponse(response); return link; } private LinkTool newLinkTool(Map params) { return newLinkTool(new ServletAdaptor("/test","/link.vm", params)); } private LinkTool newLinkTool(String key, Object value) { HashMap params = new HashMap(); params.put(key, value); return newLinkTool(params); } public @Test void testAddAllParameters() { LinkTool link = newLinkTool("a", "b"); Assert.assertEquals("/test", link.getContextPath()); String url = link.setRelative("/target") .addQueryData("foo", "bar") .addQueryData("bar", "baz") .addAllParameters() .toString(); Assert.assertEquals("/test/target?foo=bar&bar=baz&a=b", url); } public @Test void testAddMultiValueParameters() { LinkTool link = newLinkTool("a", new String[] { "a", "b", "c" }); String url = link.setRelative("/target") .addQueryData("foo", "bar") .addQueryData("bar", "baz") .addAllParameters() .toString(); Assert.assertEquals("/test/target?foo=bar&bar=baz&a=a&a=b&a=c", url); } public @Test void testAddIgnoreParameters() { HashMap params = new HashMap(); params.put("a", "b"); params.put("b", "c"); LinkTool link = newLinkTool(params); String url = link.setRelative("/target") .addQueryData("foo", "bar") .addQueryData("bar", "baz") .addIgnore("b") .addAllParameters() .toString(); Assert.assertEquals("/test/target?foo=bar&bar=baz&a=b", url); } public @Test void testAddAllParametersFirst() { LinkTool link = newLinkTool("a", "b"); String url = link.setRelative("/target") .addAllParameters() .addQueryData("foo", "bar") .addQueryData("bar", "baz") .toString(); Assert.assertEquals("/test/target?a=b&foo=bar&bar=baz", url); } public @Test void testAddAdditionalValue() { LinkTool link = newLinkTool("a", "b"); link.setAutoIgnoreParameters(false); String url = link.setRelative("/target") .addQueryData("a", "c") .addAllParameters() .toString(); Assert.assertEquals("/test/target?a=c&a=b", url); } public @Test void testAddAdditionalValueAfter() { LinkTool link = newLinkTool("a", "b"); link.setAutoIgnoreParameters(false); String url = link.setRelative("/target") .addAllParameters() .addQueryData("a", "c") .toString(); Assert.assertEquals("/test/target?a=b&a=c", url); } public @Test void testAutoIgnore() { LinkTool link = newLinkTool("a", "b"); String url = link.setRelative("/target") .addQueryData("a", "c") .toString(); Assert.assertEquals("/test/target?a=c", url); } public @Test void testAutoIgnoreMultiple() { LinkTool link = newLinkTool("a", new String[] { "a", "b", "c" }); String url = link.setRelative("/target") .addQueryData("a", "d") .addAllParameters() .toString(); Assert.assertEquals("/test/target?a=d", url); } public @Test void testNoIgnoreMultiple_WrongOrder() { LinkTool link = newLinkTool("a", new String[] { "a", "b", "c" }); String url = link.setRelative("/target") .addAllParameters() .addQueryData("a", "d") .toString(); Assert.assertEquals("/test/target?a=a&a=b&a=c&a=d", url); } } velocity-tools-2.0-src/src/test/java/org/apache/velocity/tools/test/blackbox/ServletAdaptor.java100644 0 0 17321 11202122663 30345 0ustar 0 0 package org.apache.velocity.tools.test.blackbox; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import org.apache.commons.collections.iterators.IteratorEnumeration; import javax.servlet.ServletContext; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** *

      Helper class for LinkToolTests class

      * * @author Christopher Schultz * @version $Id$ */ public class ServletAdaptor implements InvocationHandler { // the params now also serve as a cookie jar for CookieToolTests private Map _params; private String _contextPath; private String _pathInfo; public ServletAdaptor(Map cookies) { this(null, null, cookies); } public ServletAdaptor(String contextPath, Map params) { this(contextPath, "", params); } public ServletAdaptor(String contextPath, String pathInfo, Map params) { _contextPath = contextPath; if(null == _contextPath) { _contextPath = ""; } _pathInfo = pathInfo; if(null == _pathInfo) { _pathInfo = ""; } _params = params; if(null == _params) { _params = new HashMap(); } } public Object invoke(Object proxy, Method method, Object[] args) { Class clazz = method.getDeclaringClass(); if(clazz.isAssignableFrom(HttpServletRequest.class)) { return request(proxy, method, args); } else if(clazz.isAssignableFrom(HttpServletResponse.class)) { return response(proxy, method, args); } else if(clazz.isAssignableFrom(ServletContext.class)) { return context(proxy, method, args); } else { throw new IllegalStateException("Unexpected proxy interface: " + clazz.getName()); } } protected Object response(Object proxy, Method method, Object[] args) { String methodName = method.getName(); if("encodeURL".equals(methodName) || "encodeUrl".equals(methodName)) { // Don't worry about adding ";jsessionid" or anything. return args[0]; } else if ("addCookie".equals(methodName)) { Cookie c = (Cookie)args[0]; if (c.getMaxAge() == 0) { _params.remove(c.getName()); } else { _params.put(c.getName(), c); } return null; } else { throw new IllegalStateException("Unexpected method call: " + method); } } protected Object request(Object proxy, Method method, Object[] args) { String methodName = method.getName(); if("getContextPath".equals(methodName)) { return _contextPath; } else if("getParameter".equals(methodName)) { Object value = _params.get(args[0]); if(value instanceof String) { return value; } else if (value instanceof String[]) { return ((String[])value)[0]; } else { throw new IllegalStateException("Parameter value must be either String or String[]."); } } else if("getParameterValues".equals(methodName)) { Object value = _params.get(args[0]); if(value instanceof String) { return new String[] { (String)value }; } else if (value instanceof String[]) { return value; } else { throw new IllegalStateException("Parameter value must be either String or String[]."); } } else if("getParameterMap".equals(methodName)) { return Collections.unmodifiableMap(_params); } else if("getParameterNames".equals(methodName)) { return new IteratorEnumeration(_params.keySet().iterator()); } else if("getSession".equals(methodName)) { return null; } else if("getAttribute".equals(methodName)) { if(((String)args[0]).equals("XHTML")) { return Boolean.TRUE; // xhtml = true } else { return null; } } else if ("getScheme".equals(methodName)) { return "http"; } else if ("getServerPort".equals(methodName)) { return new Integer(8081); } else if ("getServerName".equals(methodName)) { return "localhost"; } else if ("getServletPath".equals(methodName)) { return _contextPath; } else if ("getPathInfo".equals(methodName)) { return _pathInfo; } else if("getCharacterEncoding".equals(methodName)) { return "UTF-8"; } else if ("getCookies".equals(methodName)) { // just let params double as the cookie store Cookie[] jar = new Cookie[_params.size()]; int i = 0; for (Iterator iter = _params.keySet().iterator(); iter.hasNext(); i++) { Object key = iter.next(); Object val = _params.get(key); if (val instanceof Cookie) { jar[i] = (Cookie)val; } else { String name = String.valueOf(key); String value = String.valueOf(val); jar[i] = new Cookie(name, value); _params.put(name, jar[i]); } } return jar; } else { throw new IllegalStateException("Unexpected method call: " + method); } } protected Object context(Object proxy, Method method, Object[] args) { String methodName = method.getName(); if("getContextPath".equals(methodName)) { return _contextPath; } else { throw new IllegalStateException("Unexpected method call: " + methodName); } } } velocity-tools-2.0-src/src/test/java/org/apache/velocity/tools/test/blackbox/ViewToolsTests.java100644 0 0 25500 11360645207 30373 0ustar 0 0 package org.apache.velocity.tools.test.blackbox; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.util.regex.Pattern; import java.util.regex.Matcher; import java.io.PrintWriter; import java.io.IOException; import org.junit.*; import static org.junit.Assert.*; import com.meterware.httpunit.HTMLElement; import com.meterware.httpunit.WebResponse; import com.meterware.httpunit.WebConversation; import com.meterware.httpunit.WebRequest; import com.meterware.httpunit.GetMethodWebRequest; import com.meterware.httpunit.WebForm; import com.meterware.httpunit.HttpUnitOptions; /** *

      View tools blackbox tests.

      * * @author Claude Brisson * @since Velocity Tools 1.3 * @version $Id$ */ public class ViewToolsTests { private static final String ROOT_URL = "http://localhost:@test.webcontainer.port@/"; public static @BeforeClass void initViewToolsTests() throws Exception { } /******* Helpers **********/ /** * Utility function to check the text content of an HTML element * @param resp web response * @param id HTML element id * @param text expected text * @throws Exception */ private void checkText(WebResponse resp,String id,String text) throws Exception { HTMLElement element = resp.getElementWithID(id); assertNotNull(element); assertEquals(text,element.getText()); } /** * Utility function to check the text content of an HTML element * @param resp web response * @param id HTML element id * @param text expected start of the text * @throws Exception */ private void checkTextStart(WebResponse resp,String id,String text) throws Exception { HTMLElement element = resp.getElementWithID(id); assertNotNull(element); assertTrue(element.getText().startsWith(text)); } /** * Utility function to check the text content of an HTML element * @param resp web response * @param id HTML element id * @param start expected start of the text * @param end expected end of the text * @throws Exception */ private void checkTextStartEnd(WebResponse resp,String id,String start,String end) throws Exception { HTMLElement element = resp.getElementWithID(id); assertNotNull(element); assertTrue(element.getText().startsWith(start)); assertTrue(element.getText().endsWith(end)); } /** * Utility function to check the text content of an HTML element * @param resp web response * @param id HTML element id * @param text expected contained text * @throws Exception */ private void checkTextContent(WebResponse resp,String id,String text) throws Exception { HTMLElement element = resp.getElementWithID(id); assertNotNull(element); assertTrue(element.getText().indexOf(text) != -1); } /** * Utility function to check the text content of an HTML element * @param resp web response * @param id HTML element id * @param regex expected regex * @throws Exception */ private void checkTextRegex(WebResponse resp,String id,String regex) throws Exception { HTMLElement element = resp.getElementWithID(id); assertNotNull(element); Pattern pattern = Pattern.compile(regex); // strip new lines from string to be tested String text = element.getText().replace("\n",""); Matcher matcher = pattern.matcher(text); if (!matcher.matches()) { fail(element.getText()+" did not match "+regex); } } /** * * @param orig original web response * @param formname form name * @param paramname parameter name * @param value parameter value * @return new web response * @throws Exception */ private WebResponse submitWithParam(WebResponse orig, String formname, String paramname, String value) throws Exception { WebForm form = orig.getFormWithName(formname); form.setParameter(paramname,value); return form.submit(); } /** * Used for debugging testcases * @param resp webresponse */ private void dump(WebResponse resp) { try { PrintWriter pw = new PrintWriter("/tmp/dump.html"); pw.println(resp.getText()); pw.flush(); pw.close(); } catch (IOException ioe) { } } /******* Tests **********/ public @Test void testBrowserSnifferTool() throws Exception { /* check we are identified as a Java (HttpUnit) client */ WebConversation conv = new WebConversation(); WebRequest req = new GetMethodWebRequest(ROOT_URL+"browser.vm"); WebResponse resp = conv.getResponse(req); checkText(resp,"Java","true"); /* check language */ req.setHeaderField("Accept-Language","en"); resp = conv.getResponse(req); checkText(resp,"preferredLanguage","en"); req.setHeaderField("Accept-Language","en-US,en;q=0.8"); resp = conv.getResponse(req); checkText(resp,"preferredLanguage","en"); } public @Test void testContextTool() throws Exception { WebConversation conv = new WebConversation(); WebRequest req = new GetMethodWebRequest(ROOT_URL+"context.vm"); WebResponse resp = conv.getResponse(req); /* check that getThis() is a ViewToolContext instance */ checkTextStart(resp,"getThis()","org.apache.velocity.tools.view.ViewToolContext"); /* check contains('context') */ resp = submitWithParam(resp,"contains_Object","contains_Object1","'context'"); checkText(resp,"contains(java.lang.Object)","true"); /* check get('context') */ resp = submitWithParam(resp,"get_Object","get_Object1","'context'"); checkTextStart(resp,"get(java.lang.Object)","org.apache.velocity.tools.view.ViewContextTool"); /* check keys (the only expected uppercase is in 'velocityCount') */ checkTextRegex(resp,"getKeys()","^\\[[a-z_A-Z]+(?:,\\s*[a-z_A-Z]+)*\\]$"); /* check toolbox */ checkTextRegex(resp,"getToolbox()","^\\{[a-z_A-Z]+=.*(?:,\\s*[a-z_A-Z]+=.*)*\\}$"); /* check values */ checkTextStartEnd(resp,"getValues()","[","]"); } public @Test void testLinkTool() throws Exception { WebConversation conv = new WebConversation(); String page = ROOT_URL+"link.vm"; WebRequest req = new GetMethodWebRequest(page); WebResponse resp = conv.getResponse(req); /* check anchor(foo) and anchor */ resp = submitWithParam(resp,"anchor","anchor","foo"); checkText(resp,"anchor",page+"#foo"); checkText(resp,"altanchor",page+"#foo"); /* check path(bar) and path */ resp = submitWithParam(resp,"path","path","bar"); checkText(resp,"path","http://localhost:8081/bar"); checkText(resp,"altpath","/link.vm"); /* check relative(foo) */ resp = submitWithParam(resp,"relative","relative","foo"); checkText(resp,"relative","/foo"); /* check absolute(bar) */ resp = submitWithParam(resp,"absolute","absolute","bar"); checkText(resp,"absolute",ROOT_URL + "bar"); /* check contextURL */ checkText(resp,"contextURL",ROOT_URL); /* check contextPath */ checkText(resp,"contextPath",""); /* check requestPath */ checkText(resp,"requestPath","/link.vm"); /* check baseRef */ checkText(resp,"baseRef",page); /* check self */ checkText(resp,"self",page); /* check encode */ resp = submitWithParam(resp,"encode","encode",": /"); checkText(resp,"encode","%3A+%2F"); } public @Test void testParameterParserTool() throws Exception { WebConversation conv = new WebConversation(); WebRequest req = new GetMethodWebRequest(ROOT_URL+"params.vm?foo=bar&b=false&n=55&d=1.2"); WebResponse resp = conv.getResponse(req); /* check exists(foo) */ resp = submitWithParam(resp,"exists","exists","foo"); checkText(resp,"exists","true"); /* check get(foo) */ resp = submitWithParam(resp,"get","get","foo"); checkText(resp,"get","bar"); /* check getString(foo) */ resp = submitWithParam(resp,"getString","getString","foo"); checkText(resp,"getString","bar"); /* check getBoolean(b) */ resp = submitWithParam(resp,"getBoolean","getBoolean","b"); checkText(resp,"getBoolean","false"); /* check getNumber(n) */ resp = submitWithParam(resp,"getNumber","getNumber","n"); checkText(resp,"getNumber","55"); /* check getDouble(d) */ resp = submitWithParam(resp,"getDouble","getDouble","d"); checkText(resp,"getDouble","1.2"); /* check getInteger(n) */ resp = submitWithParam(resp,"getInteger","getInteger","n"); checkText(resp,"getInteger","55"); /* check getStrings(foo) */ resp = submitWithParam(resp,"getStrings","getStrings","foo"); checkTextStart(resp,"getStrings","[Ljava.lang.String;@"); /* check getBooleans(b) */ resp = submitWithParam(resp,"getBooleans","getBooleans","b"); checkTextStart(resp,"getBooleans","[Ljava.lang.Boolean;@"); /* check getNumbers(n) */ resp = submitWithParam(resp,"getNumbers","getNumbers","n"); checkTextStart(resp,"getNumbers","[Ljava.lang.Number;@"); /* check getDoubles(d) */ resp = submitWithParam(resp,"getDoubles","getDoubles","d"); checkTextStart(resp,"getDoubles","[D@"); /* check getInts(n) */ resp = submitWithParam(resp,"getInts","getInts","n"); checkTextStart(resp,"getInts","[I@"); /* check getString(bar,foo) */ WebForm form = resp.getFormWithName("getString2"); form.setParameter("getString1","'bar'"); form.setParameter("getString2","'foo'"); resp = form.submit(); checkText(resp,"getString2","foo"); /* TODO other getters with default values */ /* check all */ checkTextRegex(resp,"all","^\\{.*\\}$"); } } velocity-tools-2.0-src/src/test/java/org/apache/velocity/tools/test/whitebox/ConfigTests.java100644 0 0 37242 11031030503 27675 0ustar 0 0 package org.apache.velocity.tools.test.whitebox; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Locale; import org.junit.*; import static org.junit.Assert.*; import org.apache.commons.beanutils.Converter; import org.apache.commons.beanutils.converters.BooleanConverter; import org.apache.commons.beanutils.converters.DoubleConverter; import org.apache.commons.beanutils.converters.IntegerConverter; import org.apache.velocity.tools.Scope; import org.apache.velocity.tools.config.*; import org.apache.velocity.tools.generic.MathTool; import org.apache.velocity.tools.generic.NumberTool; import org.apache.velocity.tools.generic.ResourceTool; /** *

      Configuration tests.

      * * @author Nathan Bubna * @since VelocityTools 2.0 * @version $Id$ */ public class ConfigTests { private static final String XML_PATH = "@test.conf.dir@/tools.test.xml"; private static final String OLD_XML_PATH = "@test.conf.dir@/toolbox.test.xml"; private static final String PROPS_PATH = "@test.conf.dir@/tools.test.properties"; protected FactoryConfiguration getBaseConfig() { FactoryConfiguration base = new FactoryConfiguration(); Data datum = new Data(); datum.setKey("version"); datum.setType("number"); datum.setValue("2.0"); base.addData(datum); ToolboxConfiguration toolbox = new ToolboxConfiguration(); toolbox.setScope(Scope.REQUEST); toolbox.setProperty("locale", Locale.US); ToolConfiguration tool = new ToolConfiguration(); tool.setClass(ResourceTool.class); toolbox.addTool(tool); base.addToolbox(toolbox); toolbox = new ToolboxConfiguration(); toolbox.setScope(Scope.APPLICATION); tool = new ToolConfiguration(); tool.setKey("calc"); tool.setClass(MathTool.class); toolbox.addTool(tool); tool = new ToolConfiguration(); tool.setClass(NumberTool.class); tool.setProperty("locale", Locale.FRENCH); toolbox.addTool(tool); base.addToolbox(toolbox); return base; } public @Test void testBaseConfig() { assertValid(getBaseConfig()); } public @Test void testXmlConfig() { FileFactoryConfiguration xml = new XmlFactoryConfiguration(); xml.read(XML_PATH); assertValid(xml); assertConfigEquals(getBaseConfig(), xml); } public @Test void testOldConfig() { FileFactoryConfiguration old = new XmlFactoryConfiguration(true); old.read(OLD_XML_PATH); FactoryConfiguration base = getBaseConfig(); // remove the request toolbox property locale=en_US manually, // because the old format provide no means to set properties // on a whole toolbox base.getToolbox("request").removeProperty("locale"); // add the expected deprecationSupportMode property base.setProperty("deprecationSupportMode", "true"); assertValid(old); assertConfigEquals(base, old); } public @Test void testPropsConfig() { FileFactoryConfiguration props = new PropertiesFactoryConfiguration(); props.read(PROPS_PATH); assertValid(props); assertConfigEquals(getBaseConfig(), props); } /** * Tests that adding two equal configs produces one that is equal * to the originals. */ public @Test void testPropsPlusXmlConfig() { FileFactoryConfiguration props = new PropertiesFactoryConfiguration(); props.read(PROPS_PATH); FileFactoryConfiguration xml = new XmlFactoryConfiguration(); xml.read(XML_PATH); // make sure they're equal assertConfigEquals(props, xml); // now add them and make sure the result is equal to the original xml.addConfiguration(props); assertValid(xml); assertConfigEquals(xml, props); } public @Test void testEasyConfig() { EasyFactoryConfiguration easy = new EasyFactoryConfiguration(); easy.number("version", 2.0); easy.toolbox("request") .property("locale", Locale.US) .tool(ResourceTool.class); easy.toolbox("application") .tool("calc", MathTool.class) .tool(NumberTool.class) .property("locale", Locale.FRENCH); assertValid(easy); assertConfigEquals(getBaseConfig(), easy); } public @Test void testToolsClassConfig() { FactoryConfiguration java = ConfigurationUtils.getFromClass("tools"); assertValid(java); assertConfigEquals(getBaseConfig(), java); } public @Test void testDefaultConfig() { FactoryConfiguration def = ConfigurationUtils.getDefaultTools(); assertValid(def); } public @Test void testAutoConfig() { FactoryConfiguration autoMinusDef = ConfigurationUtils.getAutoLoaded(false); assertValid(autoMinusDef); assertValid(autoMinusDef); assertConfigEquals(getBaseConfig(), autoMinusDef); FactoryConfiguration auto = ConfigurationUtils.getAutoLoaded(); assertValid(auto); // get the default tools FactoryConfiguration def = ConfigurationUtils.getDefaultTools(); assertValid(def); // add the autoloaded ones (sans defaults) onto the default def.addConfiguration(autoMinusDef); // and see that it comes out the same assertConfigEquals(auto, def); } public @Test void testBadData() { Data datum = new Data(); // a fresh datum should be invalid assertInvalid(datum); // setting a key is not enough to be valid datum.setKey("test"); assertInvalid(datum); // set type to number value to a non-number datum.setValue("true"); datum.setType("number"); assertInvalid(datum); // should fail to convert a decimal string to an integer datum.setValue("0.1"); datum.convertWith(new IntegerConverter()); assertInvalid(datum); } public @Test void testData() { Data datum = new Data(); datum.setKey("test"); datum.setValue("true"); assertValid(datum); // check that the default type is "auto" assertEquals(datum.getType(), "auto"); // check that "true" auto-converted to boolean assertSame(datum.getConvertedValue(), Boolean.TRUE); // check that "1" auto-converts to integer datum.setValue("1"); assertEquals(datum.getConvertedValue(), Integer.valueOf(1)); // check that a really big number converts to a Long datum.setValue(""+Integer.MAX_VALUE+"0"); assertEquals(datum.getConvertedValue().getClass(), Long.class); // check that "1.2" auto-converts to double datum.setValue("1.2"); assertEquals(datum.getConvertedValue(), 1.2); assertEquals(datum.getConvertedValue().getClass(), Double.class); // check that java.lang.Integer.MIN_VALUE auto-converts to the field datum.setValue("java.lang.Integer.MIN_VALUE"); assertEquals(datum.getConvertedValue(), Integer.MIN_VALUE); // check that "yes" also auto-converts to boolean datum.setValue("yes"); assertSame(datum.getConvertedValue(), Boolean.TRUE); // check boolean type datum.setType("boolean"); assertValid(datum); assertSame(datum.getConvertedValue(), Boolean.TRUE); // check valid field type datum.setValue("java.lang.Boolean.TRUE"); datum.setType("field"); assertValid(datum); assertSame(datum.getConvertedValue(), Boolean.TRUE); // check invalid field value datum.setValue("blahblah"); assertInvalid(datum); // check number type datum.setValue("3.16"); datum.setType("number"); assertValid(datum); assertEquals(datum.getConvertedValue(), new Double(3.16)); // check string type datum.setType("string"); assertValid(datum); assertEquals(datum.getConvertedValue(), "3.16"); // check list type (singleton) datum.setType("list"); assertValid(datum); assertEquals(datum.getConvertedValue(), Collections.singletonList("3.16")); // ok, try a three item list datum.setValue("1,2,3"); assertValid(datum); List three = new ArrayList(3); three.add("1"); three.add("2"); three.add("3"); assertEquals(datum.getConvertedValue(), three); // turn that into a list of numbers datum.setType("list.number"); assertValid(datum); three.set(0, new Integer(1)); three.set(1, new Integer(2)); three.set(2, new Integer(3)); assertEquals(datum.getConvertedValue(), three); // and a list of booleans datum.setType("list.boolean"); datum.setValue("true,false"); List two = new ArrayList(2); two.add(Boolean.TRUE); two.add(Boolean.FALSE); assertEquals(datum.getConvertedValue(), two); // and a list of fields datum.setType("list.field"); datum.setValue("java.lang.Boolean.TRUE,java.lang.Boolean.FALSE"); assertEquals(datum.getConvertedValue(), two); //TODO: test converter/target class stuff } public @Test void testConfiguration() { Configuration conf = new Configuration(); // a fresh config should be valid assertValid(conf); // add and retrieve a simple string property conf.setProperty("string", "whatever"); assertValid(conf); assertEquals("whatever", conf.getProperty("string").getValue()); // add and retrieve a simple boolean property conf.setProperty("boolean", "true"); assertValid(conf); assertEquals(Boolean.TRUE, conf.getProperty("boolean").getConvertedValue()); // add and retrieve an arbitrary object property conf.setProperty("testclass", this); assertValid(conf); assertSame(this, conf.getProperty("testclass").getValue()); // test addConfiguration Configuration cfg = new Configuration(); cfg.setProperty("string", "whoever"); conf.addConfiguration(cfg); assertEquals("whoever", conf.getProperty("string").getValue()); //TODO: test adding convertable properties } //TODO: public @Test void testCompoundConfiguration() public @Test void testBadToolConfig() { ToolConfiguration tool = new ToolConfiguration(); // a fresh tool config should be invalid assertInvalid(tool); // set a fake class name and confirm it is invalid tool.setClassname("no.such.Class"); assertInvalid(tool); } public @Test void testToolConfig() { ToolConfiguration tool = new ToolConfiguration(); // set a real class, confirm it is valid tool.setClass(OldTool.class); assertValid(tool); // and confirm the default key assertEquals("old", tool.getKey()); // the toString() should describe this as old, due // to the non-deprecated init() method assertTrue((tool.toString().indexOf("Old") >= 0)); // change to a more modern class, confirm it's valid tool.setClassname(FakeTool.class.getName()); assertValid(tool); // and confirm the default key annotation works assertEquals("test", tool.getKey()); // change the key and ensure it overrides the default tool.setKey("fake"); assertEquals("fake", tool.getKey()); // test that adding A to B copies A's class to B when B has no class ToolConfiguration alt = new ToolConfiguration(); assertNull(alt.getClassname()); alt.addConfiguration((Configuration)tool); assertNotNull(alt.getClassname()); assertEquals(FakeTool.class.getName(), alt.getClassname()); // test that adding A to B doesn't copy A's class to B when A has no class alt = new ToolConfiguration(); assertNull(alt.getClassname()); tool.addConfiguration(alt); assertEquals(FakeTool.class.getName(), tool.getClassname()); } //TODO: add tests for ToolboxConfiguration //TODO: add tests for FactoryConfiguration /************* Support classes and methods ******************/ public static class OldTool { public void init(Object foo) { // does nothing } // exists only to keep the testrunner happy public @Test @Ignore void foo() {} } @DefaultKey("test") public static class FakeTool { // exists only to keep the testrunner happy public @Test @Ignore void foo() {} } protected void assertConfigEquals(Configuration one, Configuration two) { assertNotNull(one); assertNotNull(two); // for now, just compare the toString() output assertEquals(one.toString(), two.toString()); } protected void assertConfigEquals(FactoryConfiguration one, FactoryConfiguration two) { assertNotNull(one); assertNotNull(two); // for now, just compare the toString() output without source info assertEquals(one.toString(false), two.toString(false)); } protected void assertValid(Data valid) { assertNotNull(valid); try { valid.validate(); // if we get past the call above, then the test passed } catch (ConfigurationException e) { // then the data was not valid fail("\n**** Unexpected Invalid Data ****\n" + valid + "\n" + e); } } protected void assertValid(Configuration valid) { assertNotNull(valid); try { valid.validate(); // if we get past the call above, then the test passed } catch (ConfigurationException e) { // then the config was not valid fail("\n**** Unexpected Invalid Configuration ****\n" + valid + "\n" + e); } } protected void assertInvalid(Data invalid) { try { invalid.validate(); // if we get past the call above, then the test failed fail("\n**** Unexpected Valid Data ****\n" + invalid); } catch (ConfigurationException e) { // then the data was invalid, as it ought to be } } protected void assertInvalid(Configuration invalid) { try { invalid.validate(); // if we get past the call above, then the test failed fail("\n**** Unexpected Valid Configuration ****\n" + invalid); } catch (ConfigurationException e) { // then the config was invalid, as it ought to be } } } velocity-tools-2.0-src/src/test/java/org/apache/velocity/tools/test/whitebox/GenericToolsTests.java100644 0 0 21775 11115263031 31100 0ustar 0 0 package org.apache.velocity.tools.test.whitebox; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.util.Locale; import java.util.List; import java.util.Map; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import org.junit.*; import static org.junit.Assert.*; import org.apache.velocity.tools.generic.Alternator; import org.apache.velocity.tools.generic.AlternatorTool; import org.apache.velocity.tools.generic.ComparisonDateTool; import org.apache.velocity.tools.generic.DateTool; import org.apache.velocity.tools.generic.EscapeTool; import org.apache.velocity.tools.generic.FieldTool; import org.apache.velocity.tools.generic.MathTool; import org.apache.velocity.tools.generic.NumberTool; import org.apache.velocity.tools.generic.ResourceTool; import org.apache.velocity.tools.ToolManager; import org.apache.velocity.tools.ToolContext; /** *

      Generic tools whitebox tests.

      * * @author Claude Brisson * @author Nathan Bubna * @since Velocity Tools 1.3 * @version $Id$ */ public class GenericToolsTests { private static final String TOOLBOX_PATH = "@test.conf.dir@/whiteboxtest-toolbox.xml"; private static ToolContext toolbox = null; public static @BeforeClass void initGenericToolsTests() throws Exception { ToolManager manager = new ToolManager(false); manager.configure(TOOLBOX_PATH); toolbox = manager.createContext(); } protected void assertStringEquals(String expected, Object testThis) { assertEquals(expected, String.valueOf(testThis)); } public @Test void testDateTool() { /* TODO still incomplete */ DateTool dateTool = (DateTool)toolbox.get("date"); assertNotNull(dateTool); Date date = new GregorianCalendar(2007,0,2).getTime(); String disp = "2007-01-02"; String disp2 = "2007/01/02"; /* check configured format */ assertEquals("yyyy-MM-dd",dateTool.getFormat()); /* test formatting */ assertEquals(disp,dateTool.format(date)); assertEquals(disp2,dateTool.format("yyyy/MM/dd",date)); /* test parsing */ assertEquals(2007,dateTool.getYear(disp)); assertEquals(0,dateTool.getMonth(disp)); assertEquals(2,dateTool.getDay(disp)); } public @Test void testEscapeTool() { EscapeTool escapeTool = (EscapeTool)toolbox.get("esc"); assertNotNull(escapeTool); assertEquals("${esc.d}foo ${esc.h}bar()",escapeTool.velocity("$foo #bar()")); /* propertyKey */ assertEquals("\\ C\\:\\\\Program\\ Files",escapeTool.propertyKey(" C:\\Program Files")); /* propertyValue */ assertEquals("\\ C\\:\\\\Program Files",escapeTool.propertyValue(" C:\\Program Files")); /* java */ assertEquals("\\uFFFF\\b\\n\\t\\f\\r\\\"\\\\",escapeTool.java("\uFFFF\b\n\t\f\r\"\\")); /* javascript */ assertEquals("\\uFFFF\\b\\n\\t\\f\\r\\\"\\'\\\\",escapeTool.javascript("\uFFFF\b\n\t\f\r\"'\\")); /* html */ assertEquals(""&<> ",escapeTool.html("\"&<>"+(char)160)); /* url */ assertEquals("%40%2F%3F%3D+%26",escapeTool.url("@/?= &")); /* sql */ assertEquals("''",escapeTool.sql("'")); /* xml */ assertEquals(""&<>",escapeTool.html("\"&<>")); /* unicode */ assertEquals("\uf00b", escapeTool.unicode("f00b")); assertEquals("\u1010", escapeTool.unicode("\\u1010")); assertEquals("\u1111", escapeTool.unicode(1111)); } public static String MUTABLE_FIELD = "foo"; public @Test void testFieldTool() { FieldTool fieldTool = (FieldTool)toolbox.get("field"); assertNotNull(fieldTool); // read a constant from the configured included Class assertEquals(Integer.MAX_VALUE, fieldTool.get("MAX_VALUE")); // read a constant from java.lang.Boolean and make sure it is the same assertSame(Boolean.TRUE, fieldTool.in("java.lang.Boolean").get("TRUE")); // tell it to read constants from a non-existant class // (which should return null) assertNull(fieldTool.in("no.such.Class")); // tell field tool to read constants from this instance's Class // (which should NOT return null) assertNotNull(fieldTool.in(this)); assertEquals(MUTABLE_FIELD, fieldTool.get("MUTABLE_FIELD")); // grab the mutable field String foo = MUTABLE_FIELD; // change it MUTABLE_FIELD = MUTABLE_FIELD + MUTABLE_FIELD; // make sure it changed assertFalse(foo.equals(MUTABLE_FIELD)); // make sure the fieldtool recognized that it changed assertEquals(MUTABLE_FIELD, fieldTool.get("MUTABLE_FIELD")); // pass a full field path to the get() method assertEquals(Long.MIN_VALUE, fieldTool.get("java.lang.Long.MIN_VALUE")); } public @Test void testMathTool() { MathTool mathTool = (MathTool)toolbox.get("math"); assertNotNull(mathTool); assertEquals(1,mathTool.abs(-1)); assertEquals(2,mathTool.add(1,1)); assertEquals(3,mathTool.ceil(2.5)); assertEquals(4,mathTool.div(8,2)); assertEquals(5,mathTool.floor(5.1)); assertEquals(6,mathTool.getAverage(new long[] {5,6,7})); /* getTotal() watches the type of its first argument, so assertEquals needs a long */ assertEquals((long)7,mathTool.getTotal(new long[] {2,2,3})); assertEquals(8,mathTool.idiv(130,16)); assertEquals(9,mathTool.max(9,-10)); assertEquals(10,mathTool.min(10,20)); assertEquals(11,mathTool.mod(37,13)); assertEquals(12,mathTool.mul(3,4)); assertEquals(13,mathTool.round(12.8)); assertEquals(14.2,mathTool.roundTo(1,14.18)); assertEquals(-5.0,mathTool.roundTo(2,-4.999)); assertEquals(15,mathTool.sub(30,15)); assertEquals(16,mathTool.pow(4,2)); assertEquals(17,mathTool.toInteger("17")); assertEquals(18.1,mathTool.toDouble("18.1")); } public @Test void testNumberTool() { NumberTool numberTool = (NumberTool)toolbox.get("number"); assertNotNull(numberTool); // assertEquals() } public @Test void testResourceTool() { ResourceTool textTool = (ResourceTool)toolbox.get("text"); assertNotNull(textTool); List keys = textTool.getKeys(); assertTrue(keys.contains("foo")); assertTrue(keys.contains("hello.whoever")); assertTrue(keys.contains("world")); keys = textTool.get("hello").getKeys(); assertTrue(keys.contains("whoever")); assertFalse(keys.contains("foo")); ResourceTool.Key foo = textTool.get("foo"); assertStringEquals("bar", foo); ResourceTool.Key frenchFoo = foo.locale(Locale.FRENCH); assertStringEquals("barre", frenchFoo); ResourceTool.Key otherFoo = foo.bundle("resources2"); assertStringEquals("woogie", otherFoo); ResourceTool.Key helloWhoever = textTool.get("hello").get("whoever"); assertStringEquals("Hello {0}!", helloWhoever); ResourceTool.Key helloWorld = helloWhoever.insert(textTool.get("world")); assertStringEquals("Hello World!", helloWorld); ResourceTool.Key halfFrenchHelloWorld = helloWorld.locale(Locale.FRENCH); assertStringEquals("Bonjour World!", halfFrenchHelloWorld); ResourceTool.Key frenchTool = textTool.locale("fr"); ResourceTool.Key frenchHelloWorld = frenchTool.get("hello.whoever").insert(frenchTool.get("world")); assertStringEquals("Bonjour Monde!", frenchHelloWorld); } public @Test void testComparisonDateTool() { /* TODO still incomplete */ ComparisonDateTool dateTool = (ComparisonDateTool)toolbox.get("date"); assertNotNull(dateTool); Calendar date1 = new GregorianCalendar(2007,0,2); Calendar date2 = new GregorianCalendar(2007,1,15); /* test comparing */ ComparisonDateTool.Comparison whenIs = dateTool.whenIs(date1, date2); assertEquals(0l, whenIs.getYears()); assertEquals(1l, whenIs.getMonths()); assertEquals(44l, whenIs.getDays()); // the toolbox config says to skip months, so this should be in weeks assertStringEquals("6 weeks later", whenIs); } } velocity-tools-2.0-src/src/test/java/resources2.properties100644 0 0 1437 11115263031 21162 0ustar 0 0 # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. foo = woogie velocity-tools-2.0-src/src/test/java/resources_en.properties100644 0 0 1505 11115263031 21556 0ustar 0 0 # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. foo = bar hello.whoever = Hello {0}! world = World velocity-tools-2.0-src/src/test/java/resources_fr.properties100644 0 0 1511 11115263031 21560 0ustar 0 0 # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. foo = barre hello.whoever = Bonjour {0}! world = Monde velocity-tools-2.0-src/src/test/java/tools.java100644 0 0 3362 11030275241 16754 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.util.Locale; import org.apache.velocity.tools.config.EasyFactoryConfiguration; import org.apache.velocity.tools.config.FactoryConfiguration; import org.apache.velocity.tools.generic.MathTool; import org.apache.velocity.tools.generic.NumberTool; import org.apache.velocity.tools.generic.ResourceTool; /** * Test java configuration class * * @author Nathan Bubna * @version $Id: tools.java 511959 2007-02-26 19:24:39Z nbubna $ */ public class tools { public static FactoryConfiguration getConfiguration() { EasyFactoryConfiguration easy = new EasyFactoryConfiguration(); easy.number("version", 2.0); easy.toolbox("request") .property("locale", Locale.US) .tool(ResourceTool.class); easy.toolbox("application") .tool("calc", MathTool.class) .tool(NumberTool.class) .property("locale", Locale.FRENCH); return easy; } } velocity-tools-2.0-src/src/test/java/tools.properties100644 0 0 2233 11030275241 20223 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. tools.toolbox = request,application tools.data.version = 2.0 tools.data.version.type = number tools.request.property.locale = en_US tools.request.text = org.apache.velocity.tools.generic.ResourceTool tools.application.calc = org.apache.velocity.tools.generic.MathTool tools.application.number = org.apache.velocity.tools.generic.NumberTool tools.application.number.locale = fr velocity-tools-2.0-src/src/test/java/tools.xml100644 0 0 2271 11030275241 16631 0ustar 0 0 velocity-tools-2.0-src/test.xml100644 0 0 26144 11035250473 14013 0ustar 0 0 Working with FindBugs at: ${findbugs.home} Analyzing ${dist.dir}/${project.id}.jar built from ${source.home} Analyzing ${source.home}/main/java... unusedcode imports braces Generated report is at ${test.build.dir}\pmd_report.html velocity-tools-2.0-src/test/conf/commons-logging.properties100644 0 0 1553 11115263026 21405 0ustar 0 0 # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. org.apache.commons.logging.Log=org.apache.velocity.tools.test.FilteredLogChuteCommonsLog velocity-tools-2.0-src/test/conf/toolbox.test.xml100644 0 0 2540 11030275231 17350 0ustar 0 0 version 2.0 org.apache.velocity.tools.generic.ResourceTool text org.apache.velocity.tools.generic.MathTool calc application org.apache.velocity.tools.generic.NumberTool number application velocity-tools-2.0-src/test/conf/tools.test.properties100644 0 0 2233 11030275231 20415 0ustar 0 0 ## Licensed to the Apache Software Foundation (ASF) under one ## or more contributor license agreements. See the NOTICE file ## distributed with this work for additional information ## regarding copyright ownership. The ASF licenses this file ## to you under the Apache License, Version 2.0 (the ## "License"); you may not use this file except in compliance ## with the License. You may obtain a copy of the License at ## ## http://www.apache.org/licenses/LICENSE-2.0 ## ## Unless required by applicable law or agreed to in writing, ## software distributed under the License is distributed on an ## "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ## KIND, either express or implied. See the License for the ## specific language governing permissions and limitations ## under the License. tools.toolbox = request,application tools.data.version = 2.0 tools.data.version.type = number tools.request.property.locale = en_US tools.request.text = org.apache.velocity.tools.generic.ResourceTool tools.application.calc = org.apache.velocity.tools.generic.MathTool tools.application.number = org.apache.velocity.tools.generic.NumberTool tools.application.number.locale = fr velocity-tools-2.0-src/test/conf/tools.test.xml100644 0 0 2271 11030275231 17023 0ustar 0 0 velocity-tools-2.0-src/test/conf/whiteboxtest-toolbox.xml100644 0 0 2573 10730012232 21123 0ustar 0 0 velocity-tools-2.0-src/test/etc/jetty.xml.tmpl100644 0 0 14117 11115263026 16672 0ustar 0 0 1 5 10 30000 2 8443 ../examples/showcase / /etc/webdefault.xml localhost 600 /yyyy_mm_dd.request.log 90 true false GMT true true velocity-tools-2.0-src/test/etc/webdefault.xml100644 0 0 52631 11115263026 16705 0ustar 0 0 Default web.xml file. This file is applied to a Web application before it's own WEB_INF/web.xml file default org.mortbay.jetty.servlet.DefaultServlet acceptRanges true dirAllowed true redirectWelcome false maxCacheSize 2000000 maxCachedFileSize 254000 maxCachedFiles 1000 useFileMappedBuffer true 0 default / jsp org.apache.jasper.servlet.JspServlet logVerbosityLevel DEBUG fork false xpoweredBy false 0 jsp *.jsp *.jspf *.jspx *.xsp *.JSP *.JSPF *.JSPX *.XSP 30 index.html index.htm index.jsp arISO-8859-6 beISO-8859-5 bgISO-8859-5 caISO-8859-1 csISO-8859-2 daISO-8859-1 deISO-8859-1 elISO-8859-7 enISO-8859-1 esISO-8859-1 etISO-8859-1 fiISO-8859-1 frISO-8859-1 hrISO-8859-2 huISO-8859-2 isISO-8859-1 itISO-8859-1 iwISO-8859-8 jaShift_JIS koEUC-KR ltISO-8859-2 lvISO-8859-2 mkISO-8859-5 nlISO-8859-1 noISO-8859-1 plISO-8859-2 ptISO-8859-1 roISO-8859-2 ruISO-8859-5 shISO-8859-5 skISO-8859-2 slISO-8859-2 sqISO-8859-2 srISO-8859-5 svISO-8859-1 trISO-8859-9 ukISO-8859-5 zhGB2312 zh_TWBig5 velocity-tools-2.0-src/xdocs/changes.xml100644 0 0 44760 11360645634 15600 0ustar 0 0 Change Log xdocs/project.xml

      This document tracks the changes in VelocityTools between releases.

      This section very briefly and generally describes changes after the 1.x series.

      • More convention over configuration and smart defaults (ndb)
      • New configuration formats (more concise/flexible/powerful xml, properties, java) (ndb)
      • Entirely new core infrastructure (lazy-loading tools, easier access, standalone support etc) (ndb)
      • Added VelocityViewTag for JSP integration (ndb)
      • Added DisplayTool, ConversionTool, ClassTool, LoopTool, FieldTool, a generic version of LinkTool and more (ndb)
      • Refactored and enhanced a number of existing tools (ndb)
      • Improved documentation (ndb)
      • Deprecated many outdated things (ndb)
      • -->
      • Legacy support for almost all Tools 1.4 configurations and extensions (ndb)
      • Better integration of $application, $session and $request scope control objects (cbn)
      • and lots more...

      This section describes changes after the 1.3 release.

      • Added ability to add current request parameters to LinkTool, including controls for automatically and/or manually ignoring some of those. Thanks to Christopher Schultz. (ndb)
      • VELTOOLS-87: fixed infinite recursion in RenderTool. Thanks to Andrea Bernardo Ciddio. (ndb)
      • Upgraded DVSL version used for documentation to v1.0 (ndb)
      • VELTOOLS-85: Fix order preservation problem in SortTool. Thanks to Tatyana. (ndb)
      • Protect BrowserSniffer from requests without user-agent. (cb)
      • Added support for a MethodExceptionHandler - the TilesTool.get() method now only returns null if one isn't present. (maj)
      • Changed StrutsLinkTool.setForward() to look for forwards local to the action mapping, before looking up global forwards. Thanks to Christopher Schultz. (ndb)
      • Rearrange/refactor/deprecate some internal methods in VelocityViewServlet in preparation for VelocityTools 2.0 upgrades. (ndb)
      • Upgraded Velocity Engine dependency to build and test against v1.5. (NOTE: Velocity Engine 1.5 will be required for VelocityTools 2.0.) (ndb)
      • Added propertyKey() and propertyValue() escaping support to EscapeTool (VELTOOLS-81). Thanks to Phil Cornelius for this patch. (ndb)
      • Fixed bug in request-path restriction when using wildcards. (ndb)
      • Make default locale and format for NumberTool configurable, just as they are in DateTool. (ndb)
      • Add ComparisonDateTool (with some tests and showcase demos) for comparing dates and displaying the comparisons textually. Thanks to Chris Townsen for the initial implementation. (ndb)
      • Add ability to configure default Locale for DateTool and to lock down configure() so it is safe to use in application scope. (ndb)
      • Add better support for dynamic locales in MessageTool. Thanks to Christopher Schultz. (ndb)
      • Use ResourceTool for common text throughout the Showcase example. (ndb)

      This section describes changes after the 1.2 release.

      • Added ResourceTool and ViewResourceTool for access to and use of ResourceBundles. (ndb)
      • Upgraded to latest versions of Commons-Digester (1.8) and Commons-Validator (1.3.1). (ndb)
      • VELTOOLS-58: Updated ValidatorTool to mirror key changes/features in Struts 1.3.x's JavascriptValidatorTag. Thanks to Christopher Schultz and Niall Pemberton. (ndb)
      • VELTOOLS-73: Added url(String) method to EscapeTool for URL encoding. Thanks to Marc Novakowski for this. (cb)
      • Added start.showcase.webapp and stop.showcase.webapp ant targets to manually launch the showcase webapp using the embedded Jetty servlet container. (cb)
      • Added a testcases framework for generic and view tools. (cb)
      • Changed VelocityViewServlet to look for toolbox config at "/WEB-INF/toolbox.xml" and velocity init properties at "/WEB-INF/velocity.properties" when no other locations are specified (i.e. change the standard location into a convention to reduce configuration needs). (ndb)
      • Upgraded VelocityStruts dependencies to those for Struts 1.3.x series and updated "struts" example app according to provided directions. (ndb)
      • Replaced "layout" example with new "showcase" example to interactively demonstrate all tools and the VelocityLayoutServlet. (ndb)
      • Added auto() and manual() methods to AlternatorTool and deprecated the make() methods that took a boolean parameter. (ndb)
      • Added getAll() method to ParameterParser to retrieve map of all params via $params.all. (ndb)
      • Added configurable getSelf() function to LinkTool to make self-referencing links easier. (ndb)
      • Added create() methods to CookieTool to support more complex Cookie creation. (ndb)
      • Added ContextTool for convenient access to context data and meta-data. (ndb)
      • VELTOOLS-71: Overhauled ant build process: dependencies are now automatically download, jars have manifests, checksums are auto-generated, and more. Also, building with JDK 1.3 is no longer supported. (ndb)
      • Updated license headers and notices to comply with new ASF policy. (henning)
      • Made auto-alternate default of AlternatorTool configurable via toolbox config. (ndb)
      • Add addQueryData(Map) and params(Map) method to LinkTool. Thanks to Mark Brunkhart for this. (ndb)
      • VELTOOLS-56: Fixed a number of problems with ImportSupport. Thanks to Christopher Schultz for this. (ndb)
      • VELTOOLS-67: Add ability to restrict availability of request-scoped tools according to a request path value set in the tool configuration. Thanks to Claude Brisson for this. (ndb)
      • VELTOOLS-68: Change VelocityViewServlet to read logger and resource loader config from velocity.properties file instead of hard-coding it. (henning)
      • Added setAbsolute() and absolute() methods to LinkTool. (ndb)
      • Made default format of DateTool configurable via toolbox definition. (ndb)
      • Deprecated ViewTool and Configurable interfaces. ViewToolInfo has been enhanced to automatically recognize such tools by checking for init(Object) and/or configure(Map) methods. (ndb)
      • Enhanced TextKey trick in MessageTool to make using args and bundles easier. (ndb)
      • Add getInteger() and getDouble() convenience methods to ValueParser. (ndb)
      • Added get() method to StrutsLinkTool to allow syntax like $link.action.saveFoo. (ndb)
      • Added param(), relative(), anchor(), and uri() convenience methods to LinkTool. (ndb)
      • Added currency(), number(), integer(), and percent() convenience methods to NumberTool. (ndb)
      • Changed auto-alternate default in AlternatorTool to match Alternator default.

      This section describes changes after the 1.1 release.

      • Updated documentation to cover new features and sync to many infrastructure changes. (ndb)
      • Fixed incomplete escaping in ValidatorTool (patch from Christopher Schultz. Jira Issue VELTOOLS-52). (ndb)
      • Fixed infinite loop logging problem with Tomcat 5.5 in the "simple" example webapp. (ndb)
      • Upgraded jars to Struts 1.2.7, Commons-Logging 1.0.4, Commons-Validator 1.1.4, Digester 1.7, Commons-Collections 3.1, Beanutils 1.7.0, Struts SSL Extension for 1.2, and Commons-Lang 2.1. (ndb)
      • Added VelocityStruts support for non-resource and session-scoped action messages (patch and help from Niall Pemberton. See Jira issues VELTOOLS-1 and VELTOOLS-51). (ndb)
      • Factored generic parsing code out of ParameterParser into new ValueParser for parsing strings pulled from any Map. (ndb)
      • Improved error handling/recovery in toolbox xml parsing by adding validation of tool info. (henning)
      • Added BrowserSnifferTool for identifying browsers and their features (contributed by Claude Brisson). This depends on Java 1.4's regexp support for use. (ndb)
      • Added EscapeTool for commons escaping needs (contributed by Shinobu Kawai). This requires commons-lang for use. (ndb)
      • Added ListTool as utility for using arrays like Lists in templates (contributed by Shinobu Kawai). (ndb)
      • Added DateTool methods to provide easy access to date values (e.g. month, year, day). (ndb)
      • Converted VelocityView and VelocityStruts to use a VelocityEngine instead of the Velocity singleton. This means only the servlets log directly to the VelocityEngine instance; the tools and other classes now use commons-logging (which can still be redirected to the VVS's VelocityEngine). Also, both the RenderTool and LogSystemCommonsLog now support either the singleton or non-singleton approach. (ndb)
      • Fixed bad relative URIs in LinkTool when webapp is installed as root (#32104, reported by Laurent Dauvilaire). (ndb)
      • Factored basic pagination code out of AbstractSearchTool into new AbstractPagerTool. (ndb)
      • Make StrutsUtils.errorMarkup() support errors.prefix/suffix (#31768, patch by Shinobu Kawai). (ndb)
      • Fixed ImportSupport bug with multiple calls to ImportResponseWrapper.getWriter() or getOutputStream() (#32146, patch by Shinobu Kawai). (ndb)
      • Made DateTool.toDate(Object) accept Number in place of Long. (ndb)
      • Fixed RenderTool NPE when passed null VTL string (#31583, reported by Tim Colson). (ndb)
      • Enable template cache refreshing and global macro autoreloading in WebappLoader. (maj)
      • Stopped using Velocity's dependency jar. (maj)
      • Upgraded Struts, commons-collections, commons-logging, and commons-validator to Struts 1.2.4 versions. (maj)
      • Added new SortTool (based on contribution from Brett Sutton). (ndb)
      • Added MathTool methods for totalling or averaging lists or arrays of values (adapted from a contribution by Leon Messerschmidt). (ndb)
      • Prevent NPE in RenderTool.recurse() when an evaluation fails. (ndb)
      • Upgraded jars from Velocity 1.3.1 to Velocity 1.4 (ndb)
      • Simplified MessageTool interface to support $text.this.that syntax instead of just $text.get('this.that') (ndb)
      • Added Alternator and AlternatorTool to improve on the old VelocityFormatter.makeAutoAlternator(). (ndb/dlr)
      • Added new Configurable interface and support for configuring tools in the toolbox definition. (ndb)
      • Added methods for integer division and modulus to MathTool. (ndb)
      • Remove members, methods, and classes deprecated in 1.1. (ndb)
      • Bring example Struts apps up to speed with latest Struts version. (maj)
      • Upgrade jars to Struts 1.2.0 and Validator 1.1.2. (maj)

      This section describes changes after the 1.1-rc1 release.

      • Deprecated StrutsUtils' getActionErrors() and getActionMessages() in favor of getErrors() and getMessages(). (ndb)
      • Fixed javadoc warnings during build (patch contributed by Nathan Green). (ndb)
      • Some sort of improvements to Struts example apps. (maj)

      This section describes changes after the 1.1-beta release.

      • Changed recommended keys for MessageTool and ActionMessagesTool to $text and $messages. (ndb)
      • Changed XMLToolboxManager to use thread context classloader when digesting toolbox. (ndb)
      • Fixed session tool initialization/synchronization issue. (ndb)
      • Added TilesTool methods to import attributes to specific scopes (page/request/session/application). (maj)
      • Added new demos for using ValidatorTool, TilesTool, and SecureLinkTool to VelocityStruts example app. (maj)
      • Upgraded/refactored MathTool to add floor() and ceil(), make type-handling more intuitive and flexible, and improve number parsing. (ndb)
      • Improved resource bundle support in ActionMessagesTool. (ndb)
      • ErrorsTool now extends ActionMessagesTool. (ndb)
      • LinkTool now encodes URLs using the response's character encoding. (ndb)
      • Removed inadvertant JDK 1.4 dependencies from ImportSupport. (ndb)
      • Made XMLToolboxManager not abstract (#24840). (ndb)
      • De-staticized non-private methods in RenderTool and LinkTool. (ndb)
      • Added NumberTool for formatting numbers (contributed by Mike Kienenberger). (ndb)
      • Filled out and cleaned up DateTool's toDate(...) methods. (ndb)
      • Changed VelocityViewServlet's error method to print the stack trace of the root cause when it encounters a MethodInvocationException. (ndb)
      • Added importAttributes() method to TilesTool to automatically put all attributes of the current Tiles context into the Velocity context. (maj)
      • Replaced TilesTool's getString(String) method with getAttribute(String) in order to support "put lists." (maj)

      This section describes changes after the 1.0 release.

      • Made VelocityViewServlet use response.getOutputStream() if response.getWriter() fails. This is functionality is deprecated and provided as a migration path from 1.0 behavior. (dlr, ndb)
      • De-staticized MathTool to make it extendable. (ndb)
      • Factored common functionality of ErrorsTool, MessageTool, and ActionMessagesTool into abstract MessageResourcesTool. (ndb)
      • Added ImportTool as a simple ImportSupport-based tool. (maj)
      • Converted TilesTool to extend ImportSupport. This allows easy mixing of view technologies (JSP, Velocity, etc.) in VelocityStruts applications. (thanks go to Matthew Payne for the idea!) (maj)
      • Added ImportSupport class for building tools that can import resources from local or remote URLS. (maj)
      • Overhauled DateTool to make it more extendable, user-friendly, and add support for standard, localized date-time styles (see DateTool javadoc for more). (ndb)
      • Added support for specifying message resource bundles to StrutsUtils, ErrorsTool, ActionMessagesTool, and MessageTool. (maj,ndb)
      • Added commons-validator (1.0.2) and sslext jars to library. (maj)
      • Added SecureLinkTool for using Struts SSL Extension with VelocityStruts. (maj)
      • Added ValidatorTool to provide Struts 1.1 javascript validation for VelocityStruts. (maj)
      • output.encoding property (if non-default) is appended to default content-type as the charset. (ndb)
      • VelocityViewServlet now uses response.getWriter() instead of response.getOutputStream() as suggested by Matthew Payne. (ndb)
      • Improved VelocityViewServlet error handling (exceptions are logged and error() is now more robust). (ndb)
      • Put VelocityViewServlet's requestCleanup() call in a 'finally' clause to allow clean after errors during a request. (dlr)
      • Fixed miscellaneous javadoc and doc typos (many of which were reported by Takayoshi Kimura) (ndb)
      • Allow system to reclaim objects held by pooled writers in VelocityViewServlet (see bug 18951) (ndb)
      • Changed LinkTool to automatically check for XHTML setting (ndb)
      • Added support for standard XHTML mode setting via toolbox config (ndb)
      • Moved request/response/session/application keys to ViewContext and add getAttribute() method (ndb)
      • Added selectModule() and getForwardURL() to StrutsUtils (maj)
      • Convert VelocityStruts tools to use new StrutsUtils methods and be module aware (maj)
      • Removed unused imports from StrutsLinkTool (ndb)
      • Refactor StrutsUtils to use Struts 1.1 classes and support modules (maj)
      • Added TilesTool (maj)
      • Allow subclasses of VelocityViewServlet to use different ToolboxManager implementations (ndb)
      • Added CookieTool (contributed by Dmitri Colebatch) (ndb)
      • Added demo of <data> elements to simple VelocityView example (ndb)
      • Made simple VelocityStruts example catch Commons-Logging output with LogSystemCommonsLog (ndb)
      • Convert toolbox setup to use Digester instead of dom4j (ndb)
      • Added LogSystemCommonsLog and CommonsLogLogSystem to provide bridges between Commons-Logging and Velocity's LogSystem (ndb)
      • Added Commons Logging 1.0.3 jar (ndb)
      • Added ActionMessagesTool (ndb)
      • Upgrade deprecated Struts 1.0 uses in examples (ndb)
      • Updated jars to Struts 1.1, BeanUtils 1.6.1, Digester 1.5, Collections 2.1 (ndb)
      • Initial release.
      velocity-tools-2.0-src/xdocs/config.java.xml100644 0 0 6317 10730012234 16311 0ustar 0 0 Using Java xdocs/project.xml xdocs/config.project.xml

      As of VelocityTools 2, its no longer merely possible to configure things purely via Java, it is now much easier to do and can be done in several different ways. Here again, is an example that is equivalent to those demonstrated in the properties and xml configurations:

      EasyFactoryConfiguration config = new EasyFactoryConfiguration(); config.toolbox("request").property("xhtml", true) .tool("toytool", ToyTool.class).restrictTo("index.vm") .tool("custom", CustomTool.class).property("randomProperty", "whatever"); config.toolbox("session").property("create-session", true) .tool("map", HashMap.class); config.toolbox("application") .tool(DateTool.class); config.number("version", 1.1); config.data("date", "Mon Sep 17 10:08:03 PDT 2007") .target(Date.class) .converter(DateLocaleConverter.class); config.bool("isSimple", true); config.string("foo", "this is foo."); config.string("bar", "this is bar."); config.data("dataKeys", "list", "version,date,isSimple,foo,bar,dataKeys,switches"); config.data("switches", "list.boolean", "true,false,false,true");

      This example uses the EasyFactoryConfiguration API for brevity, but you can also directly use the FactoryConfiguration/ ToolboxConfiguration/ ToolConfiguration/ Data API, as you would probably do if you were to construct your configuration via a dependency injection framework (such as Spring).

      velocity-tools-2.0-src/xdocs/config.project.xml100644 0 0 1663 10730012234 17035 0ustar 0 0 Configuration velocity-tools-2.0-src/xdocs/config.properties.xml100644 0 0 4727 10730012234 17567 0ustar 0 0 Using Properties xdocs/project.xml xdocs/config.project.xml

      VelocityTools 2 can be configured using a properties file. Here's the same configuration as the XML and Java examples in the properties format:

      tools.toolbox = request,session,application tools.request.property.xhtml = true tools.request.toytool = ToyTool tools.request.toytool.restrictTo = index.vm tools.request.custom = org.mine.CustomTool tools.request.custom.randomProperty = whatever tools.session.property.create-session = true tools.session.property.create-session.type = boolean tools.session.map = java.util.HashMap tools.application.date = org.apache.velocity.tools.generic.DateTool tools.data.version = 1.1 tools.data.version.type = number tools.data.date = Mon Sep 17 10:08:03 PDT 2007 tools.data.date.class = java.util.Date tools.data.date.converter = org.apache.commons.beanutils.locale.converters.DateLocaleConverter tools.data.isSimple = true tools.data.type = boolean tools.data.foo = this is foo. tools.data.bar = this is bar. tools.data.dataKeys = version,date,isSimple.foo,bar,dataKeys,switches tools.data.dataKeys.type = list tools.data.switches = true,false,false,true tools.data.switches.type = list.boolean
      velocity-tools-2.0-src/xdocs/config.xml100644 0 0 14752 10730012234 15413 0ustar 0 0 Overview xdocs/project.xml xdocs/config.project.xml

      The VelocityTools support infrastructure exists to provide all your templates a common set of tools and data. This is inspired by the Pull MVC model, which deviates from the strict MVC purist approach out for the sake of convenience and clarity. The goal here is to provide template authors a common interface of data and functions across all templates (we call this a "toolbox"), whether they need all of those functions and data or not. This saves the template author from having to remember what keys were used where and makes it easy to drop a new template (i.e. View) into an app without having to modify the controller (which would typically involve creating a new action class). The degree to which this Pull MVC pattern violates MVC principles can (and should) vary widely depending on your needs and goals.

      The default VelocityTools 2 configuration does not include any "gross MVC offenders", as such things would be hard to generalize usefully. The default configuration primarily includes tools for manipulating values made available in the template's context by a controller and a few for accessing static resources.

      However, it is likely that you will want to add your own data and tools to your VelocityTools 2 configuration or at least want to change the default settings of the standard tools. To that end, configuration of your applications "toolbox(es)" can be done via XML, Java or properties. Different configurations can also be easily combined together.

      There a few basic concepts to the configuration that it is useful to know. First, what you are creating a configuration for is a ToolboxFactory. This factory produces your toolbox(es) as needed by VelocityView or your own application. A factory can have any number of toolboxes, all distinguished by their scope property. There are three special scopes automatically recognized by VelocityTools 2: "request", "application", and "session". The "session" scope is only relevant within a VelocityView app, but the other two may be useful anywhere. Placing a tool within "request" scope means that a new instance will be created for every context. Placing a tool within "application" scope means that only one instance of the tool will be created and shared throughout the application, effectively acting as a singleton. This, of course, means that thread-safety must be considered when putting a tool in "application" scope.

      Because of such concerns, Velocity Tools now provides annotations to allow developers to restrict the scope(s) in which a tool can be placed. For more on these and other available annotations, see Creating Your Own Tools.

      When the "application" toolbox is requested, the ToolboxFactory will also include any "data" configured for it. These are unchanging, static values that are meant to be available to all templates in your application. You can configure any number of data for your application and the configuration supports both automatic and explicit type conversion (via Commons-BeanUtils converters ) for these values (since XML and properties formats only allow string inputs).

      Other things to know are that each toolbox can have any number of tools within it, and that "properties" may be added for any and all tools, toolboxes, and the factory itself. A "property" added to one of these also has all of the same type conversion support as the "data" values do. Properties set on a toolbox are made available to all tools within that toolbox and properties set for the factory itself are made available to all tools in your application.

      Now on to the formats for specifying these things...

      velocity-tools-2.0-src/xdocs/config.xml.xml100644 0 0 6445 10730012234 16172 0ustar 0 0 Using XML xdocs/project.xml xdocs/config.project.xml

      Providing an xml format configuration file is still the standard, but unlike VelocityTools 1.x, it is no longer necessary at all, thanks to the introduction of default configurations. The default configurations for GenericTools, VelocityView and VelocityStruts are all defined via XML.

      Here's a somewhat thorough example:

      <tools> <toolbox scope="request" xhtml="true"> <tool key="toytool" class="ToyTool" restrictTo="index.vm"/> <tool key="custom" class="org.mine.CustomTool" randomProperty="whatever"/> </toolbox> <toolbox scope="session"> <property name="create-session" value="true" type="boolean"/> <tool key="map" class="java.util.HashMap"/> </toolbox> <toolbox scope="application"> <tool class="org.apache.velocity.tools.generic.DateTool"/> </toolbox> <data type="number" key="version" value="1.1"/> <data key="startdate" value="Mon Sep 17 10:08:03 PDT 2007" class="java.util.Date" converter="org.apache.commons.beanutils.locale.converters.DateLocaleConverter"/> <data type="boolean" key="isSimple" value="true"/> <data key="foo" value="this is foo."/> <data key="bar">this is bar.</data> <data type="list" key="dataKeys" value="version,date,isSimple,foo,bar,dataKeys,switches"/> <data type="list.boolean" key="switches" value="true,false,false,true"/> </tools>

      For those upgrading from VelocityTools 1.x, you will notice that the format has changed rather drastically. Not to worry, the old format is still supported, though it has been deprecated and does not offer as many features as the new one. We strongly recommend you upgrade to the new format.

      velocity-tools-2.0-src/xdocs/creatingtools.xml100644 0 0 65466 11360645207 17047 0ustar 0 0 Creating Tools xdocs/project.xml

      This page contains advice and instructions for creating your own "tools". Of course, almost any POJO can be used as a tool, but there are ways to make your tools much more useful, maintainable and secure. The tips here should help you do that. If you have tips to add, email them to our development mailing list.

      1. Basics
      2. Conventions
        1. Tool Keys/Names
        2. Tool Properties
      3. Standard Tool Properties
        1. Standard Properties in a Standalone Environment
        2. Standard Properties in a Web Environment
      4. Annotations
      5. Support Classes
        1. Base Classes
        2. Utility Classes
      6. Template-Friendly Interfaces
        1. Be Robust
        2. Be Flexible
        3. Be Careful
        4. Be Fluent

      Any class you wish to use as a tool must be declared public and have a public, no-argument constructor.

      As of VelocityTools 2, the toolbox support can now automatically determine the key name for a tool from its classname. So, a tool named org.com.FooTool would be assigned the key $foo in your templates, tool named org.com.FooBarTool would be $fooBar, and a tool named org.com.FooBar would be also be $fooBar.

      If you would prefer to give your org.com.FooBar tool the key $foob, you can use the org.apache.velocity.tools.config.DefaultKey annotation like this:

      package org.com; import org.apache.velocity.tools.config.DefaultKey; @DefaultKey("foob") public class FooBar { ... }

      Of course, you or your tool users can always override your intended key by specifying a different one in the configuration. Configured key values take precedence over @DefaultKey annotations, and the annotations take precedence over the tool's class name.

      If you want to allow your tool to be configured, you have two options:

      • add a public setter for each property
      • add a public void configure(Map props) method
      You can, of course, do both, but if you do so keep in mind that the specific setters will be called before the configure() method. The application of configuration properties to specific setters is done using org.apache.commons.beanutils.PropertyUtils from the Commons-BeanUtils project, so the rules follow the typical bean property conventions.

      One thing to consider here is the scope of your tool and whether or not you want the template authors to be able to alter tool settings from within the template. Remember, templates can call any public method on any public class, so your specific property setters will be accesible. This is almost always a bad thing for application or session scoped tools as it would make the tool non-threadsafe, and may or may not matter for a request scoped tool depending on how you use it. If you cannot rely on your template authors to avoid using those setters or just want to make sure nothing can be changed from within the template, you will probably want to use the configure() method and have your tool extend SafeConfig or one of its subclasses. (This is discussed more later.)

      Apart from custom properties you may define for your custom tool, the following properties are always defined and accessible to it, via the configure(Map) method or the appropriate setter.

      • key: the context key this tool was mapped to.
      • velocityContext: the current Velocity context (an org.apache.velocity.tools.ToolContext object)
      • key: the context key this tool was mapped to.
      • velocityEngine: the Velocity engine (an org.apache.velocity.app.VelocityEngine object).
      • log: the Velocity log (an org.apache.velocity.runtime.log.LogChute object).
      • locale: the tool's locale.
      • scope: the tool's scope: request, session or application.
      • servletContext: the current J2EE servlet context, used to store all application-scoped properties (a javax.servlet.ServletContext object).
      • session: the current J2EE session, null if it hasn't been created (a javax.servlet.http.HttpSession object). Contains the current session at the time of the tool's initialization for application scoped tools, generally relevant only for session and request scoped tools.
      • request: the current J2EE request (a javax.servlet.http.HttpServletRequest object). Contains the current request at the time of the tool's initialization for session and application scoped tools, so generally relevant only for request scoped tools.
      • response: the current J2EE response (a javax.servlet.http.HttpServletResponse object). Contains the current response at the time of the tool's initialization for session and application scoped tools, so generally relevant only for request scoped tools.
      • requestPath: the current request path portion of the URI. Generally relevant only for request scoped tools.
      • velocityContext: the current Velocity context (an org.apache.velocity.tools.view.context.ChainedContext object). Generally relevant only for request scoped tools.

      There are three Annotations provided for tool authors: DefaultKey, InvalidScope and ValidScope

      As described above, the @DefaultKey annotation is used to specify a default key for your tool. The @InvalidScope and @ValidScope annotations allow you to restrict the Scope(s) in which the tool can be used in either negative or positive terms. When described positively using the @ValidScope annotation, the tool may only be used in a toolbox with the specified scope. If placed in any other toolbox, an org.apache.velocity.tools.config.InvalidScopeException will be thrown. Using @InvalidScope, on the other hand, allows you reject specific scope(s), whilst implicitly allowing any others.

      Here's a scope annotation example:

      @InvalidScope({Scope.APPLICATION,Scope.SESSION}) public class PagerTool { ... }

      SafeConfig - This serves as a base class for tools who need to have their configuration be read-only for thread-safety or other reasons. By default, tools which extend this can only be configured once.

      LocaleConfig - Subclass of SafeConfig that has standardized support for configuring a Locale for the tool to use as its default.

      FormatConfig - Subclass of LocaleConfig that has standardized support for providing a format string value for the tool to use as its default.

      ClassUtils - Provides utility methods for loading classes, finding methods, accessing static field values, and more.

      ConversionUtils - Provides utility methods for common type conversions/value parsing.

      ServletUtils - Utility methods for the servlet environment, mostly centered on accessing the VelocityView or tool instances handled thereby.

      ValueParser - Used to retrieve and parse (aka convert) String values pulled from a map; this is mostly commonly used directly by other tools rather than within templates.

      Following a few best-practices can make your tools much more elegant and friendly to template authors.

      • Be robust. Catch exceptions and return null on errors.
      • Be flexible. Have methods accept Object when possible.
      • Be careful. Choose scope carefully and be aware of thread safety issues.
      • Be fluent. Subtools or get(key) methods can make a clear and flexible API.

      Always return null on errors! No Exceptions! Ok, maybe there are some exceptions if you are sure that's what you want your tool to do. Just be aware that this will likely surprise the user because uncaught exceptions halt template processing at the point the exception is thrown. If the output of the template is not buffered, this will result in an awkward, partial rendering. So, if you are going to let an exception through, make sure it is worth halting everything for. Often it is sufficient to return null, thus allowing the failed reference to appear in the output like this:

      $mytool.somemethod('bad input')

      This, of course, assumes that quiet notation is not being used for that reference. For this reason, it may be prudent to give your tool access to a logging facility in order to log exceptions and make sure important errors are not silently swallowed. Standard tool management for VelocityTools (even just GenericTools) makes the result of velocityEngine.getLog() available to tools as a property under the key "log". So log access can be added as simply as adding a public void setLog(org.apache.velocity.runtime.log.Log log) method and utilizing the provided Log instance.

      If you wish to toggle the exception catching or, more importantly, if you prefer to catch exceptions globally with a Velocity Event Handler, then have your tool watch for the "catchExceptions" property. This is false by default, but if the VelocityEngine has a MethodExceptionEventHandler configured, then it will be automatically set to true. Again, just add a public void setCatchExceptions(boolean catch) method to your tool or watch for the "catchExceptions" property in your public void configure(Map props) method. See RenderTool for an example of this.

      Variables in templates are strongly, but dynamically typed. As the current type (or whole subject of typing) is often not transparently obvious to the person working on the template, it is best to accept Object for most method parameters and handle any necessary conversions in your tool (either through overloading or actual conversion). This way template authors and maintainers don't have to worry about the variable being passed to tool methods.

      Of course, there may be times when you wish to restrict what a method can accept or when a method is public for use by other classes, not templates. If the method is not meant to be used by the template, ignore this advice and pay careful attention to the advice below. If you have other reasons for restricting the types accepted by a method that you do intend to be used, just be sure to document this plainly so it is easy to discover why the method isn't being called and what parameters it expects to receive.

      The first thing to remember is that all public methods declared in public classes may be called from templates. If it is imperative that a method not be called from a template, you must either change its permissions, its class's permissions or else put some sort of guard into the implementation of the method that renders it harmless when used by a template. See the implementation of configure(Map) in SafeConfig for an example of the latter option.

      The second thing to think about is thread-safety. If your tool maintains internal state that is in any way changed by the calling of its public methods, then your tool is not thread safe. The only thread-safe tools are those that maintain no state or are otherwise immutable (e.g. return new, copied instances w/changed state and leave original unchanged). If your tool is not thread-safe, you should seriously consider using a scope-limiting annotation to prevent such problems.

      Thread-safety is, of course, most important if your tool is meant to be used in "application" or "session" scoped toolboxes for web applications or any other multi-threaded application. Allowing access to non-thread-safe tools in those scopes can lead to all sorts of unpleasant problems. Please note that sometimes request scope isn't safe either! if you #parse subtemplates or are otherwise composing your page of separate pieces (e.g. Tiles) that may not know what each other are doing at any one time.

      SafeConfig and its subclasses can help you have safely configurable tools in any scope. They do this by only allowing the public configure(Map) method to be called once. All other configuration methods should then be declared protected and the tool cannot be re-configured by a template. This technique may, in the future, be changed to allow you to replace the configure(Map) method with a constructor that takes a Map of configuration properties, but for various reasons, this is not currently the case.

      As a final note here, if you really have good reason to use a mutable, non-thread-safe application or session scoped tool, tool path restrictions can help you limit possible damage here. Of course, this is something done purely at the configuration level and cannot be currently defined by the tool itself.

      When writing tools, you should take care in how you design its methods to make the resulting syntax in the templates clear, succinct and simple and thus decrease typos and "visual clutter". Readability is important for maintainability and things can get ugly and unreadable fast if you aren't careful. Typical Java method naming tends to be fairly verbose, which works fine in Java development environment with auto-complete and Java conventions to respect. It wouldn't be out of line for a BubbleGum class to have a method getStickWithName(String name), but using that in a template (e.g. $bubbleGum.getStickWithName('bigred')) is not ideal. It would be much better to have a simple get(String name) method to simplify that down to just $bubbleGum.bigred.

      One of your best assets when trying to simplify your tools' template-facing interface is the fact that Velocity includes get('name') in the method lookup for $tool.name. For some tools, this can greatly simplify the syntax, as shown above. Also, by encouraging the use of such short syntax, you give yourself greater flexibility in making changes to the tool later, which you would not have if the template references were all explicit method calls like $tool.getName().

      Another handy technique available to tool author's like yourself is the use of what we call subtools. These are examples of the fluent interface pattern. Essentially, the idea is that most methods return either the tool itself again, or else another object that has a similar or otherwise naturally subsequent interface. Such "fluent" interfaces tend to be very natural, clear and succinct, both saving keystrokes and keeping templates easy to read and maintain.

      In VelocityTools' standard set of tools, this practice is put into place often and in a few different ways. Here's a few examples, out of the many tools which make good use of fluent interfaces and a get(key) method.

      • ResourceTool uses subtools to allow you to type $text.org.com.Foo instead of $text.get('org.com.Foo') or worse, something very java-ish like $text.getResourceFromBundle('messages.properties', 'org.com.Foo'). This is achieved by having the get() method return a new instance of its Key subclass that carries with it the value to be gotten. The Key, in turn, has a get() method that does the same (and more), returning a new Key instance that carries the concatenated values of both get() calls. And so on it goes, until the final resulting value is rendered by Velocity calling the last Key's toString() method.

      • LinkTool takes a different approach. Rather than use a subclass as the subtool, it uses itself. Almost every method in LinkTool returns a copy of the original instance with the addition of the latest value. Both this approach and that of ResourceTool provide great flexibility to the template author. They can use the tools however they wish, with no concerns about thread collisions, shared state or lifecycle. And with modern JVMs, the performance cost of this flexibility is minimal--light object creation and reflection have become cheap and fast, and short-lived instances like those created in the process are quickly garbage collected.

      • ClassTool uses subtools to a somewhat different end. Rather than simply replicating the interface of the parent, the subtools provide a natural interface wrapping around the result of the previous call. This is done because the reflection API provided by JavaSE is not at all template-friendly. ClassTool wraps almost all returned methods, contructors and fields with subtools that continue to provide a natural, template-friendly interface.

      • AlternatorTool falls into a very simple class of "subtool" uses. In this case, the AlternatorTool class serves only as a factory for creating instances of the separate Alternator class. In this case, the so-called "subtool" is really the main thing and the tool exists solely to provide access to it.

      • LoopTool might be the strangest of them all. It is unlikely that you would find need to create such a tool, but if you are curious, read on. LoopTool exists to add value and convenience to using the #foreach directive. The methods on the main class are either used when starting a #foreach loop or else for use during said loop. The starting ones return a "subtool" of sorts called ManagedIterator, which provides a few fluent methods for refinement of the loop control. The final result of those, however, is largely just used by #foreach internally. While the loop is going, however, the original LoopTool itself may be directly used to observe and/or influence the ManagedIterator being used internally by #foreach. This is because the main LoopTool keeps track of all its subtool instances in a Stack. This is very different from most subtool situations, where the tool and subtool are immediately disassociated.

      velocity-tools-2.0-src/xdocs/css/maven-base.css100644 0 0 5717 10730012232 16723 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ body { margin: 0px; padding: 0px; } img { border:none; } table { padding:0px; width: 100%; margin-left: -2px; margin-right: -2px; } acronym { cursor: help; border-bottom: 1px dotted #feb; } table.bodyTable th, table.bodyTable td { padding: 2px 4px 2px 4px; vertical-align: top; } div.clear{ clear:both; visibility: hidden; } div.clear hr{ display: none; } #bannerLeft, #bannerRight { font-size: xx-large; font-weight: bold; } #bannerLeft img, #bannerRight img { margin: 0px; } .xleft, #bannerLeft img { float:left; text-shadow: #7CFC00; } .xright, #bannerRight img { float:right; text-shadow: #7CFC00; } #banner { padding: 0px; } #banner img { border: none; } #breadcrumbs { padding: 3px 10px 3px 10px; } #leftColumn { width: 170px; float:left; overflow: auto; } #bodyColumn { margin-right: 1.5em; margin-left: 197px; } #legend { padding: 8px 0 8px 0; } #navcolumn { padding: 8px 4px 0 8px; } #navcolumn h5 { margin: 0; padding: 0; font-size: small; } #navcolumn ul { margin: 0; padding: 0; font-size: small; } #navcolumn li { list-style-type: none; background-image: none; background-repeat: no-repeat; background-position: 0 0.4em; padding-left: 16px; list-style-position: outside; line-height: 1.2em; font-size: smaller; } #poweredBy { text-align: center; } #navcolumn img { margin-top: 10px; margin-bottom: 3px; } #poweredBy img { display:block; margin: 20px 0 20px 17px; } #search img { margin: 0px; display: block; } #search #q, #search #btnG { border: 1px solid #999; margin-bottom:10px; } #search form { margin: 0px; } #lastPublished { font-size: x-small; } .navSection { margin-bottom: 2px; padding: 8px; } .navSectionHead { font-weight: bold; font-size: x-small; } .section { padding: 4px; } #footer { padding: 3px 10px 3px 10px; font-size: x-small; } #breadcrumbs { font-size: x-small; margin: 0pt; } .source { padding: 12px; margin: 1em 7px 1em 7px; } .source pre { margin: 0px; padding: 0px; } velocity-tools-2.0-src/xdocs/css/maven-theme.css100644 0 0 7233 11360645207 17124 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ body { background-color: white; padding: 0px 0px 10px 0px; font-family: "Times New Roman", Times, serif; font-size: 12pt; } code, pre { font-family: "Courier New", Courier, monospace; font-size: 10pt; line-height: normal; } a { text-decoration: none; } a:link, a:visited, a:active, a:hover { color: #525D76; } #breadcrumbs a:link, #breadcrumbs a:visited, #breadcrumbs a:active, #breadcrumbs a:hover { color: white; text-decoration: none; } h1,h2 { padding: 4px 4px 4px 6px; border: none; background-color: #525D76; color: white; font-size: 14pt; font-weight: normal; } h3 { padding: 4px 4px 4px 6px; border: solid 1px #525D76; background-color: white; color: #525D76; font-size: 12pt; font-weight: bold; } h4 { padding: 4px 4px 4px 6px; border: 1px solid #bbb; color: #900; background-color: white; font-weight: normal; font-size: large; } h5 { padding: 4px 4px 4px 6px; color: #900; font-size: medium; } p, table, ul, dl, div, span { line-height: 1.3em; } tt { font-family: Courier New, Courier, monospace; } #breadcrumbs { font-family: Arial, Verdana, Helvetica, sans-serif; border: none; background-color: #525D76; color: white; } #leftColumn { border: 1px solid #999; font-family: Arial, Verdana, Helvetica, sans-serif; margin: 10px 0 0 5px; background-color: white; } #leftColumn a { text-decoration: none; } #leftColumn li { font-family: Arial, Verdana, Helvetica, sans-serif; } img.poweredBy { display:block; margin-left: auto; margin-right: auto; } a.poweredBy { padding: 0px; margin: 0px; } #navcolumn { padding: 8px 4px 10px 8px; } #navcolumn h5 { padding: 8px 4px 4px 6px; font-size: small; border-bottom: 1px solid #aaaaaa; color: #525D76; } table.bodyTable th { background-color: #039acc; color: #000000; vertical-align: top; text-align:left; border:1px white solid; padding: 2px; } table.bodyTable tr.a { background-color: #a0ddf0; color: #000000; vertical-align: top; text-align:left; border:1px white solid; padding: 2px; } table.bodyTable tr.b { background-color: #88c5d8; color: #000000; vertical-align: top; text-align:left; border:1px white solid; padding: 2px; } table.bodyTable th, table.bodyTable td { font-size: 10pt; } .source { border: 1px solid #999; background-color: #f8fff8; } dt.question { color: #900; background-color: #eee; } dl { padding: 4px 4px 4px 6px; border: 1px solid #aaa; background-color: white; } dt { color: #900; } #organizationLogo img, #projectLogo img, #projectLogo span{ margin: 8px; } #banner { border-bottom: 1px solid white; } #bannerRight p { float: right; font-family: Arial, Verdana, Helvetica, sans-serif; color: #525D76; padding: 4px; border: solid black 1px; margin: 4px 4px; background-color: #f8fff8; } #bannerLeft img, #bannerRight img { padding: 4px 4px; } velocity-tools-2.0-src/xdocs/css/print.css100644 0 0 3174 11115263027 16044 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ #bodyColumn, #banner, #title { width: 625px; margin: 0px; } #organizationLogo img, #projectLogo img, #projectLogo span{ margin: 2px; } ul { padding: 0px 0px 5px 40px; } p { margin:3px 0px 5px 1px; } h1, h2 { padding: 1px 1px 1px 2px; margin: 10px 1px 1px 2px; background-color: white; color: black; } h3, h4, h5 { padding: 1px 1px 1px 2px; margin: 8px 0px 0px 20px; border: none; color: black; background-color: white; } #title h1 { font-size: 16pt; font-weight: bold; text-align: center; } .source { background-color: white; } .note { background-color: white; font-style: italic; } th { background-color: #eeeeee; border: 1px dotted #111111; } td { background-color: white; border: 1px dotted #111111; } dt { color: black; font-weight: bold; } velocity-tools-2.0-src/xdocs/css/style.css100644 0 0 3037 11360645207 16054 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ th { background-color: #039acc; color: #000000; text-align: left; } td { background-color: #a0ddf0; color: #000000; } #navcolumn h5#printLink { border-top: 1px solid #AAAAAA; border-bottom: none; margin-top: 10px; } .subsection h3 { border: 0px; padding: 0px; margin: 25px 0px -10px 0px; } .subsection h3 a { border-bottom: 1px dotted black; display: block; font-size: 1.2em; } .subsection h3 a.nolink, .subsection h3 a.nolink:hover, .subsection table a.nolink { text-decoration: none; color: black; } .note { background-color: #ffeeff; border: 1px dotted #111111; padding: 3px 3px; } .subsubSection { font-weight: bold; margin-top: 30px; margin-bottom: -5px; } velocity-tools-2.0-src/xdocs/dependencies.xml100644 0 0 35206 11202122663 16574 0ustar 0 0 Dependencies xdocs/project.xml

      VelocityTools requires certain external jar dependencies at different times. These charts should help you determine which jars you need and when.

      Note: Java version 1.5+ is required for compilation, testing and use of VelocityTools 2.

      Jar Name Version Compile Runtime Notes
      commons-beanutils 1.7.0 Yes Yes Required for core infrastructure, MathTool and SortTool
      commons-collections 3.1 Yes Yes Velocity requires this.
      commons-digester 1.8 Yes Yes Required for xml configuration
      commons-lang 2.1 Yes No Required for EscapeTool
      commons-logging 1.1 Yes Yes Required for Digester and LogChuteCommonsLog
      dom4j 1.1+ Yes No Required only for XmlTool
      oro 2.0+ No No A Velocity dependency (only used by certain EventHandlers)
      velocity 1.5 Yes Yes Required for core infrastructure, ClassTool, LinkTool, LoopTool, RenderTool and XmlTool
      Jar Name Version Compile Runtime Notes
      commons-beanutils 1.7.0 Yes Yes Required for core infrastructure, MathTool and SortTool
      commons-collections 3.1 Yes Yes Velocity requires this.
      commons-digester 1.8 Yes Yes Required for xml configuration
      commons-lang 2.1 Yes No Required for EscapeTool and VelocityViewServlet
      commons-logging 1.1 Yes Yes Required for Digester and LogChuteCommonsLog
      dom4j 1.1+ Yes No Required only for XmlTool
      oro 2.0+ No No A Velocity dependency (only used by certain EventHandlers)
      servletapi 2.3 Yes Yes Required for all VelocityView tools except for RenderTool
      velocity 1.5 Yes Yes Required for core infrastructure, ClassTool, RenderTool XmlTool AbstractSearchTool, ContextTool, ImportTool, LinkTool, LoopTool, and MultiViewsTool
      Jar Name Version Compile Runtime Notes
      commons-beanutils 1.7.0 Yes Yes Required for core infrastructure, MathTool and SortTool
      commons-chain 1.1 No Yes Struts 1.3+ requires this.
      commons-collections 3.1 Yes Yes Velocity requires this.
      commons-digester 1.8 Yes Yes Required for xml configuration
      commons-lang 2.1 Yes Yes Required for Struts, EscapeTool and VelocityViewServlet
      commons-logging 1.1 Yes Yes Required for Struts, Digester, and LogChuteCommonsLog
      dom4j 1.1+ Yes No Required only for XmlTool
      struts-core 1.3.8 Yes Yes Required for all VelocityStruts tools
      struts-taglib 1.3.8 Yes Yes Required for FormTool, SecureLinkTool and StrutsLinkTool
      struts-tiles 1.3.8 Yes Yes Required for TilesTool
      ssl-ext 1.2 Yes No Required for SecureLinkTool
      commons-validator 1.3.1 Yes Yes Required for ValidatorTool
      oro 2.0+ No No A Velocity dependency (only used by certain EventHandlers)
      servletapi 2.3 Yes Yes Required for all VelocityStruts tools and all VelocityView tools except for RenderTool
      velocity 1.5 Yes Yes Required for core infrastructure, ClassTool, RenderTool, XmlTool, AbstractSearchTool, ContextTool, ImportTool, LinkTool, LoopTool, MultiViewsTool, SecureLinkTool, StrutsLinkTool, TilesTool and MessageTool
      velocity-tools-2.0-src/xdocs/frameworks.xml100644 0 0 22626 11202122663 16330 0ustar 0 0 Web Framework Integration xdocs/project.xml

      VelocityTools is not meant to be a framework in itself, but rather should ideally be integrated with other frameworks for applications of much size. The simplest means of integration is to have your framework handle requests, placing contextual data into the request, session or servlet context attributes where templates and/or tools can find them, then forward those requests to a VelocityViewServlet or VelocityLayoutServlet, letting those servlets manage your VelocityView support for you and render your templates into the response. If, however, your framework is one like Spring MVC and you either cannot or do not wish to forward requests to one of the provided servlets, then the instructions, tips and code below should make it easy for you to integrate VelocityTools support into your framework of choice.

      VelocityView supports the following configuration parameters as <init-param>s in web.xml:

      org.apache.velocity.toolbox
      Path and name of the toolbox configuration file. The path must be relative to the web application root directory. If this parameter is not found, the servlet will check for a toolbox file at /WEB-INF/tools.xml.
      org.apache.velocity.properties
      Path and name of the Velocity configuration file. The path must be relative to the web application root directory. If this parameter is not present, Velocity will check for a properties file at /WEB-INF/velocity.properties. If no file is found there, then Velocity is initialized with the settings in the classpath at org.apache.velocity.tools.view.velocity.properties.
      org.apache.velocity.tools.deprecationSupportMode
      Tells VelocityView whether or not it should
      • support old tools that rely on init(Object) methods,
      • look for and translate old toolbox.xml configurations, and
      • use the deprecated ChainedContext class instead of ViewToolContext.
      By default, this is true, so turn it to false if you want to fully upgrade to the new systems. Also, specific tools may look for and respect the deprecationSupportMode setting (e.g. ValueParser, ResourceTool) to provide old behavior where it has otherwise changed.
      org.apache.velocity.tools.loadDefaults
      Tells VelocityView whether or not it should include the default tools.xml configurations provided in the VelocityTools jar(s). This is true by default.
      org.apache.velocity.tools.cleanConfiguration
      Tells VelocityView to test all the tool configurations and remove any invalid ones, rather than allow them to throw errors. This is false by default.
      org.apache.velocity.tools.userCanOverwriteTools
      Tells VelocityView to construct the context in such a way that any user-set variables with the same keys as any of the configured tools are given primacy when resolving references. This is true by default, unlike in Tools 1.x.

      The VelocityView instance is typically the heart of any VelocityTools-using application. It encapsulates all necessary VelocityEngine and ToolboxFactory configuration and provides a simple API for processing templates or other VTL (e.g. VelocityViewTag body content).

      You can, of course, simply create a VelocityView instance for your framework to use, but if you are supporting multiple ways of using Velocity (e.g. VelocityViewTag and separate templates) or if you suspect your users might want access to the VelocityView facilities, it is better to get your VelocityView instance using the getVelocityView(...) methods of the org.apache.velocity.tools.view.ServletUtils class. These methods will automatically create an instance, store it for you, return it, and then retrieve it again on subsequent calls to any of those methods. This allows the VelocityView (which is a rather heavy object) to be shared across multiple servlets, tags, and filters in the same application. Of course, if you do not wish to share your VelocityEngine configuration (template cache, global macros) or Toolbox configuration(s), then you should explicitly avoid using these methods and construct and manage your own VelocityView instance.

      If you are using VelocityViewServlet, VelocityLayoutServlet, and/or VelocityViewTag in the same application and do not want them to share a VelocityView instance for some reason, you can tell them to keep their VelocityViews private by setting org.apache.velocity.tools.shared.config to false in the init-params of the servlet config.

      discuss basic functions, config options, etc
      Discuss lifecycle, configuration, and use.
      See this email thread for more on this, including code samples.

      The so-called "standalone" methods of tool use developed from a desire to use tools directly, particularly the GenericTools which had no servlet dependencies. However, now many VelocityView tools can also be used "standalone" with varying degrees of effort and no need to create any VelocityView instances. Most of the time, you just treat them like any other POJO--create an instance, provide any need values/objects and use it.

      If you want a little more help with things, consider using a ToolManager.

      velocity-tools-2.0-src/xdocs/generic.project.xml100644 0 0 6356 11110347746 17224 0ustar 0 0 GenericTools /> /> /> velocity-tools-2.0-src/xdocs/generic.xml100644 0 0 13733 11110347746 15574 0ustar 0 0 Overview xdocs/project.xml xdocs/generic.project.xml

      GenericTools is the set of classes that provide basic infrastructure for using tools in standard Java SE Velocity projects, as well as a set of tools for use in generic Velocity templates. These tools have no Java EE dependencies and are often safe to use as "singletons". Some of them are not thread-safe to allow both a no-arg constructor and configurability, but the state-changing methods are declared protected with the exception of configure(Map) which is--by default--rendered useless after being used just once. If you require strict thread-safety, be cautious in using any configurable tools and consider restricting the abilities of template authors to prevent circumvention of the lockdown placed on configuration methods.

      The default configuration provided for GenericTools is here. It includes all of the tools listed below.

      The dependencies required for GenericTools vary somewhat depending on which tools you use, whether you will rely on core tool management infrastructure, and if so, how you choose to configure your toolbox. More details can be found on the dependencies chart.

      • - For creating s to easily alternate over a set of values.
      • - For simplifying reflective lookup of information about Classes and their fields, methods and constructors.
      • - For convenient access to Context data and meta-data.
      • - For converting String values to richer object types.
      • & - For manipulating, formatting, and comparing dates.
      • - For controlling display of references (e.g. truncating values, "pretty printing" lists, and displaying alternates when a reference is null).
      • - For common escaping needs in Velocity templates (e.g. escaping html, xml, javascript etc.)
      • - For (easy) access to static fields in a class, such as string constants.
      • - A convenience tool to use with #foreach loops. It wraps a list with a custom iterator to provide greater control, allowing loops to end early, skip ahead and more.
      • - For creating and manipulating URIs and URLs. The API for this tool is designed to closely resemble that of the VelocityView tool of the same name.
      • - For working with arrays and lists, treats both transparently the same.
      • - For performing math functions.
      • - For formatting and converting numbers.
      • - To evaluate and render arbitrary strings of VTL, including recursive rendering.
      • - For simplified access to ResourceBundles for internationalization or other dynamic content needs.
      • - Used to sort collections (or arrays, iterators, etc) on any arbitary set of properties exposed by the objects contained within the collection.
      • - For reading/navigating XML files. This uses dom4j under the covers and provides complete XPath support.
      velocity-tools-2.0-src/xdocs/images/velocitytools.png100644 0 0 20200 11030275235 20305 0ustar 0 0 PNG  IHDREGL#tsRGBbKGD pHYs  tIME%lF IDATxyU6==K&d#EWDP^EDA6@" .3DVQv ,)aK df2kUu~ۙJzLç>COU:9ϻs0hOvɮ: ]3 bAEځƧU\h<4ao9$ X8|]k@o@9tfzggN69j#PSAS{K[ &@B9D"󥊚;nPB 6z!?vXx| =94jF\ϗ^`3gv\?IQ0rP(rnRe _#-yЁDUg_'w+/TYg ;ϩ! {+yaR :h^ <ܫSg]jJDG@[,BEJQ_sw!Fw`ed4"@5khslP _ h RLr-R4+aJqRܢ7*JS\?)g,5hmOv-#@"<˖ }٫>QS\ p쏛XOR5253WëP C7B9u]c :"àb%[=Rhָfv8nR#nmcA}87Dui+L] C״ :|Kaư;:nBYQJ7lƢ׌>.6Ô{ʐML`q?[(#hi!0q}@+nY:mTX(ϓHCt^]:(z:!<#lvMmncL#\Xz,pұ7y#|5!ltnCDCG#r2TQ{W yBUhP Ʋ+E|{S w_p,NXm"@05M3pލ~qGXFg'*QNU?˜trsGUTIJ(!a5r9UDph) X83(TQH3 .'}J6_D=jd{DB-h>pN,lF@E(m3K߮Plq"@0‰Fx,dNAG+6}G6G"R9PUiZ,jcr(#[Î٪8 E`ڎSuhxC5Qϟ0ae;AzdnN5*ET;Rη'u}Y av@zٲl["pPQ%a~ J4@mghmz+BSJ=aGbȒBTq'X%@䠡|< {̕i!0\h2SsG- e xemny2 JCmHC4|+BJ)eJC44Ė% 72@BT2 ]oMgŠB (*AJFL#T,lA ߚJ򃣅2x/6R‘vrhOvi^ϗeOGeӅrE5m9R FPʒu*;4664*ʚAd(*kFŖD ̺is(>)F#-R*OM"@9gk[ ,8~L TE)Uؑ>x9ОjF#G a`]$ؚF7)X4yh$t\;(TQ% ʚcb'l;|sxНKeQZ1ѓTjԈ3QjgCF"xTT*߻6 6|Vw}s&S[p7a |"a'w{&rNwЙyhC5_h~~O|;1+_&fy\61Jo3*mU*wOԊR󛀇1kڝl->fg>!}#JeE"ښRnsPJ,c0*Nu1#%c12QHb;|8x(BB~G(*ǹmh_~w[2ua[6 ֙h6|bVyy2HB"@P(l.- 33J|F7pÿ%`w5s̑㨙6H3?fnw|~;ߚ8/ G:ǺtfzНa%,^rxZNtHݿX(gh0"ƚ:Pp6o>ArNw7 %.t~K"⶯{plq| Lʩn4 x0Wq,OJ̏,olm6 kKvi9h3ӳ;1S%aړ]i'ToJ5KvD xwoF[^T2n豈:3[,)NK?f2'bP$CTz%p_.)MP|8Lwgl-(0L~䲙d*V8w; pN-t,< 7l '3N:M qX/LWƕr>/,3"$Si3RRoE\XRd*K\6hWX,²%7ţ^2bRl%b0Ƌa KSbT$> O>/`O zQGx-Tlq j2"A pi2n׈_5Ā28rHNp_I~tUbf?E)$!3Ry'kTՔ(|)i<;[N^N_Sd@vށolGغ;Xҭ*+zg#}ZOoT,j' ʋ1)^yNb7׈N4e^!|3J>H2JO%/!>˪}#>_'dTuzW3[?t,:$?d!e%\) /cZIw;ܧua_Pёv5GQDŽ8SQ-}{xR>מ/Jo=9J/bNpj.Y!#m1 \Ly>Aw:盅0ULFZ$&Pxx;G%S]jC\O;=d=p2nk+䲙 W=6Jsہ8߇l }G2>p 1u&H|\ LS/m8; }qn¶ݞ}^cUT{+ksˋK H$7d&q(Jjt4sr.%d""#l#$l Q( DqéS.?RU6lϲuT8W"qYT#_I9k_B˼U@)aI}'vfʡ~|n jsy;Ī岙)^Q{I$ځL?A:g"H9Н{P(,Qi,lk>qa[5MkD8 +bk'DObsCQ|a]R?mT{ۦ:wj=G4<6|GBQ WϪy }#.rO 8)lf8dpB|ȹAU촤oTC= ѪC|)OP)GDW)|8H"\bܙfw`0LuS_r2 58R3Hwcs$Jm1͐wibgBfqa4T*XS4ΚbvOҷl|d5y"fLOɻ5m+0ړ]iLӸ<PȌ*\?CxP<_)fmnxjq4?oŦU>T:GODM'k"O$y8~?i6Ncif 3lkeMQZ'3<($٣ܪu(,"as]$QjZ B?N'&S)3#z7hh` Ki,hm9xɂ_7DTJÃ%dځH7XIS%b/ʗ-J ڧ#ibKD3v4zD\ө8}7·;}|M^֧Cfakyٜr&"=^y''?:w<zS@9l+l͉_ۻyLe@dU{QٞJqZ8:;뺻P*ض}S="ZbwpN-qSΈOSUnhI$EbmCC ~3D9ZNeCH$|V4#J9((W*r9mO斏'%oʨK|:/uu:oKS?W ( 7/tA`yڙL [y5j>gbN_|gDŽU(g)gV%5d*}(}fj]Lw/<|zCTqp05*wg'1hƤVjOvўvd8e$>4̈R8)Q*Krڲ-OPQӑ\ @O'`IW^&s&-}SRΓ2"XQ_矩 bAMu/0ógEͣ&opDŽxڧ8Gw8lf YT؈ǧXnPw`C#Bh-M5'ےhXi^8+I0H îZpRZeQ~sY0˽uCV@we,ܝgTY|U&QJU,T)=ҡb\NRΖ%T1_^I2`O8L '׼ͧ;lf8J/n2Vf$_LnIZلЁTs J]=*#LoƝt|fkAY#s^2FMLayƦЯQ2.t91&dWLKKԕy0^Nw8r宗{޺oz8|Ѣd)Z-jk%m4&^biN0~nDGg;6rRfqn"1 liu5هaN7XrA{vVqmt :}y7 ڋUw}mHWo= ;Rȴ5dJ $JF}wדUu nLi y+ yyJ꼚p)py2>@1pC?6^DNf>LPtL !;s̋LTTwC.<-Ǯ kf-l k>p o|웫B=ٵLh(t-eٔʕ˲O}0L.yf(ǜ)f^ܣS)$#\)~#oő: ^;]O'Sࠉ wsQY'?ymS~:gpCˀ+?%ijZpA84/^iFF†iضPWЌphZe:3=w/Q4_״t0 MHkBTQ-\vs<0Ϲ_]g<1{Nl+C4r_q'w]7 bg;Q_y#"_SiF?O{A->C܅jB3.lfX[xyN+&Z׋ }AEBX>4&"LEu[kY5Ršb9XiD"хpBte/|1dF{i.,C+PJa9Nm8JQͶ)0q Jҧ7ɗdf??zfM2>S AG,Wa25c MX'y'G*O8EG}䲙gd9&Z<|0d(d0$ :-d*}tgC w9ժDL/C8ZbO)u8| w剂fTzc}Ti/DEj :3=F4OoN; 3)Vlʖ(t LC'd4FMya=$8(e[QJԝޖWqm8岙54}Ul@gm?Enjl5eVTlRvSv+`+g89J]6|c<Cn v@t; _!NNBD:>Rg+m. !H߼;9A8Jg ;4<) HH5w^e;X}iJ{  l;[A-fA(`3s]rn/*'/cypilF)UBp:Rx m69IXӝ-~P(}!9\쩛zRJ[[>u&9٬& mG޼3n0a[mz -`f VEPIENDB`velocity-tools-2.0-src/xdocs/images/velstruts_diag1.png100644 0 0 30267 10730012232 20514 0ustar 0 0 PNG  IHDR;>\-!GgAMA7tEXtSoftwareAdobe ImageReadyqe<PLTE̙ff3̙̙3f3̙̙f̙f3f3f3f333fffffffffff3f3fff3f333f3ff3333f3333f333fff33ff3^/IDATxb`<@h hr@Q@.Q4 4F F( (E\@h hr@!>? Y_@LU ;!2+1-I3x +@pĊH ,&'6vM ?̈Ĥʏ"NtHS$SP(v 1xMU4@E?(UAA( wHq\0wUHQFYTP~ h{gB*w w gV`2bY@ kTh9$GkZ@fXtEHBQ8ZEEEA. HA `&k@Z8rTTJѴpӌVLE8Rc\@ZlhTz Di UaRQv'@0pÊ `*{R܃Dkp .\0 Ii GA4 @hZ &d : "%TATBP#d7A .ҳMĥnAzHBl4ij R%$S@Qe/Ғ*G2If 9hСVcE()96&! |0 jтuE ōRq1 3rzYW\OLXMٙS@13~1+Cba_*, # DBtIAզ=G)J*C9P1k@ xhV@Ԃ0m#b5#@ Z: 6eCj= xnhWy45y:쒒FP@qfOX{VijAJ d0@ +nz k -"GUPUX_$.jSZ鲃p9U Iz:T4#@!Jb@A( D*hDJ;zd{+fH "h{Vj0)%-F%#`N<0tE44#Bps41bzh' 0`ĺׂGCZ.(͏a.g4Z,-bEnv)iK@Ѥ=ZG+MWZ+h? oQn_1UYEV;Z@KK@!bzB=#UP~+ ](q*[ tG-Fb4im js9kMŲbD %^} @4<@J )`]cqH#L@TmΈ*!t+ th>=@,9CSh aHQv,T`Ut }\ Ї%T8uYf"5C#v)b|NBmerVf0x#R ‚zb zVBp#бAX]Ōv -L[ȋZ;JCv j lM<*Gh7u2@ҒTx{]F J 4+`]@}tjGf#Ayig<ܰ*v% D:k6ogeX-L8Շ@-F04׵HYh q! UcT*xFX%CC+d| pX PK;L T3$bN/g CRuȔG: h҈m"a7t{(@j0+ 9?zHqo[YCPfl n $5dψ@ѲK;h]tDk@\:M;FL\@]Shȴ @Ѳívu0SuD\ل]JPn >M5$`¤q l]076D4n֕#0XAo :ѳE1v0V]n~ϬC% @Ѻ%Fʹ:0`5F<БaUBtx傺w|A { @4!urhe5EP9tQEX\7@o~ˢ#9 |" HN4$YA2DRgTk(ȝ۾tإ{@zB йD>5guBZx5X ._vb 6!| t+j#{A3T2 =kJmp@r+C:UDl dFHMًJ3`.;19v'F}AqNfAU "f:@a` ~́w {=+;.]t1nUrG T@V 0ނClڑ5,bTlАo .-Fb;#"eA:4. svdPD R٦<%kj ,@%Q,Ӈ(+3t1bl%LӆP!4#k5!Zs!"h(FQ#e *tX @,`z'6sa<)Nbs1Df4),lbpӆN7vp$rGMI]Z.&&P:\Pa5gapA̾ ` /Ղޛ9t P 4 KPŰk lY@2B@i5Dw5A*~!,)I R*JCa`a$PyX"6`&Ƥw Yk r8@/5j~bJ.4BK4r\&BA3C \])(w@e.,kXe& Ylx"ba'3ʂE`2,=%rs t@Y: Y3$@M)L;R¢,s@B,G#I<U z)8퀛8 OvbD= ,)AX Hh;;%В$TC <.w <8~ oq ƕ A\$ rca ;2/2VS=8"`Qᬮj,G;Dvǂ;:ƑXJ*Vcл̕.V% 1AvIWÑoNڡ<:?DvځLQC/Ղ}$k0ydŰЃ`pMc7$)u/7"`wxb B: T'A0t 8-C* zb#D=tX.i`@tJ;HI*^iPh ` v"WA6@G Y8,o#툢,6b@=68%VFYFXJ#ZgH@SqheF[ Ew Ca h 7NJ93~$܁]+ ľ n&֔7Zw&Jp :36`&S(2߆u LnQPQVpl po`b#k8r;h> <.4 lQEQ+ : >Fi|6xU!fCS`6(j̅m8Z \d }4,P!%^d y"r˃)4sYH:DM;b!2_'Qgv3:@ᮦr{V^v"X? Vܡ\PvASr(}tJ$Yď@l &44meN;nĥؾh!p$" ^U^+h<"&+OT c[y`;Н؄@fYWtQiQ'ȴCZwnJfރeX/ံKhC7Me6{0{0v3S: ɐ u33)$89ZAsa8Ț7@u# Di`"L?s&m F' bK@ӎrv7z *$-whhC=urNThCpK;4Zм3lur~;iq :_j GTCS|-wk[ 3`Bæ4Z `{E|B s!f]) uA ) N;z<,2,A D@m 8jGn& ]Yp¢+\X XTQM1@͝{\ŀzW2d\9pQk.I*E,0aȳ& fa($%@ES+!@K Q:ϛ ) @;4O;&u`;ZҎ>| AU$uyX +Q;Ḑܓ&H Mm:)  F˝a!Vv O1b`ՀP.wG[9dhH@!6Hj Z8̃#z@ b| F˝@ e"AY_u@,}~"`͚X,-w^`+X 1 }^.ֱAD@>:/j4/_#9$Y4Zм3lBh:kH@ aTA ^ "`6v34 YsX7@EVs`aN%f]F!H9Bl4gAc"IFp</m~'@ r^ia6fCgPX!jL2T@T@!tߡt? uçh#*%l!ˤb\hMA'aô1ZFa0Trua 7eY sì ,%5,)pWaZ,4}phΏ!3:LVuv R͹[$FDا 0Cs1 i#u~xM;]/u5Іi!dXi,t!-,DL<:yNi1e@-w5`c @iXφukL3(F&i| X5FEw P;2ރ8,wX!CІ;ື^V@!ȡ2XX? Q; 36S@=;hg[Z`;#G;FF0DO0)CQ&2^}tO sx&Qu2 H ,!*hߥd"̈́a6h^[0CJ%x e%bt7i8DHya_FT@C<(8Udiԣ(O;4;z<0<Mς@Þ|d%dLĀspMSvh;N:t|GU|l͠Jѧ5()O;49`}h@ùAWi̊Rvh;C׉iPvhĔ;C9yd!i F#fзwh3DHyrvh<h3$ )O;4Z C2i F˝v?DHyrgRvh*ie@;C&PCyrgȤ*r% F˝v8D^MyHX[!dAvbS,t"dE,VHXQ*nbs,(1ډ^O 0GSǻ6DhCa1@!TgQ,ޑGY@Hh{*ѶI!B* @p7;CPkPb FYTN;4*-(2@ѣQ͏VABC!y1m+2I;6}t|ʉHrzb @hE-0р*T(~!B`.^Jses>&mC`bQ+ea *w;F˝l•/@Y*rDmh?X 0cr>2%p@h*厰 :@tCBd&*ԁ@^y lIpȚ,e. ,@meqȕf@biv=Ț  (ɀ (c.lh>Z `{!BB+jAA,@M `G;"L@;BC@e ̋V6bm QBMݲ`n`rjٕģGZځY+ .Y-"fO!GQ;-$4Dv;,Zn>?3i CFwhQ"A\I& awv#ѣk&oN@r b;D2:3 erA;Zdw>ig;Jl&"W@*.ENE]EGQ;f|CYrGOIYr SrG vFI&*4h{|0B?r{@JcA:pZH܁ xԴ@4O;JJr[opg^ =%!X"2@ѣ%!f47s[Po si h_*Q1bhWPmlj8^l`@ѣ c1 ԍ?pH :Go?RdWeD1;zH;DĆp>DH@tIeCK5[ H^y dYH09lM"! 8jbw`Gi H(j-4NJQ&&!@$Gra1:[4ZPǝx ^; f:wf7aN;/FsFEX)9v:wF\kwK;4Zg >D50rgWb`Qµf@$M;>ñC;w,u┕;DBvM;^ƞv @d;%M;3P֔X׹vHG˝!G%n|me![ځivv4c/ q<*w+7LHAw`C@F`*%7ʐ20(<;s,HAA?$i=Z OnR`Xj/)< ^ƙvTN;$G*i |:0  098 )fSZ$@l̇R b6k0<z4O;DxDz@!PD\HkP" f1e_b@R-$@S zPd =܁j逞qo&2m-oty T.w`iv0*8Ly+GAB"mВ#,`R;HK <(`u!`Auv Yh}@е$ =G[@COrG* ,qN~FuXb'hFXT p9 xv ^\!h2[u b4O;DM;̰KqX1B B”Cor ,wiޱZԀ`Ai^H Lj@R@Qa|a]"` WB6 `-`Z F&( Ԉh+CDA$:(rƒV3a4YQ$QPu jaDH;&rv` V`C/֤bCD VC r! Cu@@ItmYRr $y50+n3xX|, Fr 2V;rH- (S@iZ/S12v098hB}tspj1k#i\4VTH] ,:R36 s##h(+0C53r3ܸ:rF~@P)w`pc-w 2jCke;!ά+TgA`0jJ#fC0(+j9Be d 8ibRT`vvȆ -YC@dn 줝x$)B6+@91 P,Xk8@AjU@'dSG0*wfA7L0\C8=2'}|g (uMPZ貃 B^FPA v`fA6L00v }vn;0]bdaZ0@oCKP(;в aŀ@i$ /@  ( V6Ђ(n@;HX? Tjxc$@lkC_ *G136j+W 2@ |4i F: lX![-y(@YԎA]gd1&U) Fш * [/VYDS PT)H? 9OI̚ 裃wxBw*vhC|E#hN Fшj+S5Ezz Jb@ZLAO*h,I7A+/H'FL x5 F&U^ybĤEui FhJ5b{O4F:PS#]EiR#b+@Ѵ,l(M;]n="(M;XUc(M;Me1"(M;ib FhfPQ4vлYjQ4vлYX4F6'#h ߴG& Ep(E\@h hr@Q@.Q4 4F F( (eQHfIENDB`velocity-tools-2.0-src/xdocs/index.xml100644 0 0 30114 10730012234 15243 0ustar 0 0 Overview xdocs/project.xml

      A Velocity "tool" is just a POJO (plain old java object) that is "useful" in a template and is not meant to be rendered in the output. In other words, a "tool" (in Velocity-speak) is meant to be used but not seen themselves (e.g. for formatting dates or numbers, url building, etc).

      The VelocityTools project is, first of all, a collection of such useful Java classes, as well as infrastructure to easily, automatically and transparently make these tools available to your Velocity templates. Other aims of the project include providing easy integration of Velocity into the view-layer of your web applications (via the VelocityViewTag and VelocityViewServlet) and integration with Struts 1.x applications.

      In recognition of these varying aims, the VelocityTools project is divided into three parts: GenericTools, VelocityView and VelocityStruts. Each of these parts builds on the previous one and has its own JAR distribution.

      GenericTools is the set of classes that provide basic infrastructure for using tools in standard Java SE Velocity projects, as well as a set of tools for use in generic Velocity templates. Perenial favorites here are the DateTool, NumberTool and RenderTool, though there are many others available as well.

      VelocityView includes all of the GenericTools structure and specialized tools for using Velocity in the view layer of web applications (Java EE projects). This includes the VelocityViewServlet or VelocityLayoutServlet for processing Velocity template requests and the VelocityViewTag for embedding Velocity in JSP. Popular tools here are the LinkTool and the ParameterTool.

      VelocityStruts includes both VelocityView and GenericTools and adds tools for use in Struts 1.x applications. These tools match the functions of the key Struts taglibs and provide access to Struts resources, messages, tiles, validation functions and more.

      It is worth noting that these tools, being POJOs (though some require a little configuration) are generally useful and may be used within your java classes or even other template languages, though you may need to instantiate and configure them manually (not difficult) to do so. VelocityTools 2 has been designed with this in mind. Ask on the user mailing list if you have questions about using VelocityTools without Velocity.

      Those already familiar with VelocityTools 1.x may be curious about the goals and motivations behind developing VelocityTools 2. In planning and developing the 2.0 release, there were three main goals:

      • Transparent, on-demand tool instantiation (aka lazy loading for tools) - This allows you to have many tools available (even ones that are expensive to instantiate), but not waste time instantiating or initializing/configuring those you don't use for every request.
      • More accessible, reusable infrastructure - This allows easier access to tools outside of your templates and provides better means to integrate VelocityTools support into other web frameworks or even other view technologies (e.g. VelocityViewTag).
      • Simpler, more flexible toolbox configuration - Now you can configure via a properties file, plain java, or really whatever you want (though perhaps with a bit more work). No XML required anymore; though, if you do use it, it's now a lot better than it was.

      These things could not have been accomplished without rewriting most of the core infrastructure and configuration code. At the same time, we wanted to make it easy for people to upgrade from the 1.x series. This led to the decision to aim for complete backwards compatibility. Granted much has been deprecated and those who directly used or extended the 1.x infrastructure will have to update their code in just a few releases, but for the time being they should be able to use 2.0 in their applications with few problems. Those who merely used the old toolbox.xml format or the old tools directly will be immediately able to take advantage of the new infrastructure without even updating their configuration, though eventually even the old toolbox.xml format may be retired. Don't cry. You'll like the new one better once you get to know it! It can do much more with much less typing.

      All VelocityTools project code is maintained in the Subversion repository which can be reached in a number of ways. The most direct method of accessing the repository is through a web browser, but to effectively work on the code, a Subversion client is required.

      Repository: http://svn.apache.org/viewcvs.cgi/velocity/tools/trunk/

      Feedback about the project, whether positive or gently critical, is always helpful to those working on the project. Such feedback may be sent to either the user@velocity.apache.org or dev@velocity.apache.org mailing lists.

      Another great way to help is to simply participate in conversations on the mailing list. On the user list, you can help answer questions that other users have. This frees the developers to focus on development more than user support. On the dev list, you can participate in design discussions and release votes to help maintain the high quality of the releases and direct the future directions of the project.

      Those interested in furthering the development of this project have an open invitation to jump in and help out. We welcome your contributions! Patches can be sent to the mailing list or attached to a JIRA issue. The Wiki can also be a good place to discuss and develop ideas.

      A few good places to get started include:

      • Documentation (patches for the site or additions to the Wiki)
      • Improving the example apps
      • Working on unresolved tasks in JIRA
      • Contributing to the VelocimacroLibrary

      Other project goals and proposals can be found in the project STATUS file.

      When contributing code, it helps immensely if you follow through with the things on this checklist, especially the coding conventions. Keeping our code style consistent, our codebase stays easy to read and easy to patch. Adding javadoc (and examples therein) simplifies the documentation process and reduces confusion about the purpose of various methods and classes. Tests make sure that things work as expected, especially as development continues down the road. Of course, contributions that don't follow the checklist will be considered and often accepted, but you can expect the project committers to be slower and less enthusiastic in doing so. :)

      Checklist for Code Contributions:

      • Velocity coding conventions
      • Javadoc included (the more detailed the better)
      • Examples included (in JavaDoc or as stand-alone template example)
      • Tests included (not required but GREATLY appreciated)
      velocity-tools-2.0-src/xdocs/project.xml100644 0 0 7042 11360645207 15602 0ustar 0 0 ## PAGE HEADER (LOGOS) ## PRINTER FRIENDLY TITLE #if( $printerFriendly )

      #if( $subtitle )$subtitle - #end#if( $pagetitle )$pagetitle#end


      #end ## BREADCRUMB LINKS #if( !$printerFriendly ) #end #if( !$printerFriendly )
      #end
      $context.applyTemplates("body/section")


      #end #* * Process a menu for the navigation bar *# #match( "group" ) #if ($attrib.href)
      $attrib.name
      #else
      $attrib.name
      #end
        $context.applyTemplates()
      #end #* * Process a submenu for the navigation bar *# #match( "subGroup" ) #if ($attrib.href)
    • $attrib.name #else
    • $attrib.name #end
        $context.applyTemplates("item")
    • #end #* * Process a menu item for the navigation bar *# #match( "item" ) #if ($attrib.href)
    • $attrib.name
    • #else
    • $attrib.name
    • #end #end #* * Insert a link to a printerfriendly version of the document *# #match( "printerversion" ) #set( $filename = $context.getAppValue('infilename') ) #set( $filename = $filename.substring(0, $filename.lastIndexOf('.')) ) #end #* * process a documentation section *# #match( "section" )
      ##

      $attrib.name

      $context.applyTemplates("*")
      #end #* * process a documentation subsection *# #match( "subsection" )
      ##

      $attrib.name

      $context.applyTemplates("*")
      #end #* * process a TODO note *# #match( "todo" )

      This is unfinished. You can help fix that!
      #set( $todo = "$!node.copy()" ) #if( $todo != '' ) TODO: $todo #end

      #end #* * process a 'sourcecode' block. *# #match( "sourcecode" )
      $node.copy()
      #end #match("table") $context.applyTemplates("*")
      #end #match("tr") $context.applyTemplates("*") #end #match( "td" ) $node.copy( $node.children() ) #end #match( "th" ) $node.copy( $node.children() ) #end #* * process a javadoc element *# #match( 'javadoc' )## #if( $attrib.package ) #set( $package = $attrib.package ) #if( !$package.startsWith('org.apache.velocity.tools') ) #set( $package = "org.apache.velocity.tools.$package" ) #end #else #set( $package = 'org.apache.velocity.tools' ) #end #set( $href = "javadoc/$package.replace('.','/')/${attrib.name}.html" ) #set( $content = "$!node.value()" ) #if( $content == '' ) #if( $attrib.full ) #set( $content = $package + '.' + $attrib.name ) #else #set( $content = $attrib.name ) #end #end## $content## #end #* * macro to navigate document and replace tags *# #macro( digFor $name $tag ) #set( $kids = $tag.children() ) #if( "$!tag.name()" == $name ) $context.applyTemplates($tag) #elseif( $kids.isEmpty() ) $tag.copy() #elseif( $tag.selectNodes("$name|*//$name").isEmpty() ) $tag.copy() #else <$tag.name()#foreach( $key in $attrib.keySet() ) $key="$!attrib.get($key)"#end> #foreach( $kid in $kids ) #digFor( $name $kid ) #end #end #end #match("*") #digFor( 'javadoc' $node ) #end velocity-tools-2.0-src/xdocs/standalone.xml100644 0 0 5555 11030275237 16267 0ustar 0 0 Standalone Use xdocs/project.xml

      There's nothing particularly special about the tools in VelocityTools 2. No special interfaces, most don't ''need'' any configuration or API access, and those that do are now relatively easy to handle (compared to VelocityTools 1.x). So, if you need a tool, just create an instance, do any configuration you want or need and go. Nothing else to it.

      However, if you want to externalize your configuration or have your tools created and configured for you on demand and you are not working in a servlet environment, then we have created a simple ToolManager that you can use. It's relatively simple. Just create a ToolManager (can be created with or without default tools available), configure it (if you want to), ask it to create a context for you, and use the context as you would any other. Of course, there's more to it, but this should get you started:

      ToolManager manager = new ToolManager(); manager.configure("/path/to/my/configuration.xml"); Context context = manager.createContext(); myVelocityEngine.evaluate(context, myOutputWriter, "This is a $text.test", "Test template");

      Of course, if you are going to be working in a servlet environment and don't want to create and configure tools yourself, then you should being using VelocityView either directly or through the servlets or JSP tag provided for you.

      velocity-tools-2.0-src/xdocs/struts.project.xml100644 0 0 4452 11030275237 17143 0ustar 0 0 VelocityStruts velocity-tools-2.0-src/xdocs/struts.userguide.xml100644 0 0 54521 11030275237 17513 0ustar 0 0 User Guide Gabriel Sidler xdocs/project.xml xdocs/struts.project.xml

      This guide explains how to setup and configure a VelocityViewServlet which can render the views of a Struts-based web application. The servlet will create a VelocityEngine to render *.vm (velocity template) files using contextual information provided by a Struts Controller action.

      A set of built-in tools have been created which provide the same functions as the Struts JSP Tag libraries for Tiles, Validator, forms, links, messages, and errors.

      The distribution contains examples which demonstrate the use of the built-in Struts tools. The examples are packaged into a web archive file (velstruts.war).

      This document is not a general introduction to the Velocity template language and its syntax. If you are new to Velocity, please consult Getting Started with Velocity.

      Table of Contents

      1. Background
      2. Model 2 Architecture
      3. Installation
      4. Rendering the View
        1. Velocity Template Language
        2. Exposing Data
        3. Access to Servlet Resources
        4. Access to Struts Framework Resources

      The documentation will explain the steps necessary to integrate Velocity with Struts 1.x applications. It is expected that the reader already has a basic understanding of those projects.

      To start working with Velocity and Struts we recommend reading the user guide, installing and browsing the example applications and reference documentation, then installing the VelocityStruts view layer into your own application.

      If this documentation does not answer all your questions, please post questions to the Velocity-User mailing list and we'll be happy to help! (And we'll update this doc!)


      In the JSP world, the terms Model 1 architectures and Model 2 architectures were coined to refer to particular ways of designing and building web applications. It is important that you understand the fundamental difference between these two architectural approaches. JSP can be used in applications designed after Model 1 architectures as well as Model 2 architectures. Velocity cannot. It has been designed very consciouly as a view technology for web application architectures based on Model 2.

      Model 1 Architectures

      In a Model 1 architecture, the JSP page alone is responsible for processing the incoming request and replying back to the client. Using MVC speak, the controller and the view are implemented within the same JSP page. Model 1 architecture are suitable only for very simple application scenarios. In medium size to large projects, the lack of a separation between business logic and view oftentimes leads to difficulties in separating the web designer's works from the server developer's work and causes project management headaches.

      Model 2 Architectures

      In a Model 2 architecture, the control component, including business logic, data access and request handling, are strictly separated from the view component. The view does not contain any processing logic. It is simply responsible for displaying the data that resulted from processing the request. This may be a static page or more often a dynamic page. Such an approach typically facilitates are clear delineation of the roles and responsibilities of the developers and the web designers. The more complex an application, the greater the benefits of using a Model 2 architecture will be.

      The paper Understanding JavaServer Pages Model 2 Architecture provides a more in-depth discussion of Model 1 and Model 2 architectures.

      What does this mean?

      The Struts framework can support both architectures, but all the facilities it provides are really aimed at making the construction of Model 2 applications easy. Velocity on the other hand cannot be used to build Model 1 architectures. It lacks the libraries to support such a design. I am emphasizing this here because I want to make sure that you have all the relevant facts before you decide on Velocity for your projects. This is especially important for people considering to port existing application built on the Model 1 approach or a mixed Model 1 / Model 2 approach. The good news is, that today for any serious application Model 2 is state of the art and Velocity will support you very well on that route.


      This section explains the basic setup to configure the VelocityViewServlet to render the web application views in Struts applications.

      Setup is almost identical to the standard VelocityViewServlet installation, please review that for more details. The extended VelocityLayoutServlet, or any custom extension, can also be used with Struts. (That particular servlet adds the ability to reuse shared html layout across multiple pages.)

      Steps by step:

      1. velocity-tools-x.x.jar which contains the VelocityStruts and VelocityView classes must be added to the WEB-INF/lib directory.
      2. VelocityViewServlet needs to be installed into the servlet container (web.xml) so it can handle all request for *.vm files.
      3. velocity.properties configuration file must be added
      4. toolbox.xml file must be added, and mappings must be setup for the standard tools which expose the Struts objects to the template. (sample toolbox.xml file below)

      And that's all there is to it!

      At this point, it should be possible to change a Struts ActionMapping to 'forward' to a *.vm file placed in the webapp root directory and have it be displayed!

      toolbox.xml

      <?xml version="1.0"?> <toolbox> <tool> <key>link</key> <scope>request</scope> <class>org.apache.velocity.tools.struts.StrutsLinkTool</class> </tool> <tool> <key>msg</key> <scope>request</scope> <class>org.apache.velocity.tools.struts.MessageTool</class> </tool> <tool> <key>errors</key> <scope>request</scope> <class>org.apache.velocity.tools.struts.ErrorsTool</class> </tool> <tool> <key>form</key> <scope>request</scope> <class>org.apache.velocity.tools.struts.FormTool</class> </tool> <tool> <key>tiles</key> <scope>request</scope> <class>org.apache.velocity.tools.struts.TilesTool</class> </tool> <tool> <key>validator</key> <scope>request</scope> <class>org.apache.velocity.tools.struts.ValidatorTool</class> </tool> </toolbox>

      This section introduces you to the key concepts of rendering the view with Velocity in a Struts application.

      Velocity is a template engine implemented in Java. Velocity templates typically are HTML pages with embedded scripts (although Velocity has been used for many other application scenarios). Scripts are written in the Velocity Template Language (VTL). Following is a simple example of a HTML view with embedded VTL statements:

      <HTML> <BODY> <h2>Order Confirmation</h2> <h3>Delivery Adress:</h3><br> Name: $customer.name<br> Street: $customer.street<br> City: $customer.zip $customer.city <h3>Ordered Items</h3><br> <table> #foreach( $item in $order.items ) <tr> <td>$item.quantity</td> <td>$item.description</td> </tr> #end </table> </body> </html>

      When processed this will produce output similar to the following.

      <HTML> <BODY> <h2>Order Confirmation</h2> <h3>Delivery Address:</h3><br> Name: Peter Pan<br> Street: Crain St. 10<br> City: 60201 Evanston IL <h3>Ordered Items</h3><br> <table> <tr> <td>1</td> <td>Hair Dryer, Philips, 1000W, white</td> </tr> <tr> <td>1</td> <td>Kitchen Mixer, Betty Bossy, 240W, black</td> </tr> </table> </body> </html>

      VTL has been designed from the ground up as a simple template language for view designers. With less than ten supported directives it is easy to learn. In fact, most people are up and productive within less than a day.

      Velocity does not allow Java scriptlets, which helps enforce a strict MVC separation.

      Please consult the following two documents for an in-depth coverage of VTL:


      The main purpose of Velocity in a web application is typically to merge HTML templates with dynamic application data to generate dynamic views. An essential aspect of Velocity is therefore the mechanism that allows the application controller (in MVC speak) to expose data to the template.

      It is important to understand the relationship between a Struts-based application and the Velocity template servlet. Both are simply Java Servlets which perform a specific task.

      Requests to the Struts application are processed, application data is manipulated and eventually all data and control is forwarded to a View layer.

      The Velocity servlet in this case is responsible for merging the provided application data with a template to produce HTML output.

      We should note that the Velocity servlet is not exclusively tied to the Struts application. It can serve requests from web clients directly or any other servlet application as well. Technically, the Struts application hands over a request to Velocity through the forward method of javax.servlet.RequestDispatcher.

      Application data is passed from the Struts servlet to the Velocity servlet as attributes of either the servlet request, session or context.

      Therefore a developer simply needs to set an attribute to pass data to the View layer and make that data available for the template. For example:

      request.setAttribute("Customer", CustomerObj); Whatever public methods are available on the CustomerObj instance will be made available to the template designer. Assuming there is a public getName() method, they may for example write: $Customer.name or $Customer.getName().

      There is a heirarchy to the objects exposed to the template designer. For instance, if you have set an attribute "foo" in both the session and the request,

      request.setAttribute("foo", "request foo"); session.setAttribute("foo", "session foo");

      then the request attribute will take priority, and using

      $foo

      in the template will give you

      request foo

      Priority is given in the following order:

      1. Tools specified in the toolbox.xml (e.g. $link, $tiles, etc.)
      2. The servlet classes (e.g. $request, $response, $session, $application)
      3. References set locally within the template
      4. Request attributes
      5. Session attributes
      6. Servlet context (application) attributes

      This heirarchy allows the developer to reserve control of key references (for tools and servlet resources) from the template designer and allows for values to be set at various servlet scopes in a manner similar to working with JSP and Struts.


      VelocityStruts automatically populates the context with the following objects of the Servlet API on each template processing request:

      Context Key Class Remarks
      $request javax.servlet.http.HttpServletRequest the current servlet request
      $session javax.servlet.http.HttpSession the current session, if one exists
      $application javax.servlet.ServletContext the servlet context
      $response javax.servlet.http.HttpServletResponse the current servlet response

      The following examples illustrates how servlet resources are accessed from within Velocity template. The example renders the list of HTTP header fields of the current servlet request. In the same way, any public method of the above listed objects can be called from within templates:

      #foreach( $header in $request.HeaderNames ) <b>$header:</b> $request.getHeader($header)<br> #end

      The resulting output is something like this:

      Referer: http://localhost:8080/struts/doc/examples.html Connection: Keep-Alive User-Agent: Mozilla/4.79 [en] (Windows NT 5.0; U) Pragma: no-cache Host: localhost:8080 Accept: image/gif, image/jpeg, image/pjpeg, image/png, */* Accept-Encoding: gzip Accept-Language: en Accept-Charset: iso-8859-1,*,utf-8 Cookie: JSESSIONID=aaaecXd7bnLPAr

      The Struts framework provides resources that are useful to template designers. These include logical names for physical resources, internationalized messages, error handling, form handling, etc. The interesting question is now how template designers can gain access these framework resources. In the JSP world, a set of custom tag libraries provide template designers access to the Struts framework resources. In the Velocity world, the equivalent of the JSP custom tag libraries are view tools. View tools are a very simple concept. They are Java objects with public methods that are put into the Velocity context. Tools are accessed by key and allows template designers to call on their public methods.

      A set of seven view tools is included with VelocityStruts that provide template designers access to Struts framework resources. These seven view tools essentially achieve the integration between Struts and Velocity and they can be considered the core of this project.

      Context Key Class Remarks
      $text MessageTool Provides access to the Struts application resources for internationalized text.
      $errors ErrorsTool Provides methods to check for and output Struts error messages.
      $messages ActionMessagesTool Provides methods to work with Struts action messages.
      $link StrutsLinkTool Provides methods to work with URIs.
      $form FormTool Provides miscellaneous methods to work with forms and form beans in the context of Struts applications.
      $tiles TilesTool Provides miscellaneous methods to work with Tiles in the context of Struts applications.
      $validator ValidatorTool Provides methods to dynamically generate javascript validation in the context of Struts applications.
      Note: The shown keys are the recommended values. They can be changed in the configuration.

      The following example illustrates some of the features of the MessageTool for working with internationalized messages. For the example we assume that the Struts message resources contain the following two key=value pairs:

      title=Struts Example Application test=This string has 4 replacement parameters: {1}, {2}, {3}, {4} foo.bar=whatever

      Then, the following script...

      $text.title $text.get('test', ['bear', 'dog', 'cat']) $text.exists('tutle') $text.foo.bar

      ..will produce this output:

      Struts Example Application This string has 4 replacement parameters: bear, dog, cat, {4} false whatever

      Please see the Tool Reference Documentation for more details about the view tools. Furthermore, the Velocity/Struts example application comes with several working examples that show how these tools are used.



      velocity-tools-2.0-src/xdocs/struts.xml100644 0 0 25760 11030275237 15523 0ustar 0 0 Overview xdocs/project.xml xdocs/struts.project.xml

      The VelocityStruts sub-project integrates Velocity with the Apache Struts web application framework and enables the use of Velocity templates interchangeably with JSP pages for the view layer.

      Various other web application frameworks offer built-in support for Velocity templates. This project provides the minimal glue necessary to give Struts developers an alternative to JSP.

      Diagram 1. Comparison of JSP and Velocity for the view layer in a Struts application.

      As we follow the typical Struts process flow in Diagram 1, notice how there is relatively little change except for the addition of Velocity. The velocity-struts.jar leverages a standalone Velocity servlet to process template files (specifically, the jar file is velocity-tools-x.x.jar) and uses some drop-in tools to provide transparent access to Struts specific objects (ex. message resources, form beans, errors, links). The action mapping file will simply contain ActionForwards that send control to a Velocity-based View layer instead of sending to a JSP.

      Also notable is that Velocity and JSP are not mutually exclusive. Both technologies can be used in the same application without any problems. This allows developers the option of trying Velocity without heavy modification to existing applications.

      We're convinced that once you give Velocity a try, you'll really like it.

      VelocityStruts includes both the GenericTools and VelocityView and adds tools for use in Struts 1.x applications. These tools match the functions of the key Struts taglibs and provide access to Struts resources, messages, tiles, validation functions and more.

      The default configuration provided for VelocityStruts is here and here and here.

      The dependencies required for VelocityStruts can be found on our dependencies chart.

      These are in addition to tools provided by GenericTools and VelocityView.

      • - For accessing/displaying Struts action messages.
      • ErrorsTool - For accessing/displaying Struts error messages.
      • - For working with HTML forms in Struts apps.
      • - Abstract view tool that provides access to Struts message resources.
      • - Provides methods to render Struts application resources (for i18n and other textual content access).
      • - For using Struts SSL Extensions. It has the same interface as and can function as a substitute if Struts 1.x and SSL Ext are installed.
      • - Subclass of for creating URI links in Struts by adding support for Struts actions and forwards.
      • - For using Struts-Tiles (not for Tiles 2!) in Velocity.
      • - Uses Struts-Validator to produce client side javascript validation for your forms.

      A Struts application example has been included to demonstrate the use of the VelocityViewServlet with the automatically loaded VelocityStruts tools.

      To run the examples you need Tomcat 4+ or a compatible servlet runner.

      The 'ant examples' target of the build process automatically generates a ready-to-deploy struts.war archive file located in the examples subdirectory of the distribution. Deploy (i.e. copy) one or both of these war files to the webapps directory of your servlet runner and restart. Now point a web browser at the following url:

      http://<your_server>:<port>/struts/

      VelocityStruts is also distributed with a couple other examples that use VelocityTools without the Struts 1 tools.

      There are many different reasons why people are choosing Velocity technology for the view layer. Here are some:

      • Velocity helps enforce a clean separation between the view layer and the model/control layers. This leads to clean application design and a clear separation of concerns between View Designers and back-end Developers.
      • Velocity Template Language (VTL) has few directives and is simple and easy to learn. Most people report being productive within a day.
      • Velocity is easy to extend with Tools which are simply any class which has public methods. These are typically much cleaner and easier to develop than JSP custom tag libraries.
      • Using the TilesTool it is easy to mix Velocity and JSP tiles in the same page/layout. For those using Tiles, this makes gradual migration between or integration of the two view technologies trivially easy!
      • Velocity 'macros' are a powerful tool for the View Designer. They enable the creation of reusable snippets of markup, often eliminating what would have been a need to develop a custom tag library or other server-side tool.
      • Velocity templates are not limited to HTML and can be used to produce any type of text output including XML, SQL, ASCII, PostScript, etc.
      • Velocity enables easy access to dynamic data that Web Designers can understand.
      • Velocity being interpreted, enables a simple development cycle where template errors can quickly be localized and debugged.
      • Velocity, which caches templates for speed, has been reported to have performance comparable or better than JSP.
      • Velocity is supported by an active and helpful community of users and developers.

      Comments from folks who are using Struts and Velocity:

      "We've been using Struts/Velocity for some time now and we find it to be an extremely well matched combination. One of the main advantages of Velocity is that the syntax is incredibly easy. I can explain it to a designer who has never seen it before and expect them to be useful within an hour."

      "One of the nicest things it enforces is the separation of presentation layer and business logic. It removes the desire to 'fix' problems by just putting a small change into the JSP via scriptlets. It also makes the code a lot more readable which also reduces the development time."

      "Struts is a solid framework and Velocity makes it even better."

      "I find that the VelocityTools for Struts works as well, or better, with Struts than another other presentation technology, bar none. In fact, most of the tools work just as well with any other framework you might care to name." --Ted Husted (author of Struts in Action)

      This software is licensed under the Apache Software License 2.0

      velocity-tools-2.0-src/xdocs/summary.xml100644 0 0 245501 11360645207 15675 0ustar 0 0 Summary xdocs/project.xml

      You will find here a summary of all the available standard tools, sufficient for a basic integration and usage of each of them. Please refer to the javadoc for a complete reference of all their methods and properties, since only an excerpt is show here.

      Generic Tools

      AlternatorTool, ClassTool, ComparisonDateTool, ContextTool, ConversionTool, DisplayTool, EscapeTool, FieldTool, LinkTool, MathTool, NumberTool, RenderTool, ResourceTool, SortTool, XmlTool

      View Tools

      AbstractSearchTool, BrowserTool, CookieTool, ImportTool, IncludeTool, LinkTool, PagerTool, ParameterTool, ViewContextTool

      Struts Tools

      ActionMessagesTool, ErrorsTool, FormTool, MessageResourcesTool, SecureLinkTool, StrutsLinkTool, TilesTool, ValidatorTool

      AlternatorTool tool to create alternators (variables that cycle through an array)
      default key$alternator
      configuration properties autoAlternate boolean, states whether the alternator will automatically switch values at each rendering (defaults to true)
      methods and properties $autoAlternateDefault returns true if alternators created by this tool will auto-alternate by default, or set the property to a new boolean value
      #set( $alt = $alternator.auto(value1,value2,...) ) creates an automatic alternator
      #set( $alt = $alternator.make(value1,value2,...) ) creates an alternator with default auto behaviour
      #set( $alt = $alternator.manual(value1,value2,...) ) creates a manual alternator
      Alternator alternator object created by means of an AlternatorTool
      methods and properties $alt displays current value (and shift for automatic alternators)
      $alt.current displays current value
      $alt.next displays current value and shift
      $alt.shift shifts to next value
      $alt.auto read/write property stating if this is an automatic alternator
      ClassTool tool meant to use Java reflection in templates
      default key$class
      configuration properties inspect string, class name of the class which is to be inspected (defaults to java.lang.Object)
      safeMode boolean, indicates whether to only show public members, fields and constructors (defaults to true)
      showDeprecated boolean, states whether deprecated members, fields and constructors are to be shown (defaults to false)
      methods and properties $class.annotations returns a list of the Annotations of the class being inspected
      $class.constructors returns a list of ConstructorSubs for each constructor declared in the inspected class, with the following methods and read-only properties: $ctor.name, $ctor.parameters (array of Class), $ctor.isVarArgs(), $ctor.modifiers (some were omitted)
      $class.field returns a list of FieldSubs for each field declared in the inspected class, with the following read-only properties: $field.name, $field.modifiers, $field.staticValue, $field.type (some were omitted)
      $class.fullName full name of the inspected cass
      $class.methods returns a list of MethodSubs for each method declared in the inspected class, with the following methods and read-only properties: $method.name, $method.parameters (array of Class), $method.returns, $method.isVarArgs(), $method.modifiers, $method.propertyName (If this method can be treated as a bean property in Velocity, then it will return the "bean property" equivalent of the method name), $method.isVoid() (some were omitted)
      $class.name returns the simple name of the class being inspected
      $class.package returns the package name of the class being inspected
      $class.showDeprecated returns or sets the current showDeprecated setting
      $class.super returns a new ClassTool instance that inspects the immediate superclass of the class being inspected
      $class.type returns the actual Class being inspected
      $class.inspect(class/object/string) returns a new ClassTool instance that inspects the specified class or object
      $class.abstract returns true if the class being inspected is abstract
      $class.deprecated returns true if the class being inspected is deprecated
      $class.final returns true if the class being inspected is final
      $class.interface returns true if the class being inspected is an interface
      $class.supportsNewInstance() returns true if a new instance of the class being inspected can be created via $class.type.newInstance()
      ComparisonDateTool tool used to format, parse and compare dates
      default key $date
      configuration properties format default format (see formatting pattens)
      locale default locale
      timezone time zone
      methods and properties $date returns the current date and time formatted with the default format
      $date.format( [ format, ] object [ , locale [ , timezone ] ] ) formats the specified object
      $date.get( format ) returns the current date and time formatted using hte given format
      $date.get( date style, time style ) returns the current date and time formatted using given styles, where each style is one of full, long, medium, short, default
      $date.day current day in month
      $date.month current month (warning: zero-based!)
      $date.year current year
      $date.getDay( object ) day of month of given date
      $date.getMonth( object ) month of given date (warning: zero-based!)
      $date.getYear( object ) year of given date
      $date.format returns or sets the pattern or style to be used for formatting dates when none is specified
      $date.locale returns or sets the default Locale configured for this instance
      $date.timeZone returns or sets the default TimeZone configured for this instance - $date.timeZone.ID displays the ID of the currently active TimeZone
      $date.systemDate gets the Date at the time this page was rendered for the system running this application
      $date.toCalendar( object ) converts the given object to a java.util.Calendar
      $date.toDate( object ) convers the given object to a java.util.Date
      $date.whenIs( object ) returns a ComparisonDateTool.Comparison between current and specified date ; returned comparison will have properties like: $comp.years, $comp.months, $comp.weeks, $comp.days, $comp.hours, $comp.minutes, $comp.seconds, $comp.milliseconds, along with several other formatting methods
      $date.whenIs( object, object ) returns a ComparisonDateTool.Comparison between the two specified dates ; returned comparison will have properties like: $comp.years, $comp.months, $comp.weeks, $comp.days, $comp.hours, $comp.minutes, $comp.seconds, $comp.milliseconds, along with several other formatting methods
      ContextTool tool allowing Velocity context introspection
      default key $context
      methods and properties $context.contains( key ) returns true if the context contains a non-null value for the specified key
      $context.keys returns a java.util.Set of the keys available in the current request context
      $context.this returns the ViewContext currently being analyzed by this tool
      $context.toolbox returns a java.util.Map of all the tools available in the current request context and their context keys
      $context.values returns a java.util.Set of the values available in the current request context
      $context.get( key ) returns the value for the specified key in the current request context
      ConversionTool tool allowing conversions between datatypes
      default key $convert
      configuration properties stringsDelimiter delimiter used when parsing concatenated strings arrays (defaults to ',')
      trimStrings boolean, states whether or not trim strings when parsing concatenated strings arrays (defaults to true)
      numberFormat number format to use when parsing numbers
      dateFormat date format to use when parsing dates
      methods and properties $convert.stringsDelimiter delimiter used when parsing concatenated strings arrays
      $convert.stringsTrim whether or not strings are trimmed when parsing concatenated strings arrays
      $convert.dateFormat current date format used when parsing dates
      $convert.numberFormat current number format used when parsing numbers
      $convert.parseDate( string [ , format [ , locale [ , timezone ] ] ] ) parses a date
      $convert.parseNumber( string [ , format [ , locale ] ] ) parses a number
      $convert.toType( object ) converts an object to an instance of Type, where Type can be one of Boolean, Calendar, Date, Double, Integer, Locale, Number, String
      $convert.toTypes( object ) converts an array, Collection, delimited String, or object to an array of Types, where Type can be one of Boolean, Calendar, Date, Double, Integer, Locale, Number, String
      DisplayTool tool providing a variety of methods for controlling the output displayed by various references in your templates
      default key $display
      configuration properties listDelim default delimiter used between items by the list formatting methods (defaults to ',')
      listFinalDelim default delimiter used between the last two items by the list formatting methods (defaults to ' and ')
      truncateLength default length used by truncate(Object) (defaults to 30)
      truncateSuffix> default suffix used by the truncate methods (defaults to '...')
      truncateAtWord boolean, whether to truncate at a precise character or the last fitting word (defaults to false
      cellLength cell size
      cellSuffix suffix used when cell contents need truncating
      defaultAlternate alternate used by alt(Object) (defaults to 'null')
      allowedTags tags allowed to remain by stripTags(Object) (none by defaults)
      locale used locale
      methods and properties $display.listDelimiter returns or sets the configured default delimiter used between items by the list formatting methods
      $display.listFinalDelimiter returns or sets the configured default delimiter used between the last two items by the list formatting methods
      $display.truncateLength returns or sets the configured default length used by truncate(Object)
      $display.truncateSuffix returns or sets the default suffix used by the truncate methods
      $display.truncateAtWord returns or sets whether or not to truncate at a precise character or the last fitting word
      $display.cellLength returns or sets configured cell length
      $display.cellSuffix returns or sets the suffix used when cell contents need truncating
      $display.defaultAlternate returns or sets the configured default alternate used by alt(Object)
      $display.allowedTags returns or sets the configured tags allowed to remain by stripTags(Object)
      $display.alt( object [ , object ] ) returns the configured default value (or the second argument if specified) if the specified first value is null
      $display.br( object ) inserts HTML line break tag (
      ) in front of all newline characters of the string value of the specified object and returns the resulting string
      $display.capitalize( object ) changes the first character of the string value of the specified object to upper case and returns the resulting string
      $display( object [ , suffix ] [ , length ] truncates or pads the string value of the specified object as necessary to ensure that the returned string's length equals the default or specified cell size, using the default suffix or the specified one when truncation is needed
      $display.list( object [ , delim [ , finalDelim ] ] ) Formats a collection or array into a string, using the default or provided delimiter and final delimiter
      $display.measure( object ) returns the measurements of the string value of the specified object
      $display.message( string, object...) uses java.text.MessageFormat to format the specified string with the specified arguments. If there are no arguments, then the string is returned directly
      $display.plural( count, singular [ , plural ] ) based on count, returns singular or build/specified plural
      $display.printf( format, object... ) uses String.format(Locale,String,Object...) to format the specified String with the specified arguments. Please note that the format required here is quite different from that of message(String,Object...)
      $display.space( int ) returns a string of spaces of the specified length
      $display.stripTags( object [ , allowedTags ] ) removes all not allowed HTML tags from the string value of the specified object and returns the resulting string
      $display.truncate( object [ , size ] [ , suffix ] ) limits the string output of the first argument to the specified or default number of characters. If the string gets curtailed, the specified or default suffix is used as the ending of the truncated string
      $display.uncapitalize( object ) changes the first character of the string value of the specified object to lower case and returns the resulting string
      EscapeTool tool providing some escaping facilities
      default key $esc
      methods and properties $esc.b , $esc.backslash renders a backslash (\)
      $esc.d , $esc.dollar renders a dollar sign ($)
      $esc.e , $esc.exclamation renders an exclamation mark (!)
      $esc.h , $esc.hash renders a hash (#)
      $esc.q , $esc.quote renders a double quotation mark (")
      $esc.s , $esc.singleQuote renders a single quotation mark (')
      $esc.html( string ) escapes the characters in a string using HTML entities
      $esc.url( string ) escapes the characters in a string using UTF-8 URL character encoding
      $esc.java( string ) escapes the characters in a String using Java String rules
      $esc.javascript( string ) escapes the characters in a String using JavaScript String rules
      $esc.sql( string ) escapes the characters in a String to be suitable to pass to an SQL query
      $esc.xml( string ) escapes the characters in a String using XML entities
      $esc.propertyKey( string ) escapes the characters in a String using java.util.Properties rules for escaping keys
      $esc.propertyValue( string ) escapes the characters in a String using java.util.Properties rules for escaping values
      FieldTool tool allowing easy access to public static fields in classes, such as string constants
      default key $field
      methods and properties $field.get( string ) returns the value of the field with the specified name, if found
      $fields.in( class/object/string ) loads all public static fields in the specified class or object
      LinkTool tool used to format hyperlinks ; this tool is somewhat unusual in that every method that takes parameters will return a new instance of the tool that is a copy of the one the method was called upon, with the additional change specified by the method call, allowing for chained calls like href="$link.relative('foobar.html').param('id','25').anchor('section4')" (which would produce href="foobar.html?id=25#section4")
      default key $link
      configuration properties uri sets the default scheme, user info, host, port, path, query, and anchor elements all at once
      scheme sets the default scheme (http, https, mailto, ...)
      info sets the default user info
      host sets the default host
      port sets the default port
      requestPath sets the default path
      params sets the defaut query parameters
      anchor sets the defaut anchor
      charset sets the defaut charset
      xhtml if true, uses &amp; as query delimiter (this is the default), otherwise uses &
      appendParameters sets whether or not the #setParam() method will override existing query values for the same key or simply append the new value to a list of existing values (this is the default)
      forceRelative sets whether or not the #createURI() method should ignore the scheme, user, port and host values for non-opaque URIs, thus making #toString print the link as a relative one, not an absolute one ; NOTE: using #absolute() or #relative() will alter this setting accordingly on the new instances they return
      methods and properties $link.anchor returns the anchor set for the $link
      $link.path returns the path currently set for this $link
      $link.params returns the query data set for this $link
      $link.contextURI returns the URI that addresses this web application, e.g. http://myserver.net/myapp ; this string may not end with a "/"
      $link.contextPath returns the context path that addresses this web application, e.g. /myapp ; this string starts with a "/" but does not end with a "/"
      $link.requestPath retrieves the path for the current request regardless of whether this is a direct request or an include by the RequestDispatcher
      $link.baseRef returns the full URI of this template without any query data. e.g. http://myserver.net/myapp/stuff/View.vm
      $link.self this method returns a new self-referencing $link for the current request (e.g. /myapp/stuff/View.vm) ; however, the behavior can be changed via toolbox configuration to use absolute URIs and/or add the current request parameters
      $link.anchor( string ) returns a new $link with the addition of the specified anchor value
      $link.path( string ) returns a new $link with the addition of the specified path value
      $link.relative( string ) returns a new $link with the addition of the specified relative value
      $link.absolute( string ) returns a new $link with the addition of the specified absolute value
      $link.params( key, value ) returns a new $link with the addition of the specified parameter
      $link.encode( string ) performs URL encoding on the specified text
      MathTool tool providing math functions
      default key $math
      methods and properties $math.add( object, object ) returns the sum of the numbers or null if they are invalid
      $math.sub( object, object ) returns the difference of the numbers or null if they are invalid
      $math.mul( object, object ) returns the product of the numbers or null if they are invalid
      $math.div( object, object ) returns the quotient of the numbers or null if they are invalid
      $math.pow( object, object ) returns the first number raised to the power of the second or null if they are invalid
      $math.idiv( object, object ) returns the integer division of the numbers or null if they are invalid
      $math.mod( object, object ) returns the integer molulus operation on the numbers or null if they are invalid
      $math.max( object, object ) returns the largest of the numbers or null if they are invalid
      $math.min( object, object ) returns the smallest of the numbers or null if they are invalid
      $math.abs( object ) returns the absolute value of the number or null if it is invalid
      $math.ceil( object ) returns the smallest integer that is not less than the given number or null if it is invalid
      $math.floor( object ) returns the integer portion of the given number or null if it is invalid
      $math.round( object ) returns the given number rounded to the nearest whole Integer or null if it is invalid
      $math.roundTo( object, decimals ) rounds a number to the specified number of decimal places
      $math.random returns a pseudo-random Double greater than or equal to 0.0 and less than 1.0
      $math.random( lower, upper ) this returns a random Number within the specified range - the returned value will be greater than or equal to the first number and less than the second number - if both arguments are whole numbers then the returned number will also be, otherwise a double will be returned
      $math.toInteger( object ) converts an object with a numeric value into an Integer ; valid formats are Number or a string representation of a number
      $math.toDouble( object ) converts an object with a numeric value into a Double ; valid formats are Number or a string representation of a number
      $math.toNumber( object ) converts an object with a numeric value into a Number ; valid formats are Number or a string representation of a number
      NumberTool tool used to format numbers
      default key $number
      configuration properties format default number format (depends upon the default locale, '#0.0' for en_US locale)
      locale default locale
      methods and properties $number.format returns or sets the pattern or style to be used for formatting numbers when none is specified
      $number.locale returns or sets the default locale
      $number.format( [ format/style, ] object [ , locale ] ) formats the given number using the default or specified format or style, and the default or provided locale ; style is one of currency, integer, number, percent
      $number.currency( object ) convenience method equivalent to $number.format("currency", $foo)
      $number.integer( object ) convenience method equivalent to $number.format("integer", $foo)
      $number.number( object ) convenience method equivalent to $number.format("number", $foo)
      $number.percent( object ) convenience method equivalent to $number.format("percent", $foo)
      RenderTool tool that exposes methods to evaluate the given strings as VTL (Velocity Template Language) using either a pre-configured context or one you provide directly
      default key $render
      configuration properties parse.depth default depth for recursive evaluation (default: 20)
      catch.exceptions whether to catch exceptions during rendering (defaults to true
      forceThreadSafe whether to force a thread-safe evaluation (defaults to true)
      methods and properties $render.eval( string ) evaluates a String containing VTL using the current context, and returns the result as a String
      $reder.recurse( string ) recursively evaluates a String containing VTL using the current context, and returns the result as a String
      ResourceTool tool for accessing ResourceBundles and formatting messages therein ; most methods return a new object that has mostly the same methods as the original, allowing you to build up parameters elegantly and simply, rather than try to remember how to use methods with many parameters that must be in a specific order: so, you can access a resource with the key 'hello.whoever' in the 'otherStuff' bundle with one message argument like this: $text.hello.whoever.bundle('otherStuff').insert('World') instead of like this: $text.get('hello.whoever','otherStuff', $null, 'World')
      default key $text
      configuration properties defaultBundle default bundle
      bundles coma-separated list of bundles (the first one being used as the default)
      locale current locale
      defaultLocale default locale
      methods and properties $text.key returns the resource with the specified name, if it exists
      $text.prefix.keys returns a list of the available keys starting with the given prefix
      $text.key.bundle( bundle ) returns the resource with the specified name in the specified bundle, if it exists
      $text.key.locale( locale ) returns a new $text that will try to find the resource with the specified name for the specified locale
      $text.key.insert( value [ , value ... ] ) Returns the named resource with the specified values inserted
      $text.locale returns or sets the current locale
      SortTool tool used to sort collections
      default key $sorter
      methods and properties $sorter.sort( collection [ , property / property list ] ) sorts the values of the specified Collection, Map, or array of Objects, either by their natural order or according to the values returned by the specified property or list of properties
      XmlTool tool used for reading/navigating XML files; this uses dom4j under the covers to provide complete XPath support for traversing XML files
      default key $xml
      configuration properties file target XML file
      methods and properties $xml.attr( string ) returns the value of the specified attribute for the first/sole Node in the internal Node list for this instance, if that Node is an Element; if it is a non-Element node type or there is no value for that attribute in this element, then this will return null
      $xml.attributes() returns a Map of all attributes for the first/sole Node held internally by this instance; if that Node is not an Element, this will return null
      $xml.children() returns a new XmlTool instance that wraps all the child Elements of all the current internally held nodes that are Elements themselves
      $xml.find( xpath ) performs an XPath selection on the current set of Nodes held by this instance and returns a new instance that wraps those results; if the specified value is null or this instance does not currently hold any nodes, then this will return null; if the specified value, when converted to a string, does not contain a '/' character, then it has "//" prepended to it; this means that a call to $xml.find("a") is equivalent to calling $xml.find("//a"); the full range of XPath selectors is supported here
      $xml.first returns a new instance that wraps only the first Node from this instance's internal Node list
      $xml.last returns a new instance that wraps only the last Node from this instance's internal Node list
      $xml.name asks get(Object) for "name"; if none, this will return the result of getNodeName()
      $xml.nodeName returns the name of the root node; if the internal Node list has more than one Node, it will only return the name of the first node in the list
      $xml.parent returns a new XmlTool instance that wraps the parent Element of the first/sole Node being wrapped by this instance
      $xml.path returns the XPath that identifies the first/sole Node represented by this instance
      $xml.text returns the concatenated text content of all the internally held nodes; obviously, this is most useful when only one node is held
      $xml.get( number ) returns a new instance that wraps the specified Node from this instance's internal Node list
      $xml.name, $xml.get( string ) this will first attempt to find an attribute with the specified name and return its value; if no such attribute exists or its value is null, this will attempt to convert the given value to a Number and get the result of get(Number); if the number conversion fails, then this will convert the object to a string; if that string does not start contain a '/', it appends the result of getPath() and a '/' to the front of it; finally, it delegates the string to the find(String) method and returns the result of that
      $xml.empty returns true if there are no Nodes internally held by this instance
      $xml.iterator() returns an Iterator that returns new XmlTool instances for each Node held internally by this instance; this allows VTL like #foreach($node in $xml)...#end
      $xml.node() returns the first/sole Node from this instance's internal Node list, if any
      $xml.parents() returns a new XmlTool instance that wraps the parent Elements of each of the Nodes being wrapped by this instance; this does not return all ancestors, just the immediate parents
      $xml.parse( string ) accepts XML strings. If the XML is valid, it will return a new XmlTool instance with the XML's root as its internal node
      $xml.read( filename/URL ) returns null if safe mode is on; otherwise this will accept url pointing to an XML document; it will then parse that document and return a new instance with that document's root element as its node
      $xml.size() returns the number of Nodes internally held by this instance
      $xml.toString() if this instance has no XML Nodes, then this returns the result of super.toString(); otherwise, it returns the XML (as a string) of all the internally held nodes that are not Attributes; for attributes, only the value is used

      AbstractSearchTool this tool is meant to be extended by a class defining the protected List executeQuery(Object crit) Java method; it allows doing "searching" and robust pagination of search results; the goal here is to provide a simple and uniform API for "search tools" that can be used in velocity templates (or even a standard Search.vm template); in particular, this class provides good support for result pagination and some very simple result caching
      default key $search
      scope request scope
      methods and properties all methods and properties from the PagerTool are inherited
      $search.criteria returns or sets the current search criteria
      BrowserTool browser-sniffing tool; it defines properties that are used to test the client browser, operating system, device, language... apart from properties related to browser version and language, all properties are booleans.
      default key $browser
      scope request or session scope, session scope advised (and enabled by default)
      configuration properties languagesFilter an optional coma-separated list of admissible languages in the webapp
      methods and properties $browser.languageFilter returns or sets the current languages filter
      $browser.version returns browser version
      $browser.majorVersion returns browser major version
      $browser.minorVersion returns browser minor version
      $browser.geckoVersion version of te Gecko rendering engine for browsers belonging to the Mozilla family
      $browser.browser tests for the specified browser, among: mosaic netscape nav2 nav3 nav4 nav4up nav45 nav45up nav6 nav6up navgold firefox safari ie ie3 ie4 ie4up ie5 ie5up ie55 ie55up ie6 ie6up ie7 ie7up ie8 ie8up opera opera3 opera4 opera5 opera6 opera7 opera8 opera9 lynx links w3m aol aol3 aol4 aol5 aol6 neoplanet neoplanet2 amaya icab avantgo emacs mozilla gecko webtv staroffice java hotjava httpclient lobo lotusnotes konqueror galeon kmeleon chrome
      $browser.OS tests for the specified operating system, among: win16 win3x win31 win95 win98 winnt windows win32 winme win2k winxp vista dotnet mac macosx mac68k macppc os2 unix sun sun4 sun5 suni86 irix irix5 irix6 hpux hpux9 hpux10 aix aix1 aix2 aix3 aix4 linux sco unixware mpras reliant dec sinix freebsd bsd vms x11 amiga
      $browser.device tests for the specified handled device, among: palm audrey iopener wap blackberry
      $browser.feature tests for the given feature, among: javascript css css1 css2 dom0 dom1 dom2
      $browser.robot tests for special request is issued by a known robot
      $browser.robot tests for known robots: wget getright yahoo altavista lycos infoseek lwp webcrawler linkexchange slurp google java
      $browser.preferredLanguageTag returns the browser's preferred langage tag (a string like 'en', 'da', 'en-US', ...), optionnaly affected by the languagesFilter configuration property
      $browser.preferredLocale returns the browser's preferred locale
      CookieTool tool used to read and set cookies
      default key $cookies
      scope request
      methods and properties $cookies.add( Cookie ) Adds the cookie to the current servlet response; this does NOT add it to the current request
      $cookies.add( name, value [ , expiry time ] ) adds a new Cookie with the specified name and value to the current servlet response; this does not add a Cookie to the current request
      $cookies.create( name, value [ , expiry time ] ) creates a new Cookie with the specified name and value; this does not add the Cookie to the response, so the created Cookie will not be set unless you do $cookies.add($myCookie)
      $cookies.delete( name ) instructs the browser to remove the specified cookie by setting it with a Max-Age of 0
      $cookies.all returns a list of Cookies for this request
      $cookies.name, $cookies.get( name ) returns the Cookie with the specified name, if it exists
      $cookies.toString() if there are no Cookies in the request, this returns the standard Object.toString output; otherwise, it returns a pretty printed list of cookie names and values
      ImportTool general-purpose text-importing view tool for templates
      default key $import
      scope request
      methods and properties $import.read( url ) returns the content read from the specified URL
      IncludeTool tool allowing for transparent content negotiation in a manner mimicking Apache httpd's MultiViews; reads the default language out of the ViewToolContext as org.apache.velocity.tools.view.i18n.defaultLanguage; please note that it does NOT do the actual #include or #parse for you, but is merely to aid in include content negotiation
      default key $include
      scope request or session scope
      configuration properties org.apache.velocity.tools.view.i18n.defaultLanguage this property is not searched directly in the provided tool's properties, but looked first at the Velocity context, then the servlet context, then lastly at the JVM default; this "narrow scope to wide scope" pattern makes it easy to setup language overrides at different levels within your application
      methods and properties $include.exists( name [ , locale ] ) checks whether or not a resource is available with the specified name and, if provided, specified language suffix
      $include.find( name [ , locale / language code ] ) returns the localized name for the specified resource, with the specified Locales language suffix if specified; if one for that language is unavailable, then it will "widen" the language until one is found; if none is found at all, the name parameter is returned
      LinkTool tool used to format hyperlinks ; this tool is somewhat unusual in that every method that takes parameters will return a new instance of the tool that is a copy of the one the method was called upon, with the additional change specified by the method call, allowing for chained calls like href="$link.relative('foobar.html').param('id','25').anchor('section4')" (which would produce href="foobar.html?id=25#section4")
      default key $link
      scope request
      configuration properties includeRequestParams controls whether or not this tool starts off with all parameters from the last request automatically; default is false
      methods and properties all methods and properties from the generic LinkTool are inherited
      $link.includeRequestParams returns or sets the includeRequestParams flag
      $link.requestPath returns the path for the current request, regardless of whether this is a direct request or an include by the RequestDispatcher
      $link.addRequestParams( [ amongThisOne [ , andThisOne ... ] ] ) Adds the specified parameters (if they exist) from the current request to the query data of a copy of this instance; if no parameters are specified, then all of the current request's parameters will be added
      $link.addRequestParamsExcept( [ exceptThisOne [ , andThisOne ... ] ] ) Adds all of the current request's parameters to this link's query data except for those whose keys match any of the specified strings
      $link.addMissingRequestParams( [ exceptThisOne [ , andThisOne ... ] ] ) adds all of the current request's parameters to this link's query data except for those whose keys match any of the specified strings or already have a value set for them in the current instance
      PagerTool tool for doing request-based pagination of items in an a list
      default key $pager
      scope request
      configuration properties newItemsKey key name used to search for items in request attributes
      indexKey key name used to search for current page index in request attributes
      itemsPerPageKey key name used to search for the number of items to be shown per page in request attributes
      slipSizeKey key name used to search for the max number of page indices to show in request attributes
      itemsPerPage number of items per page (defaults to 10)
      slipsize maximum number of page indices to show (defaults to 20)
      methods and properties $pager.newItemsKey returns or sets the key name used to search for items in request attributes
      $pager.indexKey returns or sets the key name used to search for the first index in the current page in request attributes
      $pager.itemsPerPageKey returns or sets the key name used to search for the number of items to be shown per page in request attributes
      $pager.slipSizeKey returns or sets the key name used to search for the max number of page indices to show in request attributes
      $pager.items returns or sets the current list of items
      $pager.index returns or sets the first index in the current page (differs from $index.firstIndex in that it is not adjusted to fit the reality of the items available)
      $pager.itemsPerPage returns or sets the number of items to show per page (defaults to 10)
      $pager.slipSize returns or sets the maximum number of page indices to show (defaults to 20)
      $pager.hasItems() checks whether or not the result list is empty
      $pager.firstIndex returns the first index in the current page (as determined by the current index, items per page, and the number of items; differs from $index.index in that it is adjusted to fit the reality of the items available)
      $pager.lastIndex returns the index of the last item on the current page of results (as determined by the current index, items per page, and the number of items)
      $pager.prevIndex return the index for the previous page of items (as determined by the current index, items per page, and the number of items)
      $pager.nextIndex returns the index for the next page of items (as determined by the current index, items per page, and the number of items)
      $pager.page returns the current page of search items
      $pager.pageDescription returns a description of the current page ("1 of n")
      $pager.pageNumber returns the page number for the current index
      $pager.pageNumber( integer ) returns the page number for the specified index
      $pager.pagesAvailable returns the number of pages that can be made from this list given the set number of items per page
      $pager.total returns the total number of items available
      $pager.slip returns a Sliding List of Indices for Pages of items
      ParameterTool tool used to parse request parameters
      default key $params
      scope request
      methods and properties $params.exists( name ) checks whether given request parameter exists
      $params.name, $params.get( name ), $params.getString( name [ , alternate ] ) returns the parameter with the specified key as a string, if it exists; otherwise, returns the specified alternate value if specified
      $params.getBoolean( name [ , alternate ] ) returns the parameter with the specified key as a java.lang.Boolean, if it exists; otherwise, returns the specified alternate Boolean if specified
      $params.getNumber( name [ , alternate ] ) returns the parameter with the specified key as a java.lang.Number, if it exists; otherwise, returns the specified alternate Number if specified
      $params.getDouble( name [ , alternate ] ) returns the parameter with the specified key as a java.lang.Double, if it exists; otherwise, returns the specified alternate Double if specified
      $params.getInteger( name [ , alternate ] ) returns the parameter with the specified key as a java.lang.Integer, if it exists; otherwise, returns the specified alternate Integer if specified
      $params.getLocale( name [ , alternate ] ) returns the parameter with the specified key as a java.util.Locale, if it exists; otherwise, returns the specified alternate Locale if specified
      $params.getStrings( name ) returns the parameter(s) with the specified key in an array of strings, if any exist; otherwise, returns null
      $params.getBooleans( name ) returns the parameter(s) with the specified key in an array of java.lang.Boolean, if any exist; otherwise, returns null
      $params.getNumbers( name ) returns the parameter(s) with the specified key in an array of java.lang.Number, if any exist; otherwise, returns null
      $params.getDoubles( name ) returns the parameter(s) with the specified key in an array of java.lang.Doubles, if any exist; otherwise, returns null
      $params.getIntegers( name ) returns the parameter(s) with the specified key in an array of java.lang.Integers, if any exist; otherwise, returns null
      $params.all returns the map of all parameters available for the current request
      ViewContextTool extension of the generic ContextTool that includes keys and values from the HttpServletRequest, HttpSession and ServletContext attributes
      default key $context
      scope request
      methods and properties all methods and properties from the generic ContextTool are inherited

      This page only covers the Generic and View subprojects, leaving aside the Struts subproject for now.
      velocity-tools-2.0-src/xdocs/upgrading.xml100644 0 0 41657 11115263027 16140 0ustar 0 0 Upgrading VelocityTools xdocs/project.xml

      VelocityTools 2.0 marks the most significant set of upgrades and changes ever done for the VelocityTools library. In order to provide flexible configurations, lazy-loading for tools, and a host of other improvements, almost all of the tool management and configuration code from Tools 1.x has been deprecated and replaced by completely different APIs. Thankfully, we were able to continue supporting old toolbox.xml configuration files and old tool design patterns, though these too have been deprecated and are unable to take full advantage of many of the new features.

      Still, as such things have only been deprecated and not removed, the first step in upgrading to 2.0 is simply replacing your old VelocityTools jar with the 2.0 jar. If this causes any errors for you, please report them to user@velocity.apache.org, so that we can fix it and help you work around it in the meantime.

      Once you have your application compiling and running with Tools 2, your next step is to begin updating or replacing deprecations. Many of these should show up with deprecation warnings during compiling or deprecation notices in your logs. Read through these carefully to be aware of all that needs updating. Below is a list of instructions for handling many of these:

      In general, anything in the packages:

      • org.apache.velocity.tools.view.tools,
      • org.apache.velocity.tools.view.servlet or
      • org.apache.velocity.tools.view.context,

      has been moved to:

      org.apache.velocity.tools.view
      The extra packages had proved superfluous and problematic. All VelocityView classes are now in the org.apache.velocity.view package. Those that remain in the subpackages are merely deprecated shells that extend the classes in the new location. Also, some classes have had their class names adjusted to be more consistent with existing conventions.

      Some specific ones to watch out for are as follows. If you directly referenced:

      • VelocityViewServlet, it is now at
      • VelocityLayoutServlet, it is now at
      • WebappLoader, it is now at
      • ViewContext, it is now at
      • ServletLogger, it has been replaced by
      • ServletUtils, it is now at
      • BrowserSniffer, it is now at
      • AbstractPagerTool, it is now at
      • ParameterParser, it is now at
      • ContextTool, it is now at

      NOTE: If you are still using the old toolbox.xml format do NOT update the tool paths in that file! First, update your configuration, otherwise your tools may not work as expected. Also, this is not a complete list. Please take note of all deprecation warnings and notices when compiling and running your app.

      Along with the class renamings above have come many deprecations that have no one-to-one replacement class. The vast majority of these have to do with tool management, as XMLToolboxManager and all of its subclasses and support classes could not simply be evolved to achieve the key goals for Tools 2. A few other classes are simply no longer necessary in any form. Here is an overview of all these deprecations-without-direct-replacements:

      XMLToolboxManager was the the central tool management class in Tools 1.x. If you used it or ServletToolboxManager you were probably a more advanced user or a framework developer working to integrate VelocityTools support. If so, you should go read this document. If you used XMLToolboxManager directly, you should familiarize yourself with these classes:

      If you used ServletToolboxManager directly, you should learn about all of the above classes (except perhaps ToolManager) and the following ones as well:
      NOTE: For the vast majority of users and developers, or should be all they really need to work with directly. Don't waste time trying to manage Toolboxes yourself until you are sure that ToolManager/VelocityView can't do the job for you.

      All of the upgrades to tool management allowed some GenericTool classes to perform functions previously only possible to implement in VelocityView tools. As such, some VelocityView subclasses of generic tools have become obsolete. If you used:

      • ViewRenderTool, you should now just use
      • ViewResourceTool, you should now just use

      Since Tools 2 does lazy-loading of tools, it now makes sense to have almost all tools available by default for most uses, as there is minimal overhead for that at startup and essentially no cost at runtime unless/until the tool is used. So, in Tools 2, unless the user is doing something to trigger the "deprecation support mode" for VelocityView (using the old toolbox.xml format would do this) or explicitly telling not to load the default tools, then all of the supported, standard VelocityTools will be automatically made available by default. If you don't custom configure any of the provided tools and don't have any custom tools of your own, then you don't actually need a configuration at all! Tools 2 comes with a default tools.xml file each for GenericTools, VelocityView and VelocityStruts, and the , , and will all automatically look for and load those unless you are using a deprecated toolbox.xml file or explicitly tell them not to by adding the init-param org.apache.velocity.tools.loadDefaults with the value of false to the relevant servlet.

      If you do need a configuration, you should update your configuration to one of the new formats. Easiest would be to go from the old xml format to the new xml format. Remember, you can just leave out standard tools that you don't do any configuration of, as your configuration will just be added to the default one (again, unless the default behavior is turned off). Also, do note that all VelocityView tools have changed packages and/or names; please avoid using the deprecated versions as those will eventually be removed.

      If you are largely happy with the default tools.xml configuration, but wish to override just a few parts, you can override them with your own file. Tool configurations are key-centric. If you just want to provide a different default format for the and a second bundle for the ResourceTool, your tools.xml can be just:

      <tools> <toolbox scope="application"> <tool key="date" format="MM/dd/yy"/> </toolbox> <toolbox scope="request"> <tool key="text" bundles="resources,otherResources"/> </toolbox> </tools>

      This just overrides the format property of the "date" tool and the bundles property of the "text" tool in the configuration. Since "date" and "text" already have classes set in the default tools.xml files that come with the GenericTools and VelocityView packages, you don't need to include those.

      You don't even have to use XML to override/extend the defaults. Other available formats are a properties file or plain java.

      Please see the framework integration page for information on this subject.

      Those of you who write your own custom tools may want to make a few changes to upgrade your custom tools to do things the "Tools 2 way". Here's a few quick starts for that, though this doesn't cover everything. More details can be found in the instructions for creating tools.

      Naming: The recommended practice is to give a tool to be used as $foo the name FooTool. This is not required but is a convention that keeps things easy follow and learn. If you have to name a tool FooBarUtility but want it to be $foo in templates, the second best thing is to provide a @DefaultKey("foo") annotation on the class, though this introduces a dependency on VelocityTools. As a last resort, if you are providing tools for a framework or otherwise can influence or control the configuration, you might consider providing a default configuration--perhaps even one automatically discoverable by --to set the tool's key for your users.

      Scoping: If your tool is only meant to be used in a particular scope, it's recommended that you give the class a @ValidScope(Scope.REQUEST) annotation as well. If you only want to ban a particular scope and allow all others, you could provide a @InvalidScope(Scope.APPLICATION) annotation on the class. The class provides constants for REQUEST, SESSION, and APPLICATION. Other scopes are now theoretically possible, but only a little work and no testing has been done there at this point.

      Configuration: If you have a configurable tool whose configuration should not changed by the templates which use it, then consider having your tool extend the class (or or ). These safely standardize configuration of these common configuration properties. Also take note that the configure(Map) and init(Object) methods have been changed into just the configure(Map) and individual setter methods (e.g. setRequest, setSession, etc). Basically, when it's time to instantiate a tool, the tool manager will gather all the "configuration properties" for that tool, its toolbox, etc and combine it into a single map with the "init data" (context, request, session, etc). The manager searches for relevant setter methods that accept that data and also for a configure(Map) method. The setters get what they're asking for (if available) and the configure() method accepts the whole combined Map. The upshot of this approach is that tools no longer need to conform to any interfaces or patterns. In fact, it's possible to write a FooTool that doesn't know anything about any VelocityTools classes whatsoever and yet be fully instantiable and configurable by VelocityTools. Your tools don't need to know about anything except what they need to know about.

      velocity-tools-2.0-src/xdocs/view.layoutservlet.xml100644 0 0 21167 10730012234 20037 0ustar 0 0 VelocityViewServlet xdocs/project.xml xdocs/view.project.xml

      This is an extension to the basic VelocityViewServlet. It provides a simple layout control and customizable error screens for Velocity Tools based projects. VelocityTools is distributed with an example app demonstrating the use of this servlet.

      Since this class is an extension of the VelocityViewServlet (VVS), to use it simply change the servlet-class value of the web.xml entry to the following class:

      org.apache.velocity.tools.view.servlet.VelocityLayoutServlet

      Three settings can be added to velocity.properties to control the VLS, or the following default values will be used:

      # Filepath for error template, # relative to web application root directory tools.view.servlet.error.template = Error.vm # Directory for layout templates, # relative to web application root directory tools.view.servlet.layout.directory = layout/ # Filepath of the default layout template # relative to the layout directory # NOT relative to the root directory of the webapp! tools.view.servlet.layout.default.template = Default.vm

      Now, in your layout templates, the only thing you really need is the screen content reference. So an acceptable layout template could be:

      $screen_content

      ...but that would make this whole thing an idiotic waste of time. At the least, you'll probably want to do something along these lines:

      <html> <head> <title>$!page_title</title> </head> <body> $screen_content </body> </html>

      This saves you the trouble of doing the basic <html>,<head>, and <body> tags in every single screen. That's the point of layouts: to save effort and eliminate redundancy. Note that this still lets the inner screen control the title of the page. This works because the layout template is blessed by the VLS with access to the same context as the screen *after* the screen is done with it. Just do a #set( $page_title = "Hello" ) in the screen.


      VLS provides two ways to specify an alternate template for a requested page:

      1. Specify the layout in the request parameters

      Just add the query string "layout=MyOtherLayout.vm" to any request params and the VLS will find it and render your screen within that layout instead of the default layout. It don't matter how you get the layout param into the query data, only that it's there. If you're using the struts tools, the most common will likely be:

      <a href="$link.setRelative('MyScreen.vm').addQueryData('layout','MyOtherLayout.vm')">

      but form post data will work just as well.

      2. Specify the layout in the requested screen.

      In the requested screen, put a line like this:
      #set( $layout = "MyOtherLayout.vm" )

      This will direct the VLS to use "MyOtherLayout.vm" instead of "Default.vm". Setting the layout in this fashion will override any layout set by the request parameters.


      Those of you who are (or were) Turbine or Struts users will probably want to do more than just set the layout and screen content. You want to include arbitrary "tiles" or "navigations", right? Well, thanks to Velocity's built-in #parse directive, this is easy.

      First, create your "tile" as a separate template file like:

      <div id="footer">I made this!</div>

      For creativity's sake, we'll pretend this code is in a file named "Footer.vm" that is located in the root of my webapp like my other non-layout templates.

      <html> <head> <title>$!page_title</title> </head> <body> $screen_content #parse('Footer.vm') </body> </html>

      Easy, eh?

      Now, what if you have a lot of different "footer" files and you want your screen to decide which one will be used? No problem! Do something like this:

      <html> <head> <title>$!page_title</title> </head> <body> $screen_content #parse( $screen_footer ) </body> </html>

      and in your screen, just do #set( $screen_footer = 'FooFooter.vm' ).

      Remember, your #parsed footer template will have access to the same velocity context as your layout, which gets the screen's context once the screen is done with it. This lets you set variables for the layout and footer to use from your screens.


      Ok, the idea here is pretty simple. If an uncaught exception or error is thrown at some point during the processing of your screen and layout, the error() method of the VLS is called. This overrides the default error() method of the VelocityViewServlet to render a template instead of hardcoded html.

      This error screen will be rendered within a layout under the same rules as any other screen, and will have the following values placed in its context to help you debug the error:


      Key available to Template Value
      $error_cause java.lang.Throwable that was thrown
      $stack_trace captured output of $error_cause.printStackTrace()

      In the event that a MethodInvocationException is behind the calling of error(), the root cause is extracted from it and dealt with as described above. But, since template reference behavior is partly at fault here, the VLS will also add the MethodInvocationException itself to the context as $invocation_exception. This allows you to discover the reference and method call that triggered the root cause. To get those, do something like this in your error template:

      #if( $invocation_exception ) oh joy! it's a MethodInvocationException! Message: $invocation_exception.message Reference name: $invocation_exception.referenceName Method name: $invocation_exception.methodName #end
      velocity-tools-2.0-src/xdocs/view.project.xml100644 0 0 4642 11030275237 16552 0ustar 0 0 VelocityView velocity-tools-2.0-src/xdocs/view.servlet.xml100644 0 0 33444 10730012234 16602 0ustar 0 0 VelocityViewServlet xdocs/project.xml xdocs/view.project.xml

      This page is still unfinished. Much of this needs to be moved or at least copied to a VelocityView page, as it applies to anything using a VelocityView instance under the covers (including the VelocityViewTag). Help is welcome!

      Javadoc is here.

      A typical application use-case for the VelocityViewServlet is to provide the view rendering layer for a servlet-based web application framework. The VelocityStruts subproject uses the approach to bring Velocity templates to the Struts 1 application framework.

      The VelocityViewServlet needs to be installed into your servlet container so it can handle all request for *.vm (velocity template) files. There are only two additional configuration files, and they are shown in detail below.

      The servlet configuration (web.xml) must be modified to include a reference to the VelocityViewServlet (or subclass thereof) which will perform the rendering. All *.vm files are mapped to this servlet which will populate the 'context' with Request, Session, and Application scopes plus any additional tools specified by your configuration (or provided as defaults). The servlet will use this contextual information and the Velocity Engine to render the template file.

      Note: Additional functionality can be achieved through subclassing the VelocityViewServlet, and will be discussed further in the VelocityLayoutServlet page.

      web.xml

      <!-- Define Velocity template handler --> <servlet> <servlet-name>velocity</servlet-name> <servlet-class> org.apache.velocity.tools.view.VelocityViewServlet </servlet-class> <!-- Unless you plan to put your tools.xml and velocity.properties under different folders or give them different names, then these two init-params are unnecessary. The VelocityViewServlet will automatically look for these files in the following locations. --> <init-param> <param-name>org.apache.velocity.toolbox</param-name> <param-value>/WEB-INF/tools.xml</param-value> </init-param> <init-param> <param-name>org.apache.velocity.properties</param-name> <param-value>/WEB-INF/velocity.properties</param-value> </init-param> </servlet> <!-- Map *.vm files to Velocity --> <servlet-mapping> <servlet-name>velocity</servlet-name> <url-pattern>*.vm</url-pattern> </servlet-mapping>

      Velocity configuration is optional, and for most applications the defaults will work fine. The velocity.properties file contains settings that affect logging, encoding, and macro settings.

      The default configuration specifies the location of a 'global' Velocimacro template. This file can contain macros which will be made available to all templates.

      The location of the configuration file may be specified in web.xml, but it is recommended the file be placed inside the hidden WEB-INF directory of the web application and named 'velocity.properties' which is where the VelocityViewServlet will look for it in the absence of any location specified in the web.xml. An example configuration file is included with the distribution.

      Please see the Velocity User's Guide for more information on Velocity configuration.

      velocimacro.library = /WEB-INF/VM_global_library.vm velocimacro.permissions.allow.inline = true velocimacro.permissions.allow.inline.to.replace.global = false velocimacro.permissions.allow.inline.local.scope = false velocimacro.context.localscope = false

      The toolbox file (located at /WEB-INF/tools.xml by convention), maps out the "tools" and data we want available for our templates to use. It's easier than that sounds.

      Think about asking our friend Jon to grab us a 'wrench' from a real toolbox. Jon just needs to know which wrench we want (metric, pipe, crescent etc,). He doesn't need to know what the wrench does nor what we are planning to do with it.

      The Velocity Toolbox works the same way, we must only specify which tool we want, and then the Velocity engine takes care of the rest by making any public method available to the template. For example, from the definitions below, the template could call $wrench.size.

      PipeWrench.java

      public class PipeWrench { public String getSize() { return "Large Pipe Wrench!"; } }

      tools.xml

      <?xml version="1.0"?> <tools> <toolbox scope="application"> <tool key="wrench" class="PipeWrench"/> </toolbox> </tools>

      Toolbox Scopes

      You may have noticed that toolbox support built into VelocityView also provides support for specifying the scope of your toolbox with regards to the servlet environment. Toolboxes may be placed within the request, session, or application scopes of your web app.

      The scope that you set for your toolbox will determine the lifecycle of the tools within it:

      • application scoped tools will be instantiated only once when first used by a template and then reused by all templates for each subsequent request. Due to this, it is strongly encouraged that your application scoped tools be completely threadsafe. The MathTool (one of the GenericTools) is a good example of tool meant to be application scoped.
      • session scoped tools are instantiated at most once per unique session (if they are used by a template processed for that session) and are then reused for every request associated with that particular session.
      • request is the most common scope. Tools with this scope are instantiated at most once per servlet request fed to that VelocityView (if they are used by a template processed during that request).

      Tool Path Restrictions

      You can specify a restriction on the request URIs for which the tool will be available in the context using the "restrictTo" attribute of your tool configuration. It can be an exact request path (matching one page) or end with the * wildcard, meaning that incoming request paths need only start with the provided value for the tool to be available. For instance:

      <tool restrictTo="/catalog/*" class="com.mycompany.tools.CatalogTool"/>

      You may have noticed that this example tool configuration doesn't have a "key" attribute. This is because VelocityTools 2 honors the [Key]Tool naming convention. So a tool with the simple name of "CatalogTool" will automatically be given the key "catalog" unless another key is specified in the tool configuration or using the DefaultKey annotation on the class.

      Tool Properties

      The toolbox support built into VelocityTools also provides support for passing configuration properties to tools. If a tool has a public void configure(java.util.Map params) method, then VelocityTools will pass that method a map of all properties set on the tool configuration, the toolbox to which it belongs and properties set for the whole configuration.

      VelocityTools will also use Commmons-BeanUtils to set any or all of those same properties directly on the tool if their keys and types have a matching public set[Key](Type) method on that tool.

      These things happen immediately after a tool instance is instantiated and before it is available to your templates. This gives much flexibility in designing and configuring your tools.

      You can specify properties for your tools, toolboxes or all tools either as <property> tags or as attributes:

      <tools foo="true"> <toolbox scope="application" someProperty="whatever"> <property key="bar">woogie</property> <tool key="myTool" class="com.foo.tools.MyTool"> <property name="my.parameter.name" value="my.parameter.value"/> </tool> </toolbox> </tools>

      Static Data

      In addition to specifiying arbitrary Java classes as tools to be automatically available to your templates, the toolbox support also includes the ability to specify arbitrary strings, booleans, numbers, lists of those, and even BeanUtils-convertable types to be automatically available in your templates. The format is as follows:

      <?xml version="1.0"?> <tools> <data type="number" key="version" value="1.1"/> <data key="startdate" value="Mon Sep 17 10:08:03 PDT 2007" class="java.util.Date" converter="org.apache.commons.beanutils.locale.converters.DateLocaleConverter"/> <data type="boolean" key="isSimple" value="true"/> <data key="foo" value="this is foo."/> <data key="bar">this is bar.</data> <data type="list" key="dataKeys" value="version,date,isSimple,foo,bar,dataKeys,switches"/> <data type="list.boolean" key="switches" value="true,false,false,true"/> </tools>

      As with your tools, your data will be exposed to your templates under the specified key (e.g. $version, $startdate, $isSimple, $foo, $bar, $dataKeys and $switches). Unlike tools, data does not go in a toolbox and is not scoped (as it is necessarily static).

      velocity-tools-2.0-src/xdocs/view.tag.xml100644 0 0 7500 10730012234 15643 0ustar 0 0 VelocityViewTag xdocs/project.xml xdocs/view.project.xml

      This page is still unfinished. For details on configuring the VelocityViewTag, you can follow most of the instructions for the VelocityViewServlet and of course on the configuration pages. Help finishing this is welcome!

      This is a JSP tag that allows you to use Velocity and VelocityTools from within a JSP page or tag. There are many ways to use this tag. This simplest is to have it process an external template using the current page context. Assuming you have a template called "foo.vm" that can be found by your resource loader(s) that looks like this:

      Hello $!bodyContent World!

      This tag can process that template by doing:

      <%@taglib prefix="velocity" uri="http://velocity.apache.org/velocity-view" %> <velocity:view template="foo.vm"/>

      VTL in the body of the tag:

      <%@taglib prefix="velocity" uri="http://velocity.apache.org/velocity-view" %> <velocity:view> #if( $date.E eq 'Friday' ) Happy #else Sad #end </velocity:view>

      or combine both by first processing the body of the tag, then inserting the results of that into the context for the separate template as $bodyContent:

      <%@taglib prefix="velocity" uri="http://velocity.apache.org/velocity-view" %> <velocity:view template="foo.vm"> #if( $date.E eq 'Friday' ) Happy #else Sad #end </velocity:view>

      You can also store the results of any of the options above into a variable of any name and scope (default scope is "page"):

      <%@taglib prefix="velocity" uri="http://velocity.apache.org/velocity-view" %> <velocity:view var="foo" scope="request" template="foo.vm"> #if( $date.E eq 'Friday' ) Happy #else Sad #end </velocity:view>

      For more details, see the Javadoc or the TLD.

      velocity-tools-2.0-src/xdocs/view.xml100644 0 0 22443 11360645207 15130 0ustar 0 0 Overview xdocs/project.xml xdocs/view.project.xml

      VelocityView includes all of the GenericTools and adds infrastructure and specialized tools for using Velocity in the view layer of web applications (Java EE projects). This includes the VelocityViewServlet or VelocityLayoutServlet for processing Velocity template requests and the VelocityViewTag for embedding Velocity in JSP.

      Key features:

      • VelocityViewServlet - standalone servlet that renders Velocity templates. Invoked directly from web clients requests, or via servlet forwarding similar to how JSP files are rendered by JSPServlet.
      • The HttpServletRequest, HttpSession, ServletContext, and their attributes are automatically available in your templates.
      • Tools can also be made available to your templates, through a tools configuration file.
      • A number of useful, extendable tools for developing web applications are already provided for your convenience.
      • Logging can be directed to the log infrastructure of the Web application. (default is the logging facility provided by the Servlet API).

      The default configuration provided for VelocityView is here and here.

      The dependencies required for VelocityView can be found on our dependencies chart.

      The object forms the core of the VelocityView infrastructure. In particular, it serves as the base class for the following:

      The class is a standalone servlet that renders Velocity templates. It can be invoked directly from web client's requests, or via servlet forwarding similar to how JSP files are rendered by JSPServlet.

      Detailed documentation is here.

      One derivative of the VelocityViewServlet is the VelocityLayoutServlet. This servlet performs a simplified 'two-pass render' in order to apply a shared, common layout to all of the web pages in an application.

      The Struts "template" tag library does something similar, but requires a separate file to define which 'layout' file to use and which .jsp files to render into that layout. The VelocityLayoutServlet takes a simpler approach. It first renders the primary template being called (example: showDetails.vm) into a content holder variable (ex. $screen_content). Next, the servlet loads a 'layout' file. It uses the existing data, including any additional variables set or changed by the first template, to render a the layout template.

      The VelocityLayoutServlet also allows you to specify an 'error' template to be displayed when an exception is thrown during the processing of a requested template. This allows you to provide a customized error screen for a more user-friendly application.

      Detailed documentation is here.

      This is a JSP tag that allows you to use Velocity and VelocityTools from within your JSP tags and files. This tag can both process templates in separate files, VTL in the tag body, or combine the two.

      Detailed documentation is here.

      These are in addition to those provided by GenericTools

      • - For doing "searching" and robust pagination of search results. Requires you to create a subclass.
      • - For identifying the browser and features thereof requesting the template.
      • - For convenient cookie access and creation.
      • - For pulling down textual content from a URL.
      • - For easy building of URLs (both relative or absolute).
      • - For doing request-based pagination of items in an arbitrary list.
      • - For easy retrieval and parsing of ServletRequest parameters.
      • - For convenient access to ViewContext data and meta-data.

      A simple application example has been included to demonstrate the use of the VelocityViewServlet with automatically loaded view tools.

      To run the examples you need Tomcat 4+ or a compatible servlet runner.

      The 'ant examples' target of the build process automatically generates ready-to-deploy simple.war and showcase.war archive files located in the examples subdirectory of the distribution. Deploy (i.e. copy) one or both of these war files to the webapps directory of your servlet runner and restart. Now point a web browser at the following urls:

      http://<your_server>:<port>/simple/

      http://<your_server>:<port>/showcase/

      You can also use the embedded servlet runner to start and stop the showcase webapp on localhost's 8081 port using the start.showcase.webapp and stop.showcase.webapp ant targets.

      Since Tomcat 5.5 used commons-logging as a complete logging facility and the Struts example directs commons-logging output to the servlet log via LogChuteCommonsLog, you will get an infinite loop if you try to run the Struts example on Tomcat 5.5. To fix this, upgrade to Tomcat 6.x or delete the commons-logging.properties file from the Struts example's classpath root.

      You may, of course, experience the same thing if you are running your web application on Tomcat 5.5 and decide to use LogChuteCommonsLog for commons-logging and stick with the ServletLogChute (the default) for Velocity(Tools) logging. You will have to change one of these two settings or else upgrade your servlet engine.

      le law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> Overview xdocs/project.xml xdocs/view.project.xml

      VelocityView includes all of the GenericTools and adds infrastructure and specialized tools for using Velocity in the view layer of web applications (Java EE projects). This includes the VelocityViewServlet or VelocityLayoutServlet for processing Velocity template requests and the VelocityViewTag for embedding Velocity in JSP.

      Key features:

      • VelocityViewServlet - standalone servlet that renders Velocity templates. Invoked directly from web clients requests, or via servlet forwarding similar to how JSP files are rendered by JSPServlet.
      • The HttpServletRequest, HttpSession, ServletContext, and their attributes are automatically available in your templates.
      • Tools can also be made available to your templates, through a tools configuration file.
      • A number of useful, extendable tools for developing web applications are already provided for your convenience.
      • Logging can be directed to the log infrastructure of the Web application. (default is the logging facility provided by the Servlet API).

      The default configuration provided for VelocityView is here and here.

      The dependencies required for VelocityView can be found on our dependencies chart.

      The object forms the core of the VelocityView infrastructure. In particular, it serves as the base class for the following:

      The class is a standalone servlet that renders Velocity templates. It can be invoked directly from web client's requests, or via servlet forwarding similar to how JSP files are rendered by JSPServlet.

      Detailed documentation is here.

      One derivative of the VelocityViewServlet is the VelocityLayoutServlet. This servlet performs a simplified 'two-pass render' in order to apply a shared, common layout to all of the web pages in an application.

      The Struts "template" tag library does something similar, but requires a separate file to define which 'layout' file to use and which .jsp files to render into that layout. The VelocityLayoutServlet takes a simpler approach. It first renders the primary template being called (example: showDetails.vm) into a content holder variable (ex. $screen_content). Next, the servlet loads a 'layout' file. It uses the existing data, including any additional variables set or changed by the first template, to render a the layout template.

      The VelocityLayoutServlet also allows you to specify an 'error' template to be displayed when an exception is thrown during the processing of a requested template. This allows you to provide a customized error screen for a more user-friendly application.

      Detailed documentation is here.

      This is a