[Japi-cvs] SF.net SVN: japi: [637] tools
Status: Beta
Brought to you by:
christianhujer
From: <chr...@us...> - 2008-03-11 22:54:14
|
Revision: 637 http://japi.svn.sourceforge.net/japi/?rev=637&view=rev Author: christianhujer Date: 2008-03-11 15:54:11 -0700 (Tue, 11 Mar 2008) Log Message: ----------- Added Replacer. Added Paths: ----------- tools/replacer/ tools/replacer/trunk/ tools/replacer/trunk/COPYING tools/replacer/trunk/build.xml tools/replacer/trunk/lib/ tools/replacer/trunk/lib/annotations.jar tools/replacer/trunk/lib/japi-lib-argparser-trunk.jar tools/replacer/trunk/src/ tools/replacer/trunk/src/prj/ tools/replacer/trunk/src/prj/net/ tools/replacer/trunk/src/prj/net/sf/ tools/replacer/trunk/src/prj/net/sf/japi/ tools/replacer/trunk/src/prj/net/sf/japi/tools/ tools/replacer/trunk/src/prj/net/sf/japi/tools/replacer/ tools/replacer/trunk/src/prj/net/sf/japi/tools/replacer/Replacer.java tools/replacer/trunk/src/prj/net/sf/japi/tools/replacer/Replacer.properties tools/replacer/trunk/src/prj/net/sf/japi/tools/replacer/Substitution.java tools/replacer/trunk/src/tst/ tools/replacer/trunk/src/tst/test/ tools/replacer/trunk/src/tst/test/net/ tools/replacer/trunk/src/tst/test/net/sf/ tools/replacer/trunk/src/tst/test/net/sf/japi/ tools/replacer/trunk/src/tst/test/net/sf/japi/tools/ tools/replacer/trunk/src/tst/test/net/sf/japi/tools/replacer/ tools/replacer/trunk/src/tst/test/net/sf/japi/tools/replacer/ReplacerTest.java tools/replacer/trunk/src/tst/test/net/sf/japi/tools/replacer/SubstitutionTest.java Added: tools/replacer/trunk/COPYING =================================================================== --- tools/replacer/trunk/COPYING (rev 0) +++ tools/replacer/trunk/COPYING 2008-03-11 22:54:11 UTC (rev 637) @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + 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 Lesser General Public License instead.) You can apply it to +your programs, too. + + 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. + + 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. + + 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. + + 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. + + 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. + + 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. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 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". + +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. + + 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. + +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 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: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + 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. + + 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.) + +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. + +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. + +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. + + 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: + + 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, + + 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, + + 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.) + +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. + +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. + + 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. + + 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. + + 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. + + 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. + +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. + + 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. + + 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. + +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. + + 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. + + NO WARRANTY + + 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. + + 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. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + 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. + + 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. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + 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. + + 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. + + 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., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +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. + +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: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + +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 Lesser General +Public License instead of this License. Property changes on: tools/replacer/trunk/COPYING ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:eol-style + LF Added: tools/replacer/trunk/build.xml =================================================================== --- tools/replacer/trunk/build.xml (rev 0) +++ tools/replacer/trunk/build.xml 2008-03-11 22:54:11 UTC (rev 637) @@ -0,0 +1,226 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ DirCount is a program for converting Strings into byte arrays. + ~ Copyright (C) 2007 Christian Hujer + ~ + ~ 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. + ~ + ~ 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. + ~ + ~ 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., + ~ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + --> + +<project name="Replacer" default="compile"> + + <property name="module.version" value="0.1" /> + <property name="module.name" value="Replacer" /> + <property name="module.shortname" value="Replacer" /> + <property name="module.title" value="Replacer" /> + <property name="main.class" value="net.sf.japi.tools.replacer.Replacer" /> + + <taskdef name="pack200" classpath="common/antlib/Pack200Task.jar" classname="com.sun.tools.apache.ant.pack200.Pack200Task" /> + + <target + name = "clean" + description = "Cleans Sandbox" + > + <delete dir="classes" /> + <delete dir="docs" /> + </target> + + <target + name = "compile" + description = "Compiles production classes" + > + <mkdir dir="classes/production/${module.shortname}" /> + <mkdir dir="classes/test/${module.shortname}" /> + <javac + srcdir="src/prj" + destdir="classes/production/${module.shortname}" + encoding="utf-8" + source="1.5" + target="1.5" + > + <classpath> + <fileset dir="lib" includes="*.jar" excludes="LICENSE-*.jar" /> + <fileset dir="common/lib" includes="*.jar" excludes="LICENSE-*.jar" /> + </classpath> + <exclude name="test/**/*.java" /> + </javac> + <copy + todir="classes/production/${module.shortname}" + > + <fileset dir="src/prj" includes="**/*.properties" excludes="test/**/*.properties" /> + <fileset dir="src/prj" includes="META-INF/services/**" /> + </copy> + <copy + todir="classes/production/${module.shortname}" + > + <fileset dir="lib" includes="LICENSE-*" /> + <fileset dir="." includes="COPYING" /> + </copy> + </target> + + <target + name = "dist" + description = "Packs distribution archives." + depends = "clean, compile" + > + <!--depends = "clean, compile, doc" + --> + <delete dir="dist" /> + <mkdir dir="dist" /> + <property name="distName" value="dist/${module.name}-${module.version}" /> + <parallel> + <tar tarfile="${distName}.src.tar"> + <tarfileset dir="." prefix="${module.name}-${module.version}"> + <include name="src/**" /> + <include name="build.xml" /> + </tarfileset> + </tar> + <zip destfile="${distName}.src.zip"> + <zipfileset dir="." prefix="${module.name}-${module.version}"> + <include name="src/**" /> + <include name="build.xml" /> + </zipfileset> + </zip> + <jar destfile="${distName}.src.jar"> + <zipfileset dir="." prefix="${module.name}-${module.version}"> + <include name="src/**" /> + <include name="build.xml" /> + </zipfileset> + </jar> + <jar destfile="${distName}.jar"> + <zipfileset dir="classes/production/${module.shortname}"/> + <manifest> + <attribute name="Main-Class" value="${main.class}" /> + <attribute name="Class-Path" value="lib/annotations.jar lib/japi-lib-lang-0.1.jar lib/japi-lib-swing-about-0.1.jar lib/japi-lib-swing-action-0.1.jar" /> + <attribute name="Implementation-Title" value="${module.name}" /> + <attribute name="Implementation-Vendor" value="Christian Hujer + the JAPI Developers" /> + <attribute name="Implementation-Version" value="${module.version}" /> + <attribute name="Implementation-URL" value="http://sourceforge.net/projects/japi/" /> + </manifest> + </jar> + <tar tarfile="${distName}.doc.tar"> + <tarfileset dir="." prefix="${module.name}-${module.version}"> + <include name="docs/**" /> + <include name="build.xml" /> + </tarfileset> + </tar> + <zip destfile="${distName}.doc.zip"> + <zipfileset dir="." prefix="${module.name}-${module.version}"> + <include name="docs/**" /> + <include name="build.xml" /> + </zipfileset> + </zip> + <jar destfile="${distName}.doc.jar"> + <zipfileset dir="." prefix="${module.name}-${module.version}"> + <include name="docs/**" /> + </zipfileset> + </jar> + </parallel> + <parallel> + <gzip src="${distName}.src.tar" destfile="${distName}.src.tar.gz" /> + <bzip2 src="${distName}.src.tar" destfile="${distName}.src.tar.bz2" /> + <gzip src="${distName}.doc.tar" destfile="${distName}.doc.tar.gz" /> + <bzip2 src="${distName}.doc.tar" destfile="${distName}.doc.tar.bz2" /> + <pack200 + src="${distName}.jar" + destfile="${distName}.pack.gz" + gzipoutput="true" + stripdebug="true" + effort="9" + keepfileorder="false" + modificationtime="latest" + deflatehint="false" + /> + </parallel> + <delete file="${distName}.src.tar" /> + <delete file="${distName}.doc.tar" /> + </target> + + <target + name = "doc" + description = "Creates public javadoc documentation." + > + <mkdir dir="docs/api" /> + <!--copy todir="docs/api" file="src/doc/api/public/copyright.html" /> + <copy todir="docs/api" file="src/doc/api/public/.htaccess" /--> + <javadoc + destdir = "docs/api" + access = "protected" + author = "yes" + version = "yes" + locale = "en_US" + use = "yes" + splitindex = "yes" + windowtitle = "JAPI Library ${module.title} ${module.version} API documentation" + doctitle = "JAPI<br />Yet another Java API<br />Library ${module.title} ${module.version} API documentation" + header = "JAPI Library ${module.title} ${module.version}<br />API Documentation" + footer = "JAPI<br />Yet another Java API<br />Library ${module.title} ${module.version} API documentation" + bottom = "<div style=" text-align:center;">© 2005-2006 Christian Hujer. All rights reserved. See <a href="{@docRoot}/copyright.html">copyright</a></div>" + serialwarn = "yes" + charset = "utf-8" + docencoding = "utf-8" + encoding = "utf-8" + source = "1.5" + linksource = "yes" + link = "${user.javadoc.link}" + > + <!-- + overview = "src/overview.html" + --> + <classpath> + <fileset dir="lib" includes="annotations.jar" /> + </classpath> + <sourcepath> + <pathelement path="${user.javadoc.javasrc}" /> + <pathelement path="src/prj" /> + </sourcepath> + <packageset + dir="src/prj" + defaultexcludes="yes" + > + <include name="net/**" /> + </packageset> + <tag enabled="true" name="retval" description="Return Values:" scope="methods" /> + <tag enabled="true" name="pre" description="Preconditions:" scope="methods,constructors" /> + <tag enabled="true" name="post" description="Postconditions:" scope="methods" /> + <tag enabled="true" name="invariant" description="Invariant:" scope="methods,fields" /> + <tag enabled="true" name="note" description="Notes:" /> + <tag enabled="true" name="warning" description="Warnings:" /> + <!--tag enabled="true" name="todo" description="Todo:" /--> + <taglet name="com.sun.tools.doclets.ToDoTaglet" path="" /> + <tag enabled="true" name="fixme" description="Fixme:" /> + <tag enabled="true" name="xxx" description="XXX:" /> + </javadoc> + </target> + + <target + name = "buildapp" + description = "Creates executable jar" + > + <property name="appName" value="${module.name}-${module.version}-app" /> + <jar destfile="${appName}.jar"> + <zipfileset dir="classes/production/${module.shortname}"/> + <zipgroupfileset dir="lib" includes="*.jar" excludes="LICENSE-*.jar" /> + <manifest> + <attribute name="Main-Class" value="${main.class}" /> + <!--attribute name="Class-Path" value="lib/annotations.jar lib/japi-lib-lang-0.1.jar lib/japi-lib-swing-about-0.1.jar lib/japi-lib-swing-action-0.1.jar" /--> + <attribute name="Implementation-Title" value="${module.name}" /> + <attribute name="Implementation-Vendor" value="Christian Hujer + the JAPI Developers" /> + <attribute name="Implementation-Version" value="${module.version}" /> + <attribute name="Implementation-URL" value="http://sourceforge.net/projects/japi/" /> + </manifest> + </jar> + </target> + +</project> Property changes on: tools/replacer/trunk/build.xml ___________________________________________________________________ Name: svn:mime-type + text/xml Name: svn:eol-style + LF Added: tools/replacer/trunk/lib/annotations.jar =================================================================== (Binary files differ) Property changes on: tools/replacer/trunk/lib/annotations.jar ___________________________________________________________________ Name: svn:executable + * Name: svn:mime-type + application/octet-stream Added: tools/replacer/trunk/lib/japi-lib-argparser-trunk.jar =================================================================== (Binary files differ) Property changes on: tools/replacer/trunk/lib/japi-lib-argparser-trunk.jar ___________________________________________________________________ Name: svn:executable + * Name: svn:mime-type + application/octet-stream Added: tools/replacer/trunk/src/prj/net/sf/japi/tools/replacer/Replacer.java =================================================================== --- tools/replacer/trunk/src/prj/net/sf/japi/tools/replacer/Replacer.java (rev 0) +++ tools/replacer/trunk/src/prj/net/sf/japi/tools/replacer/Replacer.java 2008-03-11 22:54:11 UTC (rev 637) @@ -0,0 +1,301 @@ +package net.sf.japi.tools.replacer; + +import net.sf.japi.io.args.ArgParser; +import net.sf.japi.io.args.BasicCommand; +import net.sf.japi.io.args.Option; +import org.jetbrains.annotations.NotNull; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.Reader; +import java.io.Writer; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +/** Performs one or more regular expression based substitutions on one or more files. + * Files will only be written if at least one of the substitution steps caused a change. + * @author <a href="mailto:ch...@ri...">Christian Hujer</a> + */ +public class Replacer extends BasicCommand { + + /** The default file ending for backup files. */ + @NotNull + public static final String DEFAULT_BACKUP_EXTENSION = ".bak"; + + /** Buffer size for read buffer. */ + private static final int BUF_SIZE = 4096; + + /** Main program. + * @param args Command line arguments (use -h or --help for info) + */ + public static void main(final String... args) { + ArgParser.simpleParseAndRun(new Replacer(), args); + } + + /** The list of substitutions that shall be performed. */ + @NotNull private final Collection<Substitution> substitutions = new ArrayList<Substitution>(); + + /** Unmodifiable view to the list of substitutions that shall be performed. */ + @NotNull private final Collection<Substitution> unmodifiableSubstitutions = Collections.unmodifiableCollection(substitutions); + + /** Whether to force overwriting files or not. + * If <code>true</code>, files will be made writable if possible. + * If <code>false</code> (default), files can only be written if they were writable before. + */ + private boolean force; + + /** Whether to recurse into subdirectories or not. + * If <code>true</code>, directories will be opened recursively and substitution performed on all files found. + * If <code>false</code> (default), directories will simply be ignored. + */ + private boolean recursive; + + /** Whether to create backups of modified files. + * If <code>true</code>, backups with the original file content will be made if a file has changed. + * If <code>false</code> (default), no backups will be made. + * Intermediate backups will always be created to make writing pseudo-atomic. + */ + private boolean backup; + + /** The number of errors that occurred. + * Errors are only cases where actual exceptions were thrown, i.e. {@link FileNotFoundException} or {@link IOException}. + * If 0 (zero) no errors occurred. + * This variable will somehow be used for the exit code. + */ + private int errors; + + /** The default file extension for backup files. */ + @NotNull private String backupExtension = DEFAULT_BACKUP_EXTENSION; + + /** The file encoding that is used for reading and writing files as weil es parsing substitutions from {@link System#in}. */ + private String encoding = Charset.defaultCharset().name(); + + /** {@inheritDoc} */ + public int run(@NotNull final List<String> args) throws Exception { + if (args.size() == 0) { + final CharSequence content = read(System.in); + final CharSequence newContent = replaceAll(content); + System.out.append(newContent); + System.out.flush(); + } + for (final String arg : args) { + replace(arg); + } + return errors; + } + + /** Performs substitutions on the file or directory specified by <var>filename</var>. + * The behaviour on directories depends on {@link #recursive}. + * @param filename Name of the file or directory to perform substitutions on. + */ + public void replace(@NotNull final String filename) { + replace(new File(filename)); + } + + /** Performs substitutions on the file or directory specified by <var>file</var>. + * The behaviour on directories depends on {@link #recursive}. + * @param file The file or directory to perform substitutions on. + */ + public void replace(@NotNull final File file) { + if (recursive && file.isDirectory()) { + for (final File f : file.listFiles()) { + replace(f); + } + } + if (file.isFile()) { + try { + final CharSequence content = readFile(file); + final CharSequence newContent = replaceAll(content); + if (!equals(content, newContent)) { + final File tmpFile = new File(file.getParentFile(), file.getName() + backupExtension); + file.renameTo(tmpFile); + writeFile(file, newContent); + if (!backup) { + tmpFile.deleteOnExit(); + } + } + } catch (final IOException e) { + System.err.println(e); + errors++; + } + } + } + + /** Returns whether two Objects are equal regarding their String representation. + * This method is particularly useful for CharSequences because CharSequence does not define a general contract about <code>equals()</code> and <code>hashCode()</code>. + * Therefore it is inappropriate to compare CharSequences using <code>equals()</code>. + * @param s1 First Object to compare. + * @param s2 Second Object to compare. + * @return <code>true</code> if <code><var>s1</var></code> and <code><var>s2</var></code> are equal regarding their String representation, otherwise <code>false</code>. + */ + public static boolean equals(@NotNull final Object s1, @NotNull final Object s2) { + return s1.toString().equals(s2.toString()); + } + + /** Performs all substitutions on the specified char sequence. + * @param orig Original char sequence to perform substitution on. + * @return New CharSequence with all substitutions performed. + */ + public CharSequence replaceAll(@NotNull final CharSequence orig) { + CharSequence temp = orig; + for (final Substitution substitution : substitutions) { + temp = substitution.replaceAll(temp); + } + return temp; + } + + /** Reads a String from an InputStream. + * @param stream InputStream to read. + * @return Contents of the InputStream. + * @throws IOException In case of I/O problems. + */ + public CharSequence read(@NotNull final InputStream stream) throws IOException { + final StringBuilder sb = new StringBuilder(); + final Reader in = new InputStreamReader(stream instanceof BufferedInputStream ? stream : new BufferedInputStream(stream), encoding); + final char[] buf = new char[BUF_SIZE]; + //noinspection NestedAssignment + for (int charsRead; (charsRead = in.read(buf)) != -1;) { + sb.append(buf, 0, charsRead); + } + return sb; + } + + /** Reads a (text) file and returns a CharSequence to the file read. + * The encoding for reading files will be {@link #encoding}. + * @param file File to read. + * @return Contents of the file. + * @throws IOException In case of I/O problems. + */ + public CharSequence readFile(@NotNull final File file) throws IOException { + final InputStream in = new FileInputStream(file); + try { + return read(in); + } finally { + in.close(); + } + } + + /** Writes a CharSequence into a (text) file. + * @param file File to write. + * @param string CharSequence to write. + * @throws IOException In case of I/O problems. + */ + public void writeFile(@NotNull final File file, @NotNull final CharSequence string) throws IOException { + if (force && !file.canWrite()) { + file.setWritable(true); + } + final Writer out = new OutputStreamWriter(new BufferedOutputStream(new FileOutputStream(file)), encoding); + try { + out.append(string); + out.flush(); + } finally { + out.close(); + } + } + + /** Sets or unsets the force option. + * @param force Value of the force option. + */ + @Option({"f", "force"}) + public void setForce(@NotNull final Boolean force) { + this.force = force; + } + + /** Returns whether the force option is set. + * @return <code>true</code> if the force option is set, otherwise <code>false</code>. + */ + public boolean isForce() { + return force; + } + + /** Sets or unsets the recurse option. + * @param recursive Value of the recurse option. + */ + @Option({"r", "recurse"}) + public void setRecursive(@NotNull final Boolean recursive) { + this.recursive = recursive; + } + + /** Returns whether the recurse option is set. + * @return <code>true</code> if the recurse option is set, otherwise <code>false</code>. + */ + public boolean isRecursive() { + return recursive; + } + + /** Sets or unsets the backup option. + * @param backup Value of the backup option. + */ + @Option({"b", "backup"}) + public void setBackup(@NotNull final Boolean backup) { + this.backup = backup; + } + + /** Returns whether the backup option is set. + * @return <code>true</code> if the backup option is set, otherwise <code>false</code>. + */ + public boolean isBackup() { + return backup; + } + + /** Sets the extension for backup files. + * @param backupExtension File extension for backup files. + */ + @Option({"backupExtension"}) + public void setBackupExtension(@NotNull final String backupExtension) { + this.backupExtension = backupExtension; + } + + /** Returns the extension for backup files. + * @return The extension for backup files. + */ + @NotNull public String getBackupExtension() { + return backupExtension; + } + + /** Adds a substitution. + * @param substitution Substitution to add + */ + @Option({"s", "substitution"}) + public void addSubstitution(@NotNull final String substitution) { + substitutions.add(new Substitution(substitution)); + } + + /** Returns the substitutions as unmodifiable collection. + * @return Unmodifiable collection with substitutions. + */ + @NotNull public Collection<Substitution> getSubstitutions() { + //noinspection ReturnOfCollectionOrArrayField + return unmodifiableSubstitutions; + } + + /** Adds substitutions from a file. + * @param filename Filename of the file to read substitutions from. + * @throws IOException in case of I/O problems. + */ + @Option({"i", "input"}) + public void addSubstitutionsFromFile(@NotNull final String filename) throws IOException { + final BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(filename), encoding)); + try { + //noinspection NestedAssignment + for (String line; (line = in.readLine()) != null; ) { + addSubstitution(line); + } + } finally { + in.close(); + } + } + +} Property changes on: tools/replacer/trunk/src/prj/net/sf/japi/tools/replacer/Replacer.java ___________________________________________________________________ Name: svn:executable + * Name: svn:mime-type + text/plain Name: svn:eol-style + LF Added: tools/replacer/trunk/src/prj/net/sf/japi/tools/replacer/Replacer.properties =================================================================== --- tools/replacer/trunk/src/prj/net/sf/japi/tools/replacer/Replacer.properties (rev 0) +++ tools/replacer/trunk/src/prj/net/sf/japi/tools/replacer/Replacer.properties 2008-03-11 22:54:11 UTC (rev 637) @@ -0,0 +1,7 @@ +setForce=Try to overwrite write-protected files. +setRecursive=Descend into subdirectories recursively. +setBackup=Create backup files. +setBackupExtension=File extension for backup files (default: .bak). +addSubstitution=Adds a substitution to the list of substitutions that will be performed. +addSubstitutionsFromFile=Specify a text file with substitutions. +helpFooter=If multiple substitutions or files are specified, they will be merged. If there are conflicting patterns, the first pattern takes precedence. Property changes on: tools/replacer/trunk/src/prj/net/sf/japi/tools/replacer/Replacer.properties ___________________________________________________________________ Name: svn:executable + * Name: svn:mime-type + text/plain Name: svn:eol-style + LF Added: tools/replacer/trunk/src/prj/net/sf/japi/tools/replacer/Substitution.java =================================================================== --- tools/replacer/trunk/src/prj/net/sf/japi/tools/replacer/Substitution.java (rev 0) +++ tools/replacer/trunk/src/prj/net/sf/japi/tools/replacer/Substitution.java 2008-03-11 22:54:11 UTC (rev 637) @@ -0,0 +1,196 @@ +package net.sf.japi.tools.replacer; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** Substitution is a small wrapper class for performing repeated substitutions. + * <h4 id="substitutionSyntax">Syntax of the substitution command</h4> + * <p> + * Whne specifying a substitution with the constructor {@link #Substitution(CharSequence)}, the parameter specifies the substitution. + * That parameter MUST follow the syntax described here. + * </p> + * <p> + * Syntax: <code>s/<var>substitution</var>/<var>replacement</var>/<var>flags</var></code> + * </p> + * <dl> + * <dt><code><var>substitution</var></code></dt> + * <dd> + * Specifies the substitution regular expression. + * </dd> + * <dt><code><var>replacement</var></code></dt> + * <dd> + * Specifies the replacement. + * </dd> + * <dt><code><var>flags</var></code></dt> + * <dd> + * Specifies the flags. + * Currently the flags are ignored. + * </dd> + * </dl> + * @author <a href="mailto:ch...@ri...">Christian Hujer</a> + */ +public class Substitution { + + /** The regular expression used to parse an sed / perl / vim like substitution command. */ + private static final Pattern rePattern = Pattern.compile("^s/((?:\\\\/|[^/])*+)/((?:\\\\/|[^/])*+)/(.*+)$"); + + /** The unmodifiable map with the flags. + * Key: Flag character. + * Value: integer flag value for {@link Pattern#compile(String, int)} resp. returned by {@link Pattern#flags()}. + */ + private static final Map<Character, Integer> flagMap = createFlagMap(); + + /** The pattern used for this substitution. */ + private final String patternString; + + /** The replacement specifier for a substitution. */ + private final String replacement; + + /** The flags used for substitution. */ + private final int flags; + + /** The matcher for performing the substitution. */ + private final Matcher matcher; + + /** Creates a Substitution based on the specified parameters. + * @param params Parameters in the order <var>pattern</var>, <var>replacement</var>, <var>flags</var>. + * @pre params.length == 3 + */ + private Substitution(@NotNull final String... params) { + this(params[0], params[1], params[2]); + assert params.length == 3 : "Expected length: 3, got length: " + params.length; + } + + /** Creates a Substitution based on a substitution command. + * @param substSpec Substitution command in the correct <a href="#substitutionSyntax">syntax</a>. + * @see <a href="#substitutionSyntax">Syntax of the substitution command</a> + */ + public Substitution(@NotNull final CharSequence substSpec) { + this(parseRegex(substSpec)); + } + + /** Creates a Substitution based on the specified pattern and replacement. + * @param patternString Regular expression matcher pattern. + * @param replacement Replacement. + */ + public Substitution(@NotNull final String patternString, @NotNull final String replacement) { + this(patternString, replacement, null); + } + + /** Creates a Substitution based on the specified pattern and replacement. + * @param patternString Regular expression matcher pattern. + * @param replacement Replacement. + * @param flags Substitution Flags (currently ignored). + */ + public Substitution(@NotNull final String patternString, @NotNull final String replacement, final int flags) { + this.patternString = patternString; + this.replacement = replacement; + this.flags = flags; + matcher = Pattern.compile(patternString, flags).matcher(""); + } + + /** Creates a Substitution based on the specified pattern and replacement. + * @param patternString Regular expression matcher pattern. + * @param replacement Replacement. + * @param flags Substitution Flags (currently ignored). + */ + public Substitution(@NotNull final String patternString, @NotNull final String replacement, @Nullable final String flags) { + this(patternString, replacement, parseFlags(flags)); + } + + /** Creates an unmodifiable map with the flags. + * @return Unmodifiable map with the flags. + */ + private static Map<Character, Integer> createFlagMap() { + final Map<Character, Integer> flagMap = new HashMap<Character, Integer>(); + flagMap.put('d', Pattern.UNIX_LINES); + flagMap.put('i', Pattern.CASE_INSENSITIVE); + flagMap.put('x', Pattern.COMMENTS); + flagMap.put('m', Pattern.MULTILINE); + flagMap.put('l', Pattern.LITERAL); // TODO check char + flagMap.put('s', Pattern.DOTALL); + flagMap.put('u', Pattern.UNICODE_CASE); + flagMap.put('c', Pattern.CANON_EQ); // TODO check char + return Collections.unmodifiableMap(flagMap); + } + + /** Converts a flag string into a flag value. + * @param flagString String that specifies substitution flags. + * @return Integer value with the flags. + * @throws IllegalArgumentException in case an invalid flag was specified. + */ + public static int parseFlags(@Nullable final String flagString) { + int flags = 0; + if (flagString != null) { + StringBuilder bogusFlags = null; + for (final char c : flagString.toCharArray()) { + final Integer flag = flagMap.get(c); + if (flag == null) { + if (bogusFlags == null) { + bogusFlags = new StringBuilder(); + } + bogusFlags.append(c); + } else { + flags |= flag; + } + } + if (bogusFlags != null) { + throw new IllegalArgumentException("Unsupported flags: " + bogusFlags); + } + } + return flags; + } + + /** Splits a substitution String into its subcomponents. + * @param regex Substitution String to split. + * @return The three subcomponents pattern, replacement and flags. + */ + public static String[] parseRegex(@NotNull final CharSequence regex) { + final String[] parsed = new String[3]; + final Matcher matcher = rePattern.matcher(regex); + if (!matcher.matches()) { + throw new IllegalArgumentException("Malformed substitution command."); + } + parsed[0] = matcher.group(1); + parsed[1] = matcher.group(2); + parsed[2] = matcher.group(3); + return parsed; + } + + /** Returns a String which represents <var>s</var> after performing all substitutions. + * @param s CharSequence in which to perform the substitution. + * @return a String which represents <var>s</var> after performing all substitutions. + */ + public String replaceAll(final CharSequence s) { + matcher.reset(s); + return matcher.replaceAll(replacement); + } + + /** Returns the regular expression pattern that is used to perform this Substitution. + * @return The regular expression pattern that is used to perform this Substitution. + */ + public String getPatternString() { + return patternString; + } + + /** Returns the replacement String that is used to perform this Substitution. + * @return The replacement String that is used to perform this Substitution. + */ + public String getReplacement() { + return replacement; + } + + /** Returns the flags that are used to perform this Substitution. + * @return The flags that are used to perform this Substitution. + */ + public int getFlags() { + return flags; + } + +} Property changes on: tools/replacer/trunk/src/prj/net/sf/japi/tools/replacer/Substitution.java ___________________________________________________________________ Name: svn:executable + * Name: svn:mime-type + text/plain Name: svn:eol-style + LF Added: tools/replacer/trunk/src/tst/test/net/sf/japi/tools/replacer/ReplacerTest.java =================================================================== --- tools/replacer/trunk/src/tst/test/net/sf/japi/tools/replacer/ReplacerTest.java (rev 0) +++ tools/replacer/trunk/src/tst/test/net/sf/japi/tools/replacer/ReplacerTest.java 2008-03-11 22:54:11 UTC (rev 637) @@ -0,0 +1,103 @@ +package test.net.sf.japi.tools.replacer; + +import net.sf.japi.io.args.BasicCommand; +import net.sf.japi.tools.replacer.Replacer; +import net.sf.japi.tools.replacer.Substitution; +import org.junit.Assert; +import org.junit.Test; + +import java.util.Collection; + +/** Unit Test for {@link Replacer}. + * @author <a href="mailto:ch...@ri...">Christian Hujer</a> + */ +public class ReplacerTest { + + /** Tests that a default constructor exists, doesn't throw an exception and creates the command with proper default options. */ + @Test + public void testConstructor() { + final Replacer replacer = new Replacer(); + Assert.assertFalse(replacer.isForce()); + Assert.assertFalse(replacer.isBackup()); + Assert.assertFalse(replacer.isRecursive()); + Assert.assertFalse(replacer.isExiting()); + Assert.assertEquals(Replacer.DEFAULT_BACKUP_EXTENSION, replacer.getBackupExtension()); + } + + /** Tests that setting the force option works. */ + @Test + public void testForce() { + final Replacer replacer = new Replacer(); + Assert.assertFalse(replacer.isForce()); + replacer.setForce(true); + Assert.assertTrue(replacer.isForce()); + replacer.setForce(false); + Assert.assertFalse(replacer.isForce()); + } + + /** Tests that setting the backup option works. */ + @Test + public void testBackup() { + final Replacer replacer = new Replacer(); + Assert.assertFalse(replacer.isBackup()); + replacer.setBackup(true); + Assert.assertTrue(replacer.isBackup()); + replacer.setBackup(false); + Assert.assertFalse(replacer.isBackup()); + } + + /** Tests that setting the backup option works. */ + @Test + public void testRecursive() { + final Replacer replacer = new Replacer(); + Assert.assertFalse(replacer.isRecursive()); + replacer.setRecursive(true); + Assert.assertTrue(replacer.isRecursive()); + replacer.setRecursive(false); + Assert.assertFalse(replacer.isRecursive()); + } + + /** Tests that setting the exiting option works. */ + @Test + public void testExiting() { + final BasicCommand replacer = new Replacer(); + Assert.assertFalse(replacer.isExiting()); + replacer.setExiting(true); + Assert.assertTrue(replacer.isExiting()); + replacer.setExiting(false); + Assert.assertFalse(replacer.isExiting()); + } + + /** Tests that setting the backup extension option works. */ + @Test + public void testBackupExtension() { + final Replacer replacer = new Replacer(); + Assert.assertEquals(Replacer.DEFAULT_BACKUP_EXTENSION, replacer.getBackupExtension()); + replacer.setBackupExtension(".foo"); + Assert.assertEquals(".foo", replacer.getBackupExtension()); + replacer.setBackupExtension(Replacer.DEFAULT_BACKUP_EXTENSION); + Assert.assertEquals(Replacer.DEFAULT_BACKUP_EXTENSION, replacer.getBackupExtension()); + } + + /** Tests that setting the substitutions works. */ + @Test + public void testSubstitutions() { + final Replacer replacer = new Replacer(); + final Collection<Substitution> substitutions = replacer.getSubstitutions(); + Assert.assertEquals(0, substitutions.size()); + replacer.addSubstitution("s/foo/bar/"); + Assert.assertEquals(1, substitutions.size()); + replacer.addSubstitution("s/buzz/bazz/"); + Assert.assertEquals(2, substitutions.size()); + } + + @Test + public void testSimple() { + final Replacer replacer = new Replacer(); + replacer.addSubstitution("s/foo/bar/"); + final String original = "foo"; + final String expected = "bar"; + final CharSequence replaced = replacer.replaceAll(original); + Assert.assertTrue(Replacer.equals(expected, replaced)); + } +} Property changes on: tools/replacer/trunk/src/tst/test/net/sf/japi/tools/replacer/ReplacerTest.java ___________________________________________________________________ Name: svn:executable + * Name: svn:mime-type + text/plain Name: svn:eol-style + LF Added: tools/replacer/trunk/src/tst/test/net/sf/japi/tools/replacer/SubstitutionTest.java =================================================================== --- tools/replacer/trunk/src/tst/test/net/sf/japi/tools/replacer/SubstitutionTest.java (rev 0) +++ tools/replacer/trunk/src/tst/test/net/sf/japi/tools/replacer/SubstitutionTest.java 2008-03-11 22:54:11 UTC (rev 637) @@ -0,0 +1,138 @@ +package test.net.sf.japi.tools.replacer; + +import org.junit.Assert; +import org.junit.Test; + +import java.util.regex.Pattern; + +import net.sf.japi.tools.replacer.Substitution; + +/** Tests that {@link net.sf.japi.tools.replacer.Substitution}. + * @author <a href="mailto:ch...@ri...">Christian Hujer</a> + */ +public class SubstitutionTest { + + /** Tests that {@link net.sf.japi.tools.replacer.Substitution (String, String)} works. */ + @Test + public void testSimpleSubstitution() { + final Substitution testling = new Substitution("foo", "bar"); + Assert.assertEquals("foo", testling.getPatternString()); + Assert.assertEquals("bar", testling.getReplacement()); + Assert.assertEquals(0, testling.getFlags()); + final String testText = "my foo my foo fuzz"; + final String replaced = testling.replaceAll(testText); + Assert.assertEquals("my bar my bar fuzz", replaced); + } + + /** Tests that {@link Substitution(String)} works for simple substitutions. */ + @Test + public void testParseSimple() { + final Substitution testling = new Substitution("s/foo/bar/"); + Assert.assertEquals("foo", testling.getPatternString()); + Assert.assertEquals("bar", testling.getReplacement()); + Assert.assertEquals(0, testling.getFlags()); + final String testText = "my foo my foo fuzz"; + final String replaced = testling.replaceAll(testText); + Assert.assertEquals("my bar my bar fuzz", replaced); + } + + /** Tests that {@link Substitution(String)} works when the substitution contains an escaped slash. */ + @Test + public void testParseRegexEscapedSlash() { + final String[] parsed = Substituti... [truncated message content] |