libgettext-commons-java-0.9.6/0000755000175000017500000000000011271112344016473 5ustar giovannigiovannilibgettext-commons-java-0.9.6/pom.xml0000644000175000017500000001122411144564350020017 0ustar giovannigiovanni 4.0.0 org.xnap.commons gettext-commons jar 0.9.6 Gettext Commons http://code.google.com/p/gettext-commons/ A library that supports gettext-based internationalization (i18n) of Java applications. Felix Berger bergerfx Developer http://www.felix.beldesign.de/ Tammo van Lessen tvanlessen Developer http://taval.de/ Steffen Pingel steffen.pingel Project Manager Developer http://steffenpingel.de junit junit 3.8.1 test scm:svn:http://gettext-commons.googlecode.com/svn/trunk scm:cvs:https://gettext-commons.googlecode.com/svn/trunk http://gettext-commons.googlecode.com/svn/trunk src/java src/test src/conf src/test-resources org.apache.maven.plugins maven-compiler-plugin 1.4 1.4 org.apache.maven.plugins maven-eclipse-plugin org.eclipse.jdt.core.javanature org.eclipse.jdt.core.javabuilder org.apache.maven.plugins maven-surefire-plugin true maven-assembly-plugin src/assembly/bin.xml src/assembly/src.xml make-assembly package attached xnap-commons XNap Commons Site scp://shell.sf.net//home/groups/x/xn/xnap-commons/htdocs/gettext-commons/ xnap-commons XNap Commons Repository scp://shell.sf.net//home/groups/x/xn/xnap-commons/htdocs/repository org.xnap.commons maven-gettext-plugin po org.xnap.commons.i18n.Messages ${basedir}/po libgettext-commons-java-0.9.6/ChangeLog0000644000175000017500000000426711137433153020263 0ustar giovannigiovanni2008-04-12 Felix Berger * src/java/org/xnap/commons/i18n/I18nCache.java: Fixed synchronization and improved visitor traversal by moving it out of the synchronized block. 2008-04-10 Felix Berger * src/java/org/xnap/commons/i18n/I18n.java: Made thread-safe. * src/java/org/xnap/commons/i18n/I18nCache.java: Made thread-safe. 2006-08-22 Steffen Pingel * Gettext Commons 0.9.1 released 2007-08-22 Steffen Pingel * src/java/org/xnap/commons/i18n/I18nFactory.java: Modified lookup strategy to only check for property files when no bundle name is provided. 2007-08-21 Steffen Pingel * src/java/org/xnap/commons/i18n/I18nManager.java: Do not set default locale anymore. * src/java/org/xnap/commons/i18n/EmptyResourceBundle.java: Added locale parameter. * src/java/org/xnap/commons/i18n/I18n.java: Store only a single bundle and also store locale. * src/java/org/xnap/commons/i18n/I18nFactory.java: Added NO_CACHE flag, extracted caching to I18nCache. * src/java/org/xnap/commons/i18n/I18nCache.java: Cache by package and locale. 2007-08-06 Steffen Pingel * src/java/org/xnap/commons/i18n/I18nFactory.java: Added private constructor. * src/java/org/xnap/commons/i18n/I18nFactory.java: Added getI18n() method that accepts configuration flags. If I18nFactory.FALLBACK is passed the lookup will fall-back to a default resource bundle instead of throwing an exception (#3). Lookup of the basename in properties can now be omitted when I18nFactory.READ_PROPERTIES is not passed as a configuration flag. 2006-01-05 Steffen Pingel * Gettext Commons 0.9 released 2006-01-03 Steffen Pingel * src/java/org/xnap/commons/i18n/I18nManager.java: Moved non-factory related methods to this class. * src/java/org/xnap/commons/i18n/I18nFactory.java: Implemented weak listener. 2005-12-24 Steffen Pingel * src/java/org/xnap/commons/i18n/: Created project: Moved i18n package from XNap Commons to this project. libgettext-commons-java-0.9.6/LICENSE.txt0000644000175000017500000006346510765242510020342 0ustar giovannigiovanni GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! libgettext-commons-java-0.9.6/src/0000755000175000017500000000000011137433153017267 5ustar giovannigiovannilibgettext-commons-java-0.9.6/src/assembly/0000755000175000017500000000000011271112344021101 5ustar giovannigiovannilibgettext-commons-java-0.9.6/src/assembly/bin.xml0000644000175000017500000000110211137433153022372 0ustar giovannigiovanni bin tar.gz tar.bz2 zip README* LICENSE* NOTICE* ChangeLog* target *.jar libgettext-commons-java-0.9.6/src/assembly/src.xml0000644000175000017500000000113311137433153022415 0ustar giovannigiovanni src tar.gz tar.bz2 zip README* LICENSE* NOTICE* ChangeLog* pom.xml true src true libgettext-commons-java-0.9.6/src/java/0000755000175000017500000000000010765242505020215 5ustar giovannigiovannilibgettext-commons-java-0.9.6/src/java/org/0000755000175000017500000000000010765242505021004 5ustar giovannigiovannilibgettext-commons-java-0.9.6/src/java/org/xnap/0000755000175000017500000000000010765242505021752 5ustar giovannigiovannilibgettext-commons-java-0.9.6/src/java/org/xnap/commons/0000755000175000017500000000000010765242505023425 5ustar giovannigiovannilibgettext-commons-java-0.9.6/src/java/org/xnap/commons/i18n/0000755000175000017500000000000011271112344024172 5ustar giovannigiovannilibgettext-commons-java-0.9.6/src/java/org/xnap/commons/i18n/I18nFactory.java0000644000175000017500000002333210765242507027123 0ustar giovannigiovanni/* * Gettext Commons * * Copyright (C) 2005 Felix Berger * Copyright (C) 2005 Steffen Pingel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package org.xnap.commons.i18n; import java.io.IOException; import java.io.InputStream; import java.util.Locale; import java.util.MissingResourceException; import java.util.Properties; /** * Factory class that creates and caches I18n instances. *

* Given a {@link Class} object the factory looks up the resource bundle * responsible for handling message translations. The bundle is returned with an * {@link I18n} object wrapped around it, which provides the translation * methods. The lookup is described at {@link #getI18n(Class,String)}. *

* Use the factory for creating I18n objects to make sure no * extraneous objects are created. * * @author Felix Berger * @author Tammo van Lessen * @author Steffen Pingel * @since 0.9 */ public class I18nFactory { private static final String BASENAME_KEY = "basename"; /** * Use the default configuration. * * @since 0.9.1 */ public static final int DEFAULT = 0; /** * Fall back to a default resource bundle that returns the passed text if no * resource bundle can be located. * * @since 0.9.1 */ public static final int FALLBACK = 1 << 0; /** * Look for files named {@link #PROPS_FILENAME} to determine the basename. * * @since 0.9.1 */ public static final int READ_PROPERTIES = 2 << 0; /** * Do not cache {@link I18n} instance. * * @since 0.9.1 */ public static final int NO_CACHE = 4 << 0; /** * Default name for Message bundles, is "i18n.Messages". * * @since 0.9.1 */ public static final String DEFAULT_BASE_NAME = "i18n.Messages"; /** * Filename of the properties file that contains the i18n properties, is * "i18n.properties". * * @since 0.9 */ public static final String PROPS_FILENAME = "i18n.properties"; private static final I18nCache i18nCache = new I18nCache(); private I18nFactory() { } /** * Clears the cache of i18n objects. Used by the test classes. */ static void clearCache() { i18nCache.visit(new I18nCache.Visitor() { public void visit(I18n i18n) { I18nManager.getInstance().remove(i18n); } }); i18nCache.clear(); } /** * Calls {@link #getI18n(Class, Locale) getI18n(clazz, Locale.getDefault())}. */ public static I18n getI18n(final Class clazz) { return getI18n(clazz, Locale.getDefault()); } /** * Calls {@link #getI18n(Class, Locale, int) getI18n(clazz, locale, * READ_PROPERTIES)}. * * @since 0.9.1 */ public static I18n getI18n(final Class clazz, final Locale locale) { return getI18n(clazz, locale, READ_PROPERTIES); } /** * Returns the I18n instance responsible for translating messages in the * package specified by clazz. *

* Lookup works by iterating upwards in the package hierarchy: First the * internal cache is asked for an I18n object for a package, otherwise the * algorithm looks for an i18n.properties file in the * package. The properties file is queried for a key named * basename whose value should be the fully qualified * resource/class name of the resource bundle, e.g * org.xnap.commons.i18n.Messages. *

* If after the first iteration no I18n instance has been found, a second * search begins by looking for resource bundles having the name * baseName. * * @param clazz * the package hierarchy of the clazz and its class loader are * used for resolving and loading the resource bundle * @param baseName * the name of the underlying resource bundle * @param locale * the locale of the underlying resource bundle * @param flags * a combination of these configuration flags: {@link #FALLBACK} * @return created or cached I18n instance * @throws MissingResourceException * if no resource bundle was found * @since 0.9.1 */ public static I18n getI18n(final Class clazz, final Locale locale, final int flags) { ClassLoader classLoader = getClassLoader(clazz.getClassLoader()); String bundleName = null; if (isReadPropertiesSet(flags)) { String path = clazz.getName(); int index; do { index = path.lastIndexOf('.'); path = (index != -1) ? path.substring(0, index) : ""; bundleName = readFromPropertiesFile(path, locale, classLoader); } while (bundleName == null && index != -1); } if (bundleName == null) { bundleName = DEFAULT_BASE_NAME; } return getI18n("", bundleName, classLoader, locale, flags); } /** * Calls * {@link #getI18n(Class, String, Locale) getI18n(clazz, bundleName, Locale.getDefault())}. * * @since 0.9 */ public static I18n getI18n(final Class clazz, final String bundleName) { return getI18n(clazz, bundleName, Locale.getDefault()); } /** * Calls * {@link #getI18n(Class, String, Locale, int) getI18n(clazz, bundleName, locale, DEFAULT)}. * * @since 0.9.1 */ public static I18n getI18n(final Class clazz, final String bundleName, final Locale locale) { return getI18n(clazz, bundleName, locale, DEFAULT); } /** * Calls * {@link #getI18n(Class, String, Locale) getI18n(getPackageName(clazz), bundleName, clazz.getClassLoader(), locale, DEFAULT)}. * * @since 0.9.1 */ public static I18n getI18n(final Class clazz, final String bundleName, final Locale locale, int flags) { return getI18n(clazz.getName(), bundleName, clazz.getClassLoader(), locale, flags); } /** * @since 0.9.1 */ public static I18n getI18n(final String path, final String bundleName, final ClassLoader classLoader, final Locale locale, final int flags) { int index; String prefix = path; do { // chop of last segment of path index = prefix.lastIndexOf('.'); prefix = (index != -1) ? prefix.substring(0, index) : ""; String name = prefix.length() == 0 ? bundleName : prefix + "." + bundleName; // check cache I18n i18n = i18nCache.get(name, locale); if (i18n != null) { return i18n; } // look for resource bundle in class path i18n = findByBaseName(name, locale, getClassLoader(classLoader), flags); if (i18n != null) { if ((flags & NO_CACHE) == 0) { i18nCache.put(name, i18n); } return i18n; } } while (index != -1); // fallback to default bundle if (isFallbackSet(flags)) { I18n i18n = i18nCache.get("", locale); if (i18n == null) { i18n = new I18n(new EmptyResourceBundle(locale)); i18nCache.put("", i18n); } return i18n; } throw new MissingResourceException("Resource bundle not found", path, bundleName); } static ClassLoader getClassLoader(ClassLoader classLoader) { return (classLoader != null) ? classLoader : ClassLoader.getSystemClassLoader(); } /** * Tries to create an I18n instance from a properties file. * * @param path * @param loader * @return null if no properties file was found * @throws MissingResourceException * if properties file was found but specified resource not */ static String readFromPropertiesFile(final String path, final Locale locale, final ClassLoader loader) { Properties props = new Properties(); String filename = path.length() == 0 ? PROPS_FILENAME : path.replace('.', '/') + "/" + PROPS_FILENAME; InputStream in = loader.getResourceAsStream(filename); if (in != null) { try { props.load(in); } catch (IOException e) { // XXX now what? } finally { try { in.close(); } catch (IOException e) { // this exception is lost } } return props.getProperty(BASENAME_KEY); } return null; } /** * Uses the class loader to look for a messages properties file. * * @param baseName * the base name of the resource bundle * @param path * the path that prefixes baseName * @param loader * the class loader used to look up the bundle * @param flags * @return the created instance */ static I18n findByBaseName(final String baseName, final Locale locale, final ClassLoader loader, int flags) { try { return createI18n(baseName, locale, loader, flags); } catch (MissingResourceException e) { return null; } } /** * Creates a new i18n instance and registers it with {@link I18nManager}. * * @param baseName * the base name of the resource bundle * @param locale * the locale * @param loader * the class loader used to look up the bundle * @return the created instance */ private static I18n createI18n(final String baseName, final Locale locale, final ClassLoader loader, final int flags) { I18n i18n = new I18n(baseName, locale, loader); if (!isNoCacheSet(flags)) { I18nManager.getInstance().add(i18n); } return i18n; } private static boolean isFallbackSet(final int flags) { return (flags & FALLBACK) != 0; } private static boolean isReadPropertiesSet(final int flags) { return (flags & READ_PROPERTIES) != 0; } private static boolean isNoCacheSet(final int flags) { return (flags & NO_CACHE) != 0; } } libgettext-commons-java-0.9.6/src/java/org/xnap/commons/i18n/I18nManager.java0000644000175000017500000001273411137433153027063 0ustar giovannigiovanni/* * Gettext Commons * * Copyright (C) 2005 Felix Berger * Copyright (C) 2005 Steffen Pingel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package org.xnap.commons.i18n; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Locale; /** * Manager class that maintains a set of {@link org.xnap.commons.i18n.I18n} * objects and {@link org.xnap.commons.i18n.LocaleChangeListener} objects. *

* The locale of all managed I18n objects can be changed by * invoking {@link org.xnap.commons.i18n.I18nManager#setDefaultLocale(Locale)}. * * @author Felix Berger * @author Steffen Pingel * @since 0.9 */ public class I18nManager { private static I18nManager instance = new I18nManager(); /** List of managed {@link I18n} objects. */ List i18ns = Collections.synchronizedList(new ArrayList()); /** List of managed {@link LocaleChangeListener} objects. */ List localeChangeListeners = new ArrayList(); private I18nManager() { } /** * Returns the global I18Manger singleton. * * @return the I18Manger instance * @since 0.9 */ public static I18nManager getInstance() { return instance; } /** * Adds i18n to the list of managed I18n * objects. * * @param i18n * the I18n instance * @see #setDefaultLocale(Locale) * @see #remove(I18n) * @since 0.9 */ public void add(I18n i18n) { i18ns.add(i18n); } /** * Sets the locale for all I18n instances that were instantiated through the * factory. *

* Use this method to globally change the locale for all I18n based * translations. *

* NOTE: This only works if the objects that display messages do not cache * translated messages. *

* * @param locale * the new default locale * @see I18n#setLocale(Locale) * @since 0.9 */ public void setDefaultLocale(Locale locale) { synchronized (i18ns) { for (Iterator it = i18ns.iterator(); it.hasNext();) { I18n i18n = (I18n)it.next(); i18n.setLocale(locale); } } fireLocaleChangedEvent(locale); } /** * Adds a listener that is notified when the default locale has been * changed. * * @param listener * the listener * @see #setDefaultLocale(Locale) * @since 0.9 */ public void addLocaleChangeListener(LocaleChangeListener listener) { synchronized (localeChangeListeners) { localeChangeListeners.add(listener); } } /** * Adds a listener that is notified when the default locale has been changed * using a {@link WeakReference}. The listener is removed when it has been * cleaned up by the garbage collection. *

* This is useful for temporary objects that may have an indeterminate * lifetime such as dialogs. * * @param listener * the listener * @see #setDefaultLocale(Locale) * @since 0.9 */ public void addWeakLocaleChangeListener(LocaleChangeListener listener) { synchronized (localeChangeListeners) { localeChangeListeners.add(new WeakLocaleChangeListener(listener)); } } /** * Removes i18n from the list of managed I18n * objects. * * @param i18n * the I18n instance * @see #add(I18n) * @since 0.9 */ public void remove(I18n i18n) { i18ns.remove(i18n); } /** * Removes listener from the list of objects that are * notified when the locale has changed. * * @param listener * the listener * @since 0.9 */ public void removeLocaleChangeListener(LocaleChangeListener listener) { synchronized (localeChangeListeners) { localeChangeListeners.remove(listener); } } /** * Notifies listeners of a locale change. * * @param newLocale * new locale * @since 0.9 */ protected void fireLocaleChangedEvent(Locale newLocale) { LocaleChangeListener[] listeners; synchronized (localeChangeListeners) { listeners = (LocaleChangeListener[])localeChangeListeners.toArray(new LocaleChangeListener[0]); } if (listeners.length > 0) { LocaleChangeEvent event = new LocaleChangeEvent(I18nFactory.class, newLocale); for (int i = listeners.length - 1; i >= 0; i--) { listeners[i].localeChanged(event); } } } private static class WeakLocaleChangeListener implements LocaleChangeListener { private WeakReference reference; public WeakLocaleChangeListener(LocaleChangeListener listener) { reference = new WeakReference(listener); } public void localeChanged(LocaleChangeEvent event) { Object listener = reference.get(); if (listener != null) { ((LocaleChangeListener)listener).localeChanged(event); } else { I18nManager.getInstance().removeLocaleChangeListener(this); } } } } libgettext-commons-java-0.9.6/src/java/org/xnap/commons/i18n/LocaleChangeListener.java0000644000175000017500000000262710765242507031073 0ustar giovannigiovanni/* * Gettext Commons * * Copyright (C) 2005 Steffen Pingel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package org.xnap.commons.i18n; import java.util.Locale; /** * Defines the requirements for classes that get notified when the locale * is changed. * *

A component that implements this interface may dynamically change the * language of all user visible strings. * * @see org.xnap.commons.i18n.I18nManager#setDefaultLocale(Locale) * @author Steffen Pingel * @since 0.9 */ public interface LocaleChangeListener { /** * Invoked when the local has changed. * * @param event provides information about the new locale * @since 0.9 */ void localeChanged(LocaleChangeEvent event); } libgettext-commons-java-0.9.6/src/java/org/xnap/commons/i18n/I18nCache.java0000644000175000017500000000507011137433153026507 0ustar giovannigiovanni/* * Gettext Commons * * Copyright (C) 2005 Felix Berger * Copyright (C) 2005 Steffen Pingel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package org.xnap.commons.i18n; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; /** * Stores a list of {@link I18n} objects by a String key. * * @author Steffen Pingel */ class I18nCache { /** * Map>, list is synchronized too. */ private final Map i18nByPackage = Collections.synchronizedMap(new HashMap()); I18nCache() { } public void clear() { i18nByPackage.clear(); } public I18n get(final String packageName, final Locale locale) { if (locale == null) { throw new NullPointerException("locale is null"); } List list = (List)i18nByPackage.get(packageName); if (list != null) { synchronized (list) { for (Iterator it = list.iterator(); it.hasNext();) { I18n i18n = (I18n)it.next(); if (locale.equals(i18n.getLocale())) { return i18n; } } } } return null; } public void put(String packageName, I18n i18n) { List list; synchronized (i18nByPackage) { list = (List)i18nByPackage.get(packageName); if (list == null) { list = Collections.synchronizedList(new ArrayList(2)); i18nByPackage.put(packageName, list); } } list.add(i18n); } public void visit(final Visitor visitor) { List[] lists; synchronized (i18nByPackage) { lists = (List[])i18nByPackage.values().toArray(new List[0]); } for (int i = 0; i < lists.length; i++) { List list = lists[i]; synchronized (list) { for (Iterator it2 = list.iterator(); it2.hasNext();) { I18n i18n = (I18n)it2.next(); visitor.visit(i18n); } } } } public static interface Visitor { void visit(I18n i18n); } } libgettext-commons-java-0.9.6/src/java/org/xnap/commons/i18n/I18n.java0000644000175000017500000004157611144564271025602 0ustar giovannigiovanni/* * Gettext Commons * * Copyright (C) 2005 Felix Berger * Copyright (C) 2005 Steffen Pingel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package org.xnap.commons.i18n; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.text.MessageFormat; import java.util.Locale; import java.util.MissingResourceException; import java.util.ResourceBundle; /** * Provides methods for internationalization. *

* To learn how message strings wrapped in one of the tr*() * methods can be extracted and localized, see this tutorial. * * @author Steffen Pingel * @author Felix Berger * @author Tammo van Lessen * @since 0.9 */ public class I18n { private static final String CONTEXT_GLUE = "\u0004"; /** * Reference to the current localization bundles. */ private volatile ResourceBundle bundle; /** * The locale of the strings used in the source code. * * @see #trc(String, String) */ private volatile Locale sourceCodeLocale = Locale.ENGLISH; private String baseName; private ClassLoader loader; private volatile Locale locale; /** * Constructs an I18n object for a resource bundle. * * @param bundle * must not be null * @throws NullPointerException * if bundle is null * @since 0.9 */ public I18n(ResourceBundle bundle) { setResources(bundle); } /** * Constructs an I18n object by calling {@link #setResources(String, Locale, * ClassLoader)}. * * @throws MissingResourceException * if the resource bundle could not be loaded * @throws NullPointerException * if one of the arguments is null * @since 0.9 */ public I18n(String baseName, Locale locale, ClassLoader loader) { setResources(baseName, locale, loader); } /** * Returns the current resource bundle. * * @since 0.9 */ public ResourceBundle getResources() { return bundle; } /** * Returns the locale this instance was created with. This can be different * from the locale of the resource bundle returned by * {@link #getResources()}. * * @return the locale or null, if this instance was directly created from a * resource bundle * @since 0.9 */ public Locale getLocale() { return locale; } /** * Sets a resource bundle to be used for message translations. *

* If this is called, the possibly previously specified class loader and * baseName are invalidated, since the bundle might be from a different * context. Subsequent calls to {@link #setLocale(Locale)} won't have any * effect. * * @since 0.9 */ public synchronized void setResources(ResourceBundle bundle) { if (bundle == null) { throw new NullPointerException(); } this.bundle = bundle; this.baseName = null; this.locale = bundle.getLocale(); this.loader = null; } /** * Tries to load a resource bundle using {@link * ResourceBundle#getBundle(java.lang.String, java.util.Locale, * java.lang.ClassLoader)}. * * @throws MissingResourceException * if the bundle could not be loaded * @throws NullPointerException * if one of the arguments is null * @since 0.9 */ public synchronized void setResources(String baseName, Locale locale, ClassLoader loader) { this.bundle = ResourceBundle.getBundle(baseName, locale, loader); this.baseName = baseName; this.locale = locale; this.loader = loader; } /** * Marks text to be translated, but doesn't return the * translation but text itself. * * @since 0.9 */ public static final String marktr(String text) { return text; } /** * Tries to load a resource bundle for the locale. *

* The resource bundle is then used for message translations. Note, you have * to retrieve all messages anew after a locale change in order for them to * be translated to the language specified by the new locale. *

* * @return false if there is not enough information for loading a new * resource bundle, see {@link #setResources(ResourceBundle)}. * @throws MissingResourceException * if the resource bundle for locale could not be * found * @throws NullPointerException * if locale is null * @since 0.9 */ public synchronized boolean setLocale(Locale locale) { if (baseName != null && loader != null) { setResources(baseName, locale, loader); return true; } else { this.locale = locale; } return false; } /** * Sets the locale of the text in the source code. *

* Only languages that have one singular and one plural form can be used as * source code locales, since {@link #trn(String, String, long)} takes * exactly these two forms as parameters. * * @param locale * the locale * @throws NullPointerException * if locale is null * @see #trc(String, String) * @since 0.9 */ public void setSourceCodeLocale(Locale locale) { if (locale == null) { throw new NullPointerException("locale must not be null"); } sourceCodeLocale = locale; } /** * Returns text translated into the currently selected * language. Every user-visible string in the program must be wrapped into * this function. * * @param text * text to translate * @return the translation * @since 0.9 */ public final String tr(String text) { try { return bundle.getString(text); } catch (MissingResourceException e) { return text; } } /** * Returns text translated into the currently selected * language. *

* Occurrences of {number} placeholders in text are replaced by * objects. *

* Invokes * {@link MessageFormat#format(java.lang.String, java.lang.Object[])}. * * @param text * text to translate * @param objects * arguments to MessageFormat.format() * @return the translated text * @since 0.9 */ public final String tr(String text, Object[] objects) { return MessageFormat.format(tr(text), objects); } /** * Convenience method that invokes {@link #tr(String, Object[])}. * * @since 0.9 */ public final String tr(String text, Object o1) { return tr(text, new Object[]{ o1 }); } /** * Convenience method that invokes {@link #tr(String, Object[])}. * * @since 0.9 */ public final String tr(String text, Object o1, Object o2) { return tr(text, new Object[]{ o1, o2 }); } /** * Convenience method that invokes {@link #tr(String, Object[])}. * * @since 0.9 */ public final String tr(String text, Object o1, Object o2, Object o3) { return tr(text, new Object[]{ o1, o2, o3 }); } /** * Convenience method that invokes {@link #tr(String, Object[])}. * * @since 0.9 */ public final String tr(String text, Object o1, Object o2, Object o3, Object o4) { return tr(text, new Object[]{ o1, o2, o3, o4 }); } /** * Returns the plural form for n of the translation of * text. * * @param text * the key string to be translated. * @param pluralText * the plural form of text. * @param n * value that determines the plural form * @return the translated text * @since 0.9 */ public final String trn(String text, String pluralText, long n) { try { return trnInternal(bundle, text, pluralText, n); } catch (MissingResourceException e) { return (n == 1) ? text : pluralText; } } /** * Returns the plural form for n of the translation of * text. * * @param text * the key string to be translated. * @param pluralText * the plural form of text. * @param n * value that determines the plural form * @param objects * object args to be formatted and substituted. * @return the translated text * @since 0.9 */ public final String trn(String text, String pluralText, long n, Object[] objects) { return MessageFormat.format(trn(text, pluralText, n), objects); } /** * Overloaded method that invokes * {@link #trn(String, String, long, Object[])} passing Object * arguments as an array. * * @since 0.9 */ public final String trn(String text, String pluralText, long n, Object o1) { return trn(text, pluralText, n, new Object[]{ o1 }); } /** * Overloaded method that invokes * {@link #trn(String, String, long, Object[])} passing Object * arguments as an array. * * @since 0.9 */ public final String trn(String text, String pluralText, long n, Object o1, Object o2) { return trn(text, pluralText, n, new Object[]{ o1, o2 }); } /** * Overloaded method that invokes * {@link #trn(String, String, long, Object[])} passing Object * arguments as an array. * * @since 0.9 */ public final String trn(String text, String pluralText, long n, Object o1, Object o2, Object o3) { return trn(text, pluralText, n, new Object[]{ o1, o2, o3 }); } /** * Overloaded method that invokes * {@link #trn(String, String, long, Object[])} passing Object * arguments as an array. * * @since 0.9 */ public final String trn(String text, String pluralText, long n, Object o1, Object o2, Object o3, Object o4) { return trn(text, pluralText, n, new Object[]{ o1, o2, o3, o4 }); } /** * Returns the plural form for n of the translation of ??? * * Based on GettextResource.java that is part of GNU gettext for Java * Copyright (C) 2001 Free Software Foundation, Inc. * * @param bundle a ResourceBundle * @param text the key string to be translated, an ASCII string * @param pluralText its English plural form * @return the translation of text depending on n, * or text or pluralText if none is found */ private static String trnInternal(ResourceBundle orgBundle, String text, String pluralText, long n) { ResourceBundle bundle = orgBundle; do { boolean isGetTextBundle = false; boolean hasPluralHandling = false; Method handleGetObjectMethod = null; Method getParentMethod = null; Method lookupMethod = null; Method pluralEvalMethod = null; try { handleGetObjectMethod = bundle.getClass().getMethod("handleGetObject", new Class[]{ String.class }); getParentMethod = bundle.getClass().getMethod("getParent", new Class[0]); isGetTextBundle = Modifier.isPublic(handleGetObjectMethod.getModifiers()); lookupMethod = bundle.getClass().getMethod("lookup", new Class[]{ String.class }); pluralEvalMethod = bundle.getClass().getMethod("pluralEval", new Class[]{ Long.TYPE }); hasPluralHandling = true; } catch (Exception e) {} if (isGetTextBundle) { // GNU gettext generated bundle if (hasPluralHandling) { // GNU gettext generated bundle w/ plural handling try { Object localValue = lookupMethod.invoke(bundle, new Object[]{ text }); if (localValue.getClass().isArray()) { String[] pluralforms = (String[])localValue; long index = 0; try { index = ((Long)pluralEvalMethod.invoke(bundle, new Object[]{ new Long(n) })) .longValue(); if (!(index >= 0 && index < pluralforms.length)) { index = 0; } } catch (IllegalAccessException e) {} return pluralforms[(int)index]; } else { // Found the value. It doesn't depend on n in this // case. return (String)localValue; } } catch (Exception e) {} } else { // GNU gettext generated bundle w/o plural handling try { Object localValue = handleGetObjectMethod.invoke(bundle, new Object[]{ text }); if (localValue != null) { return (String)localValue; } } catch (Exception e) {} } bundle = null; try { bundle = (ResourceBundle)getParentMethod.invoke(bundle, new Object[0]); } catch (Exception e) {} } else { return bundle.getString(text); } } while (bundle != null); throw new MissingResourceException("Can not find resource for key " + text + " in bundle " + orgBundle.getClass().getName(), orgBundle.getClass().getName(), text); } /** * Disambiguates translation keys. * * @param context * the context of the text to be translated * @param text * the ambiguous key message in the source locale * @return text if the locale of the underlying resource * bundle equals the source code locale, the translation of * comment otherwise. * @see #setSourceCodeLocale(Locale) * @since 0.9 */ public final String trc(String context, String text) { if (sourceCodeLocale.equals(getResources().getLocale())) { return text; } else { String key = context + CONTEXT_GLUE + text; String translated = tr(key); // if no translation was found return text in source locale return translated == key ? text : translated; } } /** * Returns the plural form for n of the translation of * text. * * @param context * the context of the message to disambiguate it when translating * @param text * the key string to be translated. * @param pluralText * the plural form of text. * @param n * value that determines the plural form * @return the translated text * @since 0.9.5 */ public final String trnc(String context, String singularText, String pluralText, long n) { try { return trnInternal(bundle, context + CONTEXT_GLUE + singularText, pluralText, n); } catch (MissingResourceException e) { return (n == 1) ? singularText : pluralText; } } /** * Returns the plural form for n of the translation of * text. * * @param context * the context of the message to disambiguate it when translating * @param text * the key string to be translated. * @param pluralText * the plural form of text. * @param n * value that determines the plural form * @param objects * object args to be formatted and substituted. * @return the translated text * @since 0.9 */ public final String trnc(String context, String singularText, String pluralText, long n, Object[] objects) { return MessageFormat.format(trnc(context, singularText, pluralText, n), objects); } /** * Overloaded method that invokes * {@link #trnc(String, String, String, long, Object[]) passing obj * arguments as an array. * * @since 0.9.5 */ public final String trnc(String comment, String singularText, String pluralText, long n, Object obj) { return MessageFormat.format(trnc(comment, singularText, pluralText, n), new Object[] { obj }); } /** * Overloaded method that invokes * {@link #trnc(String, String, String, long, Object[]) passing obj1 and obj2 * arguments as an array. * * @since 0.9.5 */ public final String trnc(String comment, String singularText, String pluralText, long n, Object obj1, Object obj2) { return MessageFormat.format(trnc(comment, singularText, pluralText, n), new Object[] { obj1, obj2 }); } /** * Overloaded method that invokes * {@link #trnc(String, String, String, long, Object[]) passing obj1, obj2 and obj3 * arguments as an array. * * @since 0.9.5 */ public final String trnc(String comment, String singularText, String pluralText, long n, Object obj1, Object obj2, Object obj3) { return MessageFormat.format(trnc(comment, singularText, pluralText, n), new Object[] { obj1, obj2, obj3 }); } /** * Overloaded method that invokes * {@link #trnc(String, String, String, long, Object[]) passing obj1, obj2, obj3 and obj4 * arguments as an array. * * @since 0.9.5 */ public final String trnc(String comment, String singularText, String pluralText, long n, Object obj1, Object obj2, Object obj3, Object obj4) { return MessageFormat.format(trnc(comment, singularText, pluralText, n), new Object[] { obj1, obj2, obj3, obj4 }); } } libgettext-commons-java-0.9.6/src/java/org/xnap/commons/i18n/LocaleChangeEvent.java0000644000175000017500000000301111137433336030347 0ustar giovannigiovanni/* * Gettext Commons * * Copyright (C) 2005 Steffen Pingel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package org.xnap.commons.i18n; import java.util.EventObject; import java.util.Locale; /** * Provides information about a locale change. * * @author Steffen Pingel * @since 0.9 */ public class LocaleChangeEvent extends EventObject { private static final long serialVersionUID = 7640942181212009222L; private Locale newLocale; /** * Constructs the event. * @param source the source of the event * @param newLocale the new locale * @since 0.9 */ public LocaleChangeEvent(Object source, Locale newLocale) { super(source); this.newLocale = newLocale; } /** * Returns the new locale. * * @return the new locale * @since 0.9 */ public Locale getNewLocale() { return newLocale; } } libgettext-commons-java-0.9.6/src/java/org/xnap/commons/i18n/package.html0000644000175000017500000000053210765242507026467 0ustar giovannigiovanni

Provides classes for internationalization (i18n).

To learn how to make use of the Gettext Commons internationalization, please have a look at this tutorial.

libgettext-commons-java-0.9.6/src/java/org/xnap/commons/i18n/EmptyResourceBundle.java0000644000175000017500000000175610765242505031020 0ustar giovannigiovannipackage org.xnap.commons.i18n; import java.util.Enumeration; import java.util.Locale; import java.util.ResourceBundle; /** * A ResourceBundle that returns the key as a value. * * FIXME needs to implement proper plural handling * FIXME the bundle needs to have a valid locale for proper sourceCodeLocale handling */ class EmptyResourceBundle extends ResourceBundle { private Locale locale; public EmptyResourceBundle(Locale locale) { this.locale = locale; } /** * Returns the key as value. */ protected Object handleGetObject(String key) { return key; } public Enumeration getKeys() { return new EmptyStringEnumeration(); } public Locale getLocale() { return locale; } private static class EmptyStringEnumeration implements Enumeration { public boolean hasMoreElements() { return false; } public Object nextElement() { throw new IllegalStateException("nextElement must not be " + "called on empty enumeration"); } } }libgettext-commons-java-0.9.6/src/examples/0000755000175000017500000000000011271112344021100 5ustar giovannigiovannilibgettext-commons-java-0.9.6/src/examples/en.properties0000644000175000017500000000165510765242510023635 0ustar giovannigiovanni# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy !=Project-Id-Version\: PACKAGE VERSION\nReport-Msgid-Bugs-To\: \nPOT-Creation-Date\: 2004-10-17 19\:24+0200\nPO-Revision-Date\: YEAR-MO-DA HO\:MI+ZONE\nLast-Translator\: FULL NAME \nLanguage-Team\: LANGUAGE \nMIME-Version\: 1.0\nContent-Type\: text/plain; charset\=UTF-8\nContent-Transfer-Encoding\: 8bit\n #: I18nExample.java:21 !This\ text\ is\ marked\ for\ translation\ and\ is\ translated= #: I18nExample.java:23 !This\ text\ is\ tranlated\ and\ padded= #: I18nExample.java:25 !This\ text\ is\ marked\ for\ translation\ but\ not\ translated= #: I18nExample.java:27 #, java-format !This\ is\ the\ {0}.\ text\ to\ be\ translated= #: I18nExample.java:29 !chat\ (verb)= #: I18nExample.java:31 !chat\ (noun)= libgettext-commons-java-0.9.6/src/examples/de.properties0000644000175000017500000000232310765242510023614 0ustar giovannigiovanni# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy !=Project-Id-Version\: PACKAGE VERSION\nReport-Msgid-Bugs-To\: \nPOT-Creation-Date\: 2004-10-17 19\:24+0200\nPO-Revision-Date\: 2004-10-17 19\:28+0200\nLast-Translator\: FULL NAME \nLanguage-Team\: LANGUAGE \nMIME-Version\: 1.0\nContent-Type\: text/plain; charset\=UTF-8\nContent-Transfer-Encoding\: 8bit\n #: I18nExample.java:21 This\ text\ is\ marked\ for\ translation\ and\ is\ translated=Dieser Text ist f\u00fcr die \u00dcbersetzung markiert und wird auch \u00fcbersetzt #: I18nExample.java:23 This\ text\ is\ tranlated\ and\ padded=Dieser Text wird \u00fcbersetzt und am Rand mit Leerzeichen aufgef\u00fcllt #: I18nExample.java:25 This\ text\ is\ marked\ for\ translation\ but\ not\ translated=Dieser Text ist f\u00fcr die \u00dcbersetzung markiert wird aber nicht \u00fcbersetzt #: I18nExample.java:27 #, java-format This\ is\ the\ {0}.\ text\ to\ be\ translated=Dies ist der {0}. Text der \u00fcbersetzt wird #: I18nExample.java:29 chat\ (verb)=Chatten #: I18nExample.java:31 chat\ (noun)=Chat libgettext-commons-java-0.9.6/src/examples/Messages.properties0000644000175000017500000000000010765242510024761 0ustar giovannigiovannilibgettext-commons-java-0.9.6/src/examples/I18nExample.java0000644000175000017500000000462210765242510024010 0ustar giovannigiovanniimport java.util.Locale; import org.xnap.commons.i18n.I18n; import org.xnap.commons.i18n.I18nFactory; /** * This example class illustrates how the methods provided by {@link i18n} * can be used to localize text messages. * * Nota bene: Contrary to this example changing the resources during * run-time is usually not a good idea, since most strings are saved in the * swing components and not reread from resource bundles. * * @author Felix Berger */ public class I18nExample { public static void main(String[] args) { I18n i18n = I18nFactory.getI18n(I18nExample.class, "Messages"); /* * We do two runs, the first with the orginal locale the second one * with the German locale, to see which messages are translated and * how. */ for (int i = 0; i < 2; i++) { if (i == 0) { print("First run"); } else { print("Second run"); i18n.setLocale(Locale.GERMAN); } /* * This is the method you will be using most of the time. */ print(i18n.tr("This text is marked for translation and is translated")); /* * This method marks the text for translation, but doesn't * translate. This can be used for keys which should be stored * untranslated but should be translated in the user interface. */ String mark = i18n.marktr("This text is marked for translation but not translated"); /* * See in the second run, it's never translated. */ print(mark); /* * Now you can use the text in a variable and it is correctly * translated. */ print(i18n.tr(mark)); /* * A convenience wrapper for MessageFormat.format(String, Object[]). */ print(i18n.tr("Four: {0}", new Integer(4))); /* * This method disambiguates a word which has to be translated * differently depending on how it is used. In our example the * word "chat" is translated differently to German when it is * used as a noun and as a verb. */ print(i18n.trc("chat (verb)", "chat")); print(i18n.trc("chat (noun)", "chat")); /* * I18n.trn handles plurals. The third parameter contains the number * of objects to decide which plural form to use. */ print(i18n.trn("{0} file is open", "{0} files are open", 1, new Integer(1))); print(i18n.trn("{0} file is open", "{0} files are open", 2, new Integer(2))); } } private static void print(String text) { System.out.println(text); } } libgettext-commons-java-0.9.6/src/test-resources/0000755000175000017500000000000011271112344022251 5ustar giovannigiovannilibgettext-commons-java-0.9.6/src/test-resources/DefaultMessages.properties0000644000175000017500000000002510765242507027454 0ustar giovannigiovannisource=DefaultBundle libgettext-commons-java-0.9.6/src/test-resources/org/0000755000175000017500000000000010765242507023054 5ustar giovannigiovannilibgettext-commons-java-0.9.6/src/test-resources/org/xnap/0000755000175000017500000000000010765242507024022 5ustar giovannigiovannilibgettext-commons-java-0.9.6/src/test-resources/org/xnap/commons/0000755000175000017500000000000010765242507025475 5ustar giovannigiovannilibgettext-commons-java-0.9.6/src/test-resources/org/xnap/commons/i18n/0000755000175000017500000000000011271112344026240 5ustar giovannigiovannilibgettext-commons-java-0.9.6/src/test-resources/org/xnap/commons/i18n/testpackage/0000755000175000017500000000000011271112344030533 5ustar giovannigiovanni././@LongLink0000000000000000000000000000015300000000000011564 Lustar rootrootlibgettext-commons-java-0.9.6/src/test-resources/org/xnap/commons/i18n/testpackage/TestMessages.propertieslibgettext-commons-java-0.9.6/src/test-resources/org/xnap/commons/i18n/testpackage/TestMessages.prop0000644000175000017500000000003410765242507034055 0ustar giovannigiovanni#this file should stay empty././@LongLink0000000000000000000000000000015600000000000011567 Lustar rootrootlibgettext-commons-java-0.9.6/src/test-resources/org/xnap/commons/i18n/testpackage/TestMessages_de.propertieslibgettext-commons-java-0.9.6/src/test-resources/org/xnap/commons/i18n/testpackage/TestMessages_de.p0000644000175000017500000000001310765242507034001 0ustar giovannigiovannivalue=Wert ././@LongLink0000000000000000000000000000015600000000000011567 Lustar rootrootlibgettext-commons-java-0.9.6/src/test-resources/org/xnap/commons/i18n/testpackage/TestMessages_fr.propertieslibgettext-commons-java-0.9.6/src/test-resources/org/xnap/commons/i18n/testpackage/TestMessages_fr.p0000644000175000017500000000001410765242507034021 0ustar giovannigiovannivalue=valeurlibgettext-commons-java-0.9.6/src/test-resources/org/xnap/commons/i18n/testpackage/i18n.properties0000644000175000017500000000006710765242507033447 0ustar giovannigiovannibasename=org.xnap.commons.i18n.testpackage.TestMessageslibgettext-commons-java-0.9.6/src/test-resources/org/xnap/commons/i18n/testpackage/resources/0000755000175000017500000000000011271112344032545 5ustar giovannigiovanni././@LongLink0000000000000000000000000000016700000000000011571 Lustar rootrootlibgettext-commons-java-0.9.6/src/test-resources/org/xnap/commons/i18n/testpackage/resources/OwnMessages_de.propertieslibgettext-commons-java-0.9.6/src/test-resources/org/xnap/commons/i18n/testpackage/resources/OwnMess0000644000175000017500000000000710765242507034074 0ustar giovannigiovanniown=yes././@LongLink0000000000000000000000000000015500000000000011566 Lustar rootrootlibgettext-commons-java-0.9.6/src/test-resources/org/xnap/commons/i18n/testpackage/resources/i18n.propertieslibgettext-commons-java-0.9.6/src/test-resources/org/xnap/commons/i18n/testpackage/resources/i18n.pr0000644000175000017500000000010010765242507033672 0ustar giovannigiovannibasename=org.xnap.commons.i18n.testpackage.resources.OwnMessageslibgettext-commons-java-0.9.6/src/test-resources/org/xnap/commons/i18n/i18n.properties0000644000175000017500000000005010765242507031144 0ustar giovannigiovannibasename=org.xnap.commons.i18n.Messages libgettext-commons-java-0.9.6/src/test/0000755000175000017500000000000010765242503020251 5ustar giovannigiovannilibgettext-commons-java-0.9.6/src/test/org/0000755000175000017500000000000010765242503021040 5ustar giovannigiovannilibgettext-commons-java-0.9.6/src/test/org/xnap/0000755000175000017500000000000010765242503022006 5ustar giovannigiovannilibgettext-commons-java-0.9.6/src/test/org/xnap/commons/0000755000175000017500000000000010765242503023461 5ustar giovannigiovannilibgettext-commons-java-0.9.6/src/test/org/xnap/commons/i18n/0000755000175000017500000000000011271112344024230 5ustar giovannigiovannilibgettext-commons-java-0.9.6/src/test/org/xnap/commons/i18n/I18nFactoryTest.java0000644000175000017500000001102210765242505030010 0ustar giovannigiovanni/* * Gettext Commons * * Copyright (C) 2005 Steffen Pingel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package org.xnap.commons.i18n; import java.util.Locale; import junit.framework.TestCase; import org.xnap.commons.i18n.testpackage.MockResourceBundle; import org.xnap.commons.i18n.testpackage.noresources.HasNoOwnResources; import org.xnap.commons.i18n.testpackage.resources.HasItsOwnResources; /** * @author Felix Berger */ public class I18nFactoryTest extends TestCase { private static Locale[] LOCALES = { Locale.GERMAN, Locale.FRENCH }; private static String[] VALUES = { "Wert", "valeur" }; private Locale savedDefault; private String packageName; protected void setUp() throws Exception { packageName = MockResourceBundle.class.getName(); packageName = packageName.substring(0, packageName.lastIndexOf('.')); savedDefault = Locale.getDefault(); Locale.setDefault(Locale.GERMAN); I18nFactory.clearCache(); } protected void tearDown() throws Exception { Locale.setDefault(savedDefault); } public void testFindByBaseName() { for (int i = 0; i < LOCALES.length; i++) { Locale.setDefault(LOCALES[i]); I18n i18n = I18nFactory.findByBaseName(packageName + ".TestMessages", Locale.getDefault(), MockResourceBundle.class.getClassLoader(), I18nFactory.DEFAULT); assertEquals(LOCALES[i], i18n.getResources().getLocale()); assertEquals(VALUES[i], i18n.getResources().getString("value")); assertEquals(VALUES[i], i18n.tr("value")); } // same for mock up I18n i18n = I18nFactory.findByBaseName(packageName + ".MockResourceBundle", Locale.getDefault(), getClass() .getClassLoader(), I18nFactory.DEFAULT); assertEquals(MockResourceBundle.class, i18n.getResources().getClass()); assertEquals("value", i18n.getResources().getString("value")); assertEquals("value", i18n.tr("value")); } public void testReadFromPropertiesFile() { String baseName = I18nFactory.readFromPropertiesFile(packageName, Locale.getDefault(), getClass() .getClassLoader()); assertEquals("org.xnap.commons.i18n.testpackage.TestMessages", baseName); } public void testGetI18n() { I18n i18n = I18nFactory.getI18n(MockResourceBundle.class); assertNotSame(MockResourceBundle.class, i18n.getResources().getClass()); i18n = I18nFactory.getI18n(MockResourceBundle.class, "MockResourceBundle"); assertSame(MockResourceBundle.class, i18n.getResources().getClass()); } public void testGetI18nFromDefaultPackage() { I18n i18n = I18nFactory.getI18n(MockResourceBundle.class, "DefaultMessages", Locale.ENGLISH); assertEquals("DefaultBundle", i18n.tr("source")); } public void testOwnResources() { I18n i18n = I18nFactory.getI18n(HasItsOwnResources.class); i18n.setLocale(Locale.GERMAN); assertEquals("yes", i18n.tr("own")); } public void testNoOwnResources() { I18n i18n = I18nFactory.getI18n(HasNoOwnResources.class); i18n.setLocale(Locale.GERMAN); assertEquals(Locale.GERMAN, i18n.getResources().getLocale()); assertEquals("Wert", i18n.tr("value")); i18n.setLocale(Locale.FRENCH); assertEquals(Locale.FRENCH, i18n.getResources().getLocale()); assertEquals("valeur", i18n.tr("value")); } public void testGetI18nFallback() { I18n i18n = I18nFactory.getI18n(HasNoOwnResources.class, "NonExistant", Locale.getDefault(), I18nFactory.FALLBACK); assertTrue(i18n.getResources() instanceof EmptyResourceBundle); } public void testSetResources() { try { I18n i18n = I18nFactory.getI18n(MockResourceBundle.class); i18n.setResources(null); fail("NullPointerException expected"); } catch (NullPointerException npe) {} I18n i18n = I18nFactory.getI18n(MockResourceBundle.class); String baseName = MockResourceBundle.class.getName(); i18n.setResources(baseName, Locale.GERMAN, MockResourceBundle.class.getClassLoader()); assertEquals(MockResourceBundle.class, i18n.getResources().getClass()); } } libgettext-commons-java-0.9.6/src/test/org/xnap/commons/i18n/testpackage/0000755000175000017500000000000011271112344026523 5ustar giovannigiovannilibgettext-commons-java-0.9.6/src/test/org/xnap/commons/i18n/testpackage/noresources/0000755000175000017500000000000011271112344031072 5ustar giovannigiovanni././@LongLink0000000000000000000000000000015400000000000011565 Lustar rootrootlibgettext-commons-java-0.9.6/src/test/org/xnap/commons/i18n/testpackage/noresources/HasNoOwnResources.javalibgettext-commons-java-0.9.6/src/test/org/xnap/commons/i18n/testpackage/noresources/HasNoOwnResourc0000644000175000017500000000013510765242505034065 0ustar giovannigiovannipackage org.xnap.commons.i18n.testpackage.noresources; public class HasNoOwnResources { } libgettext-commons-java-0.9.6/src/test/org/xnap/commons/i18n/testpackage/MockResourceBundle.java0000644000175000017500000000127410765242505033137 0ustar giovannigiovannipackage org.xnap.commons.i18n.testpackage; import java.util.Enumeration; import java.util.Locale; import java.util.ResourceBundle; public class MockResourceBundle extends ResourceBundle { private Locale locale; public MockResourceBundle() { } public Locale getLocale() { return locale; } public void setLocale(Locale locale) { this.locale = locale; } protected Object handleGetObject(String key) { return "value"; } public Enumeration getKeys() { return new Enumeration() { boolean gotten = false; public boolean hasMoreElements() { return !gotten; } public Object nextElement() { gotten = true; return "value"; } }; } } libgettext-commons-java-0.9.6/src/test/org/xnap/commons/i18n/testpackage/resources/0000755000175000017500000000000011271112344030535 5ustar giovannigiovanni././@LongLink0000000000000000000000000000015300000000000011564 Lustar rootrootlibgettext-commons-java-0.9.6/src/test/org/xnap/commons/i18n/testpackage/resources/HasItsOwnResources.javalibgettext-commons-java-0.9.6/src/test/org/xnap/commons/i18n/testpackage/resources/HasItsOwnResource0000644000175000017500000000013410765242505034057 0ustar giovannigiovannipackage org.xnap.commons.i18n.testpackage.resources; public class HasItsOwnResources { } libgettext-commons-java-0.9.6/src/test/org/xnap/commons/i18n/I18nManagerTest.java0000644000175000017500000000615310765242505027764 0ustar giovannigiovanni/* * Gettext Commons * * Copyright (C) 2005 Steffen Pingel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package org.xnap.commons.i18n; import java.util.Locale; import junit.framework.TestCase; import org.xnap.commons.i18n.testpackage.MockResourceBundle; /** * @author Felix Berger */ public class I18nManagerTest extends TestCase { private Locale savedDefault; protected void setUp() throws Exception { I18nFactory.clearCache(); savedDefault = Locale.getDefault(); Locale.setDefault(Locale.GERMAN); } protected void tearDown() throws Exception { Locale.setDefault(savedDefault); } public void testSetLocale() { I18n i18n = I18nFactory.getI18n(MockResourceBundle.class); assertEquals(Locale.GERMAN, i18n.getResources().getLocale()); I18nManager.getInstance().setDefaultLocale(Locale.FRENCH); assertEquals(Locale.FRENCH, i18n.getResources().getLocale()); I18nManager.getInstance().setDefaultLocale(Locale.GERMAN); assertEquals(Locale.GERMAN, i18n.getResources().getLocale()); } public void testListener() { MyLocaleChangeListener listener = new MyLocaleChangeListener(); I18nManager.getInstance().addLocaleChangeListener(listener ); assertEquals(0, listener.count); I18nManager.getInstance().setDefaultLocale(Locale.GERMAN); assertEquals(1, listener.count); assertEquals(Locale.GERMAN, listener.newLocale); I18nManager.getInstance().removeLocaleChangeListener(listener); I18nManager.getInstance().setDefaultLocale(Locale.FRENCH); assertEquals(1, listener.count); assertEquals(Locale.GERMAN, listener.newLocale); } public void testWeakListener() { int listenerCount = I18nManager.getInstance().localeChangeListeners.size(); MyLocaleChangeListener listener = new MyLocaleChangeListener(); I18nManager.getInstance().addWeakLocaleChangeListener(listener ); assertEquals(0, listener.count); assertEquals(listenerCount + 1, I18nManager.getInstance().localeChangeListeners.size()); I18nManager.getInstance().setDefaultLocale(Locale.GERMAN); assertEquals(1, listener.count); listener = null; System.gc(); I18nManager.getInstance().setDefaultLocale(Locale.FRENCH); assertEquals(listenerCount, I18nManager.getInstance().localeChangeListeners.size()); } private class MyLocaleChangeListener implements LocaleChangeListener { int count; Locale newLocale; public void localeChanged(LocaleChangeEvent event) { count++; newLocale = event.getNewLocale(); } }; } libgettext-commons-java-0.9.6/src/test/org/xnap/commons/i18n/I18nCacheTest.java0000644000175000017500000000411010765242504027403 0ustar giovannigiovanni/* * Gettext Commons * * Copyright (C) 2005 Steffen Pingel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package org.xnap.commons.i18n; import java.util.Locale; import junit.framework.TestCase; import org.xnap.commons.i18n.testpackage.MockResourceBundle; /** * @author Steffen Pingel */ public class I18nCacheTest extends TestCase { public void testGet() { I18nCache cache = new I18nCache(); I18n i18n = new I18n(new MockResourceBundle()); cache.put("foo", i18n); assertNull(cache.get("foo", Locale.getDefault())); try { cache.get("foo", null); fail("Expected IllegalArgumentException"); } catch (IllegalArgumentException expected) {} i18n.setLocale(Locale.ENGLISH); assertSame(i18n, cache.get("foo", Locale.ENGLISH)); } public void testClear() { I18nCache cache = new I18nCache(); I18n i18n = new I18n(new MockResourceBundle()); i18n.setLocale(Locale.ENGLISH); cache.put("foo", i18n); assertNotNull(cache.get("foo", Locale.ENGLISH)); cache.clear(); assertNull(cache.get("foo", Locale.ENGLISH)); } public void testVisit() { I18nCache cache = new I18nCache(); final I18n i18n = new I18n(new MockResourceBundle()); cache.put("foo", i18n); final int[] count = new int[1]; cache.visit(new I18nCache.Visitor() { public void visit(I18n visited) { assertSame(i18n, visited); count[0]++; } }); assertEquals(1, count[0]); } } libgettext-commons-java-0.9.6/src/test/org/xnap/commons/i18n/I18nTest.java0000644000175000017500000001373311144417142026464 0ustar giovannigiovanni/* * Gettext Commons * * Copyright (C) 2005 Steffen Pingel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package org.xnap.commons.i18n; import java.util.Locale; import java.util.MissingResourceException; import junit.framework.TestCase; import org.xnap.commons.i18n.testpackage.MockResourceBundle; /** * @author Steffen Pingel * @author Felix Berger */ public class I18nTest extends TestCase { public static final String BASENAME = "org.xnap.commons.i18n.Messages"; private I18n i18nDE; private I18n i18nEN; protected void setUp() throws Exception { try { i18nDE = new I18n(BASENAME, Locale.GERMAN, getClass().getClassLoader()); } catch (MissingResourceException e) { throw new RuntimeException( "Please make sure you run 'mvn org.xnap.commons:maven-gettext-plugin:dist' before executing tests"); } i18nEN = new I18n(BASENAME, Locale.ENGLISH, getClass().getClassLoader()); } protected void tearDown() throws Exception { } public void testTr() { assertEquals("Haus", i18nDE.tr("house")); assertEquals("Maus", i18nDE.tr("mouse")); assertEquals("Automatisch", i18nDE.tr("Automatic")); assertEquals("Erg\u00e4nzung", i18nDE.tr("Completion")); } public void testTr1() { assertEquals("House Nr. 2 ", i18nEN.tr("House Nr. {0} ", Integer.valueOf(2))); assertEquals("0", i18nEN.tr("{0}", "0")); } public void testTr2() { assertEquals("Foo bar foo", i18nEN.tr("Foo {1} {0}", "foo", "bar")); assertEquals("Foo foo bar", i18nEN.tr("Foo {0} {1}", "foo", "bar")); } public void testTr3() { assertEquals("Foo bar baz foo", i18nEN.tr("Foo {1} {2} {0}", "foo", "bar", "baz")); assertEquals("Foo foo bar baz", i18nEN.tr("Foo {0} {1} {2}", "foo", "bar", "baz")); } public void testTr4() { assertEquals("Foo bar baz boing foo", i18nEN.tr("Foo {1} {2} {3} {0}", "foo", "bar", "baz", "boing")); assertEquals("Foo foo bar baz boing", i18nEN.tr("Foo {0} {1} {2} {3}", "foo", "bar", "baz", "boing")); } public void testMarktr() { assertEquals(I18n.marktr("Foo"), "Foo"); } public void testTrc() { assertEquals("chat", i18nEN.trc("noun", "chat")); assertEquals("chat", i18nEN.trc("verb", "chat")); assertEquals("Chat", i18nDE.trc("noun", "chat")); assertEquals("Chatten", i18nDE.trc("verb", "chat")); } public void testSetLocale() { I18n i18n = new I18n(new MockResourceBundle()); assertFalse(i18n.setLocale(Locale.FRENCH)); i18n.setResources(MockResourceBundle.class.getName(), Locale.GERMAN, MockResourceBundle.class.getClassLoader()); assertTrue(i18n.setLocale(Locale.FRENCH)); } public void testSetResources() { try { new I18n(null); fail("NullPointerException expected"); } catch (NullPointerException npe) {} String baseName = MockResourceBundle.class.getName(); try { i18nDE.setResources(null, Locale.GERMAN, MockResourceBundle.class.getClassLoader()); fail("NullPointerException expected"); } catch (NullPointerException npe) {} try { i18nDE.setResources(baseName, null, MockResourceBundle.class.getClassLoader()); fail("NullPointerException expected"); } catch (NullPointerException npe) {} try { i18nDE.setResources(baseName, Locale.GERMAN, null); fail("NullPointerException expected"); } catch (NullPointerException npe) {} } public void testSetSourceCodeLocale() { i18nDE.setSourceCodeLocale(Locale.GERMAN); assertEquals("chat", i18nDE.trc("verb", "chat")); i18nDE.setSourceCodeLocale(Locale.ENGLISH); assertEquals("Chatten", i18nDE.trc("verb", "chat")); try { i18nDE.setSourceCodeLocale(null); fail("null pointer exception expected"); } catch (NullPointerException npe) {} } public void testTrnEN() { assertEquals("Foo", i18nEN.trn("Foo", "{0} Bars", 1)); assertEquals("{0} Bars", i18nEN.trn("Foo", "{0} Bars", 2)); assertEquals("2 Bars", i18nEN.trn("Foo", "{0} Bars", 2, new Integer(2))); } public void testTrnDE() { assertEquals("Datei", i18nDE.trn("File", "{0} Files", 1, new Integer(1))); assertEquals("2 Dateien", i18nDE.trn("File", "{0} Files", 2, new Integer(2))); } public void testTrn1() { assertEquals("Foo foo ", i18nEN.trn("Foo {0} ", "Foos {0}", 1, "foo")); } public void testTrn2() { assertEquals("Foo bar foo", i18nEN.trn("Foo {1} {0}", "Foos", 1, "foo", "bar")); assertEquals("Foo foo bar", i18nEN.trn("Foo {0} {1}", "Foos", 1, "foo", "bar")); } public void testTrn3() { assertEquals("Foo bar baz foo", i18nEN.trn("Foo {1} {2} {0}", "Foos", 1, "foo", "bar", "baz")); assertEquals("Foo foo bar baz", i18nEN.trn("Foo {0} {1} {2}", "Foos", 1, "foo", "bar", "baz")); } public void testTrn4() { assertEquals("Foo bar baz boing foo", i18nEN .trn("Foo {1} {2} {3} {0}", "Foos", 1, "foo", "bar", "baz", "boing")); assertEquals("Foo foo bar baz boing", i18nEN .trn("Foo {0} {1} {2} {3}", "Foos", 1, "foo", "bar", "baz", "boing")); } public void testSetEmptyResources() { // this should load the empty resource bundle // we have to set the default to italian too, so // ResourceBundle.getBundle(...) doesn't fall back on the default locale // which might be there Locale.setDefault(Locale.ITALIAN); assertTrue(i18nDE.setLocale(Locale.ITALIAN)); assertEquals("value", i18nDE.tr("value")); } public void testTrcReturnsTextWhenTranslationNotFound() { assertEquals("baobab", i18nDE.trc("dont translate to German", "baobab")); } } libgettext-commons-java-0.9.6/src/test/org/xnap/commons/i18n/EmptyResourceBundleTest.java0000644000175000017500000000221610765242503031704 0ustar giovannigiovanni/* * Gettext Commons * * Copyright (C) 2005 Steffen Pingel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package org.xnap.commons.i18n; import junit.framework.TestCase; /** * @author Steffen Pingel */ public class EmptyResourceBundleTest extends TestCase { public void test() { EmptyResourceBundle bundle = new EmptyResourceBundle(null); assertEquals("Foo", bundle.getObject("Foo")); assertFalse(bundle.getKeys().hasMoreElements()); } } libgettext-commons-java-0.9.6/README0000644000175000017500000000311110765242510017355 0ustar giovannigiovanniINTRODUCTION The Gettext Commons project provides Java classes for internationalization (i18n) through GNU gettext and Java ResourceBundles. This makes it possible to use the original text instead of arbitrary property keys, which is less cumbersome and makes programs easier to read. Gettext supports the easy extraction of user visible strings, marks strings as fuzzy when the original text changes to allow translators to check translations, powerful plural handling, and build process integration through Maven. A tutorial that describes how to use the Gettext Commons is available at http://code.google.com/p/gettext-commons/wiki/Tutorial . REQUIREMENTS * Java 1.3 (or higher) DEVELOPMENT Apache Maven 2.0 can be used to build the Gettext Commons. COPYRIGHT XNap Commons is distributed under the terms of the GNU Lesser General Public License, see LICENSE.txt for details. The icons directory contains images from the KDE project, see LICENSE.icons for terms of use. Copyright (C) 2005 Felix Berger Copyright (C) 2005 Steffen Pingel Copyright (C) 2005 Tammo van Lessen This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.