libbase-1.1.6/0000755000175000017500000000000011635761753011602 5ustar renerenelibbase-1.1.6/common_build.xml0000644000175000017500000020225611365604666015001 0ustar renerene ------------------------------------------------------------------------------- Common Build file provides tasks needed to perform a project build. It is typically not used directly but imported by each project's build.xml file. The build.xml file can override tasks when customization is required. MAIN TARGETS ============ * clean / clean-all : remove all artifacts of the build, clean-all adds the removal of any library or jar dependencies downloaded as part of the build * resolve : download/refresh library or jar dependencies needed for the build (uses Apache IVY) * compile : run javac on the project's source * jar : creates a jar file * dist : creates all project distributables * test : runs JUnit tests from your project's test source SPECIAL TARGETS ============ * publish-local : builds a jar for your project and registers it with the local artifact repository isolated to your machine at $HOME/.ivy2/local. Further executions of the the resolve target by this or other projects will find your published jar. * ivy-clean* : this family of targets helps reset your IVY environment in the event that you are having difficulty resolving dependencies TYPICAL TARGET SEQUENCE ============ * clean-all resolve dist : a good start to build all project distributables from scratch. Note that jar dependencies will not be downloaded unless you explicitly run the resolve target. We made the resolution and retrieval completely discretionary since there are many situations in which you will not want to get or refresh dependencies, e.g. if you are offline with no Internet access. In such case, you could just run "dist" if the set of jars you already have are sufficient. libbase-1.1.6/.project0000644000175000017500000000057711365604666013261 0ustar renerene libbase org.eclipse.jdt.core.javabuilder org.eclipse.jdt.core.javanature libbase-1.1.6/ChangeLog.txt0000644000175000017500000000277411365604666014203 0ustar renerene--------------- 1. WHAT's NEW --------------- A list of changes in recent versions: 1.0.0: (30-May-2008) * [BUG] Serialized configurations did not reconnect with a global configuration. * [BUG] Booting no longer stores references to all booted classes in a global collection. * [BUG] Fixed a deadlock when booting failed and a second boot attempt was made. * Downported I18N support from the engine. * Imported the majority of the sources from the stale JCommon project. * Switched logging to Apache-Commons-Logging. * Added a ClassQueryTool that (given enough perm-gen space) travereses through all classes on the classpath and can return the names of all classes matching a given criteria. It is not recommended to use this class at runtime; but it is a great tool for build-time generators for configuration files. * CSV-Reader and Writer support added. * StringUtils now contain a equivalent for the split method, but without relying on the expensive regular expressions. The StringTokenizer is a lot faster. * The module-configuration no longer relies on a home-grown fileformat and uses standard properties-files for describing modules and dependencies. * This code is a fork based on JCommon-1.0.12. JCommon is about to be deprecated and development on the JCommon library will stop as JFreeChart 1.2 is released. libbase-1.1.6/devresource/0000755000175000017500000000000011365604666014127 5ustar renerenelibbase-1.1.6/devresource/commons-logging.properties0000644000175000017500000000011111365604666021335 0ustar renereneorg.apache.commons.logging.Log=org.apache.commons.logging.impl.SimpleLog libbase-1.1.6/devresource/META-INF/0000755000175000017500000000000011365604666015267 5ustar renerenelibbase-1.1.6/devresource/META-INF/MANIFEST.MF0000644000175000017500000000032311365604666016717 0ustar renereneImplementation-Title: LibBase Implementation-Vendor: Pentaho Corporation Implementation-ProductID: libbase Release-Major-Number: 1 Release-Minor-Number: 0 Release-Milestone-Number: 0 Release-Candidate-Token: GA libbase-1.1.6/devresource/simplelog.properties0000644000175000017500000000106711365604666020244 0ustar renerene# suppress inspection "unused property" for whole file org.apache.commons.logging.simplelog.defaultlog=trace org.apache.commons.logging.simplelog.log.org.pentaho.reporting=trace org.apache.commons.logging.simplelog.log.com.opensymphony.oscache=warn org.apache.commons.logging.simplelog.log.net.sf.ehcache=warn org.apache.commons.logging.simplelog.log.org.apache.commons=warn org.apache.commons.logging.simplelog.showlogname=true org.apache.commons.logging.simplelog.log.org.pentaho.reporting.libraries.resourceloader.modules.cache.ehcache.EHCacheModule#CacheLog=warn libbase-1.1.6/ivysettings.xml0000644000175000017500000000174311365604666014720 0ustar renerene libbase-1.1.6/build.properties0000644000175000017500000000033711365604666015021 0ustar renereneproject.revision=1.1-SNAPSHOT ivy.artifact.group=pentaho-library ivy.artifact.id=libbase impl.title=Libbase impl.productID=libbase src.dir=${basedir}/source testsrc.dir=${basedir}/testcases java.awt.headless=true libbase-1.1.6/ant/0000755000175000017500000000000011365604666012363 5ustar renerenelibbase-1.1.6/ant/build-lib.xml0000644000175000017500000006224211365604666014756 0ustar renerene libbase-1.1.6/dev-lib/0000755000175000017500000000000011365604672013120 5ustar renerenelibbase-1.1.6/licence-LGPL.txt0000644000175000017500000006605011365604666014507 0ustar renerene 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 As a special exception, the copyright holders of JFreeReport give you permission to extend JFreeReport with independent modules that communicate with JFreeReport solely through the "Expression" or the "Function" interface, regardless of the license terms of these independent modules, and to copy and distribute the resulting combined work under terms of your choice, provided that every copy of the combined work is accompanied by a complete copy of the source code of JFreeReport (the version of JFreeReport used to produce the combined work), being distributed under the terms of the GNU Lesser General Public License plus this exception. An independent module is a module which is not derived from or based on JFreeReport. This exception applies to the Java interfaces "Expression" and "Function" and the classes "AbstractExpression" and "AbstractFunction". Note that people who make modified versions of JFreeReport are not obligated to grant this special exception for their modified versions; it is their choice whether to do so. The GNU Lesser General Public License gives permission to release a modified version without this exception; this exception also makes it possible to release a modified version which carries forward this exception. 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! libbase-1.1.6/libbase.iml0000644000175000017500000001756711365604666013725 0ustar renerene libbase-1.1.6/source/0000755000175000017500000000000011365604664013077 5ustar renerenelibbase-1.1.6/source/org/0000755000175000017500000000000011365604664013666 5ustar renerenelibbase-1.1.6/source/org/pentaho/0000755000175000017500000000000011365604664015324 5ustar renerenelibbase-1.1.6/source/org/pentaho/reporting/0000755000175000017500000000000011365604664017335 5ustar renerenelibbase-1.1.6/source/org/pentaho/reporting/libraries/0000755000175000017500000000000011365604664021311 5ustar renerenelibbase-1.1.6/source/org/pentaho/reporting/libraries/base/0000755000175000017500000000000011365604666022225 5ustar renerenelibbase-1.1.6/source/org/pentaho/reporting/libraries/base/boot/0000755000175000017500000000000011365604664023166 5ustar renerenelibbase-1.1.6/source/org/pentaho/reporting/libraries/base/boot/ModuleInfo.java0000644000175000017500000000426411365604664026100 0ustar renerene/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2007 - 2009 Pentaho Corporation and Contributors. All rights reserved. */ package org.pentaho.reporting.libraries.base.boot; /** * The Module info class encapsulates metadata about a given module. It holds the * list of dependencies and the module version and description. * * @author Thomas Morgner */ public interface ModuleInfo { /** * Returns the module class of the desired base module. * * @return The module class. */ public String getModuleClass(); /** * Returns the major version of the base module. The string should * contain a compareable character sequence so that higher versions * of the module are considered greater than lower versions. * * @return The major version of the module. */ public String getMajorVersion(); /** * Returns the minor version of the base module. The string should * contain a compareable character sequence so that higher versions * of the module are considered greater than lower versions. * * @return The minor version of the module. */ public String getMinorVersion(); /** * Returns the patchlevel version of the base module. The patch level * should be used to mark bugfixes. The string should * contain a compareable character sequence so that higher versions * of the module are considered greater than lower versions. * * @return The patch level version of the module. */ public String getPatchLevel(); }libbase-1.1.6/source/org/pentaho/reporting/libraries/base/boot/PackageSorter.java0000644000175000017500000003337211365604664026573 0ustar renerene/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2007 - 2009 Pentaho Corporation and Contributors. All rights reserved. */ package org.pentaho.reporting.libraries.base.boot; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.pentaho.reporting.libraries.base.util.ObjectUtilities; /** * Compares two modules for order. A module is considered less than an other * module if the module is a required module of the compared module. Modules * are considered equal if they have no relation. *

* When sorting, we match this modules position against all dependent * modules until all positions are stable. Circular references are evil * and are filtered during the module loading process in the package manager. * * @author Thomas Morgner * @noinspection ComparableImplementedButEqualsNotOverridden */ public final class PackageSorter { /** * An Internal wrapper class which collects additional information * on the given module. Every module has a position, which is heigher * than the position of all dependent modules. * * @author Thomas Morgner */ private static class SortModule implements Comparable { /** * stores the relative position of the module in the global list. */ private int position; /** * The package state of the to be matched module. */ private final PackageState state; /** * A list of all directly dependent subsystems. */ private ArrayList dependSubsystems; // direct dependencies, indirect ones are handled by the // dependent classes ... /** * Creates a new SortModule for the given package state. * * @param state the package state object, that should be wrapped up * by this class. * @noinspection PublicConstructorInNonPublicClass */ private SortModule(final PackageState state) { this.position = -1; this.state = state; } /** * Returns the list of all dependent subsystems. The list gets defined * when the sorting is started. * * @return the list of all dependent subsystems. */ public ArrayList getDependSubsystems() { return this.dependSubsystems; } /** * Defines a list of dependent subsystems for this module. The list contains * the names of the dependent subsystems as strings. * * @param dependSubsystems a list of all dependent subsystems, never null. * @noinspection AssignmentToCollectionOrArrayFieldFromParameter as this is a 100% private class and it is * guaranteed that no one is going to change the array list in question. */ public void setDependSubsystems(final ArrayList dependSubsystems) { this.dependSubsystems = dependSubsystems; } /** * Returns the current position of this module in the global list. * The position is computed by comparing all positions of all dependent * subsystem modules. * * @return the current module position. */ public int getPosition() { return this.position; } /** * Defines the position of this module in the global list of all * known modules. * * @param position the position. */ public void setPosition(final int position) { this.position = position; } /** * Returns the package state contained in this SortModule. * * @return the package state of this module. */ public PackageState getState() { return this.state; } /** * Returns a basic string representation of this SortModule. This * should be used for debugging purposes only. * * @return a string representation of this module. * @see Object#toString() */ public String toString() { final StringBuffer buffer = new StringBuffer(100); buffer.append("SortModule: "); buffer.append(this.position); buffer.append(' '); buffer.append(this.state.getModule().getName()); buffer.append(' '); buffer.append(this.state.getModule().getModuleClass()); return buffer.toString(); } /** * Compares this module against an other sort module. * * @param o the other sort module instance. * @return -1 if the other's module position is less than * this modules position, +1 if this module is less than the * other module or 0 if both modules have an equal position in * the list. * @see Comparable#compareTo(Object) */ public int compareTo(final Object o) { final SortModule otherModule = (SortModule) o; if (this.position > otherModule.position) { return +1; } if (this.position < otherModule.position) { return -1; } return 0; } } /** A logger for debug-messages. */ private static final Log LOGGER = LogFactory.getLog(PackageSorter.class); /** * DefaultConstructor. */ private PackageSorter() { // nothing required. } /** * Sorts the given list of package states. The packages * are sorted by their dependencies in a way so that all * dependent packages are placed on lower positions than * the packages which declared the dependency. * * @param modules the list of modules. */ public static void sort(final List modules) { if (modules == null) { throw new NullPointerException(); } final HashMap moduleMap = new HashMap(); final ArrayList errorModules = new ArrayList(); final ArrayList weightModules = new ArrayList(); final int modulesCount = modules.size(); for (int i = 0; i < modulesCount; i++) { final PackageState state = (PackageState) modules.get(i); if (state.getState() == PackageState.STATE_ERROR) { errorModules.add(state); } else { final SortModule mod = new SortModule(state); weightModules.add(mod); moduleMap.put(state.getModule().getModuleClass(), mod); } } final SortModule[] weigths = (SortModule[]) weightModules.toArray(new SortModule[weightModules.size()]); for (int i = 0; i < weigths.length; i++) { final SortModule sortMod = weigths[i]; sortMod.setDependSubsystems (collectSubsystemModules(sortMod.getState().getModule(), moduleMap)); } // repeat the computation until all modules have a matching // position. This is not the best algorithm, but it works // and is relativly simple. It will need some optimizations // in the future, but as this is only executed once, we don't // have to care much about it. boolean doneWork = true; while (doneWork) { doneWork = false; for (int i = 0; i < weigths.length; i++) { final SortModule mod = weigths[i]; final int position = searchModulePosition(mod, moduleMap); if (position != mod.getPosition()) { mod.setPosition(position); doneWork = true; } } } Arrays.sort(weigths); modules.clear(); for (int i = 0; i < weigths.length; i++) { modules.add(weigths[i].getState()); } for (int i = 0; i < errorModules.size(); i++) { modules.add(errorModules.get(i)); } } /** * Computes the new module position. This position is computed * according to the dependent modules and subsystems. The returned * position will be higher than the highest dependent module position. * * @param smodule the sort module for that we compute the new positon. * @param moduleMap the map with all modules. * @return the new positon. */ private static int searchModulePosition (final SortModule smodule, final HashMap moduleMap) { final Module module = smodule.getState().getModule(); int position = 0; // check the required modules. Increase our level to at least // one point over the highest dependent module // ignore missing modules. final ModuleInfo[] optionalModules = module.getOptionalModules(); for (int modPos = 0; modPos < optionalModules.length; modPos++) { final String moduleName = optionalModules[modPos].getModuleClass(); final SortModule reqMod = (SortModule) moduleMap.get(moduleName); if (reqMod == null) { continue; } if (reqMod.getPosition() >= position) { position = reqMod.getPosition() + 1; } } // check the required modules. Increase our level to at least // one point over the highest dependent module // there are no missing modules here (or the package manager // is invalid) final ModuleInfo[] requiredModules = module.getRequiredModules(); for (int modPos = 0; modPos < requiredModules.length; modPos++) { final String moduleName = requiredModules[modPos].getModuleClass(); final SortModule reqMod = (SortModule) moduleMap.get(moduleName); if (reqMod == null) { LOGGER.warn("Invalid state: Required dependency of '" + moduleName + "' had an error."); continue; } if (reqMod.getPosition() >= position) { position = reqMod.getPosition() + 1; } } // check the subsystem dependencies. This way we make sure // that subsystems are fully initialized before we try to use // them. final String subSystem = module.getSubSystem(); final Iterator it = moduleMap.values().iterator(); while (it.hasNext()) { final SortModule mod = (SortModule) it.next(); // it is evil to compute values on ourself... if (mod.getState().getModule() == module) { // same module ... continue; } final Module subSysMod = mod.getState().getModule(); // if the module we check is part of the same subsystem as // we are, then we dont do anything. Within the same subsystem // the dependencies are computed solely by the direct references. if (ObjectUtilities.equal(subSystem, subSysMod.getSubSystem())) { // same subsystem ... ignore continue; } // does the module from the global list depend on the // subsystem we are part of? // // if yes, we have a relation and may need to adjust the level... if (smodule.getDependSubsystems().contains(subSysMod.getSubSystem())) { // check whether the module is a base module of the given // subsystem. We will not adjust our position in that case, // as this would lead to an infinite loop if (isBaseModule(subSysMod, module) == false) { if (mod.getPosition() >= position) { position = mod.getPosition() + 1; } } } } return position; } /** * Checks, whether a module is a base module of an given module. * * @param mod the module which to check * @param mi the module info of the suspected base module. * @return true, if the given module info describes a base module of the * given module, false otherwise. */ private static boolean isBaseModule(final Module mod, final ModuleInfo mi) { final ModuleInfo[] requiredModules = mod.getRequiredModules(); for (int i = 0; i < requiredModules.length; i++) { if (requiredModules[i].getModuleClass().equals(mi.getModuleClass())) { return true; } } final ModuleInfo[] optionalModules = mod.getOptionalModules(); for (int i = 0; i < optionalModules.length; i++) { if (optionalModules[i].getModuleClass().equals(mi.getModuleClass())) { return true; } } return false; } /** * Collects all directly dependent subsystems. * * @param childMod the module which to check * @param moduleMap the map of all other modules, keyed by module class. * @return the list of all dependent subsystems. */ private static ArrayList collectSubsystemModules (final Module childMod, final HashMap moduleMap) { final ArrayList collector = new ArrayList(); final ModuleInfo[] requiredModules = childMod.getRequiredModules(); for (int i = 0; i < requiredModules.length; i++) { final SortModule dependentModule = (SortModule) moduleMap.get(requiredModules[i].getModuleClass()); if (dependentModule == null) { LOGGER.warn ("A dependent module was not found in the list of known modules." + requiredModules[i].getModuleClass()); continue; } collector.add(dependentModule.getState().getModule().getSubSystem()); } final ModuleInfo[] optionalModules = childMod.getOptionalModules(); for (int i = 0; i < optionalModules.length; i++) { final Module dependentModule = (Module) moduleMap.get(optionalModules[i].getModuleClass()); if (dependentModule == null) { LOGGER.warn("A dependent module was not found in the list of known modules."); continue; } collector.add(dependentModule.getSubSystem()); } return collector; } }libbase-1.1.6/source/org/pentaho/reporting/libraries/base/boot/SubSystem.java0000644000175000017500000000356011365604664025773 0ustar renerene/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2007 - 2009 Pentaho Corporation and Contributors. All rights reserved. */ package org.pentaho.reporting.libraries.base.boot; import org.pentaho.reporting.libraries.base.config.Configuration; import org.pentaho.reporting.libraries.base.config.ExtendedConfiguration; /** * A sub-system holds a separate collection of modules. *

* On a simple level, subsystems can be just libraries. * Libraries offering services need a controlled way to * initialize these services before dependent code starts * using the library. This can be achived by embedding the * library services into an own subsystem. * * @author Thomas Morgner */ public interface SubSystem { /** * Returns the global configuration. * * @return The global configuration. */ public Configuration getGlobalConfig(); /** * Returns the global configuration as ExtendedConfiguration instance. * * @return the extended configuration. */ public ExtendedConfiguration getExtendedConfig(); /** * Returns the package manager. * * @return The package manager. */ public PackageManager getPackageManager(); }libbase-1.1.6/source/org/pentaho/reporting/libraries/base/boot/Module.java0000644000175000017500000000611111365604664025255 0ustar renerene/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2007 - 2009 Pentaho Corporation and Contributors. All rights reserved. */ package org.pentaho.reporting.libraries.base.boot; /** * A module encapsulates optional functionality within a project. Modules can * be used as an easy way to make projects more configurable. *

* The module system provides a controled way to check dependencies and to initialize * the modules in a controlled way. * * @author Thomas Morgner */ public interface Module extends ModuleInfo { /** * Returns an array of all required modules. If one of these modules is missing * or cannot be initialized, the module itself will be not available. * * @return an array of the required modules. */ public ModuleInfo[] getRequiredModules(); /** * Returns an array of optional modules. Missing or invalid modules are non fatal * and will not harm the module itself. * * @return an array of optional module specifications. */ public ModuleInfo[] getOptionalModules(); /** * Initializes the module. Use this method to perform all initial setup operations. * This method is called only once in a modules lifetime. If the initializing cannot * be completed, throw a ModuleInitializeException to indicate the error,. The module * will not be available to the system. * * @param subSystem the subSystem. * @throws ModuleInitializeException if an error ocurred while initializing the module. */ public void initialize(SubSystem subSystem) throws ModuleInitializeException; /** * Configures the module. This should load the default settings of the module. * * @param subSystem the subSystem. */ public void configure(SubSystem subSystem); /** * Returns a short description of the modules functionality. * * @return a module description. */ public String getDescription(); /** * Returns the name of the module producer. * * @return the producer name */ public String getProducer(); /** * Returns the module name. This name should be a short descriptive handle of the * module. * * @return the module name */ public String getName(); /** * Returns the modules subsystem. If this module is not part of an subsystem * then return the modules name, but never null. * * @return the name of the subsystem. */ public String getSubSystem(); }libbase-1.1.6/source/org/pentaho/reporting/libraries/base/boot/DefaultModuleInfo.java0000644000175000017500000001436211365604664027405 0ustar renerene/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2007 - 2009 Pentaho Corporation and Contributors. All rights reserved. */ package org.pentaho.reporting.libraries.base.boot; /** * Provides a default implementation of the module info interface. * * @author Thomas Morgner */ public class DefaultModuleInfo implements ModuleInfo { /** * The name of the module class. */ private String moduleClass; /** * The major version of the described module. */ private String majorVersion; /** * The minor version of the described module. */ private String minorVersion; /** * The patchlevel version of the described module. */ private String patchLevel; /** * DefaultConstructor. */ public DefaultModuleInfo() { // nothing required } /** * Creates a new module info an initalizes it with the given values. * * @param moduleClass the class name of the module implementation holding the module * description. * @param majorVersion the modules major version. * @param minorVersion the modules minor version. * @param patchLevel the modules patchlevel. * @throws NullPointerException if the moduleClass is null. */ public DefaultModuleInfo(final String moduleClass, final String majorVersion, final String minorVersion, final String patchLevel) { if (moduleClass == null) { throw new NullPointerException("Module class must not be null."); } this.moduleClass = moduleClass; this.majorVersion = majorVersion; this.minorVersion = minorVersion; this.patchLevel = patchLevel; } /** * Returns the class name of the module described implementation. * * @return the module class name. * @see ModuleInfo#getModuleClass() */ public String getModuleClass() { return this.moduleClass; } /** * Defines the module class name. * * @param moduleClass the class name of the module implementation. */ public void setModuleClass(final String moduleClass) { if (moduleClass == null) { throw new NullPointerException(); } this.moduleClass = moduleClass; } /** * Returns the major version of the module. This property may be * null to indicate that the module version is not specified. * * @return the major version. * @see ModuleInfo#getMajorVersion() */ public String getMajorVersion() { return this.majorVersion; } /** * Defines the major version of the module. This property may be * null to indicate that the module version is not specified. * * @param majorVersion the major version. * @see ModuleInfo#getMajorVersion() */ public void setMajorVersion(final String majorVersion) { this.majorVersion = majorVersion; } /** * Returns the minor version of the module. This property may be * null to indicate that the module version is not specified. * * @return the minor version. * @see ModuleInfo#getMajorVersion() */ public String getMinorVersion() { return this.minorVersion; } /** * Defines the minor version of the module. This property may be * null to indicate that the module version is not specified. * * @param minorVersion the minor version. * @see ModuleInfo#getMajorVersion() */ public void setMinorVersion(final String minorVersion) { this.minorVersion = minorVersion; } /** * Returns the patch level version of the module. This property may be * null to indicate that the module version is not specified. * * @return the patch level version. * @see ModuleInfo#getMajorVersion() */ public String getPatchLevel() { return this.patchLevel; } /** * Defines the patch level version of the module. This property may be * null to indicate that the module version is not specified. * * @param patchLevel the patch level version. * @see ModuleInfo#getMajorVersion() */ public void setPatchLevel(final String patchLevel) { this.patchLevel = patchLevel; } /** * Two moduleinfos are equal,if they have the same module class. * * @param o the other object to compare. * @return true, if the module points to the same module, false otherwise. */ public boolean equals(final Object o) { if (this == o) { return true; } if (!(o instanceof DefaultModuleInfo)) { return false; } final ModuleInfo defaultModuleInfo = (ModuleInfo) o; if (!this.moduleClass.equals(defaultModuleInfo.getModuleClass())) { return false; } return true; } /** * Computes an hashcode for this module information. * * @return the hashcode. * @see Object#hashCode() */ public int hashCode() { final int result; result = this.moduleClass.hashCode(); return result; } /** * Returns a string representation of this module information. * * @return a string describing this class. * @see Object#toString() */ public String toString() { final StringBuffer buffer = new StringBuffer(128); buffer.append(getClass().getName()); buffer.append("={ModuleClass="); buffer.append(getModuleClass()); if (getMajorVersion() != null) { buffer.append("; Version="); buffer.append(getMajorVersion()); if (getMinorVersion() != null) { buffer.append('-'); buffer.append(getMinorVersion()); if (getPatchLevel() != null) { buffer.append('_'); buffer.append(getPatchLevel()); } } } buffer.append('}'); return buffer.toString(); } }libbase-1.1.6/source/org/pentaho/reporting/libraries/base/boot/ModuleInitializer.java0000644000175000017500000000311711365604664027464 0ustar renerene/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2007 - 2009 Pentaho Corporation and Contributors. All rights reserved. */ package org.pentaho.reporting.libraries.base.boot; /** * The module initializer is used to separate the initialization process from * the module definition. An invalid classpath setup or an missing base module * may throw an ClassCastException if the module class references this missing * resource. Separating them is the best way to make sure that the classloader * does not interrupt the module loading process. * * @author Thomas Morgner */ public interface ModuleInitializer { /** * Performs the initalization of the module. * * @throws ModuleInitializeException if an error occurs which prevents the module * from being usable. */ public void performInit() throws ModuleInitializeException; }libbase-1.1.6/source/org/pentaho/reporting/libraries/base/boot/PackageState.java0000644000175000017500000001623011365604664026367 0ustar renerene/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2007 - 2009 Pentaho Corporation and Contributors. All rights reserved. */ package org.pentaho.reporting.libraries.base.boot; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * The package state class is used by the package manager to keep track of * the activation level of the installed or errornous packages. *

* This is an internal class used by the PackageManager. * * @author Thomas Morgner */ public class PackageState { /** A logger. */ private static final Log LOGGER = LogFactory.getLog(PackageState.class); /** * A constant defining that the package is new. */ public static final int STATE_NEW = 0; /** * A constant defining that the package has been loaded and configured. */ public static final int STATE_CONFIGURED = 1; /** * A constant defining that the package was initialized and is ready to use. */ public static final int STATE_INITIALIZED = 2; /** * A constant defining that the package produced an error and is not available. */ public static final int STATE_ERROR = -2; /** * The module class that contains the package information. */ private final Module module; /** * The state of the module. */ private int state; /** * Creates a new package state for the given module. The module state will * be initialized to STATE_NEW. * * @param module the module. */ public PackageState(final Module module) { this(module, STATE_NEW); } /** * Creates a new package state for the given module. The module state will * be initialized to the given initial state. * * @param module the module. * @param state the initial state */ public PackageState(final Module module, final int state) { if (module == null) { throw new NullPointerException("Module must not be null."); } if (state != STATE_CONFIGURED && state != STATE_ERROR && state != STATE_INITIALIZED && state != STATE_NEW) { throw new IllegalArgumentException("State is not valid"); } this.module = module; this.state = state; } /** * Configures the module and raises the state to STATE_CONFIGURED if the * module is not yet configured. * * @param subSystem the sub-system. * @return true, if the module was configured, false otherwise. */ public boolean configure(final SubSystem subSystem) { if (subSystem == null) { throw new NullPointerException(); } if (this.state == STATE_NEW) { try { this.module.configure(subSystem); this.state = STATE_CONFIGURED; return true; } catch (NoClassDefFoundError noClassDef) { LOGGER.warn("Unable to load module classes for " + this.module.getName() + ':' + noClassDef.getMessage()); this.state = STATE_ERROR; } catch (Exception e) { if (LOGGER.isDebugEnabled()) { // its still worth a warning, but now we are more verbose ... LOGGER.warn("Unable to configure the module " + this.module.getName(), e); } else if (LOGGER.isWarnEnabled()) { LOGGER.warn("Unable to configure the module " + this.module.getName()); } this.state = STATE_ERROR; } } return false; } /** * Returns the module managed by this state implementation. * * @return the module. */ public Module getModule() { return this.module; } /** * Returns the current state of the module. This method returns either * STATE_NEW, STATE_CONFIGURED, STATE_INITIALIZED or STATE_ERROR. * * @return the module state. */ public int getState() { return this.state; } /** * Initializes the contained module and raises the set of the module to * STATE_INITIALIZED, if the module was not yet initialized. In case of an * error, the module state will be set to STATE_ERROR and the module will * not be available. * * @param subSystem the sub-system. * @return true, if the module was successfully initialized, false otherwise. */ public boolean initialize(final SubSystem subSystem) { if (subSystem == null) { throw new NullPointerException(); } if (this.state == STATE_CONFIGURED) { try { this.module.initialize(subSystem); this.state = STATE_INITIALIZED; return true; } catch (NoClassDefFoundError noClassDef) { LOGGER.warn("Unable to load module classes for " + this.module.getName() + ':' + noClassDef.getMessage()); this.state = STATE_ERROR; } catch (ModuleInitializeException me) { if (LOGGER.isDebugEnabled()) { // its still worth a warning, but now we are more verbose ... LOGGER.warn("Unable to initialize the module " + this.module.getName(), me); } else if (LOGGER.isWarnEnabled()) { LOGGER.warn("Unable to initialize the module " + this.module.getName()); } this.state = STATE_ERROR; } catch (Exception e) { if (LOGGER.isDebugEnabled()) { // its still worth a warning, but now we are more verbose ... LOGGER.warn("Unable to initialize the module " + this.module.getName(), e); } else if (LOGGER.isWarnEnabled()) { LOGGER.warn("Unable to initialize the module " + this.module.getName()); } this.state = STATE_ERROR; } } return false; } /** * Compares this object with the given other object for equality. * * @param o the other object to be compared * @return true, if the other object is also a PackageState containing * the same module, false otherwise. * @see Object#equals(Object) */ public boolean equals(final Object o) { if (this == o) { return true; } if (!(o instanceof PackageState)) { return false; } final PackageState packageState = (PackageState) o; if (!this.module.getModuleClass().equals(packageState.module.getModuleClass())) { return false; } return true; } /** * Computes a hashcode for this package state. * * @return the hashcode. * @see Object#hashCode() */ public int hashCode() { return this.module.hashCode(); } /** * Marks this package state as invalid. */ public void markError() { this.state = STATE_ERROR; } }libbase-1.1.6/source/org/pentaho/reporting/libraries/base/boot/AbstractBoot.java0000644000175000017500000003145111365604664026424 0ustar renerene/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2007 - 2009 Pentaho Corporation and Contributors. All rights reserved. */ package org.pentaho.reporting.libraries.base.boot; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Method; import java.net.URL; import java.util.ArrayList; import java.util.Enumeration; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.pentaho.reporting.libraries.base.config.Configuration; import org.pentaho.reporting.libraries.base.config.ExtendedConfiguration; import org.pentaho.reporting.libraries.base.config.ExtendedConfigurationWrapper; import org.pentaho.reporting.libraries.base.config.HierarchicalConfiguration; import org.pentaho.reporting.libraries.base.config.PropertyFileConfiguration; import org.pentaho.reporting.libraries.base.config.SystemPropertyConfiguration; import org.pentaho.reporting.libraries.base.util.ObjectUtilities; import org.pentaho.reporting.libraries.base.versioning.DependencyInformation; import org.pentaho.reporting.libraries.base.versioning.ProjectInformation; /** * The common base for all Boot classes. *

* This initializes the subsystem and all dependent subsystems. Implementors of this class have to provide a public * static getInstance() method which returns a singleton instance of the booter implementation. *

* Further creation of Boot object should be prevented using protected or private constructors in that class, or proper * singleton behaviour cannot be guaranteed. * * @author Thomas Morgner */ public abstract class AbstractBoot implements SubSystem { /** * The logger for this class. */ private static final Log LOGGER = LogFactory.getLog(AbstractBoot.class); /** * The configuration wrapper around the plain configuration. */ private ExtendedConfigurationWrapper extWrapper; /** * A packageManager instance of the package manager. */ private PackageManager packageManager; /** * Global configuration. */ private Configuration globalConfig; /** * A flag indicating whether the booting is currenly in progress. */ private boolean bootInProgress; /** * A flag indicating whether the booting is complete. */ private boolean bootDone; /** * The reason why booting failed for easier debugging or logging. */ private Exception bootFailed; /** * Default constructor. */ protected AbstractBoot() { } /** * Returns the packageManager instance of the package manager. * * @return The package manager. */ public synchronized PackageManager getPackageManager() { if (this.packageManager == null) { this.packageManager = new PackageManager(this); } return this.packageManager; } /** * Returns the global configuration. * * @return The global configuration. */ public synchronized Configuration getGlobalConfig() { if (this.globalConfig == null) { this.globalConfig = loadConfiguration(); } return this.globalConfig; } /** * Checks, whether the booting is in progress. * * @return true, if the booting is in progress, false otherwise. */ public final synchronized boolean isBootInProgress() { return this.bootInProgress; } /** * Checks, whether the booting is complete. * * @return true, if the booting is complete, false otherwise. */ public final synchronized boolean isBootDone() { return this.bootDone; } /** * Loads the configuration. This will be called exactly once. * * @return The configuration. */ protected abstract Configuration loadConfiguration(); /** * Starts the boot process. The boot process is synchronized and will block if parallel booting is not finished yet. * Any failure in booting will set the bootFailed property to true. If booting is finished, the * bootDone property is set to true. */ public final void start() { synchronized (this) { if (isBootDone()) { return; } if (isBootFailed()) { LOGGER.error(getClass() + " failed to boot: " + bootFailed.getMessage()); } while (isBootInProgress()) { try { wait(); } catch (InterruptedException e) { // ignore .. } } if (isBootDone()) { notifyAll(); return; } this.bootInProgress = true; } try { // boot dependent libraries ... final ProjectInformation info = getProjectInfo(); if (info != null) { performBootDependencies(info.getLibraries()); performBootDependencies(info.getOptionalLibraries()); } performBoot(); if (info != null) { LOGGER.info(info.getName() + ' ' + info.getVersion() + " started."); } else { LOGGER.info(getClass() + " started."); } } catch (Exception e) { LOGGER.error(getClass() + " failed to boot: ", e); this.bootFailed = e; } finally { synchronized (this) { this.bootInProgress = false; this.bootDone = true; notifyAll(); } } } /** * Boots all dependent libraries. The dependencies must be initialized properly before the booting of this * library or application can start. If any of the dependencies fails to initialize properly, the whole * boot-process will be aborted. * * @param childs the array of dependencies, never null. */ private void performBootDependencies(final DependencyInformation[] childs) { if (childs == null) { return; } for (int i = 0; i < childs.length; i++) { final DependencyInformation child = childs[i]; if (child instanceof ProjectInformation == false) { continue; } final ProjectInformation projectInformation = (ProjectInformation) child; final AbstractBoot boot = loadBooter(projectInformation.getBootClass()); if (boot != null) { // but we're waiting until the booting is complete ... synchronized (boot) { boot.start(); while (boot.isBootDone() == false && boot.isBootFailed() == false) { try { boot.wait(); } catch (InterruptedException e) { // ignore it .. } } if (boot.isBootFailed()) { this.bootFailed = boot.getBootFailureReason(); LOGGER.error("Dependent project failed to boot up: " + projectInformation.getBootClass() + " failed to boot: ", this.bootFailed); return; } } } } } /** * Checks whether the booting failed. If booting failed, the reason for the failure (the Exception that caused * the error) is stored as property bootFailureReason. * * @return true, if booting failed, false otherwise. */ public boolean isBootFailed() { return this.bootFailed != null; } /** * Returns the failure reason for the boot process. This method returns null, if booting was successful. * * @return the failure reason. */ public Exception getBootFailureReason() { return bootFailed; } /** * Performs the boot. */ protected abstract void performBoot(); /** * Returns the project info. * * @return The project info. */ protected abstract ProjectInformation getProjectInfo(); /** * Loads the specified booter implementation. * * @param classname the class name. * @return The boot class. */ protected AbstractBoot loadBooter(final String classname) { return loadBooter(classname, getClass()); } /** * Loads the specified booter-class. * * @param classname the classname of the booter class. * @param source the source-class from where to get the classloader. * @return the instantiated booter or null, if no booter could be loaded. */ public static AbstractBoot loadBooter(final String classname, final Class source) { if (classname == null) { return null; } if (source == null) { throw new NullPointerException(); } try { final ClassLoader loader = ObjectUtilities.getClassLoader(source); final Class c = Class.forName(classname, false, loader); final Method m = c.getMethod("getInstance", (Class[]) null); return (AbstractBoot) m.invoke(null, (Object[]) null); } catch (Exception e) { LOGGER.info("Unable to boot dependent class: " + classname); return null; } } /** * Creates a default configuration setup, which loads its settings from the static configuration (defaults provided by * the developers of the library) and the user configuration (settings provided by the deployer). The deployer's * settings override the developer's settings. *

* If the parameter addSysProps is set to true, the system properties will be added as third * configuration layer. The system properties configuration allows to override all other settings. * * @param staticConfig the resource name of the developers configuration * @param userConfig the resource name of the deployers configuration * @param addSysProps a flag defining whether to include the system properties into the configuration. * @param source the classloader source to load resources from. * @return the configured Configuration instance. */ protected Configuration createDefaultHierarchicalConfiguration (final String staticConfig, final String userConfig, final boolean addSysProps, final Class source) { if (source == null) { throw new NullPointerException("SourceClass must not be null."); } final HierarchicalConfiguration globalConfig = new HierarchicalConfiguration(getClass()); if (staticConfig != null) { final PropertyFileConfiguration rootProperty = new PropertyFileConfiguration(); rootProperty.load(staticConfig, source); globalConfig.insertConfiguration(rootProperty); globalConfig.insertConfiguration(getPackageManager().getPackageConfiguration()); } if (userConfig != null) { final String userConfigStripped; if (userConfig.charAt(0) == '/') { userConfigStripped = userConfig.substring(1); } else { userConfigStripped = userConfig; } try { final Enumeration userConfigs = ObjectUtilities.getClassLoader(source).getResources(userConfigStripped); final ArrayList configs = new ArrayList(); while (userConfigs.hasMoreElements()) { final URL url = (URL) userConfigs.nextElement(); try { final PropertyFileConfiguration baseProperty = new PropertyFileConfiguration(); final InputStream in = url.openStream(); try { baseProperty.load(in); } finally { in.close(); } configs.add(baseProperty); } catch (IOException ioe) { LOGGER.warn("Failed to load the user configuration at " + url, ioe); } } for (int i = configs.size() - 1; i >= 0; i--) { final PropertyFileConfiguration baseProperty = (PropertyFileConfiguration) configs.get(i); globalConfig.insertConfiguration(baseProperty); } } catch (IOException e) { LOGGER.warn("Failed to lookup the user configurations.", e); } } if (addSysProps) { final SystemPropertyConfiguration systemConfig = new SystemPropertyConfiguration(); globalConfig.insertConfiguration(systemConfig); } return globalConfig; } /** * Returns the global configuration as extended configuration. * * @return the extended configuration. */ public synchronized ExtendedConfiguration getExtendedConfig() { if (extWrapper == null) { extWrapper = new ExtendedConfigurationWrapper(getGlobalConfig()); } return extWrapper; } }libbase-1.1.6/source/org/pentaho/reporting/libraries/base/boot/ModuleInitializeException.java0000644000175000017500000000367711365604664031174 0ustar renerene/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2007 - 2009 Pentaho Corporation and Contributors. All rights reserved. */ package org.pentaho.reporting.libraries.base.boot; import org.pentaho.reporting.libraries.base.util.StackableException; /** * This exception is thrown when the module initialization encountered an * unrecoverable error which prevents the module from being used. * * @author Thomas Morgner */ public class ModuleInitializeException extends StackableException { /** A serialization related constant. */ private static final long serialVersionUID = -8742325619631583144L; /** * Creates a ModuleInitializeException with no message and no base * exception. */ public ModuleInitializeException() { // nothing required } /** * Creates a ModuleInitializeException with the given message and base * exception. * * @param s the message * @param e the root exception */ public ModuleInitializeException(final String s, final Exception e) { super(s, e); } /** * Creates a ModuleInitializeException with the given message and no base * exception. * * @param s the exception message */ public ModuleInitializeException(final String s) { super(s); } }libbase-1.1.6/source/org/pentaho/reporting/libraries/base/boot/PackageManager.java0000644000175000017500000005520411365604664026665 0ustar renerene/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2007 - 2009 Pentaho Corporation and Contributors. All rights reserved. */ package org.pentaho.reporting.libraries.base.boot; import java.io.PrintStream; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.pentaho.reporting.libraries.base.config.Configuration; import org.pentaho.reporting.libraries.base.config.PropertyFileConfiguration; import org.pentaho.reporting.libraries.base.util.ObjectUtilities; import org.pentaho.reporting.libraries.base.util.PadMessage; /** * The PackageManager is used to load and configure the modules of JFreeReport. Modules are used to extend the basic * capabilities of JFreeReport by providing a simple plugin-interface. *

* Modules provide a simple capability to remove unneeded functionality from the JFreeReport system and to reduce the * overall code size. The modularisation provides a very strict way of removing unnecessary dependencies beween the * various packages. *

* The package manager can be used to add new modules to the system or to check the existence and state of installed * modules. * * @author Thomas Morgner */ public final class PackageManager { /** * The PackageConfiguration handles the module level configuration. * * @author Thomas Morgner */ public static class PackageConfiguration extends PropertyFileConfiguration { private static final long serialVersionUID = -2170306139946858878L; /** * DefaultConstructor. Creates a new package configuration. */ public PackageConfiguration() { // nothing required } } private static final Log LOGGER = LogFactory.getLog(PackageManager.class); /** * An internal constant declaring that the specified module was already loaded. */ private static final int RETURN_MODULE_LOADED = 0; /** * An internal constant declaring that the specified module is not known. */ private static final int RETURN_MODULE_UNKNOWN = 1; /** * An internal constant declaring that the specified module produced an error while loading. */ private static final int RETURN_MODULE_ERROR = 2; /** * The module configuration instance that should be used to store module properties. This separates the user defined * properties from the implementation defined properties. */ private final PackageConfiguration packageConfiguration; /** * A list of all defined modules. */ private final ArrayList modules; private HashMap modulesByClass; /** * A list of module name definitions. */ private final ArrayList initSections; /** * The boot implementation for which the modules are managed. */ private AbstractBoot booter; /** * Creates a new package manager. * * @param booter the booter (null not permitted). */ public PackageManager(final AbstractBoot booter) { if (booter == null) { throw new NullPointerException(); } this.booter = booter; this.packageConfiguration = new PackageConfiguration(); this.modules = new ArrayList(); this.modulesByClass = new HashMap(); this.initSections = new ArrayList(); } /** * Checks, whether a certain module is available. * * @param moduleDescription the module description of the desired module. * @return true, if the module is available and the version of the module is compatible, false otherwise. */ public boolean isModuleAvailable(final ModuleInfo moduleDescription) { if (moduleDescription == null) { throw new NullPointerException(); } final PackageState[] packageStates = (PackageState[]) this.modules.toArray(new PackageState[this.modules.size()]); for (int i = 0; i < packageStates.length; i++) { final PackageState state = packageStates[i]; if (state.getModule().getModuleClass().equals(moduleDescription.getModuleClass())) { return (state.getState() == PackageState.STATE_INITIALIZED); } } return false; } /** * Checks whether the given module is available. The method returns true if the module is defined and has been * properly initialized. * * @param moduleClass the module class to be checked. * @return true, if the module is available and initialized, false otherwise. */ public boolean isModuleAvailable(final String moduleClass) { if (moduleClass == null) { throw new NullPointerException(); } final PackageState state = (PackageState) modulesByClass.get(moduleClass); if (state == null) { return false; } return state.getState() == PackageState.STATE_INITIALIZED; } /** * Loads all modules mentioned in the report configuration starting with the given prefix. This method is used during * the boot process of JFreeReport. You should never need to call this method directly. * * @param modulePrefix the module prefix. */ public void load(final String modulePrefix) { if (modulePrefix == null) { throw new NullPointerException(); } if (this.initSections.contains(modulePrefix)) { return; } this.initSections.add(modulePrefix); final Configuration config = this.booter.getGlobalConfig(); final Iterator it = config.findPropertyKeys(modulePrefix); int count = 0; while (it.hasNext()) { final String key = (String) it.next(); if (key.endsWith(".Module")) { final String moduleClass = config.getConfigProperty(key); if (moduleClass != null && moduleClass.length() > 0) { addModule(moduleClass); count++; } } } LOGGER.debug("Loaded a total of " + count + " modules under prefix: " + modulePrefix); } /** * Initializes all previously uninitialized modules. Once a module is initialized, it is not re-initialized a second * time. */ public synchronized void initializeModules() { // sort by subsystems and dependency PackageSorter.sort(this.modules); for (int i = 0; i < this.modules.size(); i++) { final PackageState mod = (PackageState) this.modules.get(i); if (isConfigurable(mod) == false) { mod.markError(); continue; } if (mod.configure(this.booter)) { if (LOGGER.isDebugEnabled()) { LOGGER.debug("Conf: " + new PadMessage(mod.getModule().getModuleClass(), 70) + " [" + mod.getModule().getSubSystem() + ']'); } } } for (int i = 0; i < this.modules.size(); i++) { final PackageState mod = (PackageState) this.modules.get(i); if (isInitializable(mod) == false) { mod.markError(); continue; } if (mod.initialize(this.booter)) { if (LOGGER.isDebugEnabled()) { LOGGER.debug("Init: " + new PadMessage(mod.getModule().getModuleClass(), 70) + " [" + mod.getModule().getSubSystem() + ']'); } } } } /** * Checks whether the module is configurable. A module is considered configurable if all dependencies exist and * are configured. * * @param state the package state that should be checked. * @return true, if the module can be configured, false otherwise. */ private boolean isConfigurable(final PackageState state) { final ModuleInfo[] requiredModules = state.getModule().getRequiredModules(); for (int i = 0; i < requiredModules.length; i++) { final ModuleInfo module = requiredModules[i]; final String key = module.getModuleClass(); final PackageState dependentState = (PackageState) modulesByClass.get(key); if (dependentState == null) { LOGGER.warn("Required dependency '" + key + "' for module '" + state.getModule().getModuleClass() + " not found."); return false; } if (dependentState.getState() != PackageState.STATE_CONFIGURED) { LOGGER.warn("Required dependency '" + key + "' for module '" + state.getModule().getModuleClass() + " not configured."); return false; } } return true; } /** * Checks whether the module is configurable. A module is considered configurable if all dependencies exist and * are initialized. * * @param state the package state that should be checked. * @return true, if the module can be configured, false otherwise. */ private boolean isInitializable(final PackageState state) { final ModuleInfo[] requiredModules = state.getModule().getRequiredModules(); for (int i = 0; i < requiredModules.length; i++) { final ModuleInfo module = requiredModules[i]; final String key = module.getModuleClass(); final PackageState dependentState = (PackageState) modulesByClass.get(key); if (dependentState == null) { LOGGER.warn("Required dependency '" + key + "' for module '" + state.getModule().getModuleClass() + " not found."); return false; } if (dependentState.getState() != PackageState.STATE_INITIALIZED) { LOGGER.warn("Required dependency '" + key + "' for module '" + state.getModule().getModuleClass() + " not initializable."); return false; } } return true; } /** * Adds a module to the package manager. Once all modules are added, you have to call initializeModules() to configure * and initialize the new modules. * * @param modClass the module class */ public synchronized void addModule(final String modClass) { if (modClass == null) { throw new NullPointerException(); } final ArrayList loadModules = new ArrayList(); final ModuleInfo modInfo = new DefaultModuleInfo(modClass, null, null, null); if (loadModule(modInfo, new ArrayList(), loadModules, false)) { for (int i = 0; i < loadModules.size(); i++) { final Module mod = (Module) loadModules.get(i); final PackageState state = new PackageState(mod); this.modules.add(state); this.modulesByClass.put(mod.getModuleClass(), state); } } } /** * Checks, whether the given module is already loaded in either the given tempModules list or the global package * registry. If tmpModules is null, only the previously installed modules are checked. * * @param tempModules a list of previously loaded modules. * @param module the module specification that is checked. * @return true, if the module is already loaded, false otherwise. */ private int containsModule(final ArrayList tempModules, final ModuleInfo module) { if (tempModules != null) { final ModuleInfo[] mods = (ModuleInfo[]) tempModules.toArray(new ModuleInfo[tempModules.size()]); for (int i = 0; i < mods.length; i++) { if (mods[i].getModuleClass().equals(module.getModuleClass())) { return RETURN_MODULE_LOADED; } } } final PackageState[] packageStates = (PackageState[]) this.modules.toArray(new PackageState[this.modules.size()]); for (int i = 0; i < packageStates.length; i++) { if (packageStates[i].getModule().getModuleClass().equals(module.getModuleClass())) { if (packageStates[i].getState() == PackageState.STATE_ERROR) { return RETURN_MODULE_ERROR; } else { return RETURN_MODULE_LOADED; } } } return RETURN_MODULE_UNKNOWN; } /** * A utility method that collects all failed modules. Such an module caused an error while being loaded, and is now * cached in case it is referenced elsewhere. * * @param state the failed module. */ private void dropFailedModule(final PackageState state) { if (this.modules.contains(state) == false) { this.modules.add(state); } } /** * Tries to load a given module and all dependent modules. If the dependency check fails for that module (or for one * of the dependent modules), the loaded modules are discarded and no action is taken. * * @param moduleInfo the module info of the module that should be loaded. * @param incompleteModules a list of incompletly loaded modules. This are module specifications which depend on the * current module and wait for the module to be completly loaded. * @param modules the list of previously loaded modules for this module. * @param fatal a flag that states, whether the failure of loading a module should be considered an error. * Root-modules load errors are never fatal, as we try to load all known modules, regardless * whether they are active or not. * @return true, if the module was loaded successfully, false otherwise. */ private boolean loadModule(final ModuleInfo moduleInfo, final ArrayList incompleteModules, final ArrayList modules, final boolean fatal) { try { final Module module = (Module) ObjectUtilities.loadAndInstantiate(moduleInfo.getModuleClass(), getClass(), Module.class); if (module == null) { if (fatal) { LOGGER.warn("Unresolved dependency for package: " + moduleInfo.getModuleClass()); } LOGGER.debug("Module class referenced, but not in classpath: " + moduleInfo.getModuleClass()); } if (acceptVersion(moduleInfo, module) == false) { // module conflict! LOGGER.warn("Module " + module.getName() + ": required version: " + moduleInfo + ", but found Version: \n" + module); final PackageState state = new PackageState(module, PackageState.STATE_ERROR); dropFailedModule(state); return false; } final int moduleContained = containsModule(modules, module); if (moduleContained == RETURN_MODULE_ERROR) { // the module caused harm before ... LOGGER.debug("Indicated failure for module: " + module.getModuleClass()); final PackageState state = new PackageState(module, PackageState.STATE_ERROR); dropFailedModule(state); return false; } else if (moduleContained == RETURN_MODULE_UNKNOWN) { if (incompleteModules.contains(module)) { // we assume that loading will continue ... LOGGER.error ("Circular module reference: This module definition is invalid: " + module.getClass()); final PackageState state = new PackageState(module, PackageState.STATE_ERROR); dropFailedModule(state); return false; } incompleteModules.add(module); final ModuleInfo[] required = module.getRequiredModules(); for (int i = 0; i < required.length; i++) { if (loadModule(required[i], incompleteModules, modules, true) == false) { LOGGER.debug("Indicated failure for module: " + module.getModuleClass()); final PackageState state = new PackageState(module, PackageState.STATE_ERROR); dropFailedModule(state); return false; } } final ModuleInfo[] optional = module.getOptionalModules(); for (int i = 0; i < optional.length; i++) { if (loadModule(optional[i], incompleteModules, modules, true) == false) { LOGGER.debug("Optional module: " + optional[i].getModuleClass() + " was not loaded."); } } // maybe a dependent module defined the same base module ... if (containsModule(modules, module) == RETURN_MODULE_UNKNOWN) { modules.add(module); } incompleteModules.remove(module); } return true; } catch (Exception e) { LOGGER.warn("Exception while loading module: " + moduleInfo, e); return false; } } /** * Checks, whether the given module meets the requirements defined in the module information. * * @param moduleRequirement the required module specification. * @param module the module that should be checked against the specification. * @return true, if the module meets the given specifications, false otherwise. */ private boolean acceptVersion(final ModuleInfo moduleRequirement, final Module module) { if (moduleRequirement.getMajorVersion() == null) { return true; } if (module.getMajorVersion() == null) { LOGGER.warn("Module " + module.getName() + " does not define a major version."); } else { final int compare = acceptVersion(moduleRequirement.getMajorVersion(), module.getMajorVersion()); if (compare > 0) { return false; } else if (compare < 0) { return true; } } if (moduleRequirement.getMinorVersion() == null) { return true; } if (module.getMinorVersion() == null) { LOGGER.warn("Module " + module.getName() + " does not define a minor version."); } else { final int compare = acceptVersion(moduleRequirement.getMinorVersion(), module.getMinorVersion()); if (compare > 0) { return false; } else if (compare < 0) { return true; } } if (moduleRequirement.getPatchLevel() == null) { return true; } if (module.getPatchLevel() == null) { LOGGER.debug("Module " + module.getName() + " does not define a patch level."); } else { if (acceptVersion(moduleRequirement.getPatchLevel(), module.getPatchLevel()) > 0) { LOGGER.debug("Did not accept patchlevel: " + moduleRequirement.getPatchLevel() + " - " + module.getPatchLevel()); return false; } } return true; } /** * Compare the version strings. If the strings have a different length, the shorter string is padded with spaces to * make them compareable. * * @param modVer the version string of the module * @param depModVer the version string of the dependent or optional module * @return 0, if the dependent module version is equal tothe module's required version, a negative number if the * dependent module is newer or a positive number if the dependent module is older and does not fit. */ private int acceptVersion(final String modVer, final String depModVer) { final int mLength = Math.max(modVer.length(), depModVer.length()); final char[] modVerArray; final char[] depVerArray; if (modVer.length() > depModVer.length()) { modVerArray = modVer.toCharArray(); depVerArray = new char[mLength]; final int delta = modVer.length() - depModVer.length(); Arrays.fill(depVerArray, 0, delta, ' '); System.arraycopy(depVerArray, delta, depModVer.toCharArray(), 0, depModVer.length()); } else if (modVer.length() < depModVer.length()) { depVerArray = depModVer.toCharArray(); modVerArray = new char[mLength]; final char[] b1 = new char[mLength]; final int delta = depModVer.length() - modVer.length(); Arrays.fill(b1, 0, delta, ' '); System.arraycopy(b1, delta, modVer.toCharArray(), 0, modVer.length()); } else { depVerArray = depModVer.toCharArray(); modVerArray = modVer.toCharArray(); } return new String(modVerArray).compareTo(new String(depVerArray)); } /** * Returns the default package configuration. Private report configuration instances may be inserted here. These * inserted configuration can never override the settings from this package configuration. * * @return the package configuration. */ public PackageConfiguration getPackageConfiguration() { return this.packageConfiguration; } /** * Returns an array of the currently active modules. The module definition returned contain all known modules, * including buggy and unconfigured instances. * * @return the modules. */ public Module[] getAllModules() { final Module[] mods = new Module[this.modules.size()]; for (int i = 0; i < this.modules.size(); i++) { final PackageState state = (PackageState) this.modules.get(i); mods[i] = state.getModule(); } return mods; } /** * Returns all active modules. This array does only contain modules which were successfully configured and * initialized. * * @return the list of all active modules. */ public Module[] getActiveModules() { final ArrayList mods = new ArrayList(); for (int i = 0; i < this.modules.size(); i++) { final PackageState state = (PackageState) this.modules.get(i); if (state.getState() == PackageState.STATE_INITIALIZED) { mods.add(state.getModule()); } } return (Module[]) mods.toArray(new Module[mods.size()]); } /** * Prints the modules that are used. * * @param p the print stream. */ public void printUsedModules(final PrintStream p) { final Module[] allMods = getAllModules(); final ArrayList activeModules = new ArrayList(); //final ArrayList failedModules = new ArrayList(); for (int i = 0; i < allMods.length; i++) { if (isModuleAvailable(allMods[i])) { activeModules.add(allMods[i]); } // else // { // failedModules.add(allMods[i]); // } } p.print("Active modules: "); p.println(activeModules.size()); p.println("----------------------------------------------------------"); for (int i = 0; i < activeModules.size(); i++) { final Module mod = (Module) activeModules.get(i); p.print(new PadMessage(mod.getModuleClass(), 70)); p.print(" ["); p.print(mod.getSubSystem()); p.println("]"); p.print(" Version: "); p.print(mod.getMajorVersion()); p.print("-"); p.print(mod.getMinorVersion()); p.print("-"); p.print(mod.getPatchLevel()); p.print(" Producer: "); p.println(mod.getProducer()); p.print(" Description: "); p.println(mod.getDescription()); } } }libbase-1.1.6/source/org/pentaho/reporting/libraries/base/boot/AbstractModule.java0000644000175000017500000003656111365604664026755 0ustar renerene/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2007 - 2009 Pentaho Corporation and Contributors. All rights reserved. */ package org.pentaho.reporting.libraries.base.boot; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Iterator; import org.pentaho.reporting.libraries.base.config.Configuration; import org.pentaho.reporting.libraries.base.config.DefaultConfiguration; import org.pentaho.reporting.libraries.base.util.ObjectUtilities; import org.pentaho.reporting.libraries.base.util.StringUtils; /** * The abstract module provides a default implementation of the module interface. *

* The module can be specified in an external property file. The file name of this * specification defaults to "module.properties". *

* The first and mandatory section is always the module info and contains the basic module * properties like name, version and a short description. *

*

 * module.name: xls-export-gui
 * module.producer: The JFreeReport project - www.jfree.org/jfreereport
 * module.description: A dialog component for the Excel table export.
 * module.version.major: 0
 * module.version.minor: 84
 * module.version.patchlevel: 0
 * 
* The properties name, producer and description are simple strings. They may * span multiple lines, but may not contain a colon (':'). * The version properties are integer values. *

* This section may be followed by one or more "depends" sections. These * sections describe the base modules that are required to be active to make this * module work. The package manager will enforce this policy and will deactivate this * module if one of the base modules is missing. *

*

 * dependency.module-id.module: org.pentaho.reporting.engine.classic.core.modules.output.table.xls.XLSTableModule
 * dependency.module-id.version.major: 0
 * dependency.module-id.version.minor: 84
 * 
*

* The property *.module references to the module implementation of the module package. * The module-id is a per-module-definition-unique identifier and it is recommended to set it to the * referenced module's name for documentary purposes. * * @author Thomas Morgner */ public abstract class AbstractModule extends DefaultModuleInfo implements Module { /** * An empty array for performance reasons. */ private static final ModuleInfo[] EMPTY_MODULEINFO = new ModuleInfo[0]; /** * The list of required modules. */ private ModuleInfo[] requiredModules; /** * The list of optional modules. */ private ModuleInfo[] optionalModules; /** * The name of the module. */ private String name; /** * A short description of the module. */ private String description; /** * The name of the module producer. */ private String producer; /** * The modules subsystem. */ private String subsystem; /** * Default Constructor. */ protected AbstractModule() { setModuleClass(this.getClass().getName()); } /** * Loads the default module description from the file "module.properties". This file * must be in the same package as the implementing class. * * @throws ModuleInitializeException if an error occurs. */ protected void loadModuleInfo() throws ModuleInitializeException { final InputStream in = ObjectUtilities.getResourceRelativeAsStream ("module.properties", getClass()); if (in == null) { throw new ModuleInitializeException ("File 'module.properties' not found in module package."); } loadModuleInfo(in); } /** * Loads the module descriptiong from the given input stream. The module description * must conform to the rules define in the class description. The file must be encoded * with "ISO-8859-1" (like property files). * * @param in the input stream from where to read the file * @throws ModuleInitializeException if an error occurs. */ protected void loadModuleInfo(final InputStream in) throws ModuleInitializeException { if (in == null) { throw new NullPointerException ("Given InputStream is null."); } try { final DefaultConfiguration props = new DefaultConfiguration(); props.load(in); readModuleInfo(props); final ArrayList optionalModules = new ArrayList(); final ArrayList dependendModules = new ArrayList(); final Iterator keys = props.findPropertyKeys("dependency."); while (keys.hasNext()) { final String key = (String) keys.next(); if (key.endsWith(".dependency-type")) { final String moduleHandle = key.substring(0, key.length() - ".dependency-type".length()); final DefaultModuleInfo module = readExternalModule(props, moduleHandle); if ("optional".equals(props.getConfigProperty(key))) { optionalModules.add(module); } else { dependendModules.add(module); } } } this.optionalModules = (ModuleInfo[]) optionalModules.toArray(new ModuleInfo[optionalModules.size()]); this.requiredModules = (ModuleInfo[]) dependendModules.toArray(new ModuleInfo[dependendModules.size()]); } catch (IOException ioe) { throw new ModuleInitializeException("Failed to load properties", ioe); } finally { try { in.close(); } catch (IOException e) { // ignore .. } } } /** * Reads the module definition header. This header contains information about * the module itself. * * @param config the properties from where to read the content. */ private void readModuleInfo(final Configuration config) { setName(config.getConfigProperty("module.name")); setProducer(config.getConfigProperty("module.producer")); setDescription(config.getConfigProperty("module.description")); setMajorVersion(config.getConfigProperty("module.version.major")); setMinorVersion(config.getConfigProperty("module.version.minor")); setPatchLevel(config.getConfigProperty("module.version.patchlevel")); setSubSystem(config.getConfigProperty("module.subsystem")); } /** * Reads an external module description. This describes either an optional or * a required module. * * @param reader the reader from where to read the module * @param prefix the property-key prefix. * @return the read module, never null */ private DefaultModuleInfo readExternalModule(final Configuration reader, final String prefix) { final DefaultModuleInfo mi = new DefaultModuleInfo(); mi.setModuleClass(reader.getConfigProperty(prefix + ".module")); mi.setMajorVersion(reader.getConfigProperty(prefix + ".version.major")); mi.setMinorVersion(reader.getConfigProperty(prefix + ".version.minor")); mi.setPatchLevel(reader.getConfigProperty(prefix + ".version.patchlevel")); return mi; } /** * Returns the name of this module. * * @return the module name * @see Module#getName() */ public String getName() { return this.name; } /** * Defines the name of the module. * * @param name the module name. */ protected void setName(final String name) { this.name = name; } /** * Returns the module description. * * @return the description of the module. * @see Module#getDescription() */ public String getDescription() { return this.description; } /** * Defines the description of the module. * * @param description the module's desciption. */ protected void setDescription(final String description) { this.description = description; } /** * Returns the producer of the module. * * @return the producer. * @see Module#getProducer() */ public String getProducer() { return this.producer; } /** * Defines the producer of the module. * * @param producer the producer. */ protected void setProducer(final String producer) { this.producer = producer; } /** * Returns a copy of the required modules array. This array contains all * description of the modules that need to be present to make this module work. * * @return an array of all required modules. * @see Module#getRequiredModules() */ public ModuleInfo[] getRequiredModules() { if (this.requiredModules == null) { return EMPTY_MODULEINFO; } final ModuleInfo[] retval = new ModuleInfo[this.requiredModules.length]; System.arraycopy(this.requiredModules, 0, retval, 0, this.requiredModules.length); return retval; } /** * Returns a copy of the required modules array. This array contains all * description of the optional modules that may improve the modules functonality. * * @return an array of all required modules. * @see Module#getRequiredModules() */ public ModuleInfo[] getOptionalModules() { if (this.optionalModules == null) { return EMPTY_MODULEINFO; } final ModuleInfo[] retval = new ModuleInfo[this.optionalModules.length]; System.arraycopy(this.optionalModules, 0, retval, 0, this.optionalModules.length); return retval; } /** * Defines the required module descriptions for this module. * * @param requiredModules the required modules. */ protected void setRequiredModules(final ModuleInfo[] requiredModules) { this.requiredModules = new ModuleInfo[requiredModules.length]; System.arraycopy(requiredModules, 0, this.requiredModules, 0, requiredModules.length); } /** * Defines the optional module descriptions for this module. * * @param optionalModules the optional modules. */ public void setOptionalModules(final ModuleInfo[] optionalModules) { this.optionalModules = new ModuleInfo[optionalModules.length]; System.arraycopy(optionalModules, 0, this.optionalModules, 0, optionalModules.length); } /** * Returns a string representation of this module. * * @return the string representation of this module for debugging purposes. * @see Object#toString() */ public String toString() { final String lineSeparator = StringUtils.getLineSeparator(); final StringBuffer buffer = new StringBuffer(120); buffer.append("Module : "); buffer.append(getName()); buffer.append(lineSeparator); buffer.append("ModuleClass : "); buffer.append(getModuleClass()); buffer.append(lineSeparator); buffer.append("Version: "); buffer.append(getMajorVersion()); buffer.append('.'); buffer.append(getMinorVersion()); buffer.append('.'); buffer.append(getPatchLevel()); buffer.append(lineSeparator); buffer.append("Producer: "); buffer.append(getProducer()); buffer.append(lineSeparator); buffer.append("Description: "); buffer.append(getDescription()); buffer.append(lineSeparator); return buffer.toString(); } /** * Tries to load a class to indirectly check for the existence * of a certain library. * * @param name the name of the library class. * @param context the context class to get a classloader from. * @return true, if the class could be loaded, false otherwise. */ protected static boolean isClassLoadable(final String name, final Class context) { try { final ClassLoader loader = ObjectUtilities.getClassLoader(context); Class.forName(name, false, loader); return true; } catch (Exception e) { return false; } } /** * Configures the module by loading the configuration properties and * adding them to the package configuration. * * @param subSystem the subsystem. */ public void configure(final SubSystem subSystem) { final InputStream in = ObjectUtilities.getResourceRelativeAsStream ("configuration.properties", getClass()); if (in == null) { return; } try { subSystem.getPackageManager().getPackageConfiguration().load(in); } finally { try { in.close(); } catch (IOException e) { // can be ignored ... } } } /** * Tries to load an module initializer and uses this initializer to initialize * the module. * * @param classname the class name of the initializer. * @throws ModuleInitializeException if an error occures * @deprecated Use the method that provides a class-context instead. */ protected void performExternalInitialize(final String classname) throws ModuleInitializeException { try { final ModuleInitializer mi = (ModuleInitializer) ObjectUtilities.loadAndInstantiate(classname, AbstractModule.class, ModuleInitializer.class); if (mi == null) { throw new ModuleInitializeException("Failed to load specified initializer class."); } mi.performInit(); } catch (ModuleInitializeException mie) { throw mie; } catch (Exception e) { throw new ModuleInitializeException("Failed to load specified initializer class.", e); } } /** * Executes an weakly referenced external initializer. The initializer will be loaded using reflection and will * be executed once. If the initializing fails with any exception, the module will become unavailable. * * @param classname the classname of the ModuleInitializer implementation * @param context the class-loader context from where to load the module's classes. * @throws ModuleInitializeException if an error occured or the initializer could not be found. */ protected void performExternalInitialize(final String classname, final Class context) throws ModuleInitializeException { try { final ModuleInitializer mi = (ModuleInitializer) ObjectUtilities.loadAndInstantiate(classname, context, ModuleInitializer.class); if (mi == null) { throw new ModuleInitializeException("Failed to load specified initializer class."); } mi.performInit(); } catch (ModuleInitializeException mie) { throw mie; } catch (Exception e) { throw new ModuleInitializeException("Failed to load specified initializer class.", e); } } /** * Returns the modules subsystem. If this module is not part of an subsystem * then return the modules name, but never null. * * @return the name of the subsystem. */ public String getSubSystem() { if (this.subsystem == null) { return getName(); } return this.subsystem; } /** * Defines the subsystem name for this module. If no sub-system name is set, the sub-system defaults to the * module's name. * * @param name the new name of the subsystem. */ protected void setSubSystem(final String name) { this.subsystem = name; } }libbase-1.1.6/source/org/pentaho/reporting/libraries/base/encoder/0000755000175000017500000000000011365604664023642 5ustar renerenelibbase-1.1.6/source/org/pentaho/reporting/libraries/base/encoder/ImageEncoder.java0000644000175000017500000000425411365604664027034 0ustar renerene/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2009 Pentaho Corporation. All rights reserved. */ package org.pentaho.reporting.libraries.base.encoder; import java.awt.Image; import java.io.IOException; import java.io.OutputStream; /** * A image encoder. The encoder's encodeImage method must be synchronized in some way, so that * multiple calls from multiple threads do not interact with each other. * * @author Thomas Morgner */ public interface ImageEncoder { /** * Encodes the given image using the given encoder-specific quality and alpha-channel settings and writes * the encoded image-data to the given stream. * * @param image the image to be encoded. * @param outputStream the output stream, where to write the image data to. * @param quality the quality of the encoding. * @param encodeAlpha a flag controlling whether the alpha-channel should be encoded as well. * @throws IOException if there was an IO error while generating or writing the image data. * @throws UnsupportedEncoderException if the encoder is not supported. */ public void encodeImage(final Image image, final OutputStream outputStream, final float quality, final boolean encodeAlpha) throws IOException, UnsupportedEncoderException; /** * Returns the mime-type of the encoded data. * * @return the mime-type. */ public String getMimeType(); } libbase-1.1.6/source/org/pentaho/reporting/libraries/base/encoder/JpegImageEncoder.java0000644000175000017500000001347011365604664027642 0ustar renerene/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2009 Pentaho Corporation. All rights reserved. */ package org.pentaho.reporting.libraries.base.encoder; import java.awt.Color; import java.awt.Graphics; import java.awt.Image; import java.awt.image.BufferedImage; import java.io.IOException; import java.io.OutputStream; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import org.pentaho.reporting.libraries.base.util.ObjectUtilities; /** * Todo: Document Me * * @author Thomas Morgner */ public class JpegImageEncoder implements ImageEncoder { private static final String ENCODER_CLASS = "com.sun.image.codec.jpeg.JPEGCodec"; private static final String ENCODER_PARAM_CLASS = "com.sun.image.codec.jpeg.JPEGEncodeParam"; public JpegImageEncoder() { } public void encodeImage(final Image image, final OutputStream outputStream, final float quality, final boolean encodeAlpha) throws IOException, UnsupportedEncoderException { final BufferedImage bimage = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_RGB); final Graphics g = bimage.createGraphics(); g.drawImage(image, 0, 0, Color.WHITE, null); g.dispose(); //// This is what we try to do via reflection. Yes, reflection is ugly, but it guarantees that //// we dont run into strange errors just because a non-Sun-JDK is used. // // final JPEGEncodeParam jep = JPEGCodec.getDefaultJPEGEncodeParam(bimage); // jep.setQuality(quality, false); // final JPEGImageEncoder jpegImageEncoder = JPEGCodec.createJPEGEncoder(outputStream, jep); // jpegImageEncoder.encode(bimage); try { final ClassLoader loader = ObjectUtilities.getClassLoader(JpegImageEncoder.class); final Class codecClass = Class.forName(ENCODER_CLASS, false, loader); final Class paramClass = Class.forName(ENCODER_PARAM_CLASS, false, loader); final Method createParameterMethod = codecClass.getMethod ("getDefaultJPEGEncodeParam", new Class[]{BufferedImage.class}); final Object encoderParam = createParameterMethod.invoke(null, new Object[]{bimage}); final Method setQualityMethod = paramClass.getMethod ("setQuality", new Class[]{Float.TYPE, Boolean.TYPE}); setQualityMethod.invoke(encoderParam, new Object[]{new Float(quality), Boolean.FALSE}); final Method createEncoderMethod = codecClass.getMethod ("createJPEGEncoder", new Class[]{OutputStream.class, paramClass}); final Object encoder = createEncoderMethod.invoke(null, new Object[]{outputStream, encoderParam}); final Class encoderClass = encoder.getClass(); final Method encodeMethod = encoderClass.getMethod("encode", new Class[]{BufferedImage.class}); encodeMethod.invoke(encoder, new Object[]{bimage}); } catch (InvocationTargetException ie) { final Throwable throwable = ie.getTargetException(); if (throwable instanceof IOException) { // Yeah, it is ugly, but the use of reflection hides the exception.. throw (IOException) throwable; } // ignore the throwable .. throw new UnsupportedEncoderException("Failed to run the encoder", throwable); } catch (Throwable t) { // ignore the throwable .. throw new UnsupportedEncoderException("Failed to run the encoder", t); } } public void encodeImage(final Image image, final OutputStream outputStream) throws IOException, UnsupportedEncoderException { try { final ClassLoader loader = ObjectUtilities.getClassLoader(JpegImageEncoder.class); final Class codecClass = Class.forName(ENCODER_CLASS, false, loader); final Method createEncoderMethod = codecClass.getMethod("createJPEGEncoder", new Class[]{OutputStream.class}); final Object encoder = createEncoderMethod.invoke(null, new Object[]{outputStream}); final Class encoderClass = encoder.getClass(); final Method encodeMethod = encoderClass.getMethod("encode", new Class[]{Image.class}); encodeMethod.invoke(encoder, new Object[]{image}); } catch (InvocationTargetException ie) { final Throwable throwable = ie.getTargetException(); if (throwable instanceof IOException) { // Yeah, it is ugly, but the use of reflection hides the exception.. throw (IOException) throwable; } // ignore the throwable .. throw new UnsupportedEncoderException("Failed to run the encoder", throwable); } catch (Throwable t) { // ignore the throwable .. throw new UnsupportedEncoderException("Failed to run the encoder", t); } } public String getMimeType() { return "image/jpg"; } public static boolean isJpegEncodingAvailable() { try { final ClassLoader loader = ObjectUtilities.getClassLoader(JpegImageEncoder.class); final Class aClass = Class.forName(ENCODER_CLASS, false, loader); return aClass != null; } catch (Throwable t) { // ignore the throwable .. return false; } } } libbase-1.1.6/source/org/pentaho/reporting/libraries/base/encoder/UnsupportedEncoderException.java0000644000175000017500000000246411365604664032222 0ustar renerene/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2009 Pentaho Corporation. All rights reserved. */ package org.pentaho.reporting.libraries.base.encoder; import org.pentaho.reporting.libraries.base.util.StackableException; /** * Todo: Document Me * * @author Thomas Morgner */ public class UnsupportedEncoderException extends StackableException { public UnsupportedEncoderException() { } public UnsupportedEncoderException(final String message, final Throwable ex) { super(message, ex); } public UnsupportedEncoderException(final String message) { super(message); } } libbase-1.1.6/source/org/pentaho/reporting/libraries/base/encoder/ImageEncoderRegistry.java0000644000175000017500000000567311365604664030573 0ustar renerene/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2009 Pentaho Corporation. All rights reserved. */ package org.pentaho.reporting.libraries.base.encoder; import java.util.HashMap; import org.pentaho.reporting.libraries.base.util.ObjectUtilities; import org.pentaho.reporting.libraries.base.util.PngEncoder; /** * Todo: Document Me * * @author Thomas Morgner */ public class ImageEncoderRegistry { private static ImageEncoderRegistry instance; private HashMap encoders; public static final String IMAGE_PNG = "image/png"; public static final String IMAGE_JPEG = "image/jpeg"; public static synchronized ImageEncoderRegistry getInstance() { if (instance == null) { instance = new ImageEncoderRegistry(); instance.registerDefaults(); } return instance; } private ImageEncoderRegistry() { encoders = new HashMap(); } private void registerDefaults() { encoders.put (IMAGE_PNG, PngEncoder.class.getName()); if (JpegImageEncoder.isJpegEncodingAvailable()) { encoders.put(IMAGE_JPEG, JpegImageEncoder.class.getName()); encoders.put("image/jpg", JpegImageEncoder.class.getName()); } } public void addEncoder(final String mimeType, final String encoderClass) { if (mimeType == null) { throw new NullPointerException(); } if (encoderClass == null) { throw new NullPointerException(); } encoders.put(mimeType, encoderClass); } public boolean isEncoderAvailable(final String mimeType) { return encoders.containsKey(mimeType); } public String[] getRegisteredEncoders() { return (String[]) encoders.keySet().toArray(new String[encoders.size()]); } public ImageEncoder createEncoder(final String mimeType) throws UnsupportedEncoderException { final Object o = encoders.get(mimeType); if (o == null) { throw new UnsupportedEncoderException("No encoder for mime-type " + mimeType); } final ImageEncoder imageEncoder = (ImageEncoder) ObjectUtilities.loadAndInstantiate((String) o, ImageEncoderRegistry.class, ImageEncoder.class); if (imageEncoder == null) { throw new UnsupportedEncoderException("No encoder for mime-type " + mimeType); } return imageEncoder; } } libbase-1.1.6/source/org/pentaho/reporting/libraries/base/libbase.properties0000644000175000017500000000000011365604666025732 0ustar renerenelibbase-1.1.6/source/org/pentaho/reporting/libraries/base/LibBaseBoot.java0000644000175000017500000000511511365604666025217 0ustar renerene/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2007 - 2009 Pentaho Corporation and Contributors. All rights reserved. */ package org.pentaho.reporting.libraries.base; import org.pentaho.reporting.libraries.base.boot.AbstractBoot; import org.pentaho.reporting.libraries.base.config.Configuration; import org.pentaho.reporting.libraries.base.versioning.ProjectInformation; /** * An utility class to safely boot and initialize the LibBase library. * * @author : Thomas Morgner */ public class LibBaseBoot extends AbstractBoot { /** A singleton variable for the booter. */ private static LibBaseBoot instance; /** * Returns the singleton instance of LibBaseBoot. * * @return the boot class for Libbase. */ public static synchronized LibBaseBoot getInstance() { if (instance == null) { instance = new LibBaseBoot(); } return instance; } /** * Private constructor prevents object creation. */ private LibBaseBoot() { } /** * Loads the configuration for LibBase. This will be called exactly once. The configuration is loaded from * a file called "libbase.properties" located next to this class. A user overridable properties file is searched * on the classpath within all libraries using the name "/libbase.properties". * * @return The configuration. */ protected Configuration loadConfiguration() { return createDefaultHierarchicalConfiguration ("/org/pentaho/reporting/libraries/base/libbase.properties", "/libbase.properties", true, LibBaseBoot.class); } /** * Performs the boot. This method does nothing. */ protected void performBoot() { // nothing required. Just gather the configuration. } /** * Returns the project info. * * @return The project info. */ protected ProjectInformation getProjectInfo() { return LibBaseInfo.getInstance(); } } libbase-1.1.6/source/org/pentaho/reporting/libraries/base/config/0000755000175000017500000000000011365604666023472 5ustar renerenelibbase-1.1.6/source/org/pentaho/reporting/libraries/base/config/ExtendedConfigurationWrapper.java0000644000175000017500000001251511365604666032172 0ustar renerene/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2007 - 2009 Pentaho Corporation and Contributors. All rights reserved. */ package org.pentaho.reporting.libraries.base.config; import java.util.Enumeration; import java.util.Iterator; /** * A wrapper for the extended configuration interface around a plain configuration. * * @author Thomas Morgner */ public class ExtendedConfigurationWrapper implements ExtendedConfiguration { /** A constant for serialization support. */ private static final long serialVersionUID = -3600564448124904906L; /** * The base configuration. */ private Configuration parent; /** * Creates a wrapper around the given configuration. * * @param parent the wrapped up configuration. * @throws NullPointerException if the parent is null. */ public ExtendedConfigurationWrapper(final Configuration parent) { if (parent == null) { throw new NullPointerException("Parent given must not be null"); } this.parent = parent; } /** * Returns the boolean value of a given configuration property. The boolean value true * is returned, if the contained string is equal to 'true'. * * @param name the name of the property * @return the boolean value of the property. */ public boolean getBoolProperty(final String name) { return getBoolProperty(name, false); } /** * Returns the boolean value of a given configuration property. The boolean value true * is returned, if the contained string is equal to 'true'. If the property is not set, * the default value is returned. * * @param name the name of the property * @param defaultValue the default value to be returned if the property is not set * @return the boolean value of the property. */ public boolean getBoolProperty(final String name, final boolean defaultValue) { return "true".equals(parent.getConfigProperty(name, String.valueOf(defaultValue))); } /** * Returns a given property as int value. Zero is returned if the * property value is no number or the property is not set. * * @param name the name of the property * @return the parsed number value or zero */ public int getIntProperty(final String name) { return getIntProperty(name, 0); } /** * Returns a given property as int value. The specified default value is returned if the * property value is no number or the property is not set. * * @param name the name of the property * @param defaultValue the value to be returned if the property is no integer value * @return the parsed number value or the specified default value */ public int getIntProperty(final String name, final int defaultValue) { final String retval = parent.getConfigProperty(name); if (retval == null) { return defaultValue; } try { return Integer.parseInt(retval); } catch (Exception e) { return defaultValue; } } /** * Checks, whether a given property is defined. * * @param name the name of the property * @return true, if the property is defined, false otherwise. */ public boolean isPropertySet(final String name) { return parent.getConfigProperty(name) != null; } /** * Returns all keys with the given prefix. * * @param prefix the prefix * @return the iterator containing all keys with that prefix */ public Iterator findPropertyKeys(final String prefix) { return parent.findPropertyKeys(prefix); } /** * Returns the configuration property with the specified key. * * @param key the property key. * @return the property value. */ public String getConfigProperty(final String key) { return parent.getConfigProperty(key); } /** * Returns the configuration property with the specified key (or the specified default * value if there is no such property). *

* If the property is not defined in this configuration, the code will lookup the * property in the parent configuration. * * @param key the property key. * @param defaultValue the default value. * @return the property value. */ public String getConfigProperty(final String key, final String defaultValue) { return parent.getConfigProperty(key, defaultValue); } public Enumeration getConfigProperties() { return parent.getConfigProperties(); } public Object clone() throws CloneNotSupportedException { final ExtendedConfigurationWrapper wrapper = (ExtendedConfigurationWrapper) super.clone(); wrapper.parent = (Configuration) parent.clone(); return parent; } }libbase-1.1.6/source/org/pentaho/reporting/libraries/base/config/HierarchicalConfiguration.java0000644000175000017500000002431511365604666031450 0ustar renerene/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2007 - 2009 Pentaho Corporation and Contributors. All rights reserved. */ package org.pentaho.reporting.libraries.base.config; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.Arrays; import java.util.Enumeration; import java.util.HashSet; import java.util.Iterator; import java.util.Properties; import java.util.Set; import org.pentaho.reporting.libraries.base.boot.AbstractBoot; /** * A hierarchical configuration. Such a configuration can have one or more * parent configurations providing usefull default values. * * @author Thomas Morgner */ public class HierarchicalConfiguration implements ModifiableConfiguration { /** * A constant for serialization support. */ private static final long serialVersionUID = -6962432361197107831L; /** * The instance configuration properties. */ private Properties configuration; /** * The booter class from where to get the global configuration after deserialization. */ private Class booterClass; /** * The parent configuration (null if this is the root configuration). */ private transient Configuration parentConfiguration; /** * Creates a new configuration. */ public HierarchicalConfiguration() { this.configuration = new Properties(); } /** * Creates a new configuration. * * @param parentConfiguration the parent configuration. */ public HierarchicalConfiguration(final Configuration parentConfiguration) { this(); this.parentConfiguration = parentConfiguration; } /** * Creates a new configuration, that is able to reconnect itself to the global configuration after deserialization. * * @param booterClass the booter class that holds the global configuration. */ public HierarchicalConfiguration(final Class booterClass) { this(); this.booterClass = booterClass; } /** * Returns the configuration property with the specified key. * * @param key the property key. * @return the property value. */ public String getConfigProperty(final String key) { return getConfigProperty(key, null); } /** * Returns the configuration property with the specified key (or the * specified default value if there is no such property). *

* If the property is not defined in this configuration, the code will * lookup the property in the parent configuration. * * @param key the property key. * @param defaultValue the default value. * @return the property value. */ public String getConfigProperty(final String key, final String defaultValue) { String value = this.configuration.getProperty(key); if (value == null) { if (isRootConfig()) { value = defaultValue; } else { value = this.parentConfiguration.getConfigProperty(key, defaultValue); } } return value; } /** * Sets a configuration property. * * @param key the property key. * @param value the property value. */ public void setConfigProperty(final String key, final String value) { if (key == null) { throw new NullPointerException(); } if (value == null) { this.configuration.remove(key); } else { this.configuration.setProperty(key, value); } } /** * Returns true if this object has no parent. * * @return true, if this report is the root configuration, false otherwise. */ private boolean isRootConfig() { return this.parentConfiguration == null; } /** * Checks, whether the given key is localy defined in this instance or * whether the key's value is inherited. * * @param key the key that should be checked. * @return true, if the key is defined locally, false otherwise. */ public boolean isLocallyDefined(final String key) { return this.configuration.containsKey(key); } /** * Returns the collection of properties for the configuration. * * @return the properties. */ protected Properties getConfiguration() { return this.configuration; } /** * The new configuartion will be inserted into the list of report * configuration, so that this configuration has the given report * configuration instance as parent. * * @param config the new report configuration. */ public void insertConfiguration(final HierarchicalConfiguration config) { if (config == null) { throw new NullPointerException("Configuration that should be inserted is null"); } config.setParentConfig(getParentConfig()); setParentConfig(config); } /** * Set the parent configuration. The parent configuration is queried, if the * requested configuration values was not found in this report * configuration. * * @param config the parent configuration. */ protected void setParentConfig(final Configuration config) { if (this.parentConfiguration == this) { throw new IllegalArgumentException("Cannot add myself as parent configuration."); } this.parentConfiguration = config; } /** * Returns the parent configuration. The parent configuration is queried, if * the requested configuration values was not found in this report * configuration. * * @return the parent configuration. */ protected Configuration getParentConfig() { return this.parentConfiguration; } /** * Returns all defined configuration properties for the report. The * enumeration contains all keys of the changed properties, properties set * from files or the system properties are not included. * * @return all defined configuration properties for the report. */ public Enumeration getConfigProperties() { return this.configuration.keys(); } /** * Searches all property keys that start with a given prefix. * * @param prefix the prefix that all selected property keys should share * @return the properties as iterator. */ public Iterator findPropertyKeys(final String prefix) { if (prefix == null) { throw new NullPointerException("Prefix must not be null"); } final HashSet keys = new HashSet(); collectPropertyKeys(prefix, this, keys); final Object[] objects = keys.toArray(); Arrays.sort(objects); return Arrays.asList(objects).iterator(); } /** * Collects property keys from this and all parent report configurations, * which start with the given prefix. * * @param prefix the prefix, that selects the property keys. * @param config the currently processed report configuration. * @param collector the target list, that should receive all valid keys. */ private void collectPropertyKeys(final String prefix, final Configuration config, final Set collector) { final Enumeration enum1 = config.getConfigProperties(); while (enum1.hasMoreElements()) { final String key = (String) enum1.nextElement(); if (key.startsWith(prefix)) { if (collector.contains(key) == false) { collector.add(key); } } } if (config instanceof HierarchicalConfiguration) { final HierarchicalConfiguration hconfig = (HierarchicalConfiguration) config; if (hconfig.parentConfiguration != null) { collectPropertyKeys(prefix, hconfig.parentConfiguration, collector); } } } /** * Helper method for serialization. * * @param out the output stream where to write the object. * @throws java.io.IOException if errors occur while writing the stream. */ private void writeObject(final ObjectOutputStream out) throws IOException { out.defaultWriteObject(); if (parentConfiguration instanceof HierarchicalConfiguration) { final HierarchicalConfiguration parent = (HierarchicalConfiguration) parentConfiguration; if (parent.booterClass != null) { out.writeBoolean(false); } else { out.writeBoolean(true); out.writeObject(parentConfiguration); } } else if (parentConfiguration != null) { out.writeBoolean(true); out.writeObject(parentConfiguration); } else { out.writeBoolean(false); } } /** * Helper method for serialization. * * @param in the input stream from where to read the serialized object. * @throws java.io.IOException when reading the stream fails. * @throws ClassNotFoundException if a class definition for a serialized * object could not be found. */ private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); final boolean readParent = in.readBoolean(); if (readParent) { parentConfiguration = (ModifiableConfiguration) in.readObject(); } else { if (booterClass != null) { final AbstractBoot boot = AbstractBoot.loadBooter(booterClass.getName(), booterClass); parentConfiguration = boot.getGlobalConfig(); } else { parentConfiguration = null; } } } /** * Clones this configuration. * * @return a clone of this configuration. * @throws CloneNotSupportedException */ public Object clone() throws CloneNotSupportedException { final HierarchicalConfiguration config = (HierarchicalConfiguration) super.clone(); config.configuration = (Properties) configuration.clone(); return config; } }libbase-1.1.6/source/org/pentaho/reporting/libraries/base/config/Configuration.java0000644000175000017500000000453111365604666027147 0ustar renerene/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2007 - 2009 Pentaho Corporation and Contributors. All rights reserved. */ package org.pentaho.reporting.libraries.base.config; import java.io.Serializable; import java.util.Enumeration; import java.util.Iterator; /** * A simple query interface for a configuration. * * @author Thomas Morgner */ public interface Configuration extends Serializable, Cloneable { /** * Returns the configuration property with the specified key. * * @param key the property key. * @return the property value. */ public String getConfigProperty(String key); /** * Returns the configuration property with the specified key (or the * specified default value if there is no such property). *

* If the property is not defined in this configuration, the code will * lookup the property in the parent configuration. * * @param key the property key. * @param defaultValue the default value. * @return the property value. */ public String getConfigProperty(String key, String defaultValue); /** * Returns all keys with the given prefix. * * @param prefix the prefix * @return the iterator containing all keys with that prefix */ public Iterator findPropertyKeys(String prefix); /** * Returns the configuration properties. * * @return The configuration properties. */ public Enumeration getConfigProperties(); /** * Returns a clone of the object. * * @return A clone. * @throws CloneNotSupportedException if cloning is not supported for some reason. */ public Object clone() throws CloneNotSupportedException; }libbase-1.1.6/source/org/pentaho/reporting/libraries/base/config/ExtendedConfiguration.java0000644000175000017500000000540211365604666030626 0ustar renerene/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2007 - 2009 Pentaho Corporation and Contributors. All rights reserved. */ package org.pentaho.reporting.libraries.base.config; /** * The extended configuration provides methods to make using the * configuration easier. * * @author Thomas Morgner */ public interface ExtendedConfiguration extends Configuration { /** * Checks, whether a given property is defined. * * @param name the name of the property * @return true, if the property is defined, false otherwise. */ public boolean isPropertySet(String name); /** * Returns a given property as int value. Zero is returned if the * property value is no number or the property is not set. * * @param name the name of the property * @return the parsed number value or zero */ public int getIntProperty(String name); /** * Returns a given property as int value. The specified default value is returned if the * property value is no number or the property is not set. * * @param name the name of the property * @param defaultValue the value to be returned if the property is no integer value * @return the parsed number value or the specified default value */ public int getIntProperty(String name, int defaultValue); /** * Returns the boolean value of a given configuration property. The boolean value true * is returned, if the contained string is equal to 'true'. * * @param name the name of the property * @return the boolean value of the property. */ public boolean getBoolProperty(String name); /** * Returns the boolean value of a given configuration property. The boolean value true * is returned, if the contained string is equal to 'true'. If the property is not set, * the default value is returned. * * @param name the name of the property * @param defaultValue the default value to be returned if the property is not set * @return the boolean value of the property. */ public boolean getBoolProperty(String name, boolean defaultValue); }libbase-1.1.6/source/org/pentaho/reporting/libraries/base/config/DefaultConfiguration.java0000644000175000017500000000630211365604666030452 0ustar renerene/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2007 - 2009 Pentaho Corporation and Contributors. All rights reserved. */ package org.pentaho.reporting.libraries.base.config; import java.util.Collections; import java.util.Enumeration; import java.util.Iterator; import java.util.Properties; import java.util.TreeSet; /** * Default configuration. * * @author Thomas Morgner. */ public class DefaultConfiguration extends Properties implements ModifiableConfiguration { /** A constant for serialization support. */ private static final long serialVersionUID = -7812745196042984458L; /** * Creates an empty property list with no default values. */ public DefaultConfiguration() { } /** * Returns the configuration property with the specified key. * * @param key the property key. * @return the property value. */ public String getConfigProperty(final String key) { return getProperty(key); } /** * Returns the configuration property with the specified key (or the * specified default value if there is no such property). *

* If the property is not defined in this configuration, the code will * lookup the property in the parent configuration. * * @param key the property key. * @param defaultValue the default value. * @return the property value. */ public String getConfigProperty(final String key, final String defaultValue) { return getProperty(key, defaultValue); } /** * Searches all property keys that start with a given prefix. * * @param prefix the prefix that all selected property keys should share * @return the properties as iterator. */ public Iterator findPropertyKeys(final String prefix) { final TreeSet collector = new TreeSet(); final Enumeration enum1 = keys(); while (enum1.hasMoreElements()) { final String key = (String) enum1.nextElement(); if (key.startsWith(prefix)) { if (collector.contains(key) == false) { collector.add(key); } } } return Collections.unmodifiableSet(collector).iterator(); } public Enumeration getConfigProperties() { return keys(); } /** * Sets the value of a configuration property. * * @param key the property key. * @param value the property value. */ public void setConfigProperty(final String key, final String value) { if (value == null) { remove(key); } else { setProperty(key, value); } } }libbase-1.1.6/source/org/pentaho/reporting/libraries/base/config/SystemPropertyConfiguration.java0000644000175000017500000000717011365604666032123 0ustar renerene/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2007 - 2009 Pentaho Corporation and Contributors. All rights reserved. */ package org.pentaho.reporting.libraries.base.config; import java.util.Enumeration; import java.util.Collections; /** * A property configuration based on system properties. * * @author Thomas Morgner * @noinspection AccessOfSystemProperties */ public class SystemPropertyConfiguration extends HierarchicalConfiguration { /** A serialization constant. */ private static final long serialVersionUID = 4200899352924290311L; /** * Creates a report configuration that includes all the system properties (whether they are * related to reports or not). The parent configuration is a * PropertyFileConfiguration. */ public SystemPropertyConfiguration() { } /** * Sets a configuration property. * * @param key the property key. * @param value the property value. */ public void setConfigProperty(final String key, final String value) { throw new UnsupportedOperationException("The SystemPropertyConfiguration is readOnly"); } /** * Returns the configuration property with the specified key (or the specified default value * if there is no such property). *

* If the property is not defined in this configuration, the code will lookup the property in * the parent configuration. * * @param key the property key. * @param defaultValue the default value. * @return the property value. */ public String getConfigProperty(final String key, final String defaultValue) { try { final String value = System.getProperty(key); if (value != null) { return value; } } catch (SecurityException se) { // ignore security exceptions, continue as if the property was not set.. } return super.getConfigProperty(key, defaultValue); } /** * Checks, whether the given key is locally defined in the system properties. * * @param key the key that should be checked. * @return true, if the key is defined in the system properties, false otherwise. * @see HierarchicalConfiguration#isLocallyDefined(String) */ public boolean isLocallyDefined(final String key) { try { return System.getProperties().containsKey(key); } catch (SecurityException se) { return false; } } /** * Returns all defined configuration properties for the report. The enumeration * contains all keys of the changed properties, properties set from files or * the system properties are not included. * * @return all defined configuration properties for the report. */ public Enumeration getConfigProperties() { try { return System.getProperties().keys(); } catch (SecurityException se) { // should return an empty enumeration ... return Collections.enumeration(Collections.EMPTY_LIST); } } }libbase-1.1.6/source/org/pentaho/reporting/libraries/base/config/ModifiableConfiguration.java0000644000175000017500000000320511365604666031120 0ustar renerene/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2007 - 2009 Pentaho Corporation and Contributors. All rights reserved. */ package org.pentaho.reporting.libraries.base.config; import java.util.Enumeration; import java.util.Iterator; /** * A modifiable configuration. * * @author Thomas Morgner */ public interface ModifiableConfiguration extends Configuration { /** * Sets the value of a configuration property. * * @param key the property key. * @param value the property value. */ public void setConfigProperty(final String key, final String value); /** * Returns the configuration properties. * * @return The configuration properties. */ public Enumeration getConfigProperties(); /** * Returns an iterator for the keys beginning with the specified prefix. * * @param prefix the prefix. * @return The iterator. */ public Iterator findPropertyKeys(final String prefix); }libbase-1.1.6/source/org/pentaho/reporting/libraries/base/config/PropertyFileConfiguration.java0000644000175000017500000000717211365604666031520 0ustar renerene/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2007 - 2009 Pentaho Corporation and Contributors. All rights reserved. */ package org.pentaho.reporting.libraries.base.config; import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Properties; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.pentaho.reporting.libraries.base.util.ObjectUtilities; /** * A report configuration that reads its values from an arbitary property file. * * @author Thomas Morgner */ public class PropertyFileConfiguration extends HierarchicalConfiguration { /** A logger for debug-messages. */ private static final Log LOGGER = LogFactory.getLog(PropertyFileConfiguration.class); /** A serialization related constant. */ private static final long serialVersionUID = 2423181637547944866L; /** * Default constructor. */ public PropertyFileConfiguration() { // nothing required } /** * Lods the property file from a classpath resource name. The classpath resource must be loadable via * PropertyFileConfiguration.class.getResource(..) * * @param resourceName the resource name to be loaded. */ public void load(final String resourceName) { load(resourceName, PropertyFileConfiguration.class); } /** * Loads the properties stored in the given file. This method does nothing if * the file does not exist or is unreadable. Appends the contents of the loaded * properties to the already stored contents. * * @param resourceName the file name of the stored properties. * @param resourceSource the class to which relative resource paths are resolved. */ public void load(final String resourceName, final Class resourceSource) { final InputStream in = ObjectUtilities.getResourceRelativeAsStream (resourceName, resourceSource); if (in != null) { try { load(in); } finally { try { in.close(); } catch (IOException e) { // ignore } } } else { LOGGER.debug("Configuration file not found in the classpath: " + resourceName); } } /** * Loads the properties stored in the given file. This method does nothing if * the file does not exist or is unreadable. Appends the contents of the loaded * properties to the already stored contents. * * @param in the input stream used to read the properties. */ public void load(final InputStream in) { if (in == null) { throw new NullPointerException(); } try { final BufferedInputStream bin = new BufferedInputStream(in); final Properties p = new Properties(); p.load(bin); this.getConfiguration().putAll(p); bin.close(); } catch (IOException ioe) { LOGGER.warn("Unable to read configuration", ioe); } } }libbase-1.1.6/source/org/pentaho/reporting/libraries/base/util/0000755000175000017500000000000011365604666023202 5ustar renerenelibbase-1.1.6/source/org/pentaho/reporting/libraries/base/util/LFUMap.java0000644000175000017500000002676711365604666025153 0ustar renerene/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2007 - 2009 Pentaho Corporation and Contributors. All rights reserved. */ package org.pentaho.reporting.libraries.base.util; import java.util.HashMap; import java.io.Serializable; /** * A Least-Frequently-Used Map. *

* This is not a real map in the sense of the Java-Collections-API. This is a slimmed down version of a * Least-Frequently-Used map with no unnecessary extra stuff like iterators or other costly but rarely used * java.util.Collections features. The cache does not accept null-keys, and any attempt to store null-values * will yield an error. *

* To remove a couple of ugly checks and thus improving performance, this map enforces a minimum size of 3 items. * * @author Thomas Morgner */ public class LFUMap implements Serializable, Cloneable { /** * A cache map entry class holding both the key and value and acting as member of a linked list. */ private static class MapEntry { private Object key; private Object value; private MapEntry previous; private MapEntry next; /** * Creates a new map-entry for the given key and value. * * @param key the key, never null. * @param value the value, never null. */ protected MapEntry(final Object key, final Object value) { if (key == null) { throw new NullPointerException(); } if (value == null) { throw new NullPointerException(); } this.key = key; this.value = value; } /** * Returns the entry's key. * @return the key. */ public Object getKey() { return key; } /** * Returns the previous entry in the list or null if this is the first entry. * @return the previous entry. */ public MapEntry getPrevious() { return previous; } /** * Redefines the previous entry in the list or null if this is the first entry. * @param previous the previous entry. */ public void setPrevious(final MapEntry previous) { this.previous = previous; } /** * Returns the next entry in the list or null if this is the last entry. * @return the next entry. */ public MapEntry getNext() { return next; } /** * Redefines the next entry in the list or null if this is the last entry. * @param next the next entry. */ public void setNext(final MapEntry next) { this.next = next; } /** * Returns the current value. * * @return the value, never null. */ public Object getValue() { return value; } /** * Redefines the current value. * * @param value the value, never null. */ public void setValue(final Object value) { if (value == null) { throw new NullPointerException(); } this.value = value; } } private HashMap map; private MapEntry first; private MapEntry last; private int cacheSize; /** * Creates a new LFU-Map with a maximum size of cacheSize entries. * * @param cacheSize the maximum number of elements this map will be able to store. */ public LFUMap(final int cacheSize) { // having at least 3 entries saves me a lot of coding and thus gives more performance .. this.cacheSize = Math.max(3, cacheSize); this.map = new HashMap(cacheSize); } public void clear() { this.map.clear(); this.first = null; this.last = null; } /** * Return the entry for the given key. Any successful lookup moves the entry to the top of the list. * * @param key the lookup key. * @return the value stored for the key or null. */ public Object get(final Object key) { if (key == null) { throw new NullPointerException(); } if (first == null) { // the cache is empty, so there is no way how we can have a result return null; } if (first == last) { // single entry does not even need to hit the cache .. if (first.getKey().equals(key)) { return first.getValue(); } return null; } final MapEntry metrics = (MapEntry) map.get(key); if (metrics == null) { // no such key .. return null; } final MapEntry prev = metrics.getPrevious(); if (prev == null) { // already the first value return metrics.getValue(); } final MapEntry next = metrics.getNext(); if (next == null) { // metrics is last entry // prev will be the new last entry prev.setNext(null); last = prev; metrics.setPrevious(null); metrics.setNext(first); first.setPrevious(metrics); first = metrics; return metrics.getValue(); } // in the middle .. remove from the chain next.setPrevious(prev); prev.setNext(next); // and add it at the top .. metrics.setPrevious(null); metrics.setNext(first); first.setPrevious(metrics); first = metrics; return metrics.getValue(); } /** * Puts the given value into the map using the specified non-null key. The new entry is added as first entry in * the list of recently used values. * * @param key the key. * @param value the value. */ public void put(final Object key, final Object value) { if (key == null) { throw new NullPointerException(); } if (first == null) { if (value == null) { return; } first = new MapEntry(key, value); last = first; map.put(key, first); return; } if (value == null) { remove(key); return; } if (first.getKey().equals(key)) { // no need to do actual work .. return; } final MapEntry entry = (MapEntry) map.get(key); if (entry == null) { // check, whether the backend can carry another entry .. if ((1 + map.size()) >= cacheSize) { // remove the last entry map.remove(last.getKey()); final MapEntry previous = last.getPrevious(); last.setNext(null); last.setPrevious(null); previous.setNext(null); last = previous; } // now add this entry as first one .. final MapEntry cacheEntry = new MapEntry(key, value); first.setPrevious(cacheEntry); cacheEntry.setNext(first); map.put(key, cacheEntry); first = cacheEntry; return; } // replace an existing value .. entry.setValue(value); if (entry == first) { // already the first one .. // should not happen, we have checked that ... // map.put(key, entry); throw new IllegalStateException("Duplicate return?"); } if (entry == last) { // prev is now the new last entry .. final MapEntry previous = last.getPrevious(); previous.setNext(null); last = previous; first.setPrevious(entry); entry.setNext(first); entry.setPrevious(null); first = entry; return; } final MapEntry previous = entry.getPrevious(); final MapEntry next = entry.getNext(); // next cannot be null, else 'entry' would be the last entry, and we checked that already .. previous.setNext(next); next.setPrevious(previous); first.setPrevious(entry); entry.setNext(first); entry.setPrevious(null); first = entry; } /** * Removes the entry for the given key. * * @param key the key for which an entry should be removed. */ public void remove(final Object key) { if (key == null) { throw new NullPointerException(); } if (first == null) { return; } final MapEntry entry = (MapEntry) map.remove(key); if (entry == null) { return; } if (entry == first) { final MapEntry nextEntry = first.getNext(); if (nextEntry == null) { first = null; last = null; entry.setNext(null); entry.setPrevious(null); return; } first = nextEntry; nextEntry.setPrevious(null); entry.setNext(null); entry.setPrevious(null); return; } if (entry == last) { final MapEntry prev = last.getPrevious(); // prev cannot be null, else first would be the same as last prev.setNext(null); last = prev; entry.setNext(null); entry.setPrevious(null); return; } final MapEntry previous = entry.getPrevious(); final MapEntry next = entry.getNext(); // next cannot be null, else 'entry' would be the last entry, and we checked that already .. previous.setNext(next); next.setPrevious(previous); entry.setNext(null); entry.setPrevious(null); } /** * Returns the number of items in this map. * * @return the number of items in the map. */ public int size() { return map.size(); } /** * Checks whether this map is empty. * * @return true, if the map is empty, false otherwise. */ public boolean isEmpty() { return first == null; } /** * Returns the defined maximum size. * * @return the defines maximum size. */ public int getMaximumSize() { return cacheSize; } /** * Validates the map's internal datastructures. There should be no need to call this method manually. */ public void validate() { if (first == null) { return; } if (first.getPrevious() != null) { throw new IllegalStateException(); } if (this.last.getNext() != null) { throw new IllegalStateException(); } int counter = 0; MapEntry p = null; MapEntry entryFromStart = first; while (entryFromStart != null) { if (entryFromStart.getPrevious() != p) { throw new IllegalStateException(); } p = entryFromStart; entryFromStart = entryFromStart.getNext(); counter += 1; } if (counter != size()) { throw new IllegalStateException(); } int fromEndCounter = 0; MapEntry n = null; MapEntry entryFromEnd = this.last; while (entryFromEnd != null) { if (entryFromEnd.getNext() != n) { throw new IllegalStateException(); } n = entryFromEnd; entryFromEnd = entryFromEnd.getPrevious(); fromEndCounter += 1; } if (n != first) { throw new IllegalStateException(); } if (fromEndCounter != size()) { throw new IllegalStateException(); } if (size() > cacheSize) { throw new IllegalStateException(); } } public Object clone() throws CloneNotSupportedException { final LFUMap map = (LFUMap) super.clone(); map.map = (HashMap) map.clone(); map.map.clear(); MapEntry entry = first; while (entry != null) { map.put(entry.getKey(), entry.getValue()); entry = entry.getNext(); } return map; } } libbase-1.1.6/source/org/pentaho/reporting/libraries/base/util/PadMessage.java0000644000175000017500000000361611365604666026064 0ustar renerene/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2007 - 2009 Pentaho Corporation and Contributors. All rights reserved. */ package org.pentaho.reporting.libraries.base.util; import java.util.Arrays; /** * A message object that pads the output if the text is shorter than * the given length. This is usefull when concating multiple messages, * which should appear in a table like style. * * @author Thomas Morgner */ public class PadMessage { /** * The message. */ private final Object text; /** * The padding size. */ private final int length; /** * Creates a new message. * * @param message the message. * @param length the padding size. */ public PadMessage(final Object message, final int length) { this.text = message; this.length = length; } /** * Returns a string representation of the message. * * @return the string. */ public String toString() { final StringBuffer b = new StringBuffer(length); b.append(this.text); if (b.length() < this.length) { final char[] pad = new char[this.length - b.length()]; Arrays.fill(pad, ' '); b.append(pad); } return b.toString(); } }libbase-1.1.6/source/org/pentaho/reporting/libraries/base/util/Empty.java0000644000175000017500000000366711365604666025157 0ustar renerene/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2007 - 2009 Pentaho Corporation and Contributors. All rights reserved. */ package org.pentaho.reporting.libraries.base.util; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; /** * Class which holds a static reference to a set of empty objects. This is created for performance * reasons. Using this class will prevent creating duplicated "empty" object. * * @author David Kincade */ public final class Empty { /** * No reason to create an instance of this class. */ private Empty() { } /** * The empty string. */ public static final String STRING = ""; /** * An empty array of Strings. */ public static final String[] STRING_ARRAY = new String[0]; /** * An empty Map. (Collections.EMPTY_MAP is not available until JDK 1.4) * @noinspection PublicStaticCollectionField */ public static final Map MAP = Collections.unmodifiableMap(new HashMap()); /** * An empty List. * * @deprecated this is a redeclaration of the Collections.EMPTY_LIST field and should be killed. * @noinspection PublicStaticCollectionField */ public static final List LIST = Collections.EMPTY_LIST; }libbase-1.1.6/source/org/pentaho/reporting/libraries/base/util/FilesystemFilter.java0000644000175000017500000001124511365604666027342 0ustar renerene/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2007 - 2009 Pentaho Corporation and Contributors. All rights reserved. */ package org.pentaho.reporting.libraries.base.util; import java.io.File; import java.io.FilenameFilter; import java.util.Arrays; import javax.swing.filechooser.FileFilter; /** * A filesystem filter. * * @author David Gilbert */ public class FilesystemFilter extends FileFilter implements FilenameFilter { /** * The file extension, which should be accepted. */ private String[] fileext; /** * The filter description. */ private String descr; /** * A flag indicating whether to accept directories. */ private boolean accDirs; /** * Creates a new filter. * * @param fileext the file extension. * @param descr the description. */ public FilesystemFilter(final String fileext, final String descr) { this(fileext, descr, true); } /** * Creates a new filter. * * @param fileext the file extension. * @param descr the description. * @param accDirs accept directories? */ public FilesystemFilter(final String fileext, final String descr, final boolean accDirs) { this(new String[]{fileext}, descr, accDirs); } /** * Creates a new filter. * * @param fileext the file extension. * @param descr the description. * @param accDirs accept directories? * @throws NullPointerException if the file extensions are null. */ public FilesystemFilter(final String[] fileext, final String descr, final boolean accDirs) { this.fileext = (String[]) fileext.clone(); this.descr = descr; this.accDirs = accDirs; } /** * Returns true if the file is accepted, and false otherwise. * * @param dir the directory. * @param name the file name. * @return A boolean. */ public boolean accept(final File dir, final String name) { final File f = new File(dir, name); if (f.isDirectory() && acceptsDirectories()) { return true; } for (int i = 0; i < fileext.length; i++) { if (name.endsWith(this.fileext[i])) { return true; } } return false; } /** * Returns true if the specified file matches the requirements of this * filter, and false otherwise. * * @param dir the file or directory. * @return A boolean. */ public boolean accept(final File dir) { if (dir.isDirectory() && acceptsDirectories()) { return true; } for (int i = 0; i < fileext.length; i++) { if (dir.getName().endsWith(this.fileext[i])) { return true; } } return false; } /** * Returns the filter description. * * @return The filter description. */ public String getDescription() { return this.descr; } /** * Sets the flag that controls whether or not the filter accepts directories. * * @param b a boolean. */ public void acceptDirectories(final boolean b) { this.accDirs = b; } /** * Returns the flag that indicates whether or not the filter accepts directories. * * @return A boolean. */ public boolean acceptsDirectories() { return this.accDirs; } public boolean equals(final Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } final FilesystemFilter that = (FilesystemFilter) o; if (accDirs != that.accDirs) { return false; } if (descr != null ? !descr.equals(that.descr) : that.descr != null) { return false; } if (!ObjectUtilities.equalArray(fileext, that.fileext)) { return false; } return true; } public int hashCode() { int result = ObjectUtilities.hashCode(fileext); result = 31 * result + (descr != null ? descr.hashCode() : 0); result = 31 * result + (accDirs ? 1 : 0); return result; } } libbase-1.1.6/source/org/pentaho/reporting/libraries/base/util/StringBufferWriter.java0000644000175000017500000000706511365604666027652 0ustar renerene/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2007 - 2009 Pentaho Corporation and Contributors. All rights reserved. */ package org.pentaho.reporting.libraries.base.util; import java.io.Writer; import java.io.IOException; /** * Todo: Document Me * * @author Thomas Morgner */ public class StringBufferWriter extends Writer { private StringBuffer buffer; public StringBufferWriter(final StringBuffer buffer) { if (buffer == null) { throw new NullPointerException(); } this.buffer = buffer; } public StringBuffer getBuffer() { return buffer; } /** * Write a single character. The character to be written is contained in * the 16 low-order bits of the given integer value; the 16 high-order bits * are ignored. *

*

Subclasses that intend to support efficient single-character output * should override this method. * * @param c int specifying a character to be written. * @throws IOException If an I/O error occurs */ public void write(final int c) throws IOException { buffer.append((char) c); } /** * Write a string. * * @param str String to be written * @throws IOException If an I/O error occurs */ public void write(final String str) throws IOException { buffer.append(str); } /** * Write a portion of an array of characters. * * @param cbuf Array of characters * @param off Offset from which to start writing characters * @param len Number of characters to write * @throws IOException If an I/O error occurs */ public void write(final char[] cbuf, final int off, final int len) throws IOException { buffer.append(cbuf, off, len); } /** * Flush the stream. If the stream has saved any characters from the * various write() methods in a buffer, write them immediately to their * intended destination. Then, if that destination is another character or * byte stream, flush it. Thus one flush() invocation will flush all the * buffers in a chain of Writers and OutputStreams. *

* If the intended destination of this stream is an abstraction provided by * the underlying operating system, for example a file, then flushing the * stream guarantees only that bytes previously written to the stream are * passed to the operating system for writing; it does not guarantee that * they are actually written to a physical device such as a disk drive. * * @throws IOException If an I/O error occurs */ public void flush() throws IOException { } /** * Close the stream, flushing it first. Once a stream has been closed, * further write() or flush() invocations will cause an IOException to be * thrown. Closing a previously-closed stream, however, has no effect. * * @throws IOException If an I/O error occurs */ public void close() throws IOException { } } libbase-1.1.6/source/org/pentaho/reporting/libraries/base/util/CSVQuoter.java0000644000175000017500000001510211365604666025677 0ustar renerene/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2007 - 2009 Pentaho Corporation and Contributors. All rights reserved. */ package org.pentaho.reporting.libraries.base.util; import java.io.Writer; import java.io.IOException; /** * The CSVQuoter is a helper class to encode a string for the CSV file * format. * * @author Thomas Morgner. */ public final class CSVQuoter { /** * The separator used in the CSV file. */ private char separator; /** * The quoting character or a single quote. */ private char quate; /** * The double quote. This is a string containing the quate two times. */ private String doubleQuate; /** * Creates a new CSVQuoter, which uses a comma as the default separator. */ public CSVQuoter() { this(',', '"'); } /** * Creates a new CSVQuoter, which uses the defined separator. * * @param separator the separator. * @throws NullPointerException if the given separator is null. */ public CSVQuoter(final char separator) { this(separator, '"'); } /** * Creates a new CSVQuoter with the given separator and quoting character. * * @param separator the separator * @param quate the quoting character */ public CSVQuoter(final char separator, final char quate) { this.separator = separator; this.quate = quate; this.doubleQuate = String.valueOf(quate) + quate; } /** * Encodes the string, so that the string can safely be used in CSV files. If the string * does not need quoting, the original string is returned unchanged. * * @param original the unquoted string. * @return The quoted string */ public String doQuoting (final String original) { if (isQuotingNeeded(original)) { final StringBuffer retval = new StringBuffer(original.length() + 5); // a safe guess most of the time. retval.append(quate); applyQuote(retval, original); retval.append(quate); return retval.toString(); } else { return original; } } /** * A streaming version of the quoting algorithm for more performance. Encodes the string, so that the string can * safely be used in CSV files. If the string does not need quoting, the original string is returned unchanged. * * @param original the unquoted string. * @param writer the writer. * @throws IOException if an IO error occured. */ public void doQuoting (final String original, final Writer writer) throws IOException { if (isQuotingNeeded(original)) { writer.write(quate); applyQuote(writer, original); writer.write(quate); } else { writer.write(original); } } /** * Decodes the string, so that all escape sequences get removed. If the string was not * quoted, then the string is returned unchanged. * * @param nativeString the quoted string. * @return The unquoted string. */ public String undoQuoting (final String nativeString) { if (isQuotingNeeded(nativeString)) { final StringBuffer b = new StringBuffer(nativeString.length()); final int length = nativeString.length() - 1; int start = 1; int pos = start; while (pos != -1) { pos = nativeString.indexOf(doubleQuate, start); if (pos == -1) { b.append(nativeString.substring(start, length)); } else { b.append(nativeString.substring(start, pos)); start = pos + 1; } } return b.toString(); } else { return nativeString; } } /** * Tests, whether this string needs to be quoted. A string is encoded if the string * contains a newline character, a quote character or the defined separator. * * @param str the string that should be tested. * @return true, if quoting needs to be applied, false otherwise. */ private boolean isQuotingNeeded (final String str) { final int length = str.length(); for (int i = 0; i < length; i++) { final char c = str.charAt(i); if (c == separator) { return true; } if (c == '\n') { return true; } if (c == quate) { return true; } } return false; } /** * Applies the quoting to a given string, and stores the result in the StringBuffer * b. * * @param b the result buffer * @param original the string, that should be quoted. */ private void applyQuote (final StringBuffer b, final String original) { // This solution needs improvements. Copy blocks instead of single // characters. final int length = original.length(); for (int i = 0; i < length; i++) { final char c = original.charAt(i); if (c == quate) { b.append(doubleQuate); } else { b.append(c); } } } /** * Applies the quoting to a given string, and stores the result in the StringBuffer * b. * * @param b the result buffer * @param original the string, that should be quoted. * @throws IOException if an IO-Error occured. */ private void applyQuote (final Writer b, final String original) throws IOException { // This solution needs improvements. Copy blocks instead of single // characters. final int length = original.length(); for (int i = 0; i < length; i++) { final char c = original.charAt(i); if (c == quate) { b.write(doubleQuate); } else { b.write(c); } } } /** * Gets the separator used in this quoter and the CSV file. * * @return the separator (never null). */ public char getSeparator () { return separator; } /** * Returns the quoting character. * * @return the quote character. */ public char getQuate () { return quate; } }libbase-1.1.6/source/org/pentaho/reporting/libraries/base/util/IOUtils.java0000644000175000017500000006213711365604666025406 0ustar renerene/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2007 - 2009 Pentaho Corporation and Contributors. All rights reserved. */ package org.pentaho.reporting.libraries.base.util; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.Reader; import java.io.Writer; import java.io.StringWriter; import java.net.URL; import java.sql.Blob; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.StringTokenizer; import java.sql.Clob; import java.sql.SQLException; import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.Log; /** * The IOUtils provide some IO related helper methods. * * @author Thomas Morgner. */ public class IOUtils { /** * the singleton instance of the utility package. */ private static IOUtils instance; private static final Log logger = LogFactory.getLog(IOUtils.class); /** * DefaultConstructor. */ private IOUtils() { } /** * Gets the singleton instance of the utility package. * * @return the singleton instance. */ public static synchronized IOUtils getInstance() { if (instance == null) { instance = new IOUtils(); } return instance; } /** * Checks, whether the URL uses a file based protocol. * * @param url the url. * @return true, if the url is file based. */ private boolean isFileStyleProtocol(final URL url) { if (url == null) { throw new NullPointerException(); } final String protocol = url.getProtocol(); if ("http".equals(protocol)) { return true; } if ("https".equals(protocol)) { return true; } if ("ftp".equals(protocol)) { return true; } if ("file".equals(protocol)) { return true; } if ("jar".equals(protocol)) { return true; } return false; } /** * Parses the given name and returns the name elements as List of Strings. * * @param name the name, that should be parsed. * @return the parsed name. */ private List parseName(final String name) { final ArrayList list = new ArrayList(); final StringTokenizer strTok = new StringTokenizer(name, "/"); while (strTok.hasMoreElements()) { final String s = (String) strTok.nextElement(); if (s.length() != 0) { list.add(s); } } return list; } /** * Transforms the name list back into a single string, separated with "/". * * @param name the name list. * @param query the (optional) query for the URL. * @return the constructed name. */ private String formatName(final List name, final String query) { final StringBuffer b = new StringBuffer(128); final Iterator it = name.iterator(); while (it.hasNext()) { b.append(it.next()); if (it.hasNext()) { b.append('/'); } } if (query != null) { b.append('?'); b.append(query); } return b.toString(); } /** * Compares both name lists, and returns the last common index shared between the two lists. * * @param baseName the name created using the base url. * @param urlName the target url name. * @return the number of shared elements. */ private int startsWithUntil(final List baseName, final List urlName) { final int minIdx = Math.min(urlName.size(), baseName.size()); for (int i = 0; i < minIdx; i++) { final String baseToken = (String) baseName.get(i); final String urlToken = (String) urlName.get(i); if (!baseToken.equals(urlToken)) { return i; } } return minIdx; } /** * Checks, whether the URL points to the same service. A service is equal if the protocol, host and port are equal. * * @param url a url * @param baseUrl an other url, that should be compared. * @return true, if the urls point to the same host and port and use the same protocol, false otherwise. */ private boolean isSameService(final URL url, final URL baseUrl) { if (!url.getProtocol().equals(baseUrl.getProtocol())) { return false; } if (!url.getHost().equals(baseUrl.getHost())) { return false; } if (url.getPort() != baseUrl.getPort()) { return false; } return true; } /** * Creates a relative url by stripping the common parts of the the url. If the baseFile denotes a directory, * it must end with a slash. * * @param targetFile the to be stripped url * @param baseFile the base url, to which the url is relative to. * @return the relative url, or the url unchanged, if there is no relation beween both URLs. */ public String createRelativePath(final String targetFile, final String baseFile) { if (targetFile == null) { throw new NullPointerException("targetFile must not be null."); } if (baseFile == null) { throw new NullPointerException("baseFile must not be null."); } // If the URL contains a query, ignore that URL; do not // attemp to modify it... final List baseName = parseName(baseFile); if (baseName.isEmpty()) { return targetFile; } final List urlName = parseName(targetFile); if (urlName.isEmpty()) { return targetFile; } if ((baseFile.length() > 0 && baseFile.charAt(baseFile.length() - 1) == '/') == false) { // remove trailing slashes and ensure that the last element in baseName points to a directory baseName.remove(baseName.size() - 1); } // if both urls are identical, then return the plain file name... if (baseFile.equals(targetFile)) { return (String) urlName.get(urlName.size() - 1); } int commonIndex = startsWithUntil(urlName, baseName); if (commonIndex == 0) { return targetFile; } if (commonIndex == urlName.size()) { // correct the base index if there is some weird mapping // detected, // fi. the file url is fully included in the base url: // // base: /file/test/funnybase // file: /file/test // // this could be a valid configuration whereever virtual // mappings are allowed. commonIndex -= 1; } final ArrayList retval = new ArrayList(); if ((baseName.size() + 1) != urlName.size()) { final int levels = baseName.size() - commonIndex; for (int i = 0; i < levels; i++) { retval.add(".."); } } retval.addAll(urlName.subList(commonIndex, urlName.size())); return formatName(retval, null); } /** * Creates a relative url by stripping the common parts of the the url. If the base-URL denotes a directory, * it must end with a slash. * * @param url the to be stripped url * @param baseURL the base url, to which the url is relative to. * @return the relative url, or the url unchanged, if there is no relation beween both URLs. */ public String createRelativeURL(final URL url, final URL baseURL) { if (url == null) { throw new NullPointerException("content url must not be null."); } if (baseURL == null) { throw new NullPointerException("baseURL must not be null."); } if (isFileStyleProtocol(url) && isSameService(url, baseURL)) { // If the URL contains a query, ignore that URL; do not // attemp to modify it... final List urlName = parseName(getPath(url)); final List baseName = parseName(getPath(baseURL)); final String query = getQuery(url); if (!isPath(baseURL)) { baseName.remove(baseName.size() - 1); } // if both urls are identical, then return the plain file name... if (String.valueOf(url).equals(String.valueOf(baseURL))) { return (String) urlName.get(urlName.size() - 1); } int commonIndex = startsWithUntil(urlName, baseName); if (commonIndex == 0) { return url.toExternalForm(); } if (commonIndex == urlName.size()) { // correct the base index if there is some weird mapping // detected, // fi. the file url is fully included in the base url: // // base: /file/test/funnybase // file: /file/test // // this could be a valid configuration whereever virtual // mappings are allowed. commonIndex -= 1; } final ArrayList retval = new ArrayList(); if (baseName.size() != urlName.size()) { final int levels = baseName.size() - commonIndex; for (int i = 0; i < levels; i++) { retval.add(".."); } } retval.addAll(urlName.subList(commonIndex, urlName.size())); return formatName(retval, query); } return url.toExternalForm(); } /** * Returns true if the URL represents a path, and false otherwise. * * @param baseURL the URL. * @return A boolean. */ private boolean isPath(final URL baseURL) { final String path = getPath(baseURL); if (path.length() > 0 && path.charAt(path.length() - 1) == '/') { return true; } else if ("file".equals(baseURL.getProtocol())) { final File f = new File(path); try { if (f.isDirectory()) { return true; } } catch (SecurityException se) { // ignored ... } } return false; } /** * Implements the JDK 1.3 method URL.getPath(). The path is defined as URL.getFile() minus the (optional) query. * * @param url the URL * @return the path */ private String getQuery(final URL url) { final String file = url.getFile(); final int queryIndex = file.indexOf('?'); if (queryIndex == -1) { return null; } return file.substring(queryIndex + 1); } /** * Implements the JDK 1.3 method URL.getPath(). The path is defined as URL.getFile() minus the (optional) query. * * @param url the URL * @return the path */ private String getPath(final URL url) { final String file = url.getFile(); final int queryIndex = file.indexOf('?'); if (queryIndex == -1) { return file; } return file.substring(0, queryIndex); } /** * Copies the InputStream into the OutputStream, until the end of the stream has been reached. This method uses a * buffer of 4096 kbyte. * * @param in the inputstream from which to read. * @param out the outputstream where the data is written to. * @throws java.io.IOException if a IOError occurs. */ public void copyStreams(final InputStream in, final OutputStream out) throws IOException { copyStreams(in, out, 4096); } /** * Copies the InputStream into the OutputStream, until the end of the stream has been reached. * * @param in the inputstream from which to read. * @param out the outputstream where the data is written to. * @param buffersize the buffer size. * @throws java.io.IOException if a IOError occurs. */ public void copyStreams(final InputStream in, final OutputStream out, final int buffersize) throws IOException { // create a 4kbyte buffer to read the file final byte[] bytes = new byte[buffersize]; // the input stream does not supply accurate available() data // the zip entry does not know the size of the data int bytesRead = in.read(bytes); while (bytesRead > -1) { out.write(bytes, 0, bytesRead); bytesRead = in.read(bytes); } } /** * Copies the contents of the Reader into the Writer, until the end of the stream has been reached. This method uses * a buffer of 4096 kbyte. * * @param in the reader from which to read. * @param out the writer where the data is written to. * @throws java.io.IOException if a IOError occurs. */ public void copyWriter(final Reader in, final Writer out) throws IOException { copyWriter(in, out, 4096); } /** * Copies the contents of the Reader into the Writer, until the end of the stream has been reached. * * @param in the reader from which to read. * @param out the writer where the data is written to. * @param buffersize the buffer size. * @throws java.io.IOException if a IOError occurs. */ public void copyWriter(final Reader in, final Writer out, final int buffersize) throws IOException { // create a 4kbyte buffer to read the file final char[] bytes = new char[buffersize]; // the input stream does not supply accurate available() data // the zip entry does not know the size of the data int bytesRead = in.read(bytes); while (bytesRead > -1) { out.write(bytes, 0, bytesRead); bytesRead = in.read(bytes); } } /** * Reads the given number of bytes into the target array. This method does not return until all bytes are read. In * case a end-of-stream is reached, the method throws an Exception. * * @param in the inputstream from where to read. * @param data the array where to store the data. * @param offset the offset in the array where to store the data. * @param length the number of bytes to be read. * @throws IOException if an IO error occured or the End of the stream has been reached. */ public void readFully (final InputStream in, final byte[] data, final int offset, final int length) throws IOException { int bytesToRead = length; int bytesRead = 0; do { final int size = in.read(data, offset + bytesRead, bytesToRead); if (size == -1) { throw new IOException("End-Of-File reached"); } bytesToRead = bytesToRead - size; bytesRead += size; } while(bytesToRead > 0); } /** * Reads the given number of bytes into the target array. This method does not return until all bytes are read. In * case a end-of-stream is reached, the method throws an Exception. * * @param in the inputstream from where to read. * @param data the array where to store the data. * @param offset the offset in the array where to store the data. * @param length the number of bytes to be read. * @throws IOException if an IO error occured or the End of the stream has been reached. */ public int readSafely (final InputStream in, final byte[] data, final int offset, final int length) throws IOException { int bytesToRead = length; int bytesRead = 0; do { final int size = in.read(data, offset + bytesRead, bytesToRead); if (size == -1) { return bytesRead; } bytesToRead = bytesToRead - size; bytesRead += size; } while(bytesToRead > 0); // end of file reached .. return 0; } /** * Extracts the file name from the URL. * * @param url the url. * @return the extracted filename. */ public String getFileName(final URL url) { final String fileRaw = url.getFile(); final int query = fileRaw.lastIndexOf('?'); final String file; if (query == -1) { file = fileRaw; } else { file = fileRaw.substring(0, query); } // Now the processing is the same as if it is a string return getFileName(file); } /** * Extracts the last file name from the given pathname. * * @param path the path name. * @return the extracted filename. */ public String getFileName(final String path) { // Check for slash and backslash final int last = Math.max(path.lastIndexOf('/'), path.lastIndexOf('\\')); if (last < 0) { return path; } return path.substring(last + 1); } /** * Removes the file extension from the given file name. * * @param file the file name. * @return the file name without the file extension. */ public String stripFileExtension(final String file) { final int idx = file.lastIndexOf('.'); // handles unix hidden files and files without an extension. if (idx < 1) { return file; } return file.substring(0, idx); } /** * Returns the file extension of the given file name. The returned value will contain the dot. * * @param file the file name. * @return the file extension. */ public String getFileExtension(final String file) { final int idx = file.lastIndexOf('.'); // handles unix hidden files and files without an extension. if (idx < 1) { return ""; } return file.substring(idx); } /** * Checks, whether the child directory is a subdirectory of the base directory. * * @param base the base directory. * @param child the suspected child directory. * @return true, if the child is a subdirectory of the base directory. * @throws java.io.IOException if an IOError occured during the test. */ public boolean isSubDirectory(File base, File child) throws IOException { base = base.getCanonicalFile(); child = child.getCanonicalFile(); File parentFile = child; while (parentFile != null) { if (base.equals(parentFile)) { return true; } parentFile = parentFile.getParentFile(); } return false; } /** * Returns a reference to a file with the specified name that is located somewhere on the classpath. The code for * this method is an adaptation of code supplied by Dave Postill. * * @param name the filename. * @return a reference to a file or null if no file could be found. * @throws SecurityException if access to the system properties or filesystem is forbidden. * @noinspection AccessOfSystemProperties */ public File findFileOnClassPath(final String name) throws SecurityException { final String classpath = System.getProperty("java.class.path"); final String pathSeparator = System.getProperty("path.separator"); final StringTokenizer tokenizer = new StringTokenizer(classpath, pathSeparator); while (tokenizer.hasMoreTokens()) { final String pathElement = tokenizer.nextToken(); final File directoryOrJar = new File(pathElement); final File absoluteDirectoryOrJar = directoryOrJar.getAbsoluteFile(); if (absoluteDirectoryOrJar.isFile()) { final File target = new File(absoluteDirectoryOrJar.getParent(), name); if (target.exists()) { return target; } } else { final File target = new File(directoryOrJar, name); if (target.exists()) { return target; } } } return null; } /** * Computes the absolute filename for the target file using the baseFile as root directory. If the baseFile is * null or empty, the target file will be normalized (all navigation elements like ".." are removed). * * @param targetFile the target file name. * @param baseFile the base file (can be null). * @return the absolute path. */ public String getAbsolutePath (final String targetFile, final String baseFile) { if (targetFile == null) { throw new NullPointerException("targetFile must not be null."); } if (baseFile == null || "".equals(baseFile)) { return stripNavigationPaths(targetFile); } if (targetFile.length() > 0 && targetFile.charAt(0) == '/') { return stripNavigationPaths(targetFile.substring(1)); } final List baseName = parseName(baseFile); if (baseName.isEmpty()) { return stripNavigationPaths(targetFile); } final List urlName = parseName(targetFile); if (urlName.isEmpty()) { return stripNavigationPaths(baseFile); } if ((baseFile.length() > 0 && baseFile.charAt(baseFile.length() - 1) == '/') == false) { // trailing slashes indicate directory, // so remove last entry if the basefile name does not end with a slash (ie it points to a file) baseName.remove(baseName.size() - 1); if (baseName.isEmpty()) { return stripNavigationPaths(targetFile); } } for (int i = 0; i < urlName.size(); i++) { final String pathElement = (String) urlName.get(i); if ("".equals(pathElement) || pathElement == null) { continue; } if (".".equals(pathElement)) { continue; } if ("..".equals(pathElement)) { if (baseName.isEmpty() == false) { baseName.remove(baseName.size() - 1); } continue; } baseName.add(pathElement); } final String s = formatName(baseName, null); if (targetFile.length() > 0 && targetFile.charAt(targetFile.length() - 1) == '/') { return s + '/'; } return s; } /** * Normalizes the given pathname. * * @param targetFile the target file to be normalized, never null. * @return the normalized filename. */ private String stripNavigationPaths (final String targetFile) { final List list = parseName(targetFile); final int capacity = list.size(); final List path = new ArrayList(capacity); for (int i = 0; i < capacity; i++) { final String pathElement = (String) list.get(i); if ("".equals(pathElement) || pathElement == null) { continue; } if (".".equals(pathElement)) { continue; } if ("..".equals(pathElement)) { if (path.isEmpty() == false) { path.remove(path.size() - 1); } continue; } path.add(pathElement); } final String s = formatName(path, null); if (targetFile.length() > 0 && targetFile.charAt(targetFile.length() - 1) == '/') { return s + '/'; } return s; } /** * Returns the path-portion of the given path (anything before the last slash or backslash) or an empty string. * * @param path the path or filename from where to extract the path name. * @return the extracted path or a empty string. */ public String getPath(final String path) { // Check for slash and backslash final int last = Math.max(path.lastIndexOf('/'), path.lastIndexOf('\\')); if (last < 0) { return ""; } return path.substring(0, last); } /** * Converts a SQL-Clob object into a String. If the Clob is larger than 2^31 characters, we cannot convert it. * If there are errors converting it, this method will log the cause and return null. * * @param clob the clob to be read as string. * @return the string or null in case of errors. */ public String readClob(final Clob clob) { try { final long length = clob.length(); if (length > Integer.MAX_VALUE) { logger.warn ("This CLOB contains more than 2^31 characters. We cannot handle that."); return null; } final Reader inStream = clob.getCharacterStream(); final StringWriter outStream = new StringWriter((int) length); try { IOUtils.getInstance().copyWriter(inStream, outStream); } catch (IOException e) { logger.warn ("Copying the stream failed.", e); } try { inStream.close(); } catch (IOException e) { logger.warn ("Failed to close input stream. No worries, we will be alright anyway.", e); } return outStream.toString(); } catch (SQLException e) { return null; } } /** * Converts a SQL-Clob object into a String. If the Clob is larger than 2^31 characters, we cannot convert it. * If there are errors converting it, this method will log the cause and return null. * * @param clob the clob to be read as string. * @return the string or null in case of errors. */ public byte[] readBlob(final Blob clob) throws SQLException { final long length = clob.length(); if (length > Integer.MAX_VALUE) { logger.warn ("This CLOB contains more than 2^31 characters. We cannot handle that."); return null; } final InputStream inStream = clob.getBinaryStream(); final ByteArrayOutputStream outStream = new ByteArrayOutputStream((int) length); try { IOUtils.getInstance().copyStreams(inStream, outStream); } catch (IOException e) { logger.warn ("Copying the stream failed.", e); } try { inStream.close(); } catch (IOException e) { logger.warn ("Failed to close input stream. No worries, we will be alright anyway.", e); } return outStream.toByteArray(); } } libbase-1.1.6/source/org/pentaho/reporting/libraries/base/util/FloatDimension.java0000644000175000017500000001102211365604666026754 0ustar renerene/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2007 - 2009 Pentaho Corporation and Contributors. All rights reserved. */ package org.pentaho.reporting.libraries.base.util; import java.awt.geom.Dimension2D; import java.io.Serializable; /** * A dimension object specified using float values. * * @author Thomas Morgner */ public class FloatDimension extends Dimension2D implements Serializable { /** * For serialization. */ private static final long serialVersionUID = 5367882923248086744L; /** * The width. */ private float width; /** * The height. */ private float height; /** * Creates a new dimension object with width and height set to zero. */ public FloatDimension() { this.width = 0.0f; this.height = 0.0f; } /** * Creates a new dimension that is a copy of another dimension. * * @param fd the dimension to copy. */ public FloatDimension(final FloatDimension fd) { this.width = fd.width; this.height = fd.height; } /** * Creates a new dimension. * * @param width the width. * @param height the height. */ public FloatDimension(final float width, final float height) { this.width = width; this.height = height; } /** * Returns the width. * * @return the width. */ public double getWidth() { return this.width; } /** * Returns the height. * * @return the height. */ public double getHeight() { return this.height; } /** * Sets the width. * * @param width the width. */ public void setWidth(final double width) { this.width = (float) width; } /** * Sets the height. * * @param height the height. */ public void setHeight(final double height) { this.height = (float) height; } /** * Sets the size of this Dimension object to the specified width and height. This method is included * for completeness, to parallel the {@link java.awt.Component#getSize() getSize} method of {@link * java.awt.Component}. * * @param width the new width for the Dimension object * @param height the new height for the Dimension object */ public void setSize(final double width, final double height) { setHeight((float) height); setWidth((float) width); } /** * Creates and returns a copy of this object. * * @return a clone of this instance. * @see Cloneable * @noinspection CloneDoesntDeclareCloneNotSupportedException */ public Object clone() { return super.clone(); } /** * Returns a string representation of the object. In general, the toString method returns a string that * "textually represents" this object. The result should be a concise but informative representation that is easy * for a person to read. *

* * @return a string representation of the object. */ public String toString() { return getClass().getName() + ":={width=" + getWidth() + ", height=" + getHeight() + '}'; } /** * Tests this object for equality with another object. * * @param o the other object. * @return true or false. */ public boolean equals(final Object o) { if (this == o) { return true; } if (!(o instanceof FloatDimension)) { return false; } final FloatDimension floatDimension = (FloatDimension) o; if (this.height != floatDimension.height) { return false; } if (this.width != floatDimension.width) { return false; } return true; } /** * Returns a hash code. * * @return A hash code. */ public int hashCode() { int result; result = Float.floatToIntBits(this.width); result = 29 * result + Float.floatToIntBits(this.height); return result; } } libbase-1.1.6/source/org/pentaho/reporting/libraries/base/util/Messages.java0000644000175000017500000002776711365604666025637 0ustar renerene/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2007 - 2009 Pentaho Corporation and Contributors. All rights reserved. */ package org.pentaho.reporting.libraries.base.util; import java.util.Locale; import java.util.MissingResourceException; import java.util.ResourceBundle; /** * A helper class for a simplified resource-bundle access. This class simply ignores all resource-bundle related errors * and prints place-holder strings if a localization key cannot be found. * * @author David Kincade */ public class Messages extends ResourceBundleSupport { /** * Creates a new Messages-collection. The locale and baseName will be used to create the resource-bundle that backs up * this implementation. * * @param locale the locale. * @param baseName the baseName of the resource-bundle. * @see ResourceBundle#getBundle(String, Locale) */ public Messages(final Locale locale, final String baseName) { super(locale, baseName); } /** * Creates a new Messages-collection. The locale and baseName will be used to create the resource-bundle that backs up * this implementation. * * @param locale the locale. * @param baseName the baseName of the resource-bundle. * @param resourceBundle a predefined resource-bundle. */ public Messages(final Locale locale, final ResourceBundle resourceBundle, final String baseName) { super(locale, resourceBundle, baseName); } /** * Creates a new Messages-collection. The locale and baseName will be used to create the resource-bundle that backs up * this implementation. * * @param locale the locale. * @param resourceBundle a predefined resource-bundle. */ public Messages(final Locale locale, final ResourceBundle resourceBundle) { super(locale, resourceBundle); } /** * Creates a new Messages-collection. The default locale and baseName will be used to create the resource-bundle that * backs up this implementation. * * @param baseName the baseName of the resource-bundle. */ public Messages(final String baseName) { super(baseName); } /** * Creates a new Messages-collection. The default locale and baseName will be used to create the resource-bundle that * backs up this implementation. * * @param baseName the baseName of the resource-bundle. * @param resourceBundle a predefined resource-bundle. */ public Messages(final ResourceBundle resourceBundle, final String baseName) { super(resourceBundle, baseName); } /** * Creates a new Messages-collection. The default locale and baseName will be used to create the resource-bundle that * backs up this implementation. * * @param resourceBundle a predefined resource-bundle. */ public Messages(final ResourceBundle resourceBundle) { super(resourceBundle); } /** * Gets a string for the given key from this resource bundle or one of its parents. If the key is a link, the link is * resolved and the referenced string is returned instead. If the given key cannot be resolved, no exception will be * thrown and a generic placeholder is used instead. * * @param key the key for the desired string * @return the string for the given key * @throws NullPointerException if key is null * @throws MissingResourceException if no object for the given key can be found */ public String getString(final String key) { try { return super.strictString(key); } catch (final MissingResourceException e) { return '!' + key + '!'; } } /** * Formats the message stored in the resource bundle (using a MessageFormat). * * @param key the resourcebundle key * @param param1 the parameter for the message * @return the formated string */ public String getString(final String key, final String param1) { try { return formatMessage(key, param1); } catch (final MissingResourceException e) { return '!' + key + '!'; } } /** * Formats the message stored in the resource bundle (using a MessageFormat). * * @param key the resourcebundle key * @param param1 the parameter for the message * @param param2 the parameter for the message * @return the formated string */ public String getString(final String key, final String param1, final String param2) { try { return formatMessage(key, param1, param2); } catch (final MissingResourceException e) { return '!' + key + '!'; } } /** * Formats the message stored in the resource bundle (using a MessageFormat). * * @param key the resourcebundle key * @param param1 the parameter for the message * @param param2 the parameter for the message * @param param3 the parameter for the message * @return the formated string */ public String getString(final String key, final String param1, final String param2, final String param3) { try { return formatMessage(key, new Object[]{param1, param2, param3}); } catch (final MissingResourceException e) { return '!' + key + '!'; } } /** * Formats the message stored in the resource bundle (using a MessageFormat). * * @param key the resourcebundle key * @param param1 the parameter for the message * @param param2 the parameter for the message * @param param3 the parameter for the message * @param param4 the parameter for the message * @return the formated string */ public String getString(final String key, final String param1, final String param2, final String param3, final String param4) { try { return formatMessage(key, new Object[]{param1, param2, param3, param4}); } catch (final MissingResourceException e) { return '!' + key + '!'; } } /** * Get a formatted error message. The message consists of two parts. The first part is the * error numeric Id associated with the key used to identify the message in the resource file. * For instance, suppose the error key is MyClass.ERROR_0068_TEST_ERROR. The first * part of the error msg would be "0068". The second part of the returned string * is simply the msg parameter. *

* Currently the format is: * error key - error msg * For instance: * "0068 - A test error message." *

* Currently the format is: error key - error msg For instance: "0069 - You were punched by the donkey." * * @param key String containing the key that was used to obtain the msg parameter from the resource * file. * @param msg String containing the message that was obtained from the resource file using the key * parameter. * @return String containing the formatted error message. */ public String formatErrorMessage(final String key, final String msg) { try { final int end; final int errorMarker = key.indexOf(".ERROR_"); if (errorMarker < 0) { end = key.length(); } else { end = Math.min(errorMarker + ".ERROR_0000".length(), key.length()); //$NON-NLS-1$ } return getString("MESSUTIL.ERROR_FORMAT_MASK", key.substring(0, end), msg); //$NON-NLS-1$ } catch (final Exception e) { return "!MESSUTIL.ERROR_FORMAT_MASK:" + key + '!'; } } /** * Get a formatted error message from the resource-bundle. The message consists of two parts. The first part is the * error numeric Id associated with the key used to identify the message in the resource file. For instance, suppose * the error key is MyClass.ERROR_0069_DONKEY_PUNCH. The first part of the error msg would be "0069". The second part * of the returned string is simply the msg parameter. *

* Currently the format is: error key - error msg For instance: "0069 - You were punched by the donkey." * * @param key String containing the key that was used to obtain the msg parameter from the resource * file. * @return String containing the formatted error message. */ public String getErrorString(final String key) { return formatErrorMessage(key, getString(key)); } /** * Get a parametrized formatted error message from the resource-bundle. The message consists of two parts. The first * part is the error numeric Id associated with the key used to identify the message in the resource file. For * instance, suppose the error key is MyClass.ERROR_0069_DONKEY_PUNCH. The first part of the error msg would be * "0069". The second part of the returned string is simply the msg parameter. *

* Currently the format is: error key - error msg For instance: "0069 - You were punched by the donkey." * * @param key String containing the key that was used to obtain the msg parameter from the resource * file. * @param param1 the parameter for the message * @return String containing the formatted error message. */ public String getErrorString(final String key, final String param1) { return formatErrorMessage(key, getString(key, param1)); } /** * Get a parametrized formatted error message from the resource-bundle. The message consists of two parts. The first * part is the error numeric Id associated with the key used to identify the message in the resource file. For * instance, suppose the error key is MyClass.ERROR_0069_DONKEY_PUNCH. The first part of the error msg would be * "0069". The second part of the returned string is simply the msg parameter. *

* Currently the format is: error key - error msg For instance: "0069 - You were punched by the donkey." * * @param key String containing the key that was used to obtain the msg parameter from the resource * file. * @param param1 the parameter for the message * @param param2 the parameter for the message * @return String containing the formatted error message. */ public String getErrorString(final String key, final String param1, final String param2) { return formatErrorMessage(key, getString(key, param1, param2)); } /** * Get a parametrized formatted error message from the resource-bundle. The message consists of two parts. The first * part is the error numeric Id associated with the key used to identify the message in the resource file. For * instance, suppose the error key is MyClass.ERROR_0069_DONKEY_PUNCH. The first part of the error msg would be * "0069". The second part of the returned string is simply the msg parameter. *

* Currently the format is: error key - error msg For instance: "0069 - You were punched by the donkey." * * @param key String containing the key that was used to obtain the msg parameter from the resource * file. * @param param1 the parameter for the message * @param param2 the parameter for the message * @param param3 the parameter for the message * @return String containing the formatted error message. */ public String getErrorString(final String key, final String param1, final String param2, final String param3) { return formatErrorMessage(key, getString(key, param1, param2, param3)); } }libbase-1.1.6/source/org/pentaho/reporting/libraries/base/util/HashNMap.java0000644000175000017500000002605711365604666025516 0ustar renerene/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2007 - 2009 Pentaho Corporation and Contributors. All rights reserved. */ package org.pentaho.reporting.libraries.base.util; import java.io.Serializable; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.NoSuchElementException; import java.util.Set; import java.util.Map; /** * The HashNMap can be used to store multiple values by a single key value. The * values stored can be retrieved using a direct query or by creating an * enumeration over the stored elements. * * @author Thomas Morgner */ public class HashNMap implements Serializable, Cloneable { /** * Serialization support. */ private static final long serialVersionUID = -670924844536074826L; /** * An helper class to implement an empty iterator. This iterator will always * return false when hasNext is called. */ private static final class EmptyIterator implements Iterator { /** * DefaultConstructor. */ private EmptyIterator() { super(); } /** * Returns true if the iteration has more elements. (In other * words, returns true if next would return an element * rather than throwing an exception.) * * @return true if the iterator has more elements. */ public boolean hasNext() { return false; } /** * Returns the next element in the iteration. * * @return the next element in the iteration. * @throws java.util.NoSuchElementException * iteration has no more elements. */ public Object next() { throw new NoSuchElementException("This iterator is empty."); } /** * Removes from the underlying collection the last element returned by the * iterator (optional operation). This method can be called only once per * call to next. The behavior of an iterator is unspecified if * the underlying collection is modified while the iteration is in * progress in any way other than by calling this method. * * @throws UnsupportedOperationException if the remove * operation is not supported by this Iterator. * @throws IllegalStateException if the next method has not * yet been called, or the remove method has already * been called after the last call to the next * method. */ public void remove() { throw new UnsupportedOperationException("This iterator is empty, no remove supported."); } } /** * A singleton instance of the empty iterator. This object can be safely * shared. */ private static final Iterator EMPTY_ITERATOR = new EmptyIterator(); /** * The underlying storage. */ private HashMap table; /** * An empty array. */ private static final Object[] EMPTY_ARRAY = new Object[0]; /** * Default constructor. */ public HashNMap() { this.table = new HashMap(); } /** * Returns a new empty list. * * @return A new empty list. */ protected List createList() { return new ArrayList(); } /** * Inserts a new key/value pair into the map. If such a pair already * exists, it gets replaced with the given values. * * @param key the key. * @param val the value. * @return A boolean. */ public boolean put(final Object key, final Object val) { final List v = (List) this.table.get(key); if (v == null) { final List newList = createList(); newList.add(val); this.table.put(key, newList); return true; } else { v.clear(); return v.add(val); } } /** * Adds a new key/value pair into this map. If the key is not yet in the * map, it gets added to the map and the call is equal to * put(Object,Object). * * @param key the key. * @param val the value. * @return true, if the value has been added, false otherwise */ public boolean add(final Object key, final Object val) { final List v = (List) this.table.get(key); if (v == null) { put(key, val); return true; } else { return v.add(val); } } /** * Retrieves the first value registered for an key or null if there was no * such key in the list. * * @param key the key. * @return the value. */ public Object getFirst(final Object key) { return get(key, 0); } /** * Retrieves the n-th value registered for an key or null if there was no * such key in the list. An index out of bounds exception is thrown if * there are less than n elements registered to this key. * * @param key the key. * @param n the index. * @return the object. */ public Object get(final Object key, final int n) { final List v = (List) this.table.get(key); if (v == null) { return null; } return v.get(n); } /** * Returns an iterator over all elements registered to the given key. * * @param key the key. * @return an iterator. */ public Iterator getAll(final Object key) { final List v = (List) this.table.get(key); if (v == null) { return EMPTY_ITERATOR; } return v.iterator(); } /** * Returns all registered keys as an enumeration. * * @return an enumeration of the keys. */ public Iterator keys() { return this.table.keySet().iterator(); } /** * Returns all registered keys as set. * * @return a set of keys. */ public Set keySet() { return this.table.keySet(); } /** * Removes the key/value pair from the map. If the removed entry was the * last entry for this key, the key gets also removed. * * @param key the key. * @param value the value. * @return true, if removing the element was successfull, false otherwise. */ public boolean remove(final Object key, final Object value) { final List v = (List) this.table.get(key); if (v == null) { return false; } if (!v.remove(value)) { return false; } if (v.isEmpty()) { this.table.remove(key); } return true; } /** * Removes all elements for the given key. * * @param key the key. */ public void removeAll(final Object key) { this.table.remove(key); } /** * Clears all keys and values of this map. */ public void clear() { this.table.clear(); } /** * Tests whether this map contains the given key. * * @param key the key. * @return true if the key is contained in the map */ public boolean containsKey(final Object key) { return this.table.containsKey(key); } /** * Tests whether this map contains the given value. * * @param value the value. * @return true if the value is registered in the map for an key. */ public boolean containsValue(final Object value) { final Iterator e = this.table.values().iterator(); boolean found = false; while (e.hasNext() && !found) { final List v = (List) e.next(); found = v.contains(value); } return found; } /** * Tests whether this map contains the given value. * * @param value the value. * @param key the key under which to find the value * @return true if the value is registered in the map for an key. */ public boolean containsValue(final Object key, final Object value) { final List v = (List) this.table.get(key); if (v == null) { return false; } return v.contains(value); } /** * Tests whether this map contains the given key or value. * * @param value the value. * @return true if the key or value is contained in the map */ public boolean contains(final Object value) { if (containsKey(value)) { return true; } return containsValue(value); } /** * Creates a deep copy of this HashNMap. * * @return a clone. * @throws CloneNotSupportedException this should never happen. */ public Object clone() throws CloneNotSupportedException { final HashNMap map = (HashNMap) super.clone(); map.table = (HashMap) table.clone(); final Iterator iterator = map.table.entrySet().iterator(); while (iterator.hasNext()) { final Map.Entry entry = (Map.Entry) iterator.next(); final List list = (List) entry.getValue(); if (list != null) { entry.setValue(ObjectUtilities.clone(list)); } } return map; } /** * Returns the contents for the given key as object array. If there were * no objects registered with that key, an empty object array is returned. * * @param key the key. * @param data the object array to receive the contents. * @return the contents. */ public Object[] toArray(final Object key, final Object[] data) { if (key == null) { throw new NullPointerException("Key must not be null."); } final List list = (List) this.table.get(key); if (list != null) { return list.toArray(data); } if (data.length > 0) { data[0] = null; } return data; } /** * Returns the contents for the given key as object array. If there were * no objects registered with that key, an empty object array is returned. * * @param key the key. * @return the contents. */ public Object[] toArray(final Object key) { if (key == null) { throw new NullPointerException("Key must not be null."); } final List list = (List) this.table.get(key); if (list != null) { return list.toArray(); } return EMPTY_ARRAY; } /** * Returns the number of elements registered with the given key. * * @param key the key. * @return the number of element for this key, or 0 if there are no elements * registered. */ public int getValueCount(final Object key) { if (key == null) { throw new NullPointerException("Key must not be null."); } final List list = (List) this.table.get(key); if (list != null) { return list.size(); } return 0; } /** * Checks, whether the map is empty. * * @return true, if the map does not contain any keys. */ public boolean isEmpty() { return table.isEmpty(); } }libbase-1.1.6/source/org/pentaho/reporting/libraries/base/util/DebugLog.java0000644000175000017500000000504211365604666025536 0ustar renerene/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2007 - 2009 Pentaho Corporation and Contributors. All rights reserved. */ package org.pentaho.reporting.libraries.base.util; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * This class provides static log messages for on-going bug-hunting efforts. This removes the need to create * temporary log-instances that get removed later anyway. * * @author Thomas Morgner */ public final class DebugLog { /** A logger. */ private static final Log logger = LogFactory.getLog(DebugLog.class); /** * Logs a message using the debug-logger. By channeling all temporary log messages through this method, * we can later easily identify the debugger log entries so that we can remove them. * * @param message the message. */ public static void log(final Object message) { logger.info(message); } /** * Logs a message using the debug-logger. By channeling all temporary log messages through this method, * we can later easily identify the debugger log entries so that we can remove them. * * @param message the message. * @param t the throwable to be logged. */ public static void log(final Object message, final Throwable t) { logger.info(message, t); } /** * Logs a HERE message. This is only useful as some sort of cheap-and-dirty debug-point entry. */ public static void logHere() { logger.info("HERE: Debug point reached"); } /** * Logs a HERE message along with a stack-trace to identify how we got to this point. */ public static void logHereWE() { //noinspection ThrowableInstanceNeverThrown logger.info("HERE: Debug point reached", new Exception("Debug-Point reached")); } /** * Private constructor prevents object creation. */ private DebugLog() { } } libbase-1.1.6/source/org/pentaho/reporting/libraries/base/util/GenericObjectTable.java0000644000175000017500000000631211365604666027522 0ustar renerene/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2007 - 2009 Pentaho Corporation and Contributors. All rights reserved. */ package org.pentaho.reporting.libraries.base.util; /** * A generic table storing objects in an fast array backend. This generic class provides public getter and setters * for the contents of the table. * * @author Thomas Morgner */ public class GenericObjectTable extends ObjectTable { /** A constant for serialization support. */ private static final long serialVersionUID = 4870219010677984960L; /** * Creates a new object table. */ public GenericObjectTable () { } /** * Creates a new table. * * @param increment the row and column size increment. */ public GenericObjectTable(final int increment) { super(increment); } /** * Creates a new table. * * @param rowIncrement the row size increment. * @param colIncrement the column size increment. */ public GenericObjectTable(final int rowIncrement, final int colIncrement) { super(rowIncrement, colIncrement); } /** * Returns the object from a particular cell in the table. Returns null, if * there is no object at the given position. *

* Note: throws IndexOutOfBoundsException if row or column is negative. * * @param row the row index (zero-based). * @param column the column index (zero-based). * @return The object. */ public Object getObject (final int row, final int column) { return super.getObject(row, column); } /** * Sets the object for a cell in the table. The table is expanded if * necessary. * * @param row the row index (zero-based). * @param column the column index (zero-based). * @param object the object. */ public void setObject (final int row, final int column, final Object object) { super.setObject(row, column, object); } /** * Copys the contents of the old column to the new column. * * @param oldColumn the index of the old (source) column * @param newColumn the index of the new column */ public void copyColumn (final int oldColumn, final int newColumn) { super.copyColumn(oldColumn, newColumn); } /** * Copys the contents of the old row to the new row. This uses raw access to * the data and is remarkably faster than manual copying. * * @param oldRow the index of the old row * @param newRow the index of the new row */ public void copyRow (final int oldRow, final int newRow) { super.copyRow(oldRow, newRow); } } libbase-1.1.6/source/org/pentaho/reporting/libraries/base/util/ResourceBundleSupport.java0000644000175000017500000006002211365604666030363 0ustar renerene/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2007 - 2009 Pentaho Corporation and Contributors. All rights reserved. */ package org.pentaho.reporting.libraries.base.util; import java.awt.Image; import java.awt.Toolkit; import java.awt.event.InputEvent; import java.awt.event.KeyEvent; import java.awt.image.BufferedImage; import java.lang.reflect.Field; import java.net.URL; import java.text.MessageFormat; import java.util.HashMap; import java.util.HashSet; import java.util.Locale; import java.util.MissingResourceException; import java.util.ResourceBundle; import java.util.StringTokenizer; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JMenu; import javax.swing.KeyStroke; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * An utility class to ease up using property-file resource bundles. *

* The class support references within the resource bundle set to minimize the * occurence of duplicate keys. References are given in the format: *

 * a.key.name=@referenced.key
 * 
*

* A lookup to a key in an other resource bundle should be written by *

 * a.key.name=@@resourcebundle_name@referenced.key
 * 
* * @author Thomas Morgner */ public class ResourceBundleSupport { /** * A logger for debug-messages. */ private static final Log logger = LogFactory.getLog(ResourceBundleSupport.class); /** * The resource bundle that will be used for local lookups. */ private ResourceBundle resources; /** * A cache for string values, as looking up the cache is faster than looking * up the value in the bundle. */ private HashMap cache; /** * The current lookup path when performing non local lookups. This prevents * infinite loops during such lookups. */ private HashSet lookupPath; /** * The name of the local resource bundle. */ private String resourceBase; /** * The locale for this bundle. */ private Locale locale; /** * Creates a new instance. * * @param locale the locale that should be used to load the resource-bundle. * @param baseName the base name of the resource bundle, a fully qualified * class name */ public ResourceBundleSupport(final Locale locale, final String baseName) { this(locale, ResourceBundle.getBundle(baseName, locale), baseName); } /** * Creates a new instance. * * @param locale the locale for which this resource bundle is * created. * @param resourceBundle the resourcebundle * @param baseName the base name of the resource bundle, a fully * qualified class name */ protected ResourceBundleSupport(final Locale locale, final ResourceBundle resourceBundle, final String baseName) { if (locale == null) { throw new NullPointerException("Locale must not be null"); } if (resourceBundle == null) { throw new NullPointerException("Resources must not be null"); } if (baseName == null) { throw new NullPointerException("BaseName must not be null"); } this.locale = locale; this.resources = resourceBundle; this.resourceBase = baseName; this.cache = new HashMap(); this.lookupPath = new HashSet(); } /** * Creates a new instance. * * @param locale the locale for which the resource bundle is * created. * @param resourceBundle the resourcebundle */ public ResourceBundleSupport(final Locale locale, final ResourceBundle resourceBundle) { this(locale, resourceBundle, resourceBundle.toString()); } /** * Creates a new instance. * * @param baseName the base name of the resource bundle, a fully qualified * class name */ public ResourceBundleSupport(final String baseName) { this(Locale.getDefault(), ResourceBundle.getBundle(baseName), baseName); } /** * Creates a new instance. * * @param resourceBundle the resourcebundle * @param baseName the base name of the resource bundle, a fully * qualified class name */ protected ResourceBundleSupport(final ResourceBundle resourceBundle, final String baseName) { this(Locale.getDefault(), resourceBundle, baseName); } /** * Creates a new instance. * * @param resourceBundle the resourcebundle */ public ResourceBundleSupport(final ResourceBundle resourceBundle) { this(Locale.getDefault(), resourceBundle, resourceBundle.toString()); } /** * The base name of the resource bundle. * * @return the resource bundle's name. */ protected final String getResourceBase() { return this.resourceBase; } /** * Gets a string for the given key from this resource bundle or one of its * parents. If the key is a link, the link is resolved and the referenced * string is returned instead. * * @param key the key for the desired string * @return the string for the given key * @throws NullPointerException if key is null * @throws java.util.MissingResourceException * if no object for the given key can be * found * @throws ClassCastException if the object found for the given key is * not a string */ public synchronized String strictString(final String key) { if (key == null) { throw new NullPointerException(); } final String retval = (String) this.cache.get(key); if (retval != null) { return retval; } this.lookupPath.clear(); return internalGetString(key); } /** * Performs the lookup for the given key. If the key points to a link the * link is resolved and that key is looked up instead. * * @param key the key for the string * @return the string for the given key */ protected String internalGetString(final String key) { if (key == null) { throw new NullPointerException(); } if (this.lookupPath.contains(key)) { throw new MissingResourceException ("InfiniteLoop in resource lookup", getResourceBase(), this.lookupPath.toString()); } final String fromResBundle = this.resources.getString(key); if (fromResBundle.length() > 0 && fromResBundle.charAt(0) == '@') { if (fromResBundle.length() > 1 && fromResBundle.charAt(1) == '@') { // global forward ... final int idx = fromResBundle.indexOf('@', 2); if (idx == -1) { throw new MissingResourceException ("Invalid format for global lookup key.", getResourceBase(), key); } try { final ResourceBundle res = ResourceBundle.getBundle (fromResBundle.substring(2, idx)); return res.getString(fromResBundle.substring(idx + 1)); } catch (Exception e) { logger.error("Error during global lookup", e); throw new MissingResourceException("Error during global lookup", getResourceBase(), key); } } else { // local forward ... final String newKey = fromResBundle.substring(1); this.lookupPath.add(key); final String retval = internalGetString(newKey); this.cache.put(key, retval); return retval; } } else { this.cache.put(key, fromResBundle); return fromResBundle; } } /** * Returns an scaled icon suitable for buttons or menus. * * @param key the name of the resource bundle key * @param large true, if the image should be scaled to 24x24, or false for * 16x16 * @return the icon. */ public Icon getIcon(final String key, final boolean large) { if (key == null) { throw new NullPointerException(); } final String name = strictString(key); return createIcon(name, true, large); } /** * Returns an unscaled icon. * * @param key the name of the resource bundle key * @return the icon. */ public Icon getIcon(final String key) { if (key == null) { throw new NullPointerException(); } final String name = strictString(key); return createIcon(name, false, false); } /** * Returns the mnemonic stored at the given resourcebundle key. The mnemonic * should be either the symbolic name of one of the KeyEvent.VK_* constants * (without the 'VK_') or the character for that key. *

* For the enter key, the resource bundle would therefore either contain * "ENTER" or "\n". *

   * a.resourcebundle.key=ENTER
   * an.other.resourcebundle.key=\n
   * 
* * @param key the resourcebundle key * @return the mnemonic */ public Integer getMnemonic(final String key) { if (key == null) { throw new NullPointerException(); } final String name = strictString(key); return createMnemonic(name); } /** * Returns the mnemonic stored at the given resourcebundle key. The mnemonic * should be either the symbolic name of one of the KeyEvent.VK_* constants * (without the 'VK_') or the character for that key. *

* For the enter key, the resource bundle would therefore either contain * "ENTER" or "\n". *

   * a.resourcebundle.key=ENTER
   * an.other.resourcebundle.key=\n
   * 
* * @param key the resourcebundle key * @return the mnemonic or null, if the mnemonic is not defined. */ public Integer getOptionalMnemonic(final String key) { if (key == null) { throw new NullPointerException(); } final String name = strictString(key); if (name != null && name.length() > 0) { return createMnemonic(name); } return null; } /** * Returns the keystroke stored at the given resourcebundle key. *

* The keystroke will be composed of a simple key press and the plattform's * MenuKeyMask. *

* The keystrokes character key should be either the symbolic name of one of * the KeyEvent.VK_* constants or the character for that key. *

* For the 'A' key, the resource bundle would therefore either contain * "VK_A" or "a". *

   * a.resourcebundle.key=VK_A
   * an.other.resourcebundle.key=a
   * 
* * @param key the resourcebundle key * @return the keystroke * @see java.awt.Toolkit#getMenuShortcutKeyMask() */ public KeyStroke getKeyStroke(final String key) { String name = strictString(key); if (StringUtils.isEmpty(name)) { return null; } int mask = 0; final StringTokenizer strtok = new StringTokenizer(name); while (strtok.hasMoreTokens()) { final String token = strtok.nextToken(); if ("shift".equals(token)) { mask |= KeyEvent.SHIFT_MASK; } else if ("alt".equals(token)) { mask |= KeyEvent.ALT_MASK; } else if ("ctrl".equals(token)) { mask |= KeyEvent.CTRL_MASK; } else if ("meta".equals(token)) { mask |= KeyEvent.META_MASK; } else if ("menu".equals(token)) { mask |= getMenuKeyMask(); } else { name = token; } } if (mask == 0) { mask = getMenuKeyMask(); } return KeyStroke.getKeyStroke(createMnemonic(name).intValue(), mask); } /** * Returns the keystroke stored at the given resourcebundle key. *

* The keystroke will be composed of a simple key press and a keystroke mask pattern. The pattern * should be specified via the words "shift", "alt", "ctrl", "meta" or "menu". Menu should be used * to reference the platform specific menu shortcut. For the sake of safety, menu should only be * combined with "shift" and/or "alt" for menu keystrokes. *

* The keystrokes character key should be either the symbolic name of one of * the KeyEvent.VK_* constants or the character for that key. *

* For the 'A' key, the resource bundle would therefore either contain * "VK_A" or "a". *

   * a.resourcebundle.key=VK_A
   * an.other.resourcebundle.key=a
   * 
* * @param key the resourcebundle key * @return the keystroke * @see java.awt.Toolkit#getMenuShortcutKeyMask() */ public KeyStroke getOptionalKeyStroke(final String key) { try { String name = strictString(key); if (StringUtils.isEmpty(name)) { return null; } int mask = 0; final StringTokenizer strtok = new StringTokenizer(name); while (strtok.hasMoreTokens()) { final String token = strtok.nextToken(); if ("shift".equals(token)) { mask |= KeyEvent.SHIFT_MASK; } else if ("alt".equals(token)) { mask |= KeyEvent.ALT_MASK; } else if ("ctrl".equals(token)) { mask |= KeyEvent.CTRL_MASK; } else if ("meta".equals(token)) { mask |= KeyEvent.META_MASK; } else if ("menu".equals(token)) { mask |= getMenuKeyMask(); } else { name = token; } } if (mask == 0) { mask = getMenuKeyMask(); } return KeyStroke.getKeyStroke(createMnemonic(name).intValue(), mask); } catch (MissingResourceException mre) { return null; } } /** * Returns the keystroke stored at the given resourcebundle key. *

* The keystroke will be composed of a simple key press and the given * KeyMask. If the KeyMask is zero, a plain Keystroke is returned. *

* The keystrokes character key should be either the symbolic name of one of * the KeyEvent.VK_* constants or the character for that key. *

* For the 'A' key, the resource bundle would therefore either contain * "VK_A" or "a". *

   * a.resourcebundle.key=VK_A
   * an.other.resourcebundle.key=a
   * 
* * @param key the resourcebundle key * @param mask the key-moifier mask to be used to create the keystroke. * @return the keystroke that has been generated. * @see java.awt.Toolkit#getMenuShortcutKeyMask() */ public KeyStroke getKeyStroke(final String key, final int mask) { if (key == null) { throw new NullPointerException(); } final String name = strictString(key); return KeyStroke.getKeyStroke(createMnemonic(name).intValue(), mask); } /** * Returns the keystroke stored at the given resourcebundle key. *

* The keystroke will be composed of a simple key press and the given * KeyMask. If the KeyMask is zero, a plain Keystroke is returned. *

* The keystrokes character key should be either the symbolic name of one of * the KeyEvent.VK_* constants or the character for that key. *

* For the 'A' key, the resource bundle would therefore either contain * "VK_A" or "a". *

   * a.resourcebundle.key=VK_A
   * an.other.resourcebundle.key=a
   * 
* * @param key the resourcebundle key * @param mask the key-moifier mask to be used to create the keystroke. * @return the keystroke or null if the key is not defined. * @see java.awt.Toolkit#getMenuShortcutKeyMask() */ public KeyStroke getOptionalKeyStroke(final String key, final int mask) { if (key == null) { throw new NullPointerException(); } final String name = strictString(key); if (name != null && name.length() > 0) { return KeyStroke.getKeyStroke(createMnemonic(name).intValue(), mask); } return null; } /** * Returns a JMenu created from a resource bundle definition. *

* The menu definition consists of two keys, the name of the menu and the * mnemonic for that menu. Both keys share a common prefix, which is * extended by ".name" for the name of the menu and ".mnemonic" for the * mnemonic. *

*

   * # define the file menu
   * menu.file.name=File
   * menu.file.mnemonic=F
   * 
* The menu definition above can be used to create the menu by calling * createMenu ("menu.file"). * * @param keyPrefix the common prefix for that menu * @return the created menu */ public JMenu createMenu(final String keyPrefix) { if (keyPrefix == null) { throw new NullPointerException(); } final JMenu retval = new JMenu(); retval.setText(strictString(keyPrefix + ".name")); final Integer mnemonic = getOptionalMnemonic(keyPrefix + ".mnemonic"); if (mnemonic != null) { retval.setMnemonic(mnemonic.intValue()); } return retval; } /** * Returns a URL pointing to a resource located in the classpath. The * resource is looked up using the given key. *

* Example: The load a file named 'logo.gif' which is stored in a java * package named 'org.jfree.resources': *

   * mainmenu.logo=org/jfree/resources/logo.gif
   * 
* The URL for that file can be queried with: getResource("mainmenu.logo");. * * @param key the key for the resource * @return the resource URL */ public URL getResourceURL(final String key) { if (key == null) { throw new NullPointerException(); } final String name = strictString(key); final URL in = ObjectUtilities.getResource(name, ResourceBundleSupport.class); if (in == null) { logger.warn("Unable to find file in the class path: " + name + "; key=" + key); } return in; } /** * Attempts to load an image from classpath. If this fails, an empty image * icon is returned. * * @param resourceName the name of the image. The name should be a global * resource name. * @param scale true, if the image should be scaled, false otherwise * @param large true, if the image should be scaled to 24x24, or * false for 16x16 * @return the image icon. */ private ImageIcon createIcon(final String resourceName, final boolean scale, final boolean large) { final URL in = ObjectUtilities.getResource(resourceName, ResourceBundleSupport.class); if (in == null) { logger.warn("Unable to find file in the class path: " + resourceName); return new ImageIcon(createTransparentImage(1, 1)); } final Image img = Toolkit.getDefaultToolkit().createImage(in); if (img == null) { logger.warn("Unable to instantiate the image: " + resourceName); return new ImageIcon(createTransparentImage(1, 1)); } if (scale) { if (large) { return new ImageIcon(img.getScaledInstance(24, 24, Image.SCALE_SMOOTH)); } return new ImageIcon(img.getScaledInstance(16, 16, Image.SCALE_SMOOTH)); } return new ImageIcon(img); } /** * Creates the Mnemonic from the given String. The String consists of the * name of the VK constants of the class KeyEvent without VK_*. * * @param keyString the string * @return the mnemonic as integer */ private Integer createMnemonic(final String keyString) { if (keyString == null) { throw new NullPointerException("Key is null."); } if (keyString.length() == 0) { throw new IllegalArgumentException("Key is empty."); } int character = keyString.charAt(0); if (keyString.startsWith("VK_")) { try { final Field f = KeyEvent.class.getField(keyString); final Integer keyCode = (Integer) f.get(null); character = keyCode.intValue(); } catch (Exception nsfe) { // ignore the exception ... } } return new Integer(character); } /** * Returns the plattforms default menu shortcut keymask. * * @return the default key mask. */ private int getMenuKeyMask() { try { return Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(); } catch (UnsupportedOperationException he) { // headless exception extends UnsupportedOperation exception, // but the HeadlessException is not defined in older JDKs... return InputEvent.CTRL_MASK; } } /** * Creates a transparent image. These can be used for aligning menu items. * * @param width the width. * @param height the height. * @return the created transparent image. */ private BufferedImage createTransparentImage(final int width, final int height) { final BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); final int[] data = img.getRGB(0, 0, width, height, null, 0, width); img.setRGB(0, 0, width, height, data, 0, width); return img; } /** * Formats the message stored in the resource bundle (using a * MessageFormat). * * @param key the resourcebundle key * @param parameter the parameter for the message * @return the formated string */ public String formatMessage(final String key, final Object parameter) { return formatMessage(key, new Object[]{parameter}); } /** * Formats the message stored in the resource bundle (using a * MessageFormat). * * @param key the resourcebundle key * @param par1 the first parameter for the message * @param par2 the second parameter for the message * @return the formated string */ public String formatMessage(final String key, final Object par1, final Object par2) { return formatMessage(key, new Object[]{par1, par2}); } /** * Formats the message stored in the resource bundle (using a * MessageFormat). * * @param key the resourcebundle key * @param parameters the parameter collection for the message * @return the formated string */ public String formatMessage(final String key, final Object[] parameters) { final MessageFormat format = new MessageFormat(strictString(key)); format.setLocale(getLocale()); return format.format(parameters); } public String getString(final String key, final Object[] parameters) { try { return formatMessage(key, parameters); } catch (MissingResourceException mre) { logger.warn ("ResourceBundleSupport#getString(,,)", mre); return '!' + key + '!'; } } public String getString(final String key) { try { return strictString(key); } catch (MissingResourceException mre) { logger.warn ("ResourceBundleSupport#getString(,,)", mre); return '!' + key + '!'; } } public String getString(final String key, final Object par1) { try { return formatMessage(key, par1); } catch (MissingResourceException mre) { logger.warn ("ResourceBundleSupport#getString(,,)", mre); return '!' + key + '!'; } } public String getString(final String key, final Object par1, final Object par2) { try { return formatMessage(key, par1, par2); } catch (MissingResourceException mre) { logger.warn ("ResourceBundleSupport#getString(,,)", mre); return '!' + key + '!'; } } /** * Returns the current locale for this resource bundle. * * @return the locale. */ public Locale getLocale() { return locale; } } libbase-1.1.6/source/org/pentaho/reporting/libraries/base/util/StackableRuntimeException.java0000644000175000017500000000714411365604666031167 0ustar renerene/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2007 - 2009 Pentaho Corporation and Contributors. All rights reserved. */ package org.pentaho.reporting.libraries.base.util; import java.io.PrintStream; import java.io.PrintWriter; /** * A baseclass for RuntimeExceptions, which could have parent exceptions. These parent exceptions * are raised in a subclass and are now wrapped into a subclass of this Exception. *

* The parents are printed when this exception is printed. This class exists mainly for * debugging reasons, as with them it is easier to detect the root cause of an error. * * @author Thomas Morgner */ public class StackableRuntimeException extends RuntimeException { /** * The parent exception. */ private Throwable parent; private static final long serialVersionUID = -4378774171699885841L; /** * Creates a StackableRuntimeException with no message and no parent. */ public StackableRuntimeException() { super(); } /** * Creates an exception. * * @param message the exception message. * @param ex the parent exception. */ public StackableRuntimeException(final String message, final Throwable ex) { super(message); this.parent = ex; } /** * Creates an exception. * * @param message the exception message. * @param ex the parent exception. */ public StackableRuntimeException(final String message, final Exception ex) { super(message); this.parent = ex; } /** * Creates an exception. * * @param message the exception message. */ public StackableRuntimeException(final String message) { super(message); } /** * Returns the parent exception (possibly null). * * @return the parent exception. * @deprecated use the throwable instead. */ public Exception getParent() { if (this.parent instanceof Exception) { return (Exception) this.parent; } return null; } public Throwable getParentThrowable() { return parent; } /** * Prints the stack trace to the specified stream. * * @param stream the output stream. */ public void printStackTrace(final PrintStream stream) { super.printStackTrace(stream); if (getParentThrowable() != null) { stream.println("ParentException: "); getParentThrowable().printStackTrace(stream); } } /** * Prints the stack trace to the specified writer. * * @param writer the writer. */ public void printStackTrace(final PrintWriter writer) { super.printStackTrace(writer); if (getParentThrowable() != null) { writer.println("ParentException: "); getParentThrowable().printStackTrace(writer); } } /** * Prints the stack trace to System.err. * * @noinspection UseOfSystemOutOrSystemErr */ public void printStackTrace() { synchronized (System.err) { printStackTrace(System.err); } } }libbase-1.1.6/source/org/pentaho/reporting/libraries/base/util/StackableException.java0000644000175000017500000001415411365604666027622 0ustar renerene/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2007 - 2009 Pentaho Corporation and Contributors. All rights reserved. */ package org.pentaho.reporting.libraries.base.util; import java.io.PrintStream; import java.io.PrintWriter; /** * A baseclass for exceptions, which could have parent exceptions. These parent exceptions are raised in a subclass and * are now wrapped into a subclass of this Exception. *

* The parents are printed when this exception is printed. This class exists mainly for debugging reasons, as with them * it is easier to detect the root cause of an error. *

* * * @author Thomas Morgner * @noinspection UseOfSystemOutOrSystemErr */ public class StackableException extends Exception { private static final long serialVersionUID = -8649054607849486694L; /** * The parent exception. */ private Throwable parent; private String message; /** * Creates a StackableRuntimeException with no message and no parent. */ protected StackableException() { super(); } /** * Creates an exception. * * @param message the exception message. * @param ex the parent exception. */ protected StackableException(final String message, final Throwable ex) { super(); this.message = message; this.parent = ex; } /** * Creates an exception. * * @param message the exception message. * @param ex the parent exception. * @deprecated use the throwable-version instead. */ protected StackableException(final String message, final Exception ex) { super(message); this.parent = ex; this.message = message; } /** * Creates an exception. * * @param message the exception message. */ protected StackableException(final String message) { super(); this.message = message; } /** * Returns the parent exception (possibly null). * * @return the parent exception. * @deprecated use the throwable instead. */ public Exception getParent() { if (this.parent instanceof Exception) { return (Exception) this.parent; } return null; } protected void update(final String message, final Throwable parent) { this.message = message; this.parent = parent; } public Throwable getParentThrowable() { return parent; } /** * Returns the detail message string of this throwable. * * @return the detail message string of this Throwable instance * (which may be null). */ public String getMessage() { return message; } /** * Returns a short description of this throwable. * If this Throwable object was created with a non-null detail * message string, then the result is the concatenation of three strings: *

    *
  • The name of the actual class of this object *
  • ": " (a colon and a space) *
  • The result of the {@link #getMessage} method for this object *
* If this Throwable object was created with a null * detail message string, then the name of the actual class of this object * is returned. * * @return a string representation of this throwable. */ public String toString() { final String s = getClass().getName(); final String message = getLocalizedMessage(); return (message != null) ? (s + ": " + message) : s; } /** * Prints the stack trace to the specified stream. * * @param stream the output stream. */ public void printStackTrace(final PrintStream stream) { super.printStackTrace(stream); if (getParentThrowable() != null) { stream.println("ParentException: "); getParentThrowable().printStackTrace(stream); } } /** * Prints the stack trace to the specified writer. * * @param writer the writer. */ public void printStackTrace(final PrintWriter writer) { super.printStackTrace(writer); if (getParentThrowable() != null) { writer.println("ParentException: "); getParentThrowable().printStackTrace(writer); } } /** * Prints this Throwable and its backtrace to the standard error stream. This method prints a stack trace * for this Throwable object on the error output stream that is the value of the field * System.err. The first line of output contains the result of the {@link #toString()} method for this * object. Remaining lines represent data previously recorded by the method {@link #fillInStackTrace()}. The format of * this information depends on the implementation, but the following example may be regarded as typical: *
   * java.lang.NullPointerException
   *         at MyClass.mash(MyClass.java:9)
   *         at MyClass.crunch(MyClass.java:6)
   *         at MyClass.main(MyClass.java:3)
   * 
* This example was produced by running the program: *
   * 

* class MyClass { *

* public static void main(String[] argv) { * crunch(null); * } * static void crunch(int[] a) { * mash(a); * } *

* static void mash(int[] b) { * System.out.println(b[0]); * } * } *

* * @see System#err */ public void printStackTrace() { synchronized (System.err) { printStackTrace(System.err); } } }libbase-1.1.6/source/org/pentaho/reporting/libraries/base/util/WaitingImageObserver.java0000644000175000017500000001400411365604666030121 0ustar renerene/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2007 - 2009 Pentaho Corporation and Contributors. All rights reserved. */ package org.pentaho.reporting.libraries.base.util; import java.awt.Graphics; import java.awt.Image; import java.awt.image.BufferedImage; import java.awt.image.ImageObserver; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * This image observer blocks until the image is completely loaded. AWT defers the loading of images until they are * painted on a graphic. *

* While printing reports it is not very nice, not to know whether a image was completely loaded, so this observer * forces the loading of the image until a final state (either ALLBITS, ABORT or ERROR) is reached. * * @author Thomas Morgner */ public class WaitingImageObserver implements ImageObserver { /** A logger. */ private static final Log LOGGER = LogFactory.getLog(WaitingImageObserver.class); /** * For serialization. */ private static final long serialVersionUID = -807204410581383550L; /** * The lock. */ private boolean lock; /** * The image. */ private Image image; /** * A flag that signals an error. */ private boolean error; private long lastUpdate; // we better dont wait longer than two seconds for the image. This denotes the maximum time between two // updates, not the total loading time. private static final long MAX_LOADTIME_DEFAULT = 2000; private long maxLoadTime; /** * Creates a new ImageObserver for the given Image. The observer has to be started by an * external thread. * * @param image the image to observe (null not permitted). */ public WaitingImageObserver(final Image image) { this(image, MAX_LOADTIME_DEFAULT); } /** * Creates a new ImageObserver for the given Image. The observer has to be started by an * external thread. * * @param image the image to observe (null not permitted). */ public WaitingImageObserver(final Image image, final long maxLoadTime) { if (image == null) { throw new NullPointerException(); } this.image = image; this.lock = true; this.maxLoadTime = maxLoadTime; } /** * Callback function used by AWT to inform that more data is available. The observer waits until either all data is * loaded or AWT signals that the image cannot be loaded. * * @param img the image being observed. * @param infoflags the bitwise inclusive OR of the following flags: WIDTH, HEIGHT, * PROPERTIES, SOMEBITS, FRAMEBITS, ALLBITS, * ERROR, ABORT. * @param x the x coordinate. * @param y the y coordinate. * @param width the width. * @param height the height. * @return false if the infoflags indicate that the image is completely loaded; true * otherwise. */ public synchronized boolean imageUpdate(final Image img, final int infoflags, final int x, final int y, final int width, final int height) { if (img == null) { throw new NullPointerException(); } lastUpdate = System.currentTimeMillis(); if ((infoflags & ImageObserver.ALLBITS) == ImageObserver.ALLBITS) { this.lock = false; this.error = false; notifyAll(); return false; } else if ((infoflags & ImageObserver.ABORT) == ImageObserver.ABORT || (infoflags & ImageObserver.ERROR) == ImageObserver.ERROR) { this.lock = false; this.error = true; notifyAll(); return false; } //notifyAll(); return true; } /** * The workerthread. Simply draws the image to a BufferedImage's Graphics-Object and waits for the AWT to load the * image. */ public synchronized void waitImageLoaded() { if (this.lock == false) { return; } final BufferedImage img = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB); final Graphics g = img.getGraphics(); while (this.lock && error == false) { if (g.drawImage(this.image, 0, 0, img.getWidth(this), img.getHeight(this), this)) { return; } try { wait(500); } catch (InterruptedException e) { LOGGER.info("WaitingImageObserver.waitImageLoaded(): InterruptedException thrown", e); } if (maxLoadTime > 0 && lastUpdate < (System.currentTimeMillis() - maxLoadTime)) { error = true; lock = false; LOGGER.info("WaitingImageObserver.waitImageLoaded(): Image loading reached timeout."); return; } } } /** * Checks whether the loading is complete. * @return true, if the loading is complete, false otherwise. */ public boolean isLoadingComplete() { return this.lock == false; } /** * Returns true if there is an error condition, and false otherwise. * * @return A boolean. */ public boolean isError() { return this.error; } }libbase-1.1.6/source/org/pentaho/reporting/libraries/base/util/ObjectUtilities.java0000644000175000017500000004224611365604666027157 0ustar renerene/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2007 - 2009 Pentaho Corporation and Contributors. All rights reserved. */ package org.pentaho.reporting.libraries.base.util; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.Array; import java.net.URL; import java.util.ArrayList; import java.util.Arrays; import java.util.StringTokenizer; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * A collection of useful static utility methods for handling classes and object instantiation. * * @author Thomas Morgner */ public final class ObjectUtilities { private static final Log LOGGER = LogFactory.getLog(ObjectUtilities.class); /** * A constant for using the TheadContext as source for the classloader. */ public static final String THREAD_CONTEXT = "ThreadContext"; /** * A constant for using the ClassContext as source for the classloader. */ public static final String CLASS_CONTEXT = "ClassContext"; /** * By default use the thread context. */ private static String classLoaderSource = THREAD_CONTEXT; /** * The custom classloader to be used (if not null). */ private static ClassLoader classLoader; private static final Integer[] EMPTY_VERSIONS = new Integer[0]; /** * Default constructor - private. */ private ObjectUtilities() { } /** * Returns the internal configuration entry, whether the classloader of the thread context or the context classloader * should be used. * * @return the classloader source, either THREAD_CONTEXT or CLASS_CONTEXT. */ public static String getClassLoaderSource() { return classLoaderSource; } /** * Defines the internal configuration entry, whether the classloader of the thread context or the context classloader * should be used. *

* This setting can only be defined using the API, there is no safe way to put this into an external configuration * file. * * @param classLoaderSource the classloader source, either THREAD_CONTEXT or CLASS_CONTEXT. */ public static void setClassLoaderSource(final String classLoaderSource) { ObjectUtilities.classLoaderSource = classLoaderSource; } /** * Returns true if the two objects are equal OR both null. * * @param o1 object 1 (null permitted). * @param o2 object 2 (null permitted). * @return true or false. */ public static boolean equal(final Object o1, final Object o2) { if (o1 == o2) { return true; } if (o1 != null) { return o1.equals(o2); } else { return false; } } /** * Performs a comparison on two file objects to determine if they refer to the * same file. The File.equals() method requires that the files refer * to the same file in the same way (relative vs. absolute). * * @param file1 the first file (null permitted). * @param file2 the second file (null permitted). * @return true if the files refer to the same file, false otherwise */ public static boolean equals(final File file1, final File file2) { if (file1 == file2) { return true; } if (file1 != null && file2 != null) { try { return file1.getCanonicalFile().equals(file2.getCanonicalFile()); } catch(IOException ioe) { // There was an error accessing the filesystem return file1.equals(file2); } } return false; } /** * Returns a clone of the specified object, if it can be cloned, otherwise throws a CloneNotSupportedException. * * @param object the object to clone (null not permitted). * @return A clone of the specified object. * @throws CloneNotSupportedException if the object cannot be cloned. */ public static Object clone(final Object object) throws CloneNotSupportedException { if (object == null) { throw new IllegalArgumentException("Null 'object' argument."); } final Class aClass = object.getClass(); if (aClass.isArray()) { final int length = Array.getLength(object); final Object clone = Array.newInstance(aClass.getComponentType(), length); //noinspection SuspiciousSystemArraycopy System.arraycopy(object, 0, clone, 0, length); return object; } try { final Method method = aClass.getMethod("clone", (Class[]) null); if (Modifier.isPublic(method.getModifiers())) { return method.invoke(object, (Object[]) null); } throw new CloneNotSupportedException("Failed to clone: Method 'clone()' is not public on class " + aClass); } catch (NoSuchMethodException e) { LOGGER.warn("Object without clone() method is impossible on class " + aClass, e); } catch (IllegalAccessException e) { LOGGER.warn("Object.clone(): unable to call method 'clone()' on class " + aClass, e); } catch (InvocationTargetException e) { LOGGER.warn("Object without clone() method is impossible on class " + aClass, e); } throw new CloneNotSupportedException ("Failed to clone: Clone caused an Exception while cloning type " + aClass); } /** * Redefines the custom classloader. * * @param classLoader the new classloader or null to use the default. */ public static synchronized void setClassLoader(final ClassLoader classLoader) { ObjectUtilities.classLoader = classLoader; } /** * Returns the custom classloader or null, if no custom classloader is defined. * * @return the custom classloader or null to use the default. */ public static ClassLoader getClassLoader() { return classLoader; } /** * Returns the classloader, which was responsible for loading the given class. * * @param c the classloader, either an application class loader or the boot loader. * @return the classloader, never null. * @throws SecurityException if the SecurityManager does not allow to grab the context classloader. */ public static ClassLoader getClassLoader(final Class c) { final String localClassLoaderSource; synchronized (ObjectUtilities.class) { if (classLoader != null) { return classLoader; } localClassLoaderSource = classLoaderSource; } if ("ThreadContext".equals(localClassLoaderSource)) { final ClassLoader threadLoader = Thread.currentThread().getContextClassLoader(); if (threadLoader != null) { return threadLoader; } } // Context classloader - do not cache .. final ClassLoader applicationCL = c.getClassLoader(); if (applicationCL == null) { return ClassLoader.getSystemClassLoader(); } else { return applicationCL; } } /** * Returns the resource specified by the absolute name. * * @param name the name of the resource * @param c the source class * @return the url of the resource or null, if not found. */ public static URL getResource(final String name, final Class c) { if (name == null) { throw new NullPointerException(); } final ClassLoader cl = getClassLoader(c); if (cl == null) { return null; } return cl.getResource(name); } /** * Returns the resource specified by the relative name. * * @param name the name of the resource relative to the given class * @param c the source class * @return the url of the resource or null, if not found. */ public static URL getResourceRelative(final String name, final Class c) { if (name == null) { throw new NullPointerException(); } final ClassLoader cl = getClassLoader(c); final String cname = convertName(name, c); if (cl == null) { return null; } return cl.getResource(cname); } /** * Transform the class-relative resource name into a global name by appending it to the classes package name. If the * name is already a global name (the name starts with a "/"), then the name is returned unchanged. * * @param name the resource name * @param c the class which the resource is relative to * @return the tranformed name. */ private static String convertName(final String name, Class c) { if (name.length() > 0 && name.charAt(0) == '/') { // strip leading slash.. return name.substring(1); } // we cant work on arrays, so remove them ... while (c.isArray()) { c = c.getComponentType(); } // extract the package ... final String baseName = c.getName(); final int index = baseName.lastIndexOf('.'); if (index == -1) { return name; } final String pkgName = baseName.substring(0, index); return pkgName.replace('.', '/') + '/' + name; } /** * Returns the inputstream for the resource specified by the absolute name. * * @param name the name of the resource * @param context the source class * @return the url of the resource or null, if not found. */ public static InputStream getResourceAsStream(final String name, final Class context) { final URL url = getResource(name, context); if (url == null) { return null; } try { return url.openStream(); } catch (IOException e) { return null; } } /** * Returns the inputstream for the resource specified by the relative name. * * @param name the name of the resource relative to the given class * @param context the source class * @return the url of the resource or null, if not found. */ public static InputStream getResourceRelativeAsStream (final String name, final Class context) { final URL url = getResourceRelative(name, context); if (url == null) { return null; } try { return url.openStream(); } catch (IOException e) { return null; } } /** * Tries to create a new instance of the given class. This is a short cut for the common bean instantiation code. * * @param className the class name as String, never null. * @param source the source class, from where to get the classloader. * @return the instantiated object or null, if an error occured. * @deprecated This class is not typesafe and instantiates the specified object without any additional checks. */ public static Object loadAndInstantiate(final String className, final Class source) { return loadAndInstantiate(className, source, null); } /** * Tries to create a new instance of the given class. This is a short cut for the common bean instantiation code. This * method is a type-safe method and will not instantiate the class unless it is an instance of the given type. * * @param className the class name as String, never null. * @param source the source class, from where to get the classloader. * @param type the expected type of the object that is being instantiated. * @return the instantiated object, which is guaranteed to be of the given type, or null, if an error occured. */ public static Object loadAndInstantiate(final String className, final Class source, final Class type) { if (className == null || className.length() == 0) { return null; } try { final ClassLoader loader = getClassLoader(source); final Class c = Class.forName(className, false, loader); if (type != null && type.isAssignableFrom(c) == false) { // this is unacceptable and means someone messed up the configuration LOGGER.warn("Specified class " + className + " is not of expected type " + type); return null; } return c.newInstance(); } catch (ClassNotFoundException e) { if (LOGGER.isDebugEnabled()) { LOGGER.debug("Specified class " + className + " does not exist."); } // sometimes, this one is expected. } catch (NoClassDefFoundError e) { if (LOGGER.isDebugEnabled()) { LOGGER.debug("Specified class " + className + " cannot be loaded [NOCLASSDEFERROR]."); } } catch (Throwable e) { // this is more severe than a class not being found at all if (LOGGER.isDebugEnabled()) { LOGGER.info("Specified class " + className + " failed to instantiate correctly.", e); } else { LOGGER.info("Specified class " + className + " failed to instantiate correctly."); } } return null; } /** * Checks whether the current JDK is at least JDK 1.4. * * @return true, if the JDK has been recognized as JDK 1.4, false otherwise. * @noinspection AccessOfSystemProperties */ public static boolean isJDK14() { try { final ClassLoader loader = getClassLoader(ObjectUtilities.class); if (loader != null) { try { Class.forName("java.util.RandomAccess", false, loader); return true; } catch (ClassNotFoundException e) { return false; } } } catch (Exception e) { // the safe test failed, now lets check the system properties ... } // OK, the quick and dirty, but secure way failed. Lets try it // using the standard way. try { final String version = System.getProperty ("java.vm.specification.version"); // parse the beast... if (version == null) { return false; } final Integer[] versions = parseVersions(version); final Integer[] target = new Integer[]{new Integer(1), new Integer(4)}; return (ObjectUtilities.compareVersionArrays(versions, target) >= 0); } catch (Exception e) { // if that fails too, we assume the safe "no-JDK 1.4" mode. return false; } } /** * Compares version numbers. * * @param a1 the first array. * @param a2 the second array. * @return -1 if a1 is less than a2, 0 if a1 and a2 are equal, and +1 otherwise. */ public static int compareVersionArrays(final Integer[] a1, final Integer[] a2) { final int length = Math.min(a1.length, a2.length); for (int i = 0; i < length; i++) { final Integer o1 = a1[i]; final Integer o2 = a2[i]; if (o1 == null && o2 == null) { // cannot decide .. continue; } if (o1 == null) { return 1; } if (o2 == null) { return -1; } final int retval = o1.compareTo(o2); if (retval != 0) { return retval; } } return 0; } /** * Parses a version string into numbers. * * @param version the version. * @return the parsed version array. */ public static Integer[] parseVersions(final String version) { if (version == null) { return EMPTY_VERSIONS; } final ArrayList versions = new ArrayList(); final StringTokenizer strtok = new StringTokenizer(version, "."); while (strtok.hasMoreTokens()) { try { versions.add(new Integer(strtok.nextToken())); } catch (NumberFormatException nfe) { break; } } return (Integer[]) versions.toArray(new Integer[versions.size()]); } /** * Compares two arrays and determines if they are equal. This method allows to pass null null * references for any of the arrays. * * @param array1 the first array to compare. * @param array2 the second array to compare. * @return true, if both arrays are equal or both arrays are null, false otherwise. */ public static boolean equalArray(final Object[] array1, final Object[] array2) { if (array1 == array2) { return true; } else if (array1 == null || array2 == null) { return false; } else { return Arrays.equals(array1, array2); } } public static int hashCode(final Object[] array1) { if (array1 == null) { return 0; } int hashCode = 31; for (int i = 0; i < array1.length; i++) { final Object o = array1[i]; hashCode = hashCode * 31 + (o == null ? 0 : o.hashCode()); } return hashCode; } }libbase-1.1.6/source/org/pentaho/reporting/libraries/base/util/StringUtils.java0000644000175000017500000003006211365604666026335 0ustar renerene/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2007 - 2009 Pentaho Corporation and Contributors. All rights reserved. */ package org.pentaho.reporting.libraries.base.util; import java.text.Format; import java.text.MessageFormat; import java.util.HashSet; import java.util.StringTokenizer; /** * String utilities. * * @author Thomas Morgner. */ public class StringUtils { // Constants used to convert a string to a boolean private static final String TRUE = "true"; private static final String YES = "yes"; private static final String ON = "on"; /** * Private constructor prevents object creation. */ private StringUtils() { } /** * Helper functions to query a strings start portion. The comparison is case insensitive. * * @param base the base string. * @param start the starting text. * @return true, if the string starts with the given starting text. */ public static boolean startsWithIgnoreCase(final String base, final String start) { if (base.length() < start.length()) { return false; } return base.regionMatches(true, 0, start, 0, start.length()); } /** * Helper functions to query a strings end portion. The comparison is case insensitive. * * @param base the base string. * @param end the ending text. * @return true, if the string ends with the given ending text. */ public static boolean endsWithIgnoreCase(final String base, final String end) { if (base.length() < end.length()) { return false; } return base.regionMatches(true, base.length() - end.length(), end, 0, end.length()); } /** * Queries the system properties for the line separator. If access * to the System properties is forbidden, the UNIX default is returned. * * @return the line separator. * @noinspection AccessOfSystemProperties */ public static String getLineSeparator() { try { return System.getProperty("line.separator", "\n"); } catch (Exception e) { return "\n"; } } /** * Splits a given string on any whitespace character. Duplicate separators will be merged into a single separator * occurance. This implementation provides the same functionality as the REGEXP-based String.split(..) operation but * does not use Regular expressions and therefore it is faster and less memory consuming. * * @param string the text to be split. * @return the text elements as array. */ public static String[] split(final String string) { return split(string, " \t\n\r\f"); } /** * Splits a given string at the given separator string. Duplicate separators will be merged into a single separator * occurance. * * @param string the text to be split. * @param separator the separator chacters used for the split. * @return the splitted array. */ public static String[] split(final String string, final String separator) { if (separator == null) { throw new NullPointerException("Separator characters must not be null."); } if (string == null) { throw new NullPointerException("String to be split must not be null."); } final StringTokenizer strtok = new StringTokenizer(string, separator, false); final String[] tokens = new String[strtok.countTokens()]; int i = 0; while (strtok.hasMoreTokens()) { final String token = strtok.nextToken(); tokens[i] = (token); i += 1; } return tokens; } /** * Splits a given string at the given separator string. Duplicate separators will be merged into a single separator * occurance. * * @param string the text to be split. * @param separator the separator chacters used for the split. * @param quate the quoting character. * @return the splitted array. */ public static String[] split(final String string, final String separator, final String quate) { final CSVTokenizer strtok = new CSVTokenizer(string, separator, quate, false); final String[] tokens = new String[strtok.countTokens()]; int i = 0; while (strtok.hasMoreTokens()) { final String token = strtok.nextToken(); if (token.length() > 0) { tokens[i] = (token); i += 1; } } if (i == tokens.length) { return tokens; } final String[] retval = new String[i]; System.arraycopy(tokens, 0, retval, 0, i); return retval; } /** * Splits a given string at the given separator string. Duplicate separators will result in empty strings thus * preserving the number of fields specified in the original string. * * @param string the text to be split. * @param separator the separator chacters used for the split. * @return the splitted array. */ public static String[] splitCSV(final String string, final String separator) { return splitCSV(string, separator, null); } /** * Splits a given string at the given separator string. Duplicate separators will result in empty strings thus * preserving the number of fields specified in the original string. * * @param string the text to be split. * @param separator the separator chacters used for the split. * @param quate the quoting character. * @return the splitted array. */ public static String[] splitCSV(final String string, final String separator, final String quate) { final CSVTokenizer strtok = new CSVTokenizer(string, separator, quate, false); final String[] tokens = new String[strtok.countTokens()]; int i = 0; while (strtok.hasMoreTokens()) { final String token = strtok.nextToken(); tokens[i] = (token); i += 1; } return tokens; } /** * Computes a unique name using the given known-names array as filter. This method is not intended for large * datasets. * * @param knownNames the list of known names. * @param pattern the name pattern, which should have one integer slot to create derived names. * @return the unique name or null, if no unqiue name could be created. */ public static String makeUniqueName(final String[] knownNames, final String pattern) { final HashSet knownNamesSet = new HashSet(knownNames.length); for (int i = 0; i < knownNames.length; i++) { final String name = knownNames[i]; knownNamesSet.add(name); } final MessageFormat message = new MessageFormat(pattern); final Object[] objects = {""}; final String plain = message.format(objects); if (knownNamesSet.contains(plain) == false) { return plain; } final Format[] formats = message.getFormats(); if (formats.length == 0) { // there is no variation in this name. return null; } int count = 1; while (count < 2000000) { objects[0] = String.valueOf(count); final String testFile = message.format(objects); if (knownNamesSet.contains(testFile) == false) { return testFile; } count += 1; } return null; } /** * Merges the contents of the first and second array returning a array that contains only unique strings. * The order of the returned array is undefined. * * @param first the first array to be merged. * @param second the second array to be merged. * @return the merged araray. */ public static String[] merge(final String[] first, final String[] second) { if (first.length == 0) { return (String[]) second.clone(); } if (second.length == 0) { return (String[]) first.clone(); } final HashSet total = new HashSet(first.length + second.length); for (int i = 0; i < first.length; i++) { total.add(first[i]); } for (int i = 0; i < second.length; i++) { total.add(second[i]); } return (String[]) total.toArray(new String[total.size()]); } /** * Returns true if the source string evaulates (case insensative and trimmed) to true, * yes, or on. It will return false otherwise (including null). * * @param source the string to check * @return true if the source string evaulates to true or similar value, * false otherwise. */ public static boolean toBoolean(final String source) { return toBoolean(source, false); } /** * Returns true if the source string evaulates (case insensative and trimmed) to true, * yes, or on. It will return false otherwise. If the source string * is null, it will return the value of the default. * * @param source the string to check * @param nullDefault to value to return if the source string is null * @return true if the source string evaulates to true or similar value, * false otherwise. */ public static boolean toBoolean(String source, final boolean nullDefault) { // If the source is null, use the default if (source == null) { return nullDefault; } // Check for valid values source = source.trim().toLowerCase(); return (TRUE.equals(source) || YES.equals(source) || ON.equals(source)); } /** * Determines if the string is empty or null. * * @param source the string to check * @return true if the source string is null or an emptry string, * false otherwise. */ public static boolean isEmpty(final String source) { return isEmpty(source, true); } /** * Determines if the string is empty or null. If the trim is true, * the string will be trimmed before checking for an empty string. * * @param source the string to check * @param trim indicates if the string should be trimmed before checking for an empty string. * @return true if the source string is null or an emptry string, * false otherwise. */ public static boolean isEmpty(final String source, final boolean trim) { if (source == null) { return true; } if (source.length() == 0) { return true; } if (trim == false) { return false; } final char[] chars = source.toCharArray(); for (int i = 0; i < chars.length; i++) { final char c = chars[i]; if (c > ' ') { return false; } } return true; } /** * Determines if the two Strings are equals (taking nulls into account). * * @param s1 the first string to compare. * @param s2 the second string to compare. * @return true if both string are null or the contain the same value, falseotherwise */ public static boolean equals(final String s1, final String s2) { return ((s1 == null && s2 == null) || (s1 != null && s1.equals(s2))); } /** * Determines if the two Strings are equals ingnoring case sensitivity (taking nulls into account). * * @param s1 the first string to compare. * @param s2 the second string to compare. * @return true if both string are null or the contain the same case-insensitive value, falseotherwise */ public static boolean equalsIgnoreCase(final String s1, final String s2) { return ((s1 == null && s2 == null) || (s1 != null && s1.equalsIgnoreCase(s2))); } } libbase-1.1.6/source/org/pentaho/reporting/libraries/base/util/FastStack.java0000644000175000017500000001127311365604666025734 0ustar renerene/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2007 - 2009 Pentaho Corporation and Contributors. All rights reserved. */ package org.pentaho.reporting.libraries.base.util; import java.io.Serializable; import java.util.Arrays; import java.util.EmptyStackException; /** * A very simple unsynchronized stack. This one is faster than the java.util-Version, which is based on the * synchronized java.util.Vector class. * * @author Thomas Morgner */ public final class FastStack implements Serializable, Cloneable { /** * The contents of the stack. The array is likely to be larger than the actual size of the stack, so use * size to get the last accessible item. */ private Object[] contents; /** * The current fill-level of the stack. */ private int size; /** * The initial size of the stack, but also the growth-factor. */ private int initialSize; /** * A constant for serialization support. */ private static final long serialVersionUID = 3111917250800511580L; /** * Creates a new stack with an initial size and growth of 10 items. */ public FastStack() { initialSize = 10; } /** * Creates a new stack with an initial size and growth as specified. * * @param size the initial size and growth. */ public FastStack(final int size) { initialSize = Math.max(1, size); } /** * Checks whether the stack is empty. * @return true, if the stack is empty, false otherwise. */ public boolean isEmpty() { return size == 0; } /** * Returns the number of elements in the stack. * * @return the stack size. */ public int size() { return size; } /** * Pushes a new object on the stack. Null-references are allowed. * * @param o the object, maybe null. */ public void push(final Object o) { if (contents == null) { contents = new Object[initialSize]; contents[0] = o; size = 1; return; } final int oldSize = size; size += 1; if (contents.length == size) { // grow .. final Object[] newContents = new Object[size + initialSize]; System.arraycopy(contents, 0, newContents, 0, size); this.contents = newContents; } this.contents[oldSize] = o; } /** * Loads the top-most element from the stack, without removing it from the stack. * * @return the top-most object. * @throws EmptyStackException if the stack is empty. */ public Object peek() { if (size == 0) { throw new EmptyStackException(); } return contents[size - 1]; } /** * Loads the top-most element from the stack and removes it from the stack at the same time. * * @return the top-most object. * @throws EmptyStackException if the stack is empty. */ public Object pop() { if (size == 0) { throw new EmptyStackException(); } size -= 1; final Object retval = contents[size]; contents[size] = null; return retval; } /** * Creates a shallow copy of the stack. * * @return the cloned stack. */ public Object clone() { try { final FastStack stack = (FastStack) super.clone(); if (contents != null) { stack.contents = (Object[]) contents.clone(); } return stack; } catch (final CloneNotSupportedException cne) { throw new IllegalStateException("Clone not supported? Why?"); } } /** * Removes all contents from the stack. */ public void clear() { if (contents != null) { Arrays.fill(contents, 0, size, null); } this.size = 0; } /** * Returns the element from the stack at the given index-position. * * @param index the element's index. * @return the object. * @throws IndexOutOfBoundsException if the index given is greater than the number of objects in the stack. */ public Object get(final int index) { if (index >= size) { throw new IndexOutOfBoundsException(); } return contents[index]; } }libbase-1.1.6/source/org/pentaho/reporting/libraries/base/util/LinkedMap.java0000644000175000017500000004525311365604666025722 0ustar renerene/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2007 - 2009 Pentaho Corporation and Contributors. All rights reserved. */ package org.pentaho.reporting.libraries.base.util; import java.io.Serializable; import java.lang.reflect.Array; import java.util.Arrays; /** * A fast linked-hashmap that avoids any unneccessay work. It is slightly slower than an ordinary hashmap but * faster than a combined hashmap and list-index that would be needed to get this functionality on JDK 1.2. * The map is as fast as the LinkedHashMap of JDK 1.4+. * * @author Thomas Morgner * @noinspection ProtectedField */ public class LinkedMap implements Cloneable, Serializable { /** * A cache map entry class holding both the key and value and acting as member of a linked list. */ protected static final class MapEntry implements Serializable { /** * The precomputed hashkey of the key. */ protected final int hashKey; /** * The key object, which is never null and which never changes. */ protected final Object key; /** * The current value object (can be null). */ protected Object value; /** * The link to the previous entry in the list. */ protected MapEntry previous; /** * The link to the next entry in the list. */ protected MapEntry next; /** * The link to the next entry in the bucket that has the same hashkey. */ protected MapEntry collisionNext; /** * Creates a new map-entry for the given key and value. * * @param key the key, never null. * @param hashKey the precomputed hashkey for the key. * @param value the value, never null. */ protected MapEntry(final Object key, final int hashKey, final Object value) { if (key == null) { throw new NullPointerException(); } this.key = key; this.hashKey = hashKey; this.value = value; } /** * Returns the previous entry in the list or null if this is the first entry. * * @return the previous entry. */ public MapEntry getPrevious() { return previous; } /** * Redefines the previous entry in the list or null if this is the first entry. * * @param previous the previous entry. */ public void setPrevious(final MapEntry previous) { this.previous = previous; } /** * Returns the next entry in the list or null if this is the last entry. * * @return the next entry. */ public MapEntry getNext() { return next; } /** * Redefines the next entry in the list or null if this is the last entry. * * @param next the next entry. */ public void setNext(final MapEntry next) { this.next = next; } /** * Returns the current value. * * @return the value, never null. */ public Object getValue() { return value; } /** * Redefines the current value. * * @param value the value, never null. */ public void setValue(final Object value) { this.value = value; } /** * Returns the next map-entry in the bucket. If more than one object maps into the same hash-bucket, this map * stores the entries as linked list. * * @return the next entry. */ public MapEntry getCollisionNext() { return collisionNext; } /** * Defines the next map-entry in the bucket. If more than one object maps into the same hash-bucket, this map * stores the entries as linked list. * * @param collisionNext the next entry. */ public void setCollisionNext(final MapEntry collisionNext) { if (collisionNext == this) throw new IllegalStateException(); this.collisionNext = collisionNext; } } private static final int MAXIMUM_CAPACITY = 1 << 30; private static final Object NULL_MARKER = new Object(); private int size; private int mask; private float loadFactor; private int capacity; private MapEntry[] backend; private MapEntry firstEntry; private MapEntry lastEntry; /** * Default constructor. Creates a map for 16 entries with a default load-factor of 0.75. */ public LinkedMap() { this(16, 0.75f); } /** * Creates a new map with the given initial number of buckets and the given loadfactor. A load factor * greater 1 will always cause hash-collisions, while lower loadfactors reduce the likelyhood of collisions. * * @param initialCapacity the initial capacity. * @param loadFactor the load factor of the bucket-array. */ public LinkedMap(int initialCapacity, final float loadFactor) { if (initialCapacity > MAXIMUM_CAPACITY) { initialCapacity = MAXIMUM_CAPACITY; } if (loadFactor <= 0 || Float.isNaN(loadFactor)) { throw new IllegalArgumentException("Illegal load factor: " + loadFactor); } int capacity = 1; int mask = 0; while (capacity < initialCapacity) { mask = (mask << 1) | 1; capacity <<= 1; } this.mask = mask; this.loadFactor = loadFactor; this.backend = new MapEntry[capacity]; this.capacity = (int) Math.ceil(capacity * loadFactor); } /** * Ensures that the map contains enough space to store the next entry. */ private void ensureSize() { final MapEntry[] backend = this.backend; if (size <= (capacity)) { return; } // expand .. final MapEntry[] newBackend = new MapEntry[(backend.length << 1)]; final int newMask = (mask << 1) | 1; transferEntry(newBackend, newMask); this.mask = newMask; this.backend = newBackend; this.capacity = (int) Math.ceil(loadFactor * backend.length); } private void transferEntry(final MapEntry[] newBackend, final int newMask) { for (int i = 0; i < this.backend.length; i++) { MapEntry entry = this.backend[i]; while (entry != null) { final MapEntry next = entry.collisionNext; final int insertIndex = entry.hashKey & newMask; entry.setCollisionNext(newBackend[insertIndex]); newBackend[insertIndex] = entry; entry = next; } } for (int i = 0; i < newBackend.length; i++) { MapEntry mapEntry = newBackend[i]; while (mapEntry != null) { final int insertIndex = mapEntry.hashKey & newMask; if (i != insertIndex) throw new IllegalStateException(); mapEntry = mapEntry.collisionNext; } } } /** * Returns the number of entries in the map. * * @return the number of entries. */ public int size() { return size; } /** * Stores the given value in the map using the provided key. Both key and value can be null. * * @param key the key. * @param value the value to be stored under the key. * @return the previous value stored under this key or null of the entry is new. */ public Object put(final Object key, final Object value) { final Object realKey = ensureKey(key); final int hashKey = cleanHash(realKey.hashCode()); ensureSize(); final int index = hashKey & mask; final MapEntry existingEntry = backend[index]; if (existingEntry == null) { final MapEntry entry = new MapEntry(realKey, hashKey, value); addNewRecord(index, entry); return null; } MapEntry colEntry = existingEntry; while (true) { // The root entry exists and matches the current key. if (colEntry.hashKey == hashKey && colEntry.key.equals(realKey)) { // that means, we just have to update the value inside and move the entry to the last position // in the list (to make it look like a remove/add operation. return updateRecord(value, colEntry); } if (colEntry.collisionNext == null) { // create a new entry in the backend-array ... final MapEntry entry = new MapEntry(realKey, hashKey, value); addCollisionRecord(index, entry); return null; } colEntry = colEntry.collisionNext; } } /** * Updates an existing record and reinserts the record at the end of the linked list. * * @param value the new value value. * @param colEntry the entry record that should be updated. * @return the old value in the entry or null, if there is no old entry. */ private Object updateRecord(final Object value, final MapEntry colEntry) { final Object oldValue = colEntry.value; // replace the value .. colEntry.value = (value); // and reconnect the entry at the end of the queue .. final MapEntry firstEntry = this.firstEntry; final MapEntry lastEntry = this.lastEntry; if (lastEntry == colEntry) { // also covers the case where last = first = col return oldValue; } if (firstEntry == colEntry) { this.firstEntry = colEntry.next; if (this.firstEntry != null) { this.firstEntry.previous = null; } colEntry.previous = (lastEntry); colEntry.next = (null); lastEntry.next = (colEntry); this.lastEntry = colEntry; asserta(); return oldValue; } final MapEntry prevEntry = colEntry.previous; final MapEntry nextEntry = colEntry.next; prevEntry.next = (nextEntry); nextEntry.previous = (prevEntry); colEntry.previous = (lastEntry); colEntry.next = (null); lastEntry.next = (colEntry); this.lastEntry = colEntry; asserta(); return oldValue; } /** * Adds a new map-entry to an already filled bucket. * * @param index where to add the new record in the map. * @param entry the new entry to be added. */ private void addCollisionRecord(final int index, final MapEntry entry) { entry.setCollisionNext(backend[index]); backend[index] = entry; final MapEntry lastEntry = this.lastEntry; entry.previous = (lastEntry); entry.next = (null); lastEntry.next = (entry); this.lastEntry = entry; size += 1; asserta(); } /** * Adds a completely new record to an previously empty bucket. * * @param index the index of the bucket to be updated. * @param entry the new map-entry. */ private void addNewRecord(final int index, final MapEntry entry) { // thats easy ... final MapEntry lastEntry = this.lastEntry; if (lastEntry == null) { firstEntry = entry; } else { entry.previous = (lastEntry); lastEntry.next = (entry); } this.lastEntry = entry; backend[index] = entry; size += 1; asserta(); } /** * Retrieves the object stored under the given key from the map. * * @param key the key for which a value should be located. * @return the value or null, if the map did not contain a value for the key. */ public Object get(final Object key) { final Object realKey = ensureKey(key); final int hashKey = cleanHash(realKey.hashCode()); final int index = hashKey & mask; final MapEntry existingEntry = backend[index]; if (existingEntry == null) { return null; } MapEntry colEntry = existingEntry; while (colEntry != null) { // The root entry exists and matches the current key. if (colEntry.hashKey == hashKey && colEntry.key.equals(realKey)) { return colEntry.value; } colEntry = colEntry.collisionNext; } return null; } /** * Removes the object stored under the given key from the map. * * @param key the key for which a value should be located. * @return the value or null, if the map did not contain a value for the key. */ public Object remove(final Object key) { final Object realKey = ensureKey(key); final int hashKey = cleanHash(realKey.hashCode()); final int index = hashKey & mask; final MapEntry existingEntry = backend[index]; if (existingEntry == null) { return null; } MapEntry prevEntry = null; MapEntry colEntry = existingEntry; while (colEntry != null) { // The root entry exists and matches the current key. if (colEntry.hashKey == hashKey && colEntry.key.equals(realKey)) { final Object value = colEntry.value; if (prevEntry == null) { // this is a root level entry .. backend[index] = colEntry.collisionNext; } else { prevEntry.setCollisionNext(colEntry.collisionNext); } // now check the first and last entry ... if (firstEntry == lastEntry) { // there is ony one entry. firstEntry = null; lastEntry = null; size -= 1; asserta(); return value; } if (firstEntry == colEntry) { final MapEntry nextfirstEntry = colEntry.next; if (nextfirstEntry != null) { nextfirstEntry.previous = (null); colEntry.next = null; } firstEntry = nextfirstEntry; } else if (lastEntry == colEntry) { final MapEntry nextLastEntry = colEntry.previous; if (nextLastEntry != null) { nextLastEntry.next = (null); colEntry.previous = null; } lastEntry = nextLastEntry; } if (colEntry.previous != null) { colEntry.previous.next = colEntry.next; } if (colEntry.next != null) { colEntry.next.previous = colEntry.previous; } size -= 1; asserta(); return value; } prevEntry = colEntry; colEntry = colEntry.collisionNext; } asserta(); return null; } private void asserta() { if (firstEntry == null) { return; } if (firstEntry.previous != null) { throw new NullPointerException(); } } /** * Checks, whether the map contains an entry for the key. * * @param key the key for which a value should be located. * @return true if the map contains a value for the key, false otherwise. */ public boolean containsKey(final Object key) { final Object realKey = ensureKey(key); final int hashKey = cleanHash(realKey.hashCode()); final int index = hashKey & mask; final MapEntry existingEntry = backend[index]; if (existingEntry == null) { return false; } MapEntry colEntry = existingEntry; while (colEntry != null) { // The root entry exists and matches the current key. if (colEntry.hashKey == hashKey && colEntry.key.equals(realKey)) { return true; } colEntry = colEntry.collisionNext; } return false; } /** * Returns the keys used in this map as array. The keys are returned in the insertation order. * * @param data the object array that should receive the keys. * @return the array filled with the keys. */ public Object[] keys(final Object[] data) { final Object[] list; if (data.length < size) { list = (Object[]) Array.newInstance(data.getClass().getComponentType(), size); } else { list = data; } int index = 0; MapEntry entry = firstEntry; while (entry != null) { final Object o = entry.key; if (o == NULL_MARKER) { list[index] = (null); } else { list[index] = (o); } entry = entry.getNext(); index += 1; } return list; } /** * Returns the keys used in this map as array. The keys are returned in the insertation order. * * @return the array filled with the keys. */ public Object[] keys() { return keys(new Object[size]); } /** * Returns the values used in this map as array. The values are returned in the insertation order. * * @return the array filled with the values. */ public Object[] values() { return values(new Object[size]); } /** * Returns the values used in this map as array. The values are returned in the insertation order. * * @param data the object array that should receive the values. * @return the array filled with the values. */ public Object[] values(final Object[] data) { final Object[] list; if (data.length < size) { list = (Object[]) Array.newInstance(data.getClass().getComponentType(), size); } else { list = data; } int index = 0; MapEntry entry = firstEntry; while (entry != null) { final Object o = entry.value; list[index] = (o); entry = entry.getNext(); index += 1; } return list; } /** * Clears the map and removes all map records. */ public void clear() { if (firstEntry == null) { return; } firstEntry = null; lastEntry = null; Arrays.fill(backend, null); size = 0; } /** * A helper to ensure that null-keys are maped into a special marker object. * * @param o the potential key. * @return the null-marker. */ private static Object ensureKey(final Object o) { if (o == null) { return NULL_MARKER; } return o; } /** * Ensures that the hashcode produced by the key is sane. This does some bit-juggeling to avoid incorrect * hashkey implementations. * * @param h the original hashcode. * @return the cleaned hashcode. */ private static int cleanHash(int h) { h ^= (h >>> 20) ^ (h >>> 12); return h ^ (h >>> 7) ^ (h >>> 4); } /** * Clones this map. * * @return the cloned map. * @throws CloneNotSupportedException */ public Object clone() throws CloneNotSupportedException { final LinkedMap map = (LinkedMap) super.clone(); map.backend = (MapEntry[]) backend.clone(); Arrays.fill(map.backend, null); map.firstEntry = null; map.lastEntry = null; map.size = 0; MapEntry entry = firstEntry; while (entry != null) { map.put(entry.key, entry.value); entry = entry.getNext(); } return map; } /** * Checks whether this collection is empty. * * @return true, if the collection is empty, false otherwise. */ public boolean isEmpty() { return size == 0; } } libbase-1.1.6/source/org/pentaho/reporting/libraries/base/util/MemoryUsageMessage.java0000644000175000017500000000302411365604666027606 0ustar renerene/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2007 - 2009 Pentaho Corporation and Contributors. All rights reserved. */ package org.pentaho.reporting.libraries.base.util; /** * A helper class to print memory usage message if needed. * * @author Thomas Morgner */ public class MemoryUsageMessage { /** * The message. */ private final String message; /** * Creates a new message. * * @param message the message. */ public MemoryUsageMessage(final String message) { this.message = message; } /** * Returns a string representation of the message (useful for debugging). * * @return the string. */ public String toString() { return this.message + "Free: " + Runtime.getRuntime().freeMemory() + "; " + "Total: " + Runtime.getRuntime().totalMemory(); } }libbase-1.1.6/source/org/pentaho/reporting/libraries/base/util/BulkDataUtility.java0000644000175000017500000001156311365604666027126 0ustar renerene/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2009 Pentaho Corporation. All rights reserved. */ package org.pentaho.reporting.libraries.base.util; /** * A utility class to support reordering operations of arrays. * * @author Thomas Morgner */ public class BulkDataUtility { /** * Private constructor prevents instantiation. */ private BulkDataUtility() { } /** * Pushes the selected elements up. The elements are given in the data-array, while a selector on whether they * should be pushed up is given in the selection array. The operation modifies the data-array. * * @param data the array holding the data-objects. * @param selection the selection of which elements should be pushed up. */ public static void pushUp(final Object[] data, final boolean[] selection) { if (data == null) { throw new NullPointerException(); } if (selection == null) { throw new NullPointerException(); } if (selection.length != data.length) { throw new IllegalArgumentException(); } for (int i = 1; i < data.length; i++) { final Object o = data[i]; final boolean selected = selection[i]; if (selected && (selection[i - 1] == false)) { data[i] = data[i - 1]; selection[i] = selection[i - 1]; data[i - 1] = o; selection[i - 1] = true; } } } /** * Pushes the selected elements down. The elements are given in the data-array, while a selector on whether they * should be pushed down is given in the selection array. The operation modifies the data-array. * * @param data the array holding the data-objects. * @param selection the selection of which elements should be pushed down. */ public static void pushDown(final Object[] data, final boolean[] selection) { if (data == null) { throw new NullPointerException(); } if (selection == null) { throw new NullPointerException(); } if (selection.length != data.length) { throw new IllegalArgumentException(); } for (int i = data.length - 2; i >= 0; i--) { final Object o = data[i]; final boolean selected = selection[i]; if (selected && (selection[i + 1] == false)) { data[i] = data[i + 1]; selection[i] = selection[i + 1]; data[i + 1] = o; selection[i + 1] = true; } } } /** * Pushes up the selected element. The element is compared via reference-equality, so equals() will not * be called. It is assumed that the selected object is part of the data-collection. * The operation modifies the data-array. * * @param data the array holding the data-objects. * @param selection the selectioned object that be pushed up. */ public static void pushUpSingleValue(final Object[] data, final Object selection) { if (data == null) { throw new NullPointerException(); } if (selection == null) { throw new NullPointerException(); } for (int i = 1; i < data.length; i++) { final Object o = data[i]; //noinspection ObjectEquality final boolean selected = (selection == o); if (selected) { data[i] = data[i - 1]; data[i - 1] = o; } } } /** * Pushes the selected element down. The element is compared via reference-equality, so equals() will not * be called. It is assumed that the selected object is part of the data-collection. * The operation modifies the data-array. * * @param data the array holding the data-objects. * @param selection the selectioned object that be pushed down. */ public static void pushDownSingleValue(final Object[] data, final Object selection) { if (data == null) { throw new NullPointerException(); } if (selection == null) { throw new NullPointerException(); } for (int i = data.length - 2; i >= 0; i--) { final Object o = data[i]; //noinspection ObjectEquality final boolean selected = selection == o; if (selected) { data[i] = data[i + 1]; data[i + 1] = o; } } } }libbase-1.1.6/source/org/pentaho/reporting/libraries/base/util/PngEncoder.java0000644000175000017500000005701411365604666026100 0ustar renerene/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2007 - 2009 Pentaho Corporation and Contributors. All rights reserved. */ package org.pentaho.reporting.libraries.base.util; import java.awt.Image; import java.awt.image.ImageObserver; import java.awt.image.PixelGrabber; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.zip.CRC32; import java.util.zip.Deflater; import java.util.zip.DeflaterOutputStream; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.pentaho.reporting.libraries.base.encoder.ImageEncoder; import org.pentaho.reporting.libraries.base.encoder.UnsupportedEncoderException; /** * PngEncoder takes a Java Image object and creates a byte string which can be saved as a PNG file. The Image is * presumed to use the DirectColorModel. *

*

Thanks to Jay Denny at KeyPoint Software http://www.keypoint.com/ who let me develop this code on company * time.

*

*

You may contact me with (probably very-much-needed) improvements, comments, and bug fixes at:

*

*

david@catcode.com

*

*

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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. A copy of the GNU * LGPL may be found at http://www.gnu.org/copyleft/lesser.html

* * @author J. David Eisenberg * @version 1.5, 19 Oct 2003 *

* CHANGES: -------- 19-Nov-2002 : CODING STYLE CHANGES ONLY (by David Gilbert for Object Refinery Limited); * 19-Sep-2003 : Fix for platforms using EBCDIC (contributed by Paulo Soares); 19-Oct-2003 : Change private * fields to protected fields so that PngEncoderB can inherit them (JDE) Fixed bug with calculation of nRows */ public class PngEncoder implements ImageEncoder { /** A logger for debug-messages. */ private static final Log logger = LogFactory.getLog(PngEncoder.class); /** * Constant specifying that alpha channel should be encoded. */ public static final boolean ENCODE_ALPHA = true; /** * Constant specifying that alpha channel should not be encoded. */ public static final boolean NO_ALPHA = false; /** * Constants for filter (NONE). */ public static final int FILTER_NONE = 0; /** * Constants for filter (SUB). */ public static final int FILTER_SUB = 1; /** * Constants for filter (UP). */ public static final int FILTER_UP = 2; /** * Constants for filter (LAST). */ public static final int FILTER_LAST = 2; /** * IHDR tag. */ private static final byte[] IHDR = {73, 72, 68, 82}; /** * IDAT tag. */ private static final byte[] IDAT = {73, 68, 65, 84}; /** * IEND tag. */ private static final byte[] IEND = {73, 69, 78, 68}; /** * PHYS tag. */ private static final byte[] PHYS = {(byte) 'p', (byte) 'H', (byte) 'Y', (byte) 's'}; /** * The png bytes. */ private byte[] pngBytes; /** * The prior row. */ private byte[] priorRow; /** * The left bytes. */ private byte[] leftBytes; /** * The image. */ private Image image; /** * The width. */ private int width; /** * The height. */ private int height; /** * The byte position. */ private int bytePos; /** * The maximum position. */ private int maxPos; /** * CRC. */ private CRC32 crc = new CRC32(); /** * The CRC value. */ private long crcValue; /** * A flag indicating whether the alpha channel should also be encoded. */ private boolean encodeAlpha; /** * The filter type. */ private int filter; /** * The bytes-per-pixel. */ private int bytesPerPixel; /** * The physical pixel dimension : number of pixels per inch on the X axis. */ private int xDpi; /** * The physical pixel dimension : number of pixels per inch on the Y axis. */ private int yDpi; /** * Used for conversion of DPI to Pixels per Meter. */ private static final float INCH_IN_METER_UNIT = 0.0254f; /** * The compression level (1 = best speed, 9 = best compression, 0 = no compression). */ private int compressionLevel; /** * Class constructor. */ public PngEncoder() { this(null, false, PngEncoder.FILTER_NONE, 0); } /** * Class constructor specifying Image to encode, with no alpha channel encoding. * * @param image A Java Image object which uses the DirectColorModel * @see java.awt.Image */ public PngEncoder(final Image image) { this(image, false, PngEncoder.FILTER_NONE, 0); } /** * Class constructor specifying Image to encode, and whether to encode alpha. * * @param image A Java Image object which uses the DirectColorModel * @param encodeAlpha Encode the alpha channel? false=no; true=yes * @see java.awt.Image */ public PngEncoder(final Image image, final boolean encodeAlpha) { this(image, encodeAlpha, PngEncoder.FILTER_NONE, 0); } /** * Class constructor specifying Image to encode, whether to encode alpha, and filter to use. * * @param image A Java Image object which uses the DirectColorModel * @param encodeAlpha Encode the alpha channel? false=no; true=yes * @param whichFilter 0=none, 1=sub, 2=up * @see java.awt.Image */ public PngEncoder(final Image image, final boolean encodeAlpha, final int whichFilter) { this(image, encodeAlpha, whichFilter, 0); } /** * Class constructor specifying Image source to encode, whether to encode alpha, filter to use, and compression * level. * * @param image A Java Image object * @param encodeAlpha Encode the alpha channel? false=no; true=yes * @param whichFilter 0=none, 1=sub, 2=up * @param compLevel 0..9 (1 = best speed, 9 = best compression, 0 = no compression) * @see java.awt.Image */ public PngEncoder(final Image image, final boolean encodeAlpha, final int whichFilter, final int compLevel) { this.image = image; this.encodeAlpha = encodeAlpha; setFilter(whichFilter); setCompressionLevel(compLevel); if (getCompressionLevel() == 0) { setCompressionLevel(5); } } /** * Set the image to be encoded. * * @param image A Java Image object which uses the DirectColorModel * @see java.awt.Image * @see java.awt.image.DirectColorModel */ public void setImage(final Image image) { this.image = image; this.pngBytes = null; } /** * Returns the image to be encoded. * @return the image to be encoded. */ public Image getImage() { return image; } /** * Creates an array of bytes that is the PNG equivalent of the current image, specifying whether to encode alpha or * not. * * @param encodeAlpha boolean false=no alpha, true=encode alpha * @return an array of bytes, or null if there was a problem */ public byte[] pngEncode(final boolean encodeAlpha) { final byte[] pngIdBytes = {-119, 80, 78, 71, 13, 10, 26, 10}; if (this.image == null) { return null; } this.width = this.image.getWidth(null); this.height = this.image.getHeight(null); /* * start with an array that is big enough to hold all the pixels * (plus filter bytes), and an extra 200 bytes for header info */ this.pngBytes = new byte[((this.width + 1) * this.height * 3) + 200]; /* * keep track of largest byte written to the array */ this.maxPos = 0; this.bytePos = writeBytes(pngIdBytes, 0); //hdrPos = bytePos; writeHeader(); writeResolution(); //dataPos = bytePos; if (writeImageData()) { writeEnd(); final byte[] pngBytes = resizeByteArray(this.pngBytes, this.maxPos); this.pngBytes = null; return pngBytes; } else { this.pngBytes = null; return null; } } /** * Creates an array of bytes that is the PNG equivalent of the current image. Alpha encoding is determined by its * setting in the constructor. * * @return an array of bytes, or null if there was a problem */ public byte[] pngEncode() { return pngEncode(this.encodeAlpha); } /** * Set the alpha encoding on or off. * * @param encodeAlpha false=no, true=yes */ public void setEncodeAlpha(final boolean encodeAlpha) { this.encodeAlpha = encodeAlpha; } /** * Retrieve alpha encoding status. * * @return boolean false=no, true=yes */ public boolean getEncodeAlpha() { return this.encodeAlpha; } /** * Set the filter to use. * * @param whichFilter from constant list */ public void setFilter(final int whichFilter) { this.filter = PngEncoder.FILTER_NONE; if (whichFilter <= PngEncoder.FILTER_LAST) { this.filter = whichFilter; } } /** * Retrieve filtering scheme. * * @return int (see constant list) */ public int getFilter() { return this.filter; } /** * Set the compression level to use. * * @param level the compression level (1 = best speed, 9 = best compression, 0 = no compression) */ public void setCompressionLevel(final int level) { if (level >= 0 && level <= 9) { this.compressionLevel = level; } } /** * Retrieve compression level. * * @return int (1 = best speed, 9 = best compression, 0 = no compression) */ public int getCompressionLevel() { return this.compressionLevel; } /** * Increase or decrease the length of a byte array. * * @param array The original array. * @param newLength The length you wish the new array to have. * @return Array of newly desired length. If shorter than the original, the trailing elements are truncated. */ protected byte[] resizeByteArray(final byte[] array, final int newLength) { final byte[] newArray = new byte[newLength]; final int oldLength = array.length; System.arraycopy(array, 0, newArray, 0, Math.min(oldLength, newLength)); return newArray; } /** * Write an array of bytes into the pngBytes array. Note: This routine has the side effect of updating maxPos, the * largest element written in the array. The array is resized by 1000 bytes or the length of the data to be written, * whichever is larger. * * @param data The data to be written into pngBytes. * @param offset The starting point to write to. * @return The next place to be written to in the pngBytes array. */ protected int writeBytes(final byte[] data, final int offset) { this.maxPos = Math.max(this.maxPos, offset + data.length); if (data.length + offset > this.pngBytes.length) { this.pngBytes = resizeByteArray(this.pngBytes, this.pngBytes.length + Math.max(1000, data.length)); } System.arraycopy(data, 0, this.pngBytes, offset, data.length); return offset + data.length; } /** * Write an array of bytes into the pngBytes array, specifying number of bytes to write. Note: This routine has the * side effect of updating maxPos, the largest element written in the array. The array is resized by 1000 bytes or * the length of the data to be written, whichever is larger. * * @param data The data to be written into pngBytes. * @param nBytes The number of bytes to be written. * @param offset The starting point to write to. * @return The next place to be written to in the pngBytes array. */ protected int writeBytes(final byte[] data, final int nBytes, final int offset) { this.maxPos = Math.max(this.maxPos, offset + nBytes); if (nBytes + offset > this.pngBytes.length) { this.pngBytes = resizeByteArray(this.pngBytes, this.pngBytes.length + Math.max(1000, nBytes)); } System.arraycopy(data, 0, this.pngBytes, offset, nBytes); return offset + nBytes; } /** * Write a two-byte integer into the pngBytes array at a given position. * * @param n The integer to be written into pngBytes. * @param offset The starting point to write to. * @return The next place to be written to in the pngBytes array. */ protected int writeInt2(final int n, final int offset) { final byte[] temp = {(byte) ((n >> 8) & 0xff), (byte) (n & 0xff)}; return writeBytes(temp, offset); } /** * Write a four-byte integer into the pngBytes array at a given position. * * @param n The integer to be written into pngBytes. * @param offset The starting point to write to. * @return The next place to be written to in the pngBytes array. */ protected int writeInt4(final int n, final int offset) { final byte[] temp = {(byte) ((n >> 24) & 0xff), (byte) ((n >> 16) & 0xff), (byte) ((n >> 8) & 0xff), (byte) (n & 0xff)}; return writeBytes(temp, offset); } /** * Write a single byte into the pngBytes array at a given position. * * @param b The integer to be written into pngBytes. * @param offset The starting point to write to. * @return The next place to be written to in the pngBytes array. */ protected int writeByte(final int b, final int offset) { final byte[] temp = {(byte) b}; return writeBytes(temp, offset); } /** * Write a PNG "IHDR" chunk into the pngBytes array. */ protected void writeHeader() { this.bytePos = writeInt4(13, this.bytePos); final int startPos = bytePos; this.bytePos = writeBytes(PngEncoder.IHDR, this.bytePos); this.width = this.image.getWidth(null); this.height = this.image.getHeight(null); this.bytePos = writeInt4(this.width, this.bytePos); this.bytePos = writeInt4(this.height, this.bytePos); this.bytePos = writeByte(8, this.bytePos); // bit depth this.bytePos = writeByte((this.encodeAlpha) ? 6 : 2, this.bytePos); // direct model this.bytePos = writeByte(0, this.bytePos); // compression method this.bytePos = writeByte(0, this.bytePos); // filter method this.bytePos = writeByte(0, this.bytePos); // no interlace this.crc.reset(); this.crc.update(this.pngBytes, startPos, this.bytePos - startPos); this.crcValue = this.crc.getValue(); this.bytePos = writeInt4((int) this.crcValue, this.bytePos); } /** * Perform "sub" filtering on the given row. Uses temporary array leftBytes to store the original values of the * previous pixels. The array is 16 bytes long, which will easily hold two-byte samples plus two-byte alpha. * * @param pixels The array holding the scan lines being built * @param startPos Starting position within pixels of bytes to be filtered. * @param width Width of a scanline in pixels. */ protected void filterSub(final byte[] pixels, final int startPos, final int width) { final int offset = this.bytesPerPixel; final int actualStart = startPos + offset; final int nBytes = width * this.bytesPerPixel; int leftInsert = offset; int leftExtract = 0; for (int i = actualStart; i < startPos + nBytes; i++) { this.leftBytes[leftInsert] = pixels[i]; pixels[i] = (byte) ((pixels[i] - this.leftBytes[leftExtract]) % 256); leftInsert = (leftInsert + 1) % 0x0f; leftExtract = (leftExtract + 1) % 0x0f; } } /** * Perform "up" filtering on the given row. Side effect: refills the prior row with current row * * @param pixels The array holding the scan lines being built * @param startPos Starting position within pixels of bytes to be filtered. * @param width Width of a scanline in pixels. */ protected void filterUp(final byte[] pixels, final int startPos, final int width) { final int nBytes = width * this.bytesPerPixel; for (int i = 0; i < nBytes; i++) { final byte currentByte = pixels[startPos + i]; pixels[startPos + i] = (byte) ((pixels[startPos + i] - this.priorRow[i]) % 256); this.priorRow[i] = currentByte; } } /** * Write the image data into the pngBytes array. This will write one or more PNG "IDAT" chunks. In order to conserve * memory, this method grabs as many rows as will fit into 32K bytes, or the whole image; whichever is less. * * @return true if no errors; false if error grabbing pixels */ protected boolean writeImageData() { this.bytesPerPixel = (this.encodeAlpha) ? 4 : 3; final Deflater scrunch = new Deflater(this.compressionLevel); final ByteArrayOutputStream outBytes = new ByteArrayOutputStream(1024); final DeflaterOutputStream compBytes = new DeflaterOutputStream(outBytes, scrunch); try { int startRow = 0; // starting row to process this time through //noinspection SuspiciousNameCombination int rowsLeft = this.height; // number of rows remaining to write while (rowsLeft > 0) { final int nRows = Math.max(Math.min(32767 / (this.width * (this.bytesPerPixel + 1)), rowsLeft), 1); final int[] pixels = new int[this.width * nRows]; final PixelGrabber pg = new PixelGrabber(this.image, 0, startRow, this.width, nRows, pixels, 0, this.width); try { pg.grabPixels(); } catch (Exception e) { logger.error("interrupted waiting for pixels!", e); return false; } if ((pg.getStatus() & ImageObserver.ABORT) != 0) { logger.error("image fetch aborted or errored"); return false; } /* * Create a data chunk. scanLines adds "nRows" for * the filter bytes. */ final byte[] scanLines = new byte[this.width * nRows * this.bytesPerPixel + nRows]; if (this.filter == PngEncoder.FILTER_SUB) { this.leftBytes = new byte[16]; } if (this.filter == PngEncoder.FILTER_UP) { this.priorRow = new byte[this.width * this.bytesPerPixel]; } int scanPos = 0; int startPos = 1; for (int i = 0; i < this.width * nRows; i++) { if (i % this.width == 0) { scanLines[scanPos++] = (byte) this.filter; startPos = scanPos; } scanLines[scanPos++] = (byte) ((pixels[i] >> 16) & 0xff); scanLines[scanPos++] = (byte) ((pixels[i] >> 8) & 0xff); scanLines[scanPos++] = (byte) ((pixels[i]) & 0xff); if (this.encodeAlpha) { scanLines[scanPos++] = (byte) ((pixels[i] >> 24) & 0xff); } if ((i % this.width == this.width - 1) && (this.filter != PngEncoder.FILTER_NONE)) { if (this.filter == PngEncoder.FILTER_SUB) { filterSub(scanLines, startPos, this.width); } if (this.filter == PngEncoder.FILTER_UP) { filterUp(scanLines, startPos, this.width); } } } /* * Write these lines to the output area */ compBytes.write(scanLines, 0, scanPos); startRow += nRows; rowsLeft -= nRows; } compBytes.close(); /* * Write the compressed bytes */ final byte[] compressedLines = outBytes.toByteArray(); final int nCompressed = compressedLines.length; this.crc.reset(); this.bytePos = writeInt4(nCompressed, this.bytePos); this.bytePos = writeBytes(PngEncoder.IDAT, this.bytePos); this.crc.update(PngEncoder.IDAT); this.bytePos = writeBytes(compressedLines, nCompressed, this.bytePos); this.crc.update(compressedLines, 0, nCompressed); this.crcValue = this.crc.getValue(); this.bytePos = writeInt4((int) this.crcValue, this.bytePos); scrunch.finish(); scrunch.end(); return true; } catch (IOException e) { logger.error("Failed to write PNG Data", e); return false; } } /** * Write a PNG "IEND" chunk into the pngBytes array. */ protected void writeEnd() { this.bytePos = writeInt4(0, this.bytePos); this.bytePos = writeBytes(PngEncoder.IEND, this.bytePos); this.crc.reset(); this.crc.update(PngEncoder.IEND); this.crcValue = this.crc.getValue(); this.bytePos = writeInt4((int) this.crcValue, this.bytePos); } /** * Set the DPI for the X axis. * * @param xDpi The number of dots per inch */ public void setXDpi(final int xDpi) { this.xDpi = Math.round(xDpi / PngEncoder.INCH_IN_METER_UNIT); } /** * Get the DPI for the X axis. * * @return The number of dots per inch */ public int getXDpi() { return Math.round(xDpi * PngEncoder.INCH_IN_METER_UNIT); } /** * Set the DPI for the Y axis. * * @param yDpi The number of dots per inch */ public void setYDpi(final int yDpi) { this.yDpi = Math.round(yDpi / PngEncoder.INCH_IN_METER_UNIT); } /** * Get the DPI for the Y axis. * * @return The number of dots per inch */ public int getYDpi() { return Math.round(yDpi * PngEncoder.INCH_IN_METER_UNIT); } /** * Set the DPI resolution. * * @param xDpi The number of dots per inch for the X axis. * @param yDpi The number of dots per inch for the Y axis. */ public void setDpi(final int xDpi, final int yDpi) { this.xDpi = Math.round(xDpi / PngEncoder.INCH_IN_METER_UNIT); this.yDpi = Math.round(yDpi / PngEncoder.INCH_IN_METER_UNIT); } /** * Write a PNG "pHYs" chunk into the pngBytes array. */ protected void writeResolution() { if (xDpi > 0 && yDpi > 0) { bytePos = writeInt4(9, bytePos); final int startPos = bytePos; bytePos = writeBytes(PngEncoder.PHYS, bytePos); bytePos = writeInt4(xDpi, bytePos); bytePos = writeInt4(yDpi, bytePos); bytePos = writeByte(1, bytePos); // unit is the meter. crc.reset(); crc.update(pngBytes, startPos, bytePos - startPos); crcValue = crc.getValue(); bytePos = writeInt4((int) crcValue, bytePos); } } public void encodeImage(final Image image, final OutputStream outputStream, final float quality, final boolean encodeAlpha) throws IOException, UnsupportedEncoderException { setCompressionLevel(Math.min (9, Math.max(0, (int) (quality * 10)))); setImage(image); setEncodeAlpha(encodeAlpha); final byte[] bytes = this.pngEncode(); outputStream.write(bytes); } public String getMimeType() { return "image/png"; } } libbase-1.1.6/source/org/pentaho/reporting/libraries/base/util/CSVTokenizer.java0000644000175000017500000003026011365604666026374 0ustar renerene/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2007 - 2009 Pentaho Corporation and Contributors. All rights reserved. */ package org.pentaho.reporting.libraries.base.util; import java.util.Enumeration; import java.util.NoSuchElementException; /** * The csv tokenizer class allows an application to break a Comma Separated Value format into tokens. The tokenization * method is much simpler than the one used by the StringTokenizer class. The CSVTokenizer * methods do not distinguish among identifiers, numbers, and quoted strings, nor do they recognize and skip comments. *

* The set of separator (the characters that separate tokens) may be specified either at creation time or on a per-token * basis. *

* An instance of CSVTokenizer behaves in one of two ways, depending on whether it was created with the * returnSeparators flag having the value true or false:

  • If the flag is * false, delimiter characters serve to separate tokens. A token is a maximal sequence of consecutive * characters that are not separator.
  • If the flag is true, delimiter characters are themselves * considered to be tokens. A token is thus either one delimiter character, or a maximal sequence of consecutive * characters that are not separator.

A CSVTokenizer object internally maintains a current position * within the string to be tokenized. Some operations advance this current position past the characters processed.

A * token is returned by taking a substring of the string that was used to create the CSVTokenizer object. *

* The following is one example of the use of the tokenizer. The code: *

 *     CSVTokenizer csvt = new CSVTokenizer("this,is,a,test");
 *     while (csvt.hasMoreTokens()) {
 *         println(csvt.nextToken());
 *     }
 * 
*

* prints the following output: *

 *     this
 *     is
 *     a
 *     test
 * 
* * @author abupon */ public class CSVTokenizer implements Enumeration { /** * The complete record that should be separated into elements. */ private String record; /** * The separator. */ private String separator; /** * The quoting char. */ private String quate; /** * the current parsing position. */ private int currentIndex; /** * A flag indicating that the current parse position is before the start. */ private boolean beforeStart; /** * A possible separator constant. */ public static final String SEPARATOR_COMMA = ","; /** * A possible separator constant. */ public static final String SEPARATOR_TAB = "\t"; /** * A possible separator constant. */ public static final String SEPARATOR_SPACE = " "; /** * A possible quote character constant. */ public static final String DOUBLE_QUATE = "\""; /** * A possible quote character constant. */ public static final String SINGLE_QUATE = "'"; /** * Constructs a csv tokenizer for the specified string. theSeparator argument is the separator for * separating tokens. *

* If the returnSeparators flag is true, then the separator string is also returned as * tokens. separator is returned as a string. If the flag is false, the separator string is skipped and * only serve as separator between tokens. * * @param aString a string to be parsed. * @param theSeparator the separator (CSVTokenizer.SEPARATOR_COMMA, CSVTokenizer.TAB, CSVTokenizer.SPACE, etc.). * @param theQuate the quate (CSVTokenizer.SINGLE_QUATE, CSVTokenizer.DOUBLE_QUATE, etc.). */ public CSVTokenizer(final String aString, final String theSeparator, final String theQuate) { this(aString, theSeparator, theQuate, true); } /** * Constructs a csv tokenizer for the specified string. theSeparator argument is the separator for * separating tokens. *

* If the returnSeparators flag is true, then the separator string is also returned as * tokens. separator is returned as a string. If the flag is false, the separator string is skipped and * only serve as separator between tokens. * * @param aString a string to be parsed. * @param theSeparator the separator (CSVTokenizer.SEPARATOR_COMMA, CSVTokenizer.TAB, CSVTokenizer.SPACE, etc.). * @param theQuate the quate (CSVTokenizer.SINGLE_QUATE, CSVTokenizer.DOUBLE_QUATE, etc.). */ public CSVTokenizer(final String aString, final String theSeparator, final String theQuate, final boolean trim) { if (aString == null) { throw new NullPointerException("The given string is null"); } if (theSeparator == null) { throw new NullPointerException("The given separator is null"); } if (trim) { this.record = aString.trim(); } else { this.record = aString; } this.separator = theSeparator; this.quate = theQuate; this.currentIndex = 0; this.beforeStart = true; } /** * Constructs a csv tokenizer for the specified string. The characters in the theSeparator argument are * the separator for separating tokens. Separator string themselves will not be treated as tokens. * * @param aString a string to be parsed. * @param theSeparator the separator (CSVTokenizer.SEPARATOR_COMMA, CSVTokenizer.TAB, CSVTokenizer.SPACE, etc.). */ public CSVTokenizer(final String aString, final String theSeparator) { this(aString, theSeparator, CSVTokenizer.DOUBLE_QUATE); } /** * Constructs a string tokenizer for the specified string. The tokenizer uses the default separator set, which is * CSVTokenizer.SEPARATOR_COMMA. Separator string themselves will not be treated as tokens. * * @param aString a string to be parsed. */ public CSVTokenizer(final String aString) { this(aString, CSVTokenizer.SEPARATOR_COMMA, CSVTokenizer.DOUBLE_QUATE, true); } /** * Constructs a string tokenizer for the specified string. The tokenizer uses the default separator set, which is * CSVTokenizer.SEPARATOR_COMMA. Separator string themselves will not be treated as tokens. * * @param aString a string to be parsed. */ public CSVTokenizer(final String aString, final boolean trim) { this(aString, CSVTokenizer.SEPARATOR_COMMA, CSVTokenizer.DOUBLE_QUATE, trim); } /** * Tests if there are more tokens available from this tokenizer's string. If this method returns true, then a * subsequent call to nextToken with no argument will successfully return a token. * * @return true if and only if there is at least one token in the string after the current position; * false otherwise. */ public boolean hasMoreTokens() { return (this.currentIndex < this.record.length()); } /** * Returns the next token from this string tokenizer. * * @return the next token from this string tokenizer. * @throws NoSuchElementException if there are no more tokens in this tokenizer's string. * @throws IllegalArgumentException if given parameter string format was wrong */ public String nextToken() throws NoSuchElementException, IllegalArgumentException { if (!this.hasMoreTokens()) { throw new NoSuchElementException(); } if (beforeStart == false) { currentIndex += this.separator.length(); } else { beforeStart = false; } if (this.quate != null && this.record.startsWith(this.quate, this.currentIndex)) { final int quateLength = this.quate.length(); int startOffset = this.currentIndex + quateLength; final StringBuffer b = new StringBuffer(); while (true) { final int end = record.indexOf(this.quate, startOffset); if (end < 0) { throw new IllegalArgumentException("Illegal format"); } if (record.startsWith(this.quate, end + 1) == false) { b.append (record.substring(startOffset, end)); currentIndex = end + 1; return b.toString(); } else { b.append (record.substring(startOffset, end + 1)); } startOffset = end + quateLength * 2; } } final int end = this.record.indexOf(this.separator, this.currentIndex); if (end >= 0) { final int start = this.currentIndex; final String token = this.record.substring(start, end); this.currentIndex = end; return token; } else { final int start = this.currentIndex; final String token = this.record.substring(start); this.currentIndex = this.record.length(); return token; } } /** * Returns the next token in this string tokenizer's string. First, the set of characters considered to be separator * by this CSVTokenizer object is changed to be the characters in the string separator. Then the * next token in the string after the current position is returned. The current position is advanced beyond the * recognized token. The new delimiter set remains the default after this call. * * @param theSeparator the new separator. * @return the next token, after switching to the new delimiter set. * @throws NoSuchElementException * if there are no more tokens in this tokenizer's string. */ public String nextToken(final String theSeparator) { separator = theSeparator; return nextToken(); } /** * Returns the same value as the hasMoreTokens method. It exists so that this class can implement the * Enumeration interface. * * @return true if there are more tokens; false otherwise. * @see Enumeration * @see CSVTokenizer#hasMoreTokens() */ public boolean hasMoreElements() { return hasMoreTokens(); } /** * Returns the same value as the nextToken method, except that its declared return value is * Object rather than String. It exists so that this class can implement the * Enumeration interface. * * @return the next token in the string. * @throws NoSuchElementException * if there are no more tokens in this tokenizer's string. * @see Enumeration * @see CSVTokenizer#nextToken() */ public Object nextElement() { return nextToken(); } /** * Calculates the number of times that this tokenizer's nextToken method can be called before it * generates an exception. The current position is not advanced. * * @return the number of tokens remaining in the string using the current delimiter set. * @see CSVTokenizer#nextToken() */ public int countTokens() { int count = 0; final int preserve = this.currentIndex; final boolean preserveStart = this.beforeStart; while (this.hasMoreTokens()) { this.nextToken(); count++; } this.currentIndex = preserve; this.beforeStart = preserveStart; return count; } /** * Returns the quate. * * @return char */ public String getQuate() { return this.quate; } /** * Sets the quate. * * @param quate The quate to set */ public void setQuate(final String quate) { this.quate = quate; } } libbase-1.1.6/source/org/pentaho/reporting/libraries/base/util/ObjectTable.java0000644000175000017500000003030111365604666026220 0ustar renerene/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2007 - 2009 Pentaho Corporation and Contributors. All rights reserved. */ package org.pentaho.reporting.libraries.base.util; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import java.util.Arrays; /** * A lookup table for objects. This implementation is not synchronized, it is up * to the caller to synchronize it properly. * * @author Thomas Morgner */ public class ObjectTable implements Serializable { /** * For serialization. */ private static final long serialVersionUID = -3968322452944912066L; /** * The number of rows. */ private int rows; /** * The number of columns. */ private int columns; /** * An array of objects. The array may contain null values. */ private transient Object[][] data; /** * Defines how many object-slots get reserved each time we run out of * space. */ private int rowIncrement; /** * Defines how many object-slots get reserved each time we run out of * space. */ private int columnIncrement; /** * Creates a new table. */ public ObjectTable() { this(5, 5); } /** * Creates a new table. * * @param increment the row and column size increment. */ public ObjectTable(final int increment) { this(increment, increment); } /** * Creates a new table. * * @param rowIncrement the row size increment. * @param colIncrement the column size increment. */ public ObjectTable(final int rowIncrement, final int colIncrement) { if (rowIncrement < 1) { throw new IllegalArgumentException("Increment must be positive."); } if (colIncrement < 1) { throw new IllegalArgumentException("Increment must be positive."); } this.rows = 0; this.columns = 0; this.rowIncrement = rowIncrement; this.columnIncrement = colIncrement; this.data = new Object[rowIncrement][]; } /** * Returns the column size increment. * * @return the increment. */ public int getColumnIncrement() { return this.columnIncrement; } /** * Returns the row size increment. * * @return the increment. */ public int getRowIncrement() { return this.rowIncrement; } /** * Checks that there is storage capacity for the specified row and resizes * if necessary. * * @param row the row index. */ protected void ensureRowCapacity(final int row) { // does this increase the number of rows? if yes, create new storage if (row >= this.data.length) { final Object[][] enlarged = new Object[row + this.rowIncrement][]; System.arraycopy(this.data, 0, enlarged, 0, this.data.length); // do not create empty arrays - this is more expensive than checking // for null-values. this.data = enlarged; } } /** * Ensures that there is storage capacity for the specified item. * * @param row the row index. * @param column the column index. */ public void ensureCapacity(final int row, final int column) { if (row < 0) { throw new IndexOutOfBoundsException("Row is invalid. " + row); } if (column < 0) { throw new IndexOutOfBoundsException("Column is invalid. " + column); } ensureRowCapacity(row); final Object[] current = this.data[row]; if (current == null) { final Object[] enlarged = new Object[Math.max(column + 1, this.columnIncrement)]; this.data[row] = enlarged; } else if (column >= current.length) { final Object[] enlarged = new Object[column + this.columnIncrement]; System.arraycopy(current, 0, enlarged, 0, current.length); this.data[row] = enlarged; } } /** * Returns the number of rows in the table. * * @return The row count. */ public int getRowCount() { return this.rows; } /** * Returns the number of columns in the table. * * @return The column count. */ public int getColumnCount() { return this.columns; } /** * Returns the object from a particular cell in the table. Returns null, if * there is no object at the given position. *

* Note: throws IndexOutOfBoundsException if row or column is negative. * * @param row the row index (zero-based). * @param column the column index (zero-based). * @return The object. */ protected Object getObject(final int row, final int column) { if (row < this.data.length) { final Object[] current = this.data[row]; if (current == null) { return null; } if (column < current.length) { return current[column]; } } return null; } /** * Sets the object for a cell in the table. The table is expanded if * necessary. * * @param row the row index (zero-based). * @param column the column index (zero-based). * @param object the object. */ protected void setObject(final int row, final int column, final Object object) { ensureCapacity(row, column); this.data[row][column] = object; this.rows = Math.max(this.rows, row + 1); this.columns = Math.max(this.columns, column + 1); } /** * Tests this paint table for equality with another object (typically also * an ObjectTable). * * @param o the other object. * @return A boolean. */ public boolean equals(final Object o) { if (o == null) { return false; } if (this == o) { return true; } if ((o instanceof ObjectTable) == false) { return false; } final ObjectTable ot = (ObjectTable) o; if (getRowCount() != ot.getRowCount()) { return false; } if (getColumnCount() != ot.getColumnCount()) { return false; } for (int r = 0; r < getRowCount(); r++) { for (int c = 0; c < getColumnCount(); c++) { if (ObjectUtilities.equal(getObject(r, c), ot.getObject(r, c)) == false) { return false; } } } return true; } /** * Returns a hash code value for the object. * * @return the hashcode */ public int hashCode() { int result; result = this.rows; result = 29 * result + this.columns; return result; } /** * Handles serialization. * * @param stream the output stream. * @throws java.io.IOException if there is an I/O problem. */ private void writeObject(final ObjectOutputStream stream) throws IOException { stream.defaultWriteObject(); final int rowCount = this.data.length; stream.writeInt(rowCount); for (int r = 0; r < rowCount; r++) { final Object[] column = this.data[r]; stream.writeBoolean(column != null); if (column != null) { final int columnCount = column.length; stream.writeInt(columnCount); for (int c = 0; c < columnCount; c++) { writeSerializedData(stream, column[c]); } } } } /** * Handles the serialization of an single element of this table. * * @param stream the stream which should write the object * @param o the object that should be serialized * @throws java.io.IOException if an IO error occured */ protected void writeSerializedData(final ObjectOutputStream stream, final Object o) throws IOException { stream.writeObject(o); } /** * Restores a serialized object. * * @param stream the input stream. * @throws java.io.IOException if there is an I/O problem. * @throws ClassNotFoundException if a class cannot be found. */ private void readObject(final ObjectInputStream stream) throws IOException, ClassNotFoundException { stream.defaultReadObject(); final int rowCount = stream.readInt(); this.data = new Object[rowCount][]; for (int r = 0; r < rowCount; r++) { final boolean isNotNull = stream.readBoolean(); if (isNotNull) { final int columnCount = stream.readInt(); final Object[] column = new Object[columnCount]; this.data[r] = column; for (int c = 0; c < columnCount; c++) { column[c] = readSerializedData(stream); } } } } /** * Handles the deserialization of a single element of the table. * * @param stream the object input stream from which to read the object. * @return the deserialized object * @throws ClassNotFoundException if a class cannot be found. * @throws java.io.IOException Any of the usual Input/Output related * exceptions. */ protected Object readSerializedData(final ObjectInputStream stream) throws ClassNotFoundException, IOException { return stream.readObject(); } /** * Clears the table. */ public void clear() { this.rows = 0; this.columns = 0; for (int i = 0; i < this.data.length; i++) { if (this.data[i] != null) { Arrays.fill(this.data[i], null); } } } /** * Copys the contents of the old column to the new column. * * @param oldColumn the index of the old (source) column * @param newColumn the index of the new column */ protected void copyColumn(final int oldColumn, final int newColumn) { for (int i = 0; i < getRowCount(); i++) { setObject(i, newColumn, getObject(i, oldColumn)); } } /** * Copys the contents of the old row to the new row. This uses raw access to * the data and is remarkably faster than manual copying. * * @param oldRow the index of the old row * @param newRow the index of the new row */ protected void copyRow(final int oldRow, final int newRow) { this.ensureCapacity(newRow, getColumnCount()); final Object[] oldRowStorage = this.data[oldRow]; if (oldRowStorage == null) { final Object[] newRowStorage = this.data[newRow]; if (newRowStorage != null) { Arrays.fill(newRowStorage, null); } } else { this.data[newRow] = (Object[]) oldRowStorage.clone(); } } /** * Replaces the data in the table with the given two-dimensional array. For performance reasons, the array is added as * is without cloning it, so make sure that you either clone it up-front or risk instable objects. * * @param data the array to be used as new data array * @param colCount the column count in the array. * @noinspection AssignmentToCollectionOrArrayFieldFromParameter for performance reasons as this is an internal method */ protected void setData(final Object[][] data, final int colCount) { if (data == null) { throw new NullPointerException(); } if (colCount < 0) { throw new IndexOutOfBoundsException(); } this.data = data; this.rows = data.length; this.columns = colCount; } /** * Clears the row by removing the array that stores the row-data. This reduces the in-memory size of the table * at the cost of possibly having to recreate the row-data-array later. * * @param row the row to be deleted. */ public void clearRow(final int row) { if (data.length <= row) { return; } this.data[row] = null; } /** * Returns the data-storage as raw-object. You better do not modify the data-storage unless you are absolutely * sure about what you are doing. * * @return the data as raw-object. */ protected Object[][] getData() { return data; } } libbase-1.1.6/source/org/pentaho/reporting/libraries/base/util/ClassQueryTool.java0000644000175000017500000002145211365604666027002 0ustar renerene/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2007 - 2009 Pentaho Corporation and Contributors. All rights reserved. */ package org.pentaho.reporting.libraries.base.util; import java.io.File; import java.io.IOException; import java.net.URL; import java.net.URLClassLoader; import java.util.ArrayList; import java.util.StringTokenizer; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * The class-query tool loads classes using a classloader and calls "processClass" for each class encountered. This is * highly expensive and sometimes dangerous excercise as the classloading may trigger static initializers and may * exhaust the "permgen" space of the Virtual machine. * * If possible anyhow, do not use this class. * * @author Thomas Morgner */ public abstract class ClassQueryTool { /** A logger. */ private static final Log logger = LogFactory.getLog(ClassQueryTool.class); /** * The default constructor. */ protected ClassQueryTool() { } /** * Processes a single class-file entry. The method will try to load the given entry as java-class and if that * successeds will then call the "processClass" method to let the real implementation handle the class. * * @param classLoader the classloader that should be used for class- and resource loading. * @param entryName the file name in the classpath. */ protected void processEntry(final ClassLoader classLoader, final String entryName) { if (entryName == null) { throw new NullPointerException(); } if (classLoader == null) { throw new NullPointerException(); } if (entryName.endsWith(".class") == false) { return; } final String className = entryName.substring(0, entryName.length() - 6).replace('/', '.'); if (isValidClass(className) == false) { return; } try { final Class c = Class.forName(className, false, classLoader); processClass(classLoader, c); } catch (NoClassDefFoundError ndef) { // Ignore silently. This happens a lot if the classpath is incomplete. } catch (Throwable e) { // ignore .. logger.debug("At class '" + className + "': " + e); } } /** * Checks, whether the class is valid. If the class-name is not considered valid by this method, the class will * not be processed. Use this to pre-filter the class-stream as loading classes is expensive. * * @param className the name of the class. * @return true, if the class should be processed, false otherwise. */ protected boolean isValidClass(final String className) { return true; } /** * The handler method that is called for every class encountered on the classpath. * * @param classLoader the classloader used to load the class. * @param c the class that should be handled. */ protected abstract void processClass(final ClassLoader classLoader, final Class c); /** * Processes a single jar file. The Jar file is processed in the order of the entries contained within the * ZIP-directory. * * @param classLoader the classloader * @param jarFile the URL pointing to the jar file to be parsed. */ private void processJarFile(final ClassLoader classLoader, final URL jarFile) { try { final ZipInputStream zf = new ZipInputStream(jarFile.openStream()); ZipEntry ze; while ((ze = zf.getNextEntry()) != null) { if (!ze.isDirectory()) { processEntry(classLoader, ze.getName()); } } zf.close(); } catch (final IOException e1) { logger.debug("Caught IO-Exception while processing file " + jarFile, e1); } } /** * Processes all entries from a given directory, ignoring any subdirectory contents. * If the directory contains sub-directories these directories are not searched for JAR or ZIP files. *

* In addition to the directory given as parameter, the direcories and JAR/ZIP-files on the classpath are also * searched for entries. *

* If directory is null, only the classpath is searched. * * @param directory the directory to be searched, or null to just use the classpath. * @throws IOException if an error occured while loading the resources from the directory. * @throws SecurityException if access to the system properties or access to the classloader is restricted. * @noinspection AccessOfSystemProperties */ public void processDirectory(final File directory) throws IOException { final ArrayList allURLs = new ArrayList(); final ArrayList jarURLs = new ArrayList(); final ArrayList directoryURLs = new ArrayList(); final String classpath = System.getProperty("java.class.path"); final String pathSeparator = System.getProperty("path.separator"); final StringTokenizer tokenizer = new StringTokenizer(classpath, pathSeparator); while (tokenizer.hasMoreTokens()) { final String pathElement = tokenizer.nextToken(); final File directoryOrJar = new File(pathElement); final File file = directoryOrJar.getAbsoluteFile(); if (file.isDirectory() && file.exists() && file.canRead()) { allURLs.add(file.toURL()); directoryURLs.add(file); continue; } if (!file.isFile() || (file.exists() == false) || (file.canRead() == false)) { continue; } final String fileName = file.getName(); if (fileName.endsWith(".jar") || fileName.endsWith(".zip")) { allURLs.add(file.toURL()); jarURLs.add(file.toURL()); } } if (directory != null && directory.isDirectory()) { final File[] driverFiles = directory.listFiles(); for (int i = 0; i < driverFiles.length; i++) { final File file = driverFiles[i]; if (file.isDirectory() && file.exists() && file.canRead()) { allURLs.add(file.toURL()); directoryURLs.add(file); continue; } if (!file.isFile() || (file.exists() == false) || (file.canRead() == false)) { continue; } final String fileName = file.getName(); if (fileName.endsWith(".jar") || fileName.endsWith(".zip")) { allURLs.add(file.toURL()); jarURLs.add(file.toURL()); } } } final URL[] urlsArray = (URL[]) jarURLs.toArray(new URL[jarURLs.size()]); final File[] dirsArray = (File[]) directoryURLs.toArray(new File[directoryURLs.size()]); final URL[] allArray = (URL[]) allURLs.toArray(new URL[allURLs.size()]); for (int i = 0; i < allArray.length; i++) { final URL url = allArray[i]; logger.debug(url); } for (int i = 0; i < urlsArray.length; i++) { final URL url = urlsArray[i]; final URLClassLoader classLoader = new URLClassLoader(allArray); processJarFile(classLoader, url); } for (int i = 0; i < dirsArray.length; i++) { final File file = dirsArray[i]; final URLClassLoader classLoader = new URLClassLoader(allArray); processDirectory(classLoader, file, ""); } } /** * Processes all entries from a given directory. If the directory contains sub-directories these directories * are processed in recursive depth-first mannor. * * @param classLoader the classloader to be used for loading classes. * @param file the directory to be searched. * @param pathPrefix the path prefix used to construct absolute filenames within the classpath. */ private void processDirectory(final URLClassLoader classLoader, final File file, final String pathPrefix) { final File[] files = file.listFiles(); for (int i = 0; i < files.length; i++) { final File subFile = files[i]; if (subFile.exists() == false || subFile.canRead() == false) { continue; } if (subFile.isDirectory()) { processDirectory(classLoader, subFile, pathPrefix + subFile.getName() + '/'); } else if (subFile.isFile()) { processEntry(classLoader, pathPrefix + subFile.getName()); } } } } libbase-1.1.6/source/org/pentaho/reporting/libraries/base/versioning/0000755000175000017500000000000011365604664024406 5ustar renerenelibbase-1.1.6/source/org/pentaho/reporting/libraries/base/versioning/ProjectInformation.java0000644000175000017500000002164311365604664031073 0ustar renerene/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2007 - 2009 Pentaho Corporation and Contributors. All rights reserved. */ package org.pentaho.reporting.libraries.base.versioning; import java.lang.reflect.Method; import java.util.ArrayList; import org.pentaho.reporting.libraries.base.util.ObjectUtilities; /** * The project information structure contains information about the current project. This is an extended version * of the dependency information enriched with information about the boot-process and a list of dependencies. *

* This class needs to be subclassed by each project that wants to participate in the global boot process. * * @author Thomas Morgner */ public abstract class ProjectInformation extends DependencyInformation { private String copyright; private String bootClass; private ArrayList libraries; private ArrayList optionalLibraries; private VersionHelper versionHelper; private String internalName; /** * Creates a new project information object with the given name. * * @param name the name of the project, when internal and public names are equal. */ protected ProjectInformation(final String name) { this(name, name); } /** * Creates a new project information object with the given name. The internal name is used to lookup the * version information in the manifest file, while the public name is presented to the humans. * * @param internalName the internal name of the project. * @param publicName the public name of the project. */ protected ProjectInformation(final String internalName, final String publicName) { super(publicName); if (internalName == null) { this.internalName = publicName; } else { this.internalName = internalName; } this.libraries = new ArrayList(); optionalLibraries = new ArrayList(); } /** * Returs a version helper for this project. The version helper is used to extract the versioning information * from the manifest file of the project's JAR. * * @return the version helper, never null. */ private synchronized VersionHelper getVersionHelper() { if (versionHelper == null) { versionHelper = new VersionHelper(this); } return versionHelper; } /** * Returns the copyright string for thie project. * * @return the copyright string (might be null). */ public String getCopyright() { return copyright; } /** * Updates the copyright string for thie project. * * @param copyright the copyright string. */ protected void setCopyright(final String copyright) { this.copyright = copyright; } /** * Returns the internal name of the project. * * @return the internal name, never null. */ public String getInternalName() { return internalName; } /** * Returns the boot class. * * @return the bootclass (might be null). */ public String getBootClass() { return bootClass; } /** * Redefines the boot class. * * @param bootClass the bootclass (might be null). */ protected void setBootClass(final String bootClass) { this.bootClass = bootClass; } /** * Returns a list of libraries used by the project. * * @return the list of libraries. */ public DependencyInformation[] getLibraries() { return (DependencyInformation[]) this.libraries.toArray (new DependencyInformation[this.libraries.size()]); } /** * Adds a library. * * @param library the library. */ public void addLibrary(final DependencyInformation library) { if (library == null) { throw new NullPointerException(); } if (this.libraries.contains(library)) { throw new NullPointerException(); } this.libraries.add(library); } /** * Returns a list of optional libraries used by the project. * * @return the list of libraries. */ public DependencyInformation[] getOptionalLibraries() { return (DependencyInformation[]) optionalLibraries.toArray(new DependencyInformation[optionalLibraries.size()]); } /** * Adds an optional library. These libraries will be booted, if they define a boot class. A missing class is * considered non-fatal and it is assumed that the programm knows how to handle that. * * @param libraryClass the library. */ protected void addOptionalLibrary(final String libraryClass) { if (libraryClass == null) { throw new NullPointerException("Library classname must be given."); } final DependencyInformation depInfo = loadLibrary(libraryClass); if (depInfo != null) { this.optionalLibraries.add(depInfo); } } /** * Tries to load the dependency information for the given class. * * @param classname the classname of the class that contains the public static * DependencyInformation getInstance() method. * @return the dependency information for the library or null, if the library's project-info class could not be loaded. */ private DependencyInformation loadLibrary(final String classname) { if (classname == null) { return null; } try { final ClassLoader loader = ObjectUtilities.getClassLoader(getClass()); final Class c = Class.forName(classname, false, loader); try { // This cast is necessary for JDK 1.5 or later //noinspection RedundantCast final Method m = c.getMethod("getInstance", (Class[]) null); return (DependencyInformation) m.invoke(null, (Object[]) null); } catch (Exception e) { // ok, fall back ... } return (DependencyInformation) c.newInstance(); } catch (Exception e) { // ok, this library has no 'getInstance()' method. Check the // default constructor ... return null; } } /** * Adds an optional library. These libraries will be booted, if they define a boot class. A missing class is * considered non-fatal and it is assumed that the programm knows how to handle that. * * @param library the library. */ protected void addOptionalLibrary(final DependencyInformation library) { if (library == null) { throw new NullPointerException("Library must be given."); } this.optionalLibraries.add(library); } /** * Returns the version number from the Manifest. * * @return the version, or null if no version information is known. */ public String getVersion() { return getVersionHelper().getVersion(); } /** * Returns the product ID from the Manifest. * * @return the product ID, or null if none is specified in the manifest. */ public String getProductId() { return getVersionHelper().getProductId(); } /** * Returns the release milestone number from the Manifest. * * @return the release milestone number, or null if none is specified in the manifest. */ public String getReleaseMilestone() { return getVersionHelper().getReleaseMilestone(); } /** * Returns the release minor version number from the Manifest. * * @return the release minor version number, or null if none is specified in the manifest. */ public String getReleaseMinor() { return getVersionHelper().getReleaseMinor(); } /** * Returns the release major version number from the Manifest. * * @return the release major version number, or null if none is specified in the manifest. */ public String getReleaseMajor() { return getVersionHelper().getReleaseMajor(); } /** * Returns the release candidate token from the Manifest. * * @return the release candidate token, or null if none is specified in the manifest. */ public String getReleaseCandidateToken() { return getVersionHelper().getReleaseCandidateToken(); } /** * Returns the release number from the Manifest. * * @return the release number, or null if none is specified in the manifest. */ public String getReleaseNumber() { return getVersionHelper().getReleaseNumber(); } /** * Returns the release build number from the Manifest. * * @return the release build number, or null if none is specified in the manifest. */ public String getReleaseBuildNumber() { return versionHelper.getReleaseBuildNumber(); } } libbase-1.1.6/source/org/pentaho/reporting/libraries/base/versioning/VersionHelper.java0000644000175000017500000002067011365604664030043 0ustar renerene/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2007 - 2009 Pentaho Corporation and Contributors. All rights reserved. */ package org.pentaho.reporting.libraries.base.versioning; import java.io.InputStream; import java.net.URL; import java.util.Enumeration; import java.util.jar.Attributes; import java.util.jar.Manifest; import org.pentaho.reporting.libraries.base.util.ObjectUtilities; /** * A utility class for reading versioning information from a Manifest file. * * @author Thomas Morgner */ public class VersionHelper { private String version; private String title; private String productId; private String releaseMilestone; private String releaseMinor; private String releaseMajor; private String releaseCandidateToken; private String releaseNumber; private String releaseBuildNumber; private ProjectInformation projectInformation; /** * Loads the versioning information for the given project-information structure using the project information's * internal name as lookup key. * * @param projectInformation the project we load information for. */ public VersionHelper(final ProjectInformation projectInformation) { if (projectInformation == null) { throw new NullPointerException(); } this.projectInformation = projectInformation; final ClassLoader loader = projectInformation.getClass().getClassLoader(); try { final Enumeration resources = loader.getResources("META-INF/MANIFEST.MF"); while (resources.hasMoreElements()) { final URL url = (URL) resources.nextElement(); final InputStream inputStream = url.openStream(); try { if (init(inputStream)) { return; } } finally { inputStream.close(); } } } catch (Exception e) { // Ignore; Maybe log. } } /** * Initializes the instance, reaading the properties from the input stream. * * @param input the input stream. * @return true, if the manifest contains version information about this library, false otherwise. */ private boolean init(final InputStream input) { if (input == null) { return false; } try { final Manifest props = new Manifest(input); final Attributes attr = getAttributes(props, projectInformation.getInternalName()); final String maybeTitle = getValue(attr, "Implementation-ProductID", null); if (ObjectUtilities.equal(projectInformation.getInternalName(), maybeTitle) == false) { return false; } title = getValue(attr, "Implementation-Title", maybeTitle); releaseMajor = getValue(attr, "Release-Major-Number", "0"); releaseMinor = getValue(attr, "Release-Minor-Number", "0"); releaseMilestone = getValue(attr, "Release-Milestone-Number", "0"); releaseCandidateToken = getValue(attr, "Release-Candidate-Token", ""); releaseBuildNumber = getValue(attr, "Release-Build-Number", ""); releaseNumber = getValue(attr, "Release-Number", ""); if (releaseNumber.length() == 0) { releaseNumber = createReleaseVersion(); } version = getValue(attr, "Implementation-Version", ""); if (version.length() == 0) { version = createVersion(); } productId = maybeTitle; if (productId.length() == 0) { productId = createProductId(); } return true; } catch (final Exception e) { return false; } } /** * Looks up the attributes for the given module specified by name in the given Manifest. * * @param props the manifest where to search for the attributes. * @param name the name of the module. * @return the attributes for the module or the main attributes if the jar contains no such module. */ private Attributes getAttributes(final Manifest props, final String name) { final Attributes attributes = props.getAttributes(name); if (attributes == null) { return props.getMainAttributes(); } return attributes; } /** * Looks up a single value in the given attribute collection using the given key. If the key is not contained in * the attributes, this method returns the default value specified as parameter. * * @param attrs the attributes where to lookup the key. * @param name the name of the key to use for the lookup. * @param defaultValue the default value to return in case the attributes contain no such key. * @return the value from the attributes or the default values. */ private String getValue(final Attributes attrs, final String name, final String defaultValue) { final String value = attrs.getValue(name); if (value == null) { return defaultValue; } return value.trim(); } /** * Creates a product-id string, which is the implementation title plus the optional version information. * * @return the product id string. */ private String createProductId() { if (version.trim().length() == 0) { return title; } return title + '-' + version; } /** * Creates a version string using only the major, minor and milestone version information. * * @return the version. */ private String createVersion() { final StringBuffer buffer = new StringBuffer(50); buffer.append(releaseMajor); buffer.append('.'); buffer.append(releaseMinor); buffer.append('.'); buffer.append(releaseMilestone); return buffer.toString(); } /** * Creates a version string using the major, minor and milestone version information and the build number. * * @return the release version. */ private String createReleaseVersion() { final StringBuffer buffer = new StringBuffer(50); buffer.append(releaseMajor); buffer.append('.'); buffer.append(releaseMinor); buffer.append('.'); buffer.append(releaseMilestone); if (releaseCandidateToken.length() > 0) { buffer.append('-'); buffer.append(releaseCandidateToken); } if (releaseBuildNumber.length() > 0) { buffer.append(" (Build "); buffer.append(releaseBuildNumber); buffer.append(')'); } return buffer.toString(); } /** * Returns the full version string as computed by createVersion(). * * @return the version string. * @see #createVersion() */ public String getVersion() { return version; } /** * Returns the implementation title as specified in the manifest. * * @return the implementation title. */ public String getTitle() { return title; } /** * Returns the product id as computed by createProductId(). * * @return the product id. * @see #createProductId() */ public String getProductId() { return productId; } /** * Returns the release milestone number. * * @return the milestone number. */ public String getReleaseMilestone() { return releaseMilestone; } /** * Returns the release minor number. * * @return the minor version number. */ public String getReleaseMinor() { return releaseMinor; } /** * Returns the release major number. * * @return the major version number. */ public String getReleaseMajor() { return releaseMajor; } /** * Returns the release candidate token. * * @return the candidate token. */ public String getReleaseCandidateToken() { return releaseCandidateToken; } /** * Returns the release number. * * @return the release number. */ public String getReleaseNumber() { return releaseNumber; } /** * Returns the release build number. * * @return the build-number). */ public String getReleaseBuildNumber() { return releaseBuildNumber; } } libbase-1.1.6/source/org/pentaho/reporting/libraries/base/versioning/DependencyInformation.java0000644000175000017500000001074111365604664031540 0ustar renerene/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2007 - 2009 Pentaho Corporation and Contributors. All rights reserved. */ package org.pentaho.reporting.libraries.base.versioning; /** * An data-structure documenting external dependencies. Use this in your ProjectInformation implementation to * tell users what other libraries you use to give them proper credit. * * @author : Thomas Morgner */ public class DependencyInformation { /** The name of the library. */ private String name; /** The version of the library, if known. */ private String version; /** The license the library is distributed under. */ private String licenseName; /** Some more information, liek a web-site or comment. */ private String info; /** * Creates a minimal dependency information object for the library with the given name. * * @param name the name of the library, never null. */ public DependencyInformation(final String name) { if (name == null) { throw new NullPointerException("Name must be given"); } this.name = name; } /** * Creates a minimal dependency information object for the library with the given name. All properties but the name * are optional. * * @param name the name of the library, never null. * @param version The version of the library, if known. * @param licenseName The license the library is distributed under. * @param info Some more information, liek a web-site or comment. */ public DependencyInformation(final String name, final String version, final String licenseName, final String info) { this(name); this.version = version; this.licenseName = licenseName; this.info = info; } /** * Redefines the version of the dependency. * * @param version the version. */ protected void setVersion(final String version) { this.version = version; } /** * Redefines the license name of the dependency. * * @param licenseName the name of the license. */ protected void setLicenseName(final String licenseName) { this.licenseName = licenseName; } /** * Redefines the extra information of the dependency. * * @param info the version. */ protected void setInfo(final String info) { this.info = info; } /** * Returns the name of the dependency, which is never null. * * @return the name. */ public String getName() { return name; } /** * Returns the version number. * * @return the version information, or null if no version information is known. */ public String getVersion() { return version; } /** * Returns the name of the license of this dependency. * * @return the license name. */ public String getLicenseName() { return licenseName; } /** * Returns the extra information. * * @return the text information, or null if no extra information is known. */ public String getInfo() { return info; } /** * Tests this object for equality. The object is equal if the name matches, the extra information is ignored. * * @param o the other object. * @return true, if the dependency information given denotes the same library as this dependency information. */ public boolean equals(final Object o) { if (this == o) { return true; } if (!(o instanceof DependencyInformation)) { return false; } final DependencyInformation that = (DependencyInformation) o; if (!name.equals(that.name)) { return false; } return true; } /** * Computes a hashcode based on the name of the dependency. * * @return the hashcode. */ public int hashCode() { return name.hashCode(); } } libbase-1.1.6/source/org/pentaho/reporting/libraries/base/versioning/Licenses.java0000644000175000017500000015160011365604664027021 0ustar renerene/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2007 - 2009 Pentaho Corporation and Contributors. All rights reserved. */ package org.pentaho.reporting.libraries.base.versioning; /** * Contains the full texts of the GNU General Public Licence and the GNU Lesser General Public * Licence. *

* These are used in the presentation of a standard 'About' frame. * * @author David Gilbert */ public class Licenses { /** * Private constructor prevents object creation. */ private Licenses() { } /** * The GNU General Public Licence. */ public static final String GPL = "GNU GENERAL PUBLIC LICENSE\n" + '\n' + "Version 2, June 1991\n" + '\n' + "Copyright (C) 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave, Cambridge, " + "MA 02139, USA. Everyone is permitted to copy and distribute verbatim copies of this " + "license document, but changing it is not allowed.\n" + '\n' + "Preamble\n" + "The licenses for most software are designed to take away your freedom to share and " + "change it. By contrast, the GNU General Public License is intended to guarantee your " + "freedom to share and change free software--to make sure the software is free for all " + "its users. This General Public License applies to most of the Free Software " + "Foundation's software and to any other program whose authors commit to using it. (Some " + "other Free Software Foundation software is covered by the GNU Library General Public " + "License instead.) You can apply it to your programs, too.\n" + '\n' + "When we speak of free software, we are referring to freedom, 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 or use " + "pieces of it in new free programs; and that you know you can do these things." + '\n' + "To protect your rights, we need to make restrictions that forbid anyone to deny you " + "these rights or to ask you to surrender the rights. These restrictions translate to " + "certain responsibilities for you if you distribute copies of the software, or if you " + "modify it.\n" + '\n' + "For example, if you distribute copies of such a program, whether gratis or for a fee, " + "you must give the recipients all the rights that you have. You must make sure that " + "they, too, receive or can get the source code. And you must show them these terms so " + "they know their rights.\n" + '\n' + "We protect your rights with two steps: (1) copyright the software, and (2) offer you " + "this license which gives you legal permission to copy, distribute and/or modify the " + "software.\n" + '\n' + "Also, for each author's protection and ours, we want to make certain that everyone " + "understands that there is no warranty for this free software. If the software is " + "modified by someone else and passed on, we want its recipients to know that what they " + "have is not the original, so that any problems introduced by others will not reflect " + "on the original authors' reputations.\n" + '\n' + "Finally, any free program is threatened constantly by software patents. We wish to " + "avoid the danger that redistributors of a free program will individually obtain patent " + "licenses, in effect making the program proprietary. To prevent this, we have made it " + "clear that any patent must be licensed for everyone's free use or not licensed at " + "all.\n" + '\n' + "The precise terms and conditions for copying, distribution and modification follow.\n" + '\n' + "GNU GENERAL PUBLIC LICENSE\n" + "TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n" + '\n' + "0. This License applies to any program or other work which contains a notice placed by " + "the copyright holder saying it may be distributed under the terms of this General " + "Public License. The \"Program\", below, refers to any such program or work, and a " + "\"work based on the Program\" means either the Program or any derivative work under " + "copyright law: that is to say, a work containing the Program or a portion of it, " + "either verbatim or with modifications and/or translated into another language. " + "(Hereinafter, translation is included without limitation in the term " + "\"modification\".) Each licensee is addressed as \"you\".\n" + '\n' + "Activities other than copying, distribution and modification are not covered by this " + "License; they are outside its scope. The act of running the Program is not restricted, " + "and the output from the Program is covered only if its contents constitute a work " + "based on the Program (independent of having been made by running the Program). Whether " + "that is true depends on what the Program does.\n" + '\n' + "1. You may copy and distribute verbatim copies of the Program's 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 " + "give any other recipients of the Program a copy of this License along with the " + "Program.\n" + '\n' + "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.\n" + '\n' + "2. You may modify your copy or copies of the Program or any portion of it, thus " + "forming a work based on the Program, and copy and distribute such modifications or " + "work under the terms of Section 1 above, provided that you also meet all of these " + "conditions:\n" + '\n' + "a) You must cause the modified files to carry prominent notices stating that you " + "changed the files and the date of any change.\n" + '\n' + "b) You must cause any work that you distribute or publish, that in whole or in part " + "contains or is derived from the Program or any part thereof, to be licensed as a whole " + "at no charge to all third parties under the terms of this License.\n" + '\n' + "c) If the modified program normally reads commands interactively when run, you must " + "cause it, when started running for such interactive use in the most ordinary way, to " + "print or display an announcement including an appropriate copyright notice and a " + "notice that there is no warranty (or else, saying that you provide a warranty) and " + "that users may redistribute the program under these conditions, and telling the user " + "how to view a copy of this License. (Exception: if the Program itself is interactive " + "but does not normally print such an announcement, your work based on the Program is " + "not required to print an announcement.)\n" + '\n' + "These requirements apply to the modified work as a whole. If identifiable sections of " + "that work are not derived from the Program, 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 Program, " + "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.\n" + '\n' + "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 Program.\n" + '\n' + "In addition, mere aggregation of another work not based on the Program with the " + "Program (or with a work based on the Program) on a volume of a storage or distribution " + "medium does not bring the other work under the scope of this License.\n" + '\n' + "3. You may copy and distribute the Program (or a work based on it, under Section 2) in " + "object code or executable form under the terms of Sections 1 and 2 above provided that " + "you also do one of the following:\n" + '\n' + "a) 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; or,\n" + "b) Accompany it with a written offer, valid for at least three years, to give any " + "third party, for a charge no more than your cost of physically performing source " + "distribution, a complete machine-readable copy of the corresponding source code, to be " + "distributed under the terms of Sections 1 and 2 above on a medium customarily used for " + "software interchange; or,\n" + "c) Accompany it with the information you received as to the offer to distribute " + "corresponding source code. (This alternative is allowed only for noncommercial " + "distribution and only if you received the program in object code or executable form " + "with such an offer, in accord with Subsection b above.)\n" + '\n' + "The source code for a work means the preferred form of the work for making " + "modifications to it. For an executable work, 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 executable. However, " + "as a special exception, the source code 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.\n" + '\n' + "If distribution of executable or 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 counts as distribution of the source code, even though third parties are " + "not compelled to copy the source along with the object code.\n" + '\n' + "4. You may not copy, modify, sublicense, or distribute the Program except as expressly " + "provided under this License. Any attempt otherwise to copy, modify, sublicense or " + "distribute the Program 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." + '\n' + "5. 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 Program or its " + "derivative works. These actions are prohibited by law if you do not accept this " + "License. Therefore, by modifying or distributing the Program (or any work based on the " + "Program), you indicate your acceptance of this License to do so, and all its terms and " + "conditions for copying, distributing or modifying the Program or works based on it.\n" + '\n' + "6. Each time you redistribute the Program (or any work based on the Program), the " + "recipient automatically receives a license from the original licensor to copy, " + "distribute or modify the Program 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 to this " + "License." + '\n' + "7. 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 " + "Program at all. For example, if a patent license would not permit royalty-free " + "redistribution of the Program 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 Program.\n" + '\n' + "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.\n" + '\n' + "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.\n" + '\n' + "This section is intended to make thoroughly clear what is believed to be a consequence " + "of the rest of this License.\n" + '\n' + "8. If the distribution and/or use of the Program is restricted in certain countries " + "either by patents or by copyrighted interfaces, the original copyright holder who " + "places the Program 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.\n" + '\n' + "9. The Free Software Foundation may publish revised and/or new versions of the 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.\n" + '\n' + "Each version is given a distinguishing version number. If the Program 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 Program does not " + "specify a version number of this License, you may choose any version ever published by " + "the Free Software Foundation.\n" + '\n' + "10. If you wish to incorporate parts of the Program into other free programs whose " + "distribution conditions are different, 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.\n" + '\n' + "NO WARRANTY\n" + '\n' + "11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE " + "PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN " + "WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM \"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 PROGRAM IS WITH YOU. SHOULD " + "THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR " + "CORRECTION.\n" + '\n' + "12. 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 PROGRAM 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 " + "PROGRAM (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 PROGRAM TO OPERATE " + "WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE " + "POSSIBILITY OF SUCH DAMAGES.\n" + '\n' + "END OF TERMS AND CONDITIONS\n" + '\n' + '\n' + "How to Apply These Terms to Your New Programs\n" + '\n' + "If you develop a new program, and you want it to be of the greatest possible use to " + "the public, the best way to achieve this is to make it free software which everyone " + "can redistribute and change under these terms.\n" + '\n' + "To do so, attach the following notices to the program. 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.\n" + '\n' + "\n" + "Copyright (C) \n" + '\n' + "This program is free software; you can redistribute it and/or modify it under the " + "terms of the GNU General Public License as published by the Free Software Foundation; " + "either version 2 of the License, or (at your option) any later version.\n" + '\n' + "This program 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 General Public License for more details.\n" + '\n' + "You should have received a copy of the GNU General Public License along with this " + "program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite " + "330, Boston, MA 02111-1307 USA\n" + '\n' + "Also add information on how to contact you by electronic and paper mail.\n" + '\n' + "If the program is interactive, make it output a short notice like this when it starts " + "in an interactive mode:\n" + '\n' + "Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with " + "ABSOLUTELY NO WARRANTY; for details type `show w'.\n" + "This is free software, and you are welcome to redistribute it under certain " + "conditions; type `show c' for details.\n" + '\n' + "The hypothetical commands `show w' and `show c' should show the appropriate parts of " + "the General Public License. Of course, the commands you use may be called something " + "other than `show w' and `show c'; they could even be mouse-clicks or menu items" + "--whatever suits your program.\n" + '\n' + "You should also get your employer (if you work as a programmer) or your school, if " + "any, to sign a \"copyright disclaimer\" for the program, if necessary. Here is a " + "sample; alter the names:\n" + '\n' + "Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' " + "(which makes passes at compilers) written by James Hacker.\n" + '\n' + ", 1 April 1989\n" + "Ty Coon, President of Vice\n" + '\n' + "This General Public License does not permit incorporating your program into " + "proprietary programs. If your program is a subroutine library, you may consider it " + "more useful to permit linking proprietary applications with the library. If this is " + "what you want to do, use the GNU Library General Public License instead of this " + "License.\n"; /** * The GNU Lesser General Public Licence. */ public static final String LGPL = "GNU LESSER GENERAL PUBLIC LICENSE\n" + '\n' + "Version 2.1, February 1999\n" + '\n' + "Copyright (C) 1991, 1999 Free Software Foundation, Inc.\n" + "59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\n" + "Everyone is permitted to copy and distribute verbatim copies of this license document, " + "but changing it is not allowed.\n" + '\n' + "[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.]\n" + '\n' + "Preamble\n" + '\n' + "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.\n" + '\n' + "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.\n" + '\n' + "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.\n" + '\n' + "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.\n" + '\n' + "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.\n" + '\n' + "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.\n" + '\n' + "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.\n" + '\n' + "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.\n" + '\n' + "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.\n" + '\n' + "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.\n" + '\n' + "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.\n" + '\n' + "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.\n" + '\n' + "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.\n" + '\n' + "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.\n" + '\n' + "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.\n" + '\n' + "TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n" + '\n' + "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\"." + '\n' + "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.\n" + '\n' + "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\".)\n" + '\n' + "\"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.\n" + '\n' + "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." + '\n' + "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.\n" + '\n' + "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.\n" + '\n' + "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:\n" + '\n' + "* a) The modified work must itself be a software library.\n" + "* b) You must cause the files modified to carry prominent notices stating that you " + "changed the files and the date of any change.\n" + "* 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.\n" + "* 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.\n" + '\n' + "(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.)\n" + '\n' + "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.\n" + '\n' + "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.\n" + '\n' + "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.\n" + '\n' + "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.\n" + '\n' + "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.\n" + '\n' + "This option is useful when you wish to copy part of the code of the Library into a " + "program that is not a library.\n" + '\n' + "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.\n" + '\n' + "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.\n" + '\n' + "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.\n" + '\n' + "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.\n" + '\n' + "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.\n" + '\n' + "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.)\n" + '\n' + "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.\n" + '\n' + "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.\n" + '\n' + "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:\n" + '\n' + "* 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.)\n" + "* 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.\n" + "* 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.\n" + "* 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.\n" + "* e) Verify that the user has already received a copy of these materials or that " + "you have already sent this user a copy.\n" + '\n' + "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.\n" + '\n' + "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.\n" + '\n' + "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:\n" + '\n' + "* 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.\n" + "* 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.\n" + '\n' + "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.\n" + '\n' + "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.\n" + '\n' + "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.\n" + '\n' + "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.\n" + '\n' + "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.\n" + '\n' + "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.\n" + '\n' + "This section is intended to make thoroughly clear what is believed to be a consequence " + "of the rest of this License.\n" + '\n' + "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.\n" + '\n' + "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.\n" + '\n' + "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.\n" + '\n' + "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.\n" + '\n' + "NO WARRANTY\n" + '\n' + "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.\n" + '\n' + "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.\n" + '\n' + "END OF TERMS AND CONDITIONS\n" + '\n' + '\n' + "How to Apply These Terms to Your New Libraries\n" + '\n' + "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).\n" + '\n' + "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.\n" + '\n' + "\n" + "Copyright (C) \n" + '\n' + "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.\n" + '\n' + "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.\n" + '\n' + "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\n" + '\n' + "Also add information on how to contact you by electronic and paper mail.\n" + '\n' + "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:\n" + '\n' + "Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a " + "library for tweaking knobs) written by James Random Hacker.\n" + '\n' + ", 1 April 1990\n" + "Ty Coon, President of Vice\n" + '\n' + "That's all there is to it!\n"; /** * The singleton instance of this class. */ private static Licenses singleton; /** * Returns a reference to this class. * * @return the instance reference. */ public static synchronized Licenses getInstance() { if (singleton == null) { singleton = new Licenses(); } return singleton; } /** * Returns the GPL text in a non static way to prevent the compiler * to copy the contents of the field. * * @return the GPL licence text. */ public String getGPL() { return GPL; } /** * Returns the LGPL text in a non static way to prevent the compiler * to copy the contents of the field. * * @return the LGPL licence text. */ public String getLGPL() { return LGPL; } }libbase-1.1.6/source/org/pentaho/reporting/libraries/base/LibBaseInfo.java0000644000175000017500000000424511365604666025212 0ustar renerene/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2007 - 2009 Pentaho Corporation and Contributors. All rights reserved. */ package org.pentaho.reporting.libraries.base; import org.pentaho.reporting.libraries.base.versioning.ProjectInformation; /** * The project information for LibBase. * * @author Thomas Morgner * @noinspection UseOfSystemOutOrSystemErr */ public final class LibBaseInfo extends ProjectInformation { /** A singleton variable for the info-class. */ private static LibBaseInfo info; /** * Returns a singleton instance of the LibBase project information structure. * * @return the LibBase project information. */ public static synchronized ProjectInformation getInstance() { if (info == null) { info = new LibBaseInfo(); info.initialize(); } return info; } /** * Private constructor to prevent object creation. */ private LibBaseInfo() { super("libbase", "LibBase"); } /** * Initializes the project info. */ private void initialize() { setBootClass(LibBaseBoot.class.getName()); setLicenseName("LGPL"); setInfo("http://reporting.pentaho.org/libbase/"); setCopyright("(C)opyright 2007-2010, by Pentaho Corporation and Contributors"); } /** * The main method can be used to check the version of the code. * * @param args not used. */ public static void main(final String[] args) { System.out.println(getInstance().getVersion()); } } libbase-1.1.6/README.txt0000644000175000017500000000375011365604666013304 0ustar renerene**************************************************** * LibBase - A general purpose base service library * **************************************************** 30 May 2008 1. INTRODUCTION --------------- LibBase is a library developed to provide base services like logging, configuration and initialization to all other libraries and applications. The library is the root library for all other Pentaho-Reporting projects. For the latest news and information about LibBase, please refer to: http://reporting.pentaho.org/libbase 2. SUPPORT ---------- Free support is available via the Pentaho Reporting forum, follow the link from the LibBase home page. Please note that questions are answered by volunteers, so there is no guaranteed response time or level of service. Please avoid e-mailing the developers directly for support questions. If you post a message in the forum, then everyone can see the question, and everyone can see the answer. The forum is available at http://forums.pentaho.org/ 3. REPORTING BUGS ----------------- If you find bugs in LibBase, we'd like to hear about it so that we can improve future releases of LibBase. Please post a bug report in our JIRA bug-tracking system at: http://jira.pentaho.org/browse/PRE Please be sure to provide as much information as you can. We need to know the version of LibBase that you are using, the JDK version, and the steps required to replicate the bug. Include any other information that you think is relevant. 4. ANT ------ We use an open source build tool called Ant to build LibBase. An Ant script (tested using Ant 1.6) is included in the distribution: /build.xml You can find out more about Ant at: http://ant.apache.org/ Ant is licensed under the terms of the Apache Software License (a popular open source software license). 5. OTHER FEEDBACK ----------------- For other feedback and comments, please post a message on the Pentaho forums. The Forum is available at http://forums.pentaho.org/ libbase-1.1.6/ivy.xml0000644000175000017500000000170511365604666013135 0ustar renerene libbase-1.1.6/test-lib/0000755000175000017500000000000011640443162013310 5ustar renerenelibbase-1.1.6/testcases/0000755000175000017500000000000011365604666013577 5ustar renerenelibbase-1.1.6/testcases/org/0000755000175000017500000000000011365604666014366 5ustar renerenelibbase-1.1.6/testcases/org/pentaho/0000755000175000017500000000000011365604666016024 5ustar renerenelibbase-1.1.6/testcases/org/pentaho/reporting/0000755000175000017500000000000011365604666020035 5ustar renerenelibbase-1.1.6/testcases/org/pentaho/reporting/libraries/0000755000175000017500000000000011365604666022011 5ustar renerenelibbase-1.1.6/testcases/org/pentaho/reporting/libraries/base/0000755000175000017500000000000011365604666022723 5ustar renerenelibbase-1.1.6/testcases/org/pentaho/reporting/libraries/base/encoder/0000755000175000017500000000000011365604666024342 5ustar renerenelibbase-1.1.6/testcases/org/pentaho/reporting/libraries/base/encoder/ImageEncoderTest.java0000644000175000017500000000452211365604666030372 0ustar renerene/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2009 Pentaho Corporation. All rights reserved. */ package org.pentaho.reporting.libraries.base.encoder; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.IOException; import junit.framework.TestCase; /** * Todo: Document Me * * @author Thomas Morgner */ public class ImageEncoderTest extends TestCase { public ImageEncoderTest() { } public ImageEncoderTest(final String s) { super(s); } protected void setUp() throws Exception { } public void testPngEncoderAvailable() throws UnsupportedEncoderException, IOException { assertTrue(ImageEncoderRegistry.getInstance().isEncoderAvailable("image/png")); final ImageEncoder imageEncoder = ImageEncoderRegistry.getInstance().createEncoder("image/png"); assertNotNull(imageEncoder); final ByteArrayOutputStream bout = new ByteArrayOutputStream(); imageEncoder.encodeImage(new BufferedImage(10, 10, BufferedImage.TYPE_INT_ARGB), bout, 0.75f, false); assertTrue(bout.toByteArray().length > 0); } public void testJpegEncoderWorks() throws UnsupportedEncoderException, IOException { if (ImageEncoderRegistry.getInstance().isEncoderAvailable("image/jpg") == false) { return; } final ImageEncoder imageEncoder = ImageEncoderRegistry.getInstance().createEncoder("image/jpg"); assertNotNull(imageEncoder); final ByteArrayOutputStream bout = new ByteArrayOutputStream(); imageEncoder.encodeImage(new BufferedImage(10, 10, BufferedImage.TYPE_INT_ARGB), bout, 0.75f, false); assertTrue(bout.toByteArray().length > 0); } } libbase-1.1.6/testcases/org/pentaho/reporting/libraries/base/util/0000755000175000017500000000000011365604666023700 5ustar renerenelibbase-1.1.6/testcases/org/pentaho/reporting/libraries/base/util/BulkDataUtilityTest.java0000644000175000017500000000440411365604666030460 0ustar renerene/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2009 Pentaho Corporation. All rights reserved. */ package org.pentaho.reporting.libraries.base.util; import java.util.Arrays; import junit.framework.TestCase; /** * Todo: Document Me * * @author Thomas Morgner */ public class BulkDataUtilityTest extends TestCase { public BulkDataUtilityTest() { } public BulkDataUtilityTest(final String s) { super(s); } public void testPushUp() { final String[] vals1 = new String[]{"1", "2", "3", "4", "5", "6"}; final String[] vals2 = new String[]{"1", "2", "3", "4", "5", "6"}; final String[] result1 = new String[]{"1", "3", "4", "2", "6", "5"}; final String[] result2 = new String[]{"2", "3", "1", "4", "5", "6"}; final boolean[] sels1 = new boolean[]{true, false, true, true, false, true}; final boolean[] sels2 = new boolean[]{false, true, true, false, false, false}; final boolean[] ressels1 = new boolean[]{true, true, true, false, true, false}; final boolean[] ressels2 = new boolean[]{true, true, false, false, false, false}; BulkDataUtility.pushUp(vals1, sels1); BulkDataUtility.pushUp(vals2, sels2); if (Arrays.equals(vals1, result1) == false) { throw new NullPointerException(); } if (Arrays.equals(vals2, result2) == false) { throw new NullPointerException(); } if (Arrays.equals(sels1, ressels1) == false) { throw new NullPointerException(); } if (Arrays.equals(sels2, ressels2) == false) { throw new NullPointerException(); } } } libbase-1.1.6/testcases/org/pentaho/reporting/libraries/base/util/CSVTokenizerTest.java0000644000175000017500000001026111365604666027731 0ustar renerene/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2007 - 2009 Pentaho Corporation and Contributors. All rights reserved. */ package org.pentaho.reporting.libraries.base.util; import junit.framework.Test; import junit.framework.TestSuite; import junit.framework.TestCase; import org.pentaho.reporting.libraries.base.util.CSVTokenizer; /** * @author Thomas Morgner * @author Rob Edgeler */ public class CSVTokenizerTest extends TestCase { public CSVTokenizerTest(final String name) { super(name); } public void testHasMoreTokens() { CSVTokenizer tokeniser = new CSVTokenizer("", CSVTokenizer.SEPARATOR_COMMA, CSVTokenizer.DOUBLE_QUATE); assertTrue("Should have no more tokens.", (!tokeniser.hasMoreTokens())); tokeniser = new CSVTokenizer("a,b,c", CSVTokenizer.SEPARATOR_COMMA, CSVTokenizer.DOUBLE_QUATE); assertEquals("Should count tokens correctly", 3, tokeniser.countTokens()); assertEquals("a", tokeniser.nextToken()); assertEquals("b", tokeniser.nextToken()); assertEquals("c", tokeniser.nextToken()); tokeniser = new CSVTokenizer(",b,c", CSVTokenizer.SEPARATOR_COMMA, CSVTokenizer.DOUBLE_QUATE); assertEquals("Should count tokens correctly", 3, tokeniser.countTokens()); assertEquals("", tokeniser.nextToken()); assertEquals("b", tokeniser.nextToken()); assertEquals("c", tokeniser.nextToken()); tokeniser = new CSVTokenizer("a,,c", CSVTokenizer.SEPARATOR_COMMA, CSVTokenizer.DOUBLE_QUATE); assertEquals("Should count tokens correctly", 3, tokeniser.countTokens()); assertEquals("a", tokeniser.nextToken()); assertEquals("", tokeniser.nextToken()); assertEquals("c", tokeniser.nextToken()); tokeniser = new CSVTokenizer("a,b,", CSVTokenizer.SEPARATOR_COMMA, CSVTokenizer.DOUBLE_QUATE); assertEquals("Should count tokens correctly", 3, tokeniser.countTokens()); assertEquals("a", tokeniser.nextToken()); assertEquals("b", tokeniser.nextToken()); assertEquals("", tokeniser.nextToken()); tokeniser = new CSVTokenizer(",,", CSVTokenizer.SEPARATOR_COMMA, CSVTokenizer.DOUBLE_QUATE); assertEquals("Should count tokens correctly", 3, tokeniser.countTokens()); assertEquals("", tokeniser.nextToken()); assertEquals("", tokeniser.nextToken()); assertEquals("", tokeniser.nextToken()); tokeniser = new CSVTokenizer("\"\",\"\",\"\"", CSVTokenizer.SEPARATOR_COMMA, CSVTokenizer.DOUBLE_QUATE); assertEquals("Should count tokens correctly", 3, tokeniser.countTokens()); assertEquals("", tokeniser.nextToken()); assertEquals("", tokeniser.nextToken()); assertEquals("", tokeniser.nextToken()); } public void testNextToken() { CSVTokenizer tokeniser = new CSVTokenizer("\"Test\"\"Test\"", CSVTokenizer.SEPARATOR_COMMA, CSVTokenizer.DOUBLE_QUATE); assertEquals("Should count tokens correctly", 1, tokeniser.countTokens()); assertEquals("Test\"Test", tokeniser.nextToken()); tokeniser = new CSVTokenizer("\"Test Test\"", CSVTokenizer.SEPARATOR_COMMA, CSVTokenizer.DOUBLE_QUATE); assertEquals("Should count tokens correctly", 1, tokeniser.countTokens()); assertEquals("Test Test", tokeniser.nextToken()); } /** @return a TestSuite */ public static Test suite() { final TestSuite suite = new TestSuite(); suite.setName("Test for CSVTokenizer."); suite.addTest(new CSVTokenizerTest("testHasMoreTokens")); return suite; } } libbase-1.1.6/testcases/org/pentaho/reporting/libraries/base/util/LinkedMapTest.java0000644000175000017500000001055511365604666027255 0ustar renerene/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2007 - 2009 Pentaho Corporation and Contributors. All rights reserved. */ package org.pentaho.reporting.libraries.base.util; import java.util.Arrays; import junit.framework.TestCase; /** * Todo: Document Me * * @author Thomas Morgner */ public class LinkedMapTest extends TestCase { public LinkedMapTest(final String s) { super(s); } public void testValidity() throws Exception { final LinkedMap map = new LinkedMap(16, 1024); map.put("1", "A"); map.put("2", "B"); map.put("3", "C"); map.put("4", "D"); map.put("5", "E"); map.put("6", "F"); map.put("1", "A"); final Object[] expectedKeys = {"2", "3", "4", "5", "6", "1"}; final Object[] a2 = map.keys(); if (Arrays.equals(expectedKeys, a2) == false) { throw new Exception(); } if (ObjectUtilities.equal(map.get("1"), "A") == false) { throw new NullPointerException(); } if (ObjectUtilities.equal(map.get("2"), "B") == false) { throw new NullPointerException(); } if (ObjectUtilities.equal(map.get("3"), "C") == false) { throw new NullPointerException(); } if (ObjectUtilities.equal(map.get("4"), "D") == false) { throw new NullPointerException(); } if (ObjectUtilities.equal(map.get("5"), "E") == false) { throw new NullPointerException(); } if (ObjectUtilities.equal(map.get("6"), "F") == false) { throw new NullPointerException(); } if (ObjectUtilities.equal(map.get("1"), "A") == false) { throw new NullPointerException(); } map.remove("1"); map.remove("2"); final Object[] expectedKeys2 = {"3", "4", "5", "6"}; final Object[] a3 = map.keys(); if (Arrays.equals(expectedKeys2, a3) == false) { throw new Exception(); } map.remove("5"); Object[] arrayCache = map.values(new String[map.size()]); map.remove("5"); map.remove("3"); map.remove("4"); map.remove("5"); map.remove("6"); if (map.keys().length != 0) { throw new Exception(); } } public void testStrange() { final LinkedMap map = new LinkedMap(); map.put("A", "1"); map.put("B", "2"); map.put("A", "3"); map.remove("A"); map.remove("B"); map.remove("A"); } public void testResize() { final LinkedMap map = new LinkedMap(2, 0.75f); map.put("A", "1"); assertNotNull(map.get("A")); map.put("B", "2"); assertNotNull(map.get("A")); assertNotNull(map.get("B")); map.put("C", "3"); assertNotNull(map.get("A")); assertNotNull(map.get("B")); assertNotNull(map.get("C")); map.put("D", "3"); assertNotNull(map.get("A")); assertNotNull(map.get("B")); assertNotNull(map.get("C")); assertNotNull(map.get("D")); map.put("E", "3"); assertNotNull(map.get("A")); assertNotNull(map.get("B")); assertNotNull(map.get("C")); assertNotNull(map.get("D")); assertNotNull(map.get("E")); map.put("F", "3"); assertNotNull(map.get("A")); assertNotNull(map.get("B")); assertNotNull(map.get("C")); assertNotNull(map.get("D")); assertNotNull(map.get("E")); assertNotNull(map.get("F")); map.put("G", "3"); map.put("H", "3"); map.put("I", "3"); map.put("J", "3"); map.put("K", "3"); assertEquals("Size", 11, map.size()); assertNotNull(map.get("C")); assertNotNull(map.get("D")); assertNotNull(map.get("E")); assertNotNull(map.get("F")); assertNotNull(map.get("G")); assertNotNull(map.get("H")); assertNotNull(map.get("I")); assertNotNull(map.get("J")); assertNotNull(map.get("K")); } } libbase-1.1.6/testcases/org/pentaho/reporting/libraries/base/util/StringUtilsTest.java0000644000175000017500000001666011365604666027703 0ustar renerene/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2007 - 2009 Pentaho Corporation and Contributors. All rights reserved. */ package org.pentaho.reporting.libraries.base.util; import junit.framework.TestCase; import org.pentaho.reporting.libraries.base.util.StringUtils; /** * Tests for the StringUtils class. * @author David Kincade */ public class StringUtilsTest extends TestCase { public void testIsEmpty() { // TRUE assertTrue(StringUtils.isEmpty(null)); assertTrue(StringUtils.isEmpty("")); assertTrue(StringUtils.isEmpty(" ")); assertTrue(StringUtils.isEmpty("\t\n \t")); assertTrue(StringUtils.isEmpty(null, true)); assertTrue(StringUtils.isEmpty("", true)); assertTrue(StringUtils.isEmpty(" ", true)); assertTrue(StringUtils.isEmpty("\t\n \t", true)); assertTrue(StringUtils.isEmpty(null, false)); assertTrue(StringUtils.isEmpty("", false)); // FALSE assertTrue(!StringUtils.isEmpty("test")); assertTrue(!StringUtils.isEmpty(" test ")); assertTrue(!StringUtils.isEmpty("test", true)); assertTrue(!StringUtils.isEmpty(" test ", true)); assertTrue(!StringUtils.isEmpty(" ", false)); assertTrue(!StringUtils.isEmpty("\t\n \t", false)); assertTrue(!StringUtils.isEmpty("test", false)); assertTrue(!StringUtils.isEmpty(" test ", false)); } public void testToBoolean() { // TRUE assertTrue(StringUtils.toBoolean("true")); assertTrue(StringUtils.toBoolean("on")); assertTrue(StringUtils.toBoolean("yes")); assertTrue(StringUtils.toBoolean("TRUE")); assertTrue(StringUtils.toBoolean("ON")); assertTrue(StringUtils.toBoolean("YES")); assertTrue(StringUtils.toBoolean("tRUe")); assertTrue(StringUtils.toBoolean("oN")); assertTrue(StringUtils.toBoolean("yEs")); assertTrue(StringUtils.toBoolean(" true ")); assertTrue(StringUtils.toBoolean("\t on \t")); assertTrue(StringUtils.toBoolean(" \nyes\n ")); assertTrue(StringUtils.toBoolean(" TRUE ")); assertTrue(StringUtils.toBoolean("\t ON \t")); assertTrue(StringUtils.toBoolean(" \fYES\f ")); assertTrue(StringUtils.toBoolean(" tRUe ")); assertTrue(StringUtils.toBoolean("\t oN \t")); assertTrue(StringUtils.toBoolean(" \u0009yEs\u0009 ")); assertTrue(StringUtils.toBoolean("true", false)); assertTrue(StringUtils.toBoolean("on", false)); assertTrue(StringUtils.toBoolean("yes", false)); assertTrue(StringUtils.toBoolean("TRUE", false)); assertTrue(StringUtils.toBoolean("ON", false)); assertTrue(StringUtils.toBoolean("YES", false)); assertTrue(StringUtils.toBoolean("tRUe", false)); assertTrue(StringUtils.toBoolean("oN", false)); assertTrue(StringUtils.toBoolean("yEs", false)); assertTrue(StringUtils.toBoolean(" true ", false)); assertTrue(StringUtils.toBoolean("\t on \t", false)); assertTrue(StringUtils.toBoolean(" \nyes\n ", false)); assertTrue(StringUtils.toBoolean(" TRUE ", false)); assertTrue(StringUtils.toBoolean("\t ON \t", false)); assertTrue(StringUtils.toBoolean(" \fYES\f ", false)); assertTrue(StringUtils.toBoolean(" tRUe ", false)); assertTrue(StringUtils.toBoolean("\t oN \t", false)); assertTrue(StringUtils.toBoolean(" \u0009yEs\u0009 ", false)); assertTrue(StringUtils.toBoolean("true", true)); assertTrue(StringUtils.toBoolean("on", true)); assertTrue(StringUtils.toBoolean("yes", true)); assertTrue(StringUtils.toBoolean("TRUE", true)); assertTrue(StringUtils.toBoolean("ON", true)); assertTrue(StringUtils.toBoolean("YES", true)); assertTrue(StringUtils.toBoolean("tRUe", true)); assertTrue(StringUtils.toBoolean("oN", true)); assertTrue(StringUtils.toBoolean("yEs", true)); assertTrue(StringUtils.toBoolean(" true ", true)); assertTrue(StringUtils.toBoolean("\t on \t", true)); assertTrue(StringUtils.toBoolean(" \nyes\n ", true)); assertTrue(StringUtils.toBoolean(" TRUE ", true)); assertTrue(StringUtils.toBoolean("\t ON \t", true)); assertTrue(StringUtils.toBoolean(" \fYES\f ", true)); assertTrue(StringUtils.toBoolean(" tRUe ", true)); assertTrue(StringUtils.toBoolean("\t oN \t", true)); assertTrue(StringUtils.toBoolean(" \u0009yEs\u0009 ", true)); assertTrue(StringUtils.toBoolean(null, true)); // FALSE assertTrue(!StringUtils.toBoolean(null)); assertTrue(!StringUtils.toBoolean("false")); assertTrue(!StringUtils.toBoolean("off")); assertTrue(!StringUtils.toBoolean("no")); assertTrue(!StringUtils.toBoolean("FALSE")); assertTrue(!StringUtils.toBoolean("NO")); assertTrue(!StringUtils.toBoolean("OFF")); assertTrue(!StringUtils.toBoolean("fALSe")); assertTrue(!StringUtils.toBoolean("oFf")); assertTrue(!StringUtils.toBoolean("nO")); assertTrue(!StringUtils.toBoolean(" false ")); assertTrue(!StringUtils.toBoolean(" \t off \t ")); assertTrue(!StringUtils.toBoolean("\n no \n")); assertTrue(!StringUtils.toBoolean("true.", true)); assertTrue(!StringUtils.toBoolean("onn", true)); assertTrue(!StringUtils.toBoolean("yes!", true)); assertTrue(!StringUtils.toBoolean("false", true)); assertTrue(!StringUtils.toBoolean("off", true)); assertTrue(!StringUtils.toBoolean("no", true)); assertTrue(!StringUtils.toBoolean("FALSE", true)); assertTrue(!StringUtils.toBoolean("NO", true)); assertTrue(!StringUtils.toBoolean("OFF", true)); assertTrue(!StringUtils.toBoolean("fALSe", true)); assertTrue(!StringUtils.toBoolean("oFf", true)); assertTrue(!StringUtils.toBoolean("nO", true)); assertTrue(!StringUtils.toBoolean(" false ", true)); assertTrue(!StringUtils.toBoolean(" \t off \t ", true)); assertTrue(!StringUtils.toBoolean("\n no \n", true)); assertTrue(!StringUtils.toBoolean("true.", false)); assertTrue(!StringUtils.toBoolean("onn", false)); assertTrue(!StringUtils.toBoolean("yes!", false)); assertTrue(!StringUtils.toBoolean("false", false)); assertTrue(!StringUtils.toBoolean("off", false)); assertTrue(!StringUtils.toBoolean("no", false)); assertTrue(!StringUtils.toBoolean("FALSE", false)); assertTrue(!StringUtils.toBoolean("NO", false)); assertTrue(!StringUtils.toBoolean("OFF", false)); assertTrue(!StringUtils.toBoolean("fALSe", false)); assertTrue(!StringUtils.toBoolean("oFf", false)); assertTrue(!StringUtils.toBoolean("nO", false)); assertTrue(!StringUtils.toBoolean(" false ", false)); assertTrue(!StringUtils.toBoolean(" \t off \t ", false)); assertTrue(!StringUtils.toBoolean("\n no \n", false)); assertTrue(!StringUtils.toBoolean("true.", false)); assertTrue(!StringUtils.toBoolean("onn", false)); assertTrue(!StringUtils.toBoolean("yes!", false)); assertTrue(!StringUtils.toBoolean(null, false)); } } libbase-1.1.6/testcases/org/pentaho/reporting/libraries/base/util/LFUMapTest.java0000644000175000017500000000550411365604666026473 0ustar renerene/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2007 - 2009 Pentaho Corporation and Contributors. All rights reserved. */ package org.pentaho.reporting.libraries.base.util; import junit.framework.TestCase; import org.pentaho.reporting.libraries.base.util.LFUMap; import org.pentaho.reporting.libraries.base.util.DebugLog; /** * Todo: Document Me * * @author Thomas Morgner */ public class LFUMapTest extends TestCase { public LFUMapTest() { } public LFUMapTest(final String s) { super(s); } public void testAdd () { final LFUMap lfuMap = new LFUMap(10); lfuMap.put("1", "1"); lfuMap.validate(); lfuMap.put("2", "2"); lfuMap.validate(); lfuMap.put("3", "3"); lfuMap.validate(); lfuMap.put("4", "4"); lfuMap.validate(); lfuMap.put("1", "5"); lfuMap.validate(); lfuMap.put("3", "6"); lfuMap.validate(); lfuMap.put("4", "7"); lfuMap.validate(); lfuMap.put("2", "8"); lfuMap.validate(); DebugLog.logHere(); } public void testAdd2 () { final LFUMap lfuMap = new LFUMap(10); lfuMap.put("1", "1"); lfuMap.validate(); lfuMap.put("2", "2"); lfuMap.validate(); lfuMap.put("3", "3"); lfuMap.validate(); lfuMap.put("4", "4"); lfuMap.validate(); lfuMap.put("1", "5"); lfuMap.validate(); lfuMap.put("3", "6"); lfuMap.validate(); lfuMap.put("4", "7"); lfuMap.validate(); lfuMap.put("a2", "8"); lfuMap.validate(); lfuMap.put("a4", "4"); lfuMap.validate(); lfuMap.put("a1", "5"); lfuMap.validate(); lfuMap.put("a3", "6"); lfuMap.validate(); lfuMap.put("b4", "7"); lfuMap.validate(); lfuMap.put("b4", "4"); lfuMap.validate(); lfuMap.put("b1", "5"); lfuMap.validate(); lfuMap.put("b3", "6"); lfuMap.validate(); lfuMap.put("c4", "7"); lfuMap.validate(); lfuMap.get("a2"); lfuMap.validate(); lfuMap.get("a4"); lfuMap.validate(); lfuMap.get("a1"); lfuMap.validate(); lfuMap.get("a3"); lfuMap.validate(); lfuMap.get("b4"); lfuMap.validate(); lfuMap.get("b4"); lfuMap.validate(); } } libbase-1.1.6/testcases/org/pentaho/reporting/libraries/base/util/IOUtilsTest.java0000644000175000017500000001013711365604666026735 0ustar renerene/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2007 - 2009 Pentaho Corporation and Contributors. All rights reserved. */ package org.pentaho.reporting.libraries.base.util; import junit.framework.TestCase; import org.pentaho.reporting.libraries.base.util.IOUtils; /** * Todo: Document Me * * @author Thomas Morgner */ public class IOUtilsTest extends TestCase { public IOUtilsTest(final String s) { super(s); } public void testGetRelativePath() { assertEquals("../Desktop/samples/test.file", IOUtils.getInstance().createRelativePath ("/User/users/Desktop/samples/test.file", "/User/users/Downloads/someotherfile.xml")); assertEquals("../test.file", IOUtils.getInstance().createRelativePath ("/User/users/test.file", "/User/users/Downloads/someotherfile.xml")); assertEquals("../../test.file", IOUtils.getInstance().createRelativePath ("/User/users/test.file", "/User/users/Downloads/test/someotherfile.xml")); assertEquals("/User/users/test.file", IOUtils.getInstance().createRelativePath ("/User/users/test.file", "/AUser/users/Downloads/someotherfile.xml")); } public void testGetAbsolutePath() { assertEquals ("content.xml", IOUtils.getInstance().getAbsolutePath("content.xml", "")); // expect: content.xml assertEquals ("directory/content.xml", IOUtils.getInstance().getAbsolutePath("content.xml", "directory/")); // expect: directory/content.xml assertEquals ("content.xml", IOUtils.getInstance().getAbsolutePath("content.xml", "directory")); // expect: content.xml assertEquals ("content.xml", IOUtils.getInstance().getAbsolutePath("../content.xml", "")); // expect: content.xml assertEquals ("content.xml", IOUtils.getInstance().getAbsolutePath("../content.xml", "directory/")); // expect: content.xml assertEquals ("content.xml", IOUtils.getInstance().getAbsolutePath("../content.xml", "directory")); // expect: content.xml assertEquals ("content.xml", IOUtils.getInstance().getAbsolutePath("/content.xml", "")); // expect: content.xml assertEquals ("content.xml", IOUtils.getInstance().getAbsolutePath("/content.xml", "directory/")); // expect: content.xml assertEquals ("content.xml", IOUtils.getInstance().getAbsolutePath("/content.xml", "directory")); // expect: content.xml assertEquals ("content.xml", IOUtils.getInstance().getAbsolutePath("/../content.xml", "")); // expect: content.xml assertEquals ("content.xml", IOUtils.getInstance().getAbsolutePath("/../content.xml", "directory/")); // expect: content.xml assertEquals ("content.xml", IOUtils.getInstance().getAbsolutePath("/../content.xml", "directory")); // expect: content.xml assertEquals ("content.xml", IOUtils.getInstance().getAbsolutePath("test/../content.xml", "")); // expect: content.xml assertEquals ("directory/content.xml", IOUtils.getInstance().getAbsolutePath("test/../content.xml", "directory/")); // expect: directory/content.xml assertEquals ("content.xml", IOUtils.getInstance().getAbsolutePath("test/../content.xml", "directory")); // expect: content.xml assertEquals ("content/", IOUtils.getInstance().getAbsolutePath("/content/", "")); // expect: content.xml assertEquals ("content/", IOUtils.getInstance().getAbsolutePath("/content/", "directory/")); // expect: content.xml assertEquals ("content/", IOUtils.getInstance().getAbsolutePath("/content/", "directory")); // expect: content.xml } } libbase-1.1.6/lib/0000755000175000017500000000000011635761743012347 5ustar renerenelibbase-1.1.6/.classpath0000644000175000017500000000146211365604664013565 0ustar renerene libbase-1.1.6/build.xml0000644000175000017500000000323511365604666013425 0ustar renerene This build file is used to create the API project and works with the common_build.xml file.