commons-exec-1.3-src/build.xml100644 0 0 16514 12425540622 13540 0ustar 0 0 ================================= WARNING ================================ JUnit isn't present in your classpath. Tests not executed. ========================================================================== commons-exec-1.3-src/findbugs-exclude-filter.xml100644 0 0 2660 12425540624 17133 0ustar 0 0 commons-exec-1.3-src/LICENSE.txt100644 0 0 27301 12425540622 13536 0ustar 0 0 /* * Apache License * Version 2.0, January 2004 * http://www.apache.org/licenses/ * * TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION * * 1. Definitions. * * "License" shall mean the terms and conditions for use, reproduction, * and distribution as defined by Sections 1 through 9 of this document. * * "Licensor" shall mean the copyright owner or entity authorized by * the copyright owner that is granting the License. * * "Legal Entity" shall mean the union of the acting entity and all * other entities that control, are controlled by, or are under common * control with that entity. For the purposes of this definition, * "control" means (i) the power, direct or indirect, to cause the * direction or management of such entity, whether by contract or * otherwise, or (ii) ownership of fifty percent (50%) or more of the * outstanding shares, or (iii) beneficial ownership of such entity. * * "You" (or "Your") shall mean an individual or Legal Entity * exercising permissions granted by this License. * * "Source" form shall mean the preferred form for making modifications, * including but not limited to software source code, documentation * source, and configuration files. * * "Object" form shall mean any form resulting from mechanical * transformation or translation of a Source form, including but * not limited to compiled object code, generated documentation, * and conversions to other media types. * * "Work" shall mean the work of authorship, whether in Source or * Object form, made available under the License, as indicated by a * copyright notice that is included in or attached to the work * (an example is provided in the Appendix below). * * "Derivative Works" shall mean any work, whether in Source or Object * form, that is based on (or derived from) the Work and for which the * editorial revisions, annotations, elaborations, or other modifications * represent, as a whole, an original work of authorship. For the purposes * of this License, Derivative Works shall not include works that remain * separable from, or merely link (or bind by name) to the interfaces of, * the Work and Derivative Works thereof. * * "Contribution" shall mean any work of authorship, including * the original version of the Work and any modifications or additions * to that Work or Derivative Works thereof, that is intentionally * submitted to Licensor for inclusion in the Work by the copyright owner * or by an individual or Legal Entity authorized to submit on behalf of * the copyright owner. For the purposes of this definition, "submitted" * means any form of electronic, verbal, or written communication sent * to the Licensor or its representatives, including but not limited to * communication on electronic mailing lists, source code control systems, * and issue tracking systems that are managed by, or on behalf of, the * Licensor for the purpose of discussing and improving the Work, but * excluding communication that is conspicuously marked or otherwise * designated in writing by the copyright owner as "Not a Contribution." * * "Contributor" shall mean Licensor and any individual or Legal Entity * on behalf of whom a Contribution has been received by Licensor and * subsequently incorporated within the Work. * * 2. Grant of Copyright License. Subject to the terms and conditions of * this License, each Contributor hereby grants to You a perpetual, * worldwide, non-exclusive, no-charge, royalty-free, irrevocable * copyright license to reproduce, prepare Derivative Works of, * publicly display, publicly perform, sublicense, and distribute the * Work and such Derivative Works in Source or Object form. * * 3. Grant of Patent License. Subject to the terms and conditions of * this License, each Contributor hereby grants to You a perpetual, * worldwide, non-exclusive, no-charge, royalty-free, irrevocable * (except as stated in this section) patent license to make, have made, * use, offer to sell, sell, import, and otherwise transfer the Work, * where such license applies only to those patent claims licensable * by such Contributor that are necessarily infringed by their * Contribution(s) alone or by combination of their Contribution(s) * with the Work to which such Contribution(s) was submitted. If You * institute patent litigation against any entity (including a * cross-claim or counterclaim in a lawsuit) alleging that the Work * or a Contribution incorporated within the Work constitutes direct * or contributory patent infringement, then any patent licenses * granted to You under this License for that Work shall terminate * as of the date such litigation is filed. * * 4. Redistribution. You may reproduce and distribute copies of the * Work or Derivative Works thereof in any medium, with or without * modifications, and in Source or Object form, provided that You * meet the following conditions: * * (a) You must give any other recipients of the Work or * Derivative Works a copy of this License; and * * (b) You must cause any modified files to carry prominent notices * stating that You changed the files; and * * (c) You must retain, in the Source form of any Derivative Works * that You distribute, all copyright, patent, trademark, and * attribution notices from the Source form of the Work, * excluding those notices that do not pertain to any part of * the Derivative Works; and * * (d) If the Work includes a "NOTICE" text file as part of its * distribution, then any Derivative Works that You distribute must * include a readable copy of the attribution notices contained * within such NOTICE file, excluding those notices that do not * pertain to any part of the Derivative Works, in at least one * of the following places: within a NOTICE text file distributed * as part of the Derivative Works; within the Source form or * documentation, if provided along with the Derivative Works; or, * within a display generated by the Derivative Works, if and * wherever such third-party notices normally appear. The contents * of the NOTICE file are for informational purposes only and * do not modify the License. You may add Your own attribution * notices within Derivative Works that You distribute, alongside * or as an addendum to the NOTICE text from the Work, provided * that such additional attribution notices cannot be construed * as modifying the License. * * You may add Your own copyright statement to Your modifications and * may provide additional or different license terms and conditions * for use, reproduction, or distribution of Your modifications, or * for any such Derivative Works as a whole, provided Your use, * reproduction, and distribution of the Work otherwise complies with * the conditions stated in this License. * * 5. Submission of Contributions. Unless You explicitly state otherwise, * any Contribution intentionally submitted for inclusion in the Work * by You to the Licensor shall be under the terms and conditions of * this License, without any additional terms or conditions. * Notwithstanding the above, nothing herein shall supersede or modify * the terms of any separate license agreement you may have executed * with Licensor regarding such Contributions. * * 6. Trademarks. This License does not grant permission to use the trade * names, trademarks, service marks, or product names of the Licensor, * except as required for reasonable and customary use in describing the * origin of the Work and reproducing the content of the NOTICE file. * * 7. Disclaimer of Warranty. Unless required by applicable law or * agreed to in writing, Licensor provides the Work (and each * Contributor provides its Contributions) on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied, including, without limitation, any warranties or conditions * of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A * PARTICULAR PURPOSE. You are solely responsible for determining the * appropriateness of using or redistributing the Work and assume any * risks associated with Your exercise of permissions under this License. * * 8. Limitation of Liability. In no event and under no legal theory, * whether in tort (including negligence), contract, or otherwise, * unless required by applicable law (such as deliberate and grossly * negligent acts) or agreed to in writing, shall any Contributor be * liable to You for damages, including any direct, indirect, special, * incidental, or consequential damages of any character arising as a * result of this License or out of the use or inability to use the * Work (including but not limited to damages for loss of goodwill, * work stoppage, computer failure or malfunction, or any and all * other commercial damages or losses), even if such Contributor * has been advised of the possibility of such damages. * * 9. Accepting Warranty or Additional Liability. While redistributing * the Work or Derivative Works thereof, You may choose to offer, * and charge a fee for, acceptance of support, warranty, indemnity, * or other liability obligations and/or rights consistent with this * License. However, in accepting such obligations, You may act only * on Your own behalf and on Your sole responsibility, not on behalf * of any other Contributor, and only if You agree to indemnify, * defend, and hold each Contributor harmless for any liability * incurred by, or claims asserted against, such Contributor by reason * of your accepting any such warranty or additional liability. * * END OF TERMS AND CONDITIONS * * APPENDIX: How to apply the Apache License to your work. * * To apply the Apache License to your work, attach the following * boilerplate notice, with the fields enclosed by brackets "[]" * replaced with your own identifying information. (Don't include * the brackets!) The text should be enclosed in the appropriate * comment syntax for the file format. We also recommend that a * file or class name and description of purpose be included on the * same "printed page" as the copyright notice for easier * identification within third-party archives. * * Copyright [yyyy] [name of copyright owner] * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ commons-exec-1.3-src/NOTICE.txt100644 0 0 262 12425540622 13372 0ustar 0 0 Apache Commons Exec Copyright 2005-2014 The Apache Software Foundation This product includes software developed at The Apache Software Foundation (http://www.apache.org/). commons-exec-1.3-src/pmd.xml100644 0 0 2317 12425540622 13175 0ustar 0 0 Excludes from default PMD rules. commons-exec-1.3-src/pom.xml100644 0 0 25362 12425540716 13241 0ustar 0 0 org.apache.commons commons-parent 35 4.0.0 Apache Commons Exec org.apache.commons commons-exec 1.3 Apache Commons Exec is a library to reliably execute external processes from within the JVM. 2.2.1 http://commons.apache.org/proper/commons-exec/ jira http://issues.apache.org/jira/browse/EXEC scm:svn:http://svn.apache.org/repos/asf/commons/proper/exec/trunk scm:svn:https://svn.apache.org/repos/asf/commons/proper/exec/trunk http://svn.apache.org/viewvc/commons/proper/exec/trunk junit junit 4.11 test brett Brett Porter Apache +10 trygvis Trygve Laugstøl Apache +1 sgoeschl Siegfried Goeschl Apache +1 sebb Sebastian Bazley Apache +1 Gary Gregory ggregory Apache ggregory@apache.org http://www.garygregory.com -5 Niklas Gustavsson Benjamin Bentmann Marco Ferrante Jerome Lacoste Milos Kleint Pablo Hoertner Niall Pemberton org.apache.maven.plugins maven-surefire-plugin **/TestUtil.java maven-assembly-plugin src/main/assembly/bin.xml src/main/assembly/src.xml gnu org.apache.maven.plugins maven-jar-plugin true true org.apache.maven.plugins maven-release-plugin 2.0 forked-path stagingSite Apache Staging Website ${commons.deployment.protocol}://people.apache.org/www/commons.apache.org/${commons.componentid}/ org.apache.maven.plugins maven-pmd-plugin 3.2 ${maven.compiler.target} true ${basedir}/pmd.xml org.codehaus.mojo findbugs-maven-plugin 2.5.5 Normal Default ${basedir}/findbugs-exclude-filter.xml org.codehaus.sonar-plugins maven-report 0.1 coverage org.codehaus.mojo cobertura-maven-plugin 2.6 setup-checkout site-content org.apache.maven.plugins maven-antrun-plugin 1.7 prepare-checkout pre-site run 1.5 1.5 *Test exec EXEC 12310814 1.3 RC1 UTF-8 UTF-8 site-content commons-exec-1.3-src/RELEASE-NOTES.txt100644 0 0 5545 12425540622 14410 0ustar 0 0 Apache Commons Exec 1.3 RELEASE NOTES The Apache Commons Exec team is pleased to announce the commons-exec-1.3 release! Apache Commons Exec is a library to reliably execute external processes from within the JVM. Changes in this version include: New features: o DefaultExecutor async execute prevents shutdown hooks running. Issue: EXEC-69. Thanks to Richard Atkins, Michael Vorburger. Fixed Bugs: o Remove remaining raw types, unchecked conversions Issue: EXEC-81. Thanks to Stephen Compall. o NPE in EnvironmentUtils.toString(map) Issue: EXEC-80. Changes: o No need to use System.class.getMethod("getenv",...) any more Issue: EXEC-78. o Update JUnit dependency to 4.11 Issue: EXEC-77. o Update to Java 5 Issue: EXEC-76. Have fun! -Apache Commons Exec team ------------------------------------------------------------------------------- Apache Commons Exec 1.2 RELEASE NOTES The Apache Commons Exec team is pleased to announce the Apache commons-exec-1.2 release! Apache Commons Exec is a library to reliably execute external processes from within the JVM. Feature and fix release. Requires a minimum of Java 1.3. Changes in this version include: New features: o Set names for started threads. Issue: EXEC-55. Thanks to Dominik Stadler. Fixed Bugs: o Issue: EXEC-68. Watchdog kills process immediately if timeout is too large. Thanks to Joel McCance. o Issue: EXEC-57. Applied the patch from Nickolay Martinov but the timeout disguises the fact that the process might be still running. Therefore added a sanity check in order to throw an exception if the the timeout for join() was exceeded. Thanks to Nickolay Martinov. o Issue: EXEC-60. Fixed deadlock by calling the timeout observers outside of the synchronized block thereby removing a prerequisite of a deadlock. Also added a test case to demonstrate that this problem is fixed (which of course can not guarantee the absence of a dead lock). Thanks to Peter Kofler. o Issue: EXEC-52. Tests fail on HP-UX, because it uses a different syntax for the ping command. Thanks to Nickolay Martinov. o Issue: EXEC-49. "Write dead end" IOException when using Piped streams w/PumpStreamHandler. When encountering a PipedOutputStream we will automatically close it to avoid the exception. Thanks to Kevin Telford. o Issue: EXEC-34. Race condition prevent watchdog working using ExecuteStreamHandler. Patch submittd by Kristian Rosenvold. Thanks to Marco Ferrante. For complete information on Apache Commons Exec, including instructions on how to submit bug reports, patches, or suggestions for improvement, see the Apache Commons Exec website: http://commons.apache.org/proper/commons-exec/ Have fun! -Apache Commons Exec team commons-exec-1.3-src/STATUS100644 0 0 4766 12425540622 12653 0ustar 0 0 Proposal for Exec Package 28th July 2005 Rationale ------------------------------------ Executing external processes from Java is a well-known problem area. It is inheriently platform dependent and requires the developer to know and test for platform specific behaviors, for example using cmd.exe on Windows or limited buffer sizes causing deadlocks. The JRE support for this is very limited, albeit better with the new Java SE 1.5 ProcessBuilder class. Reliably executing external processes can also require knowledge of the environment variables before or after the command is executed. In J2SE 1.1-1.4 there is not support for this, since the method, System.getenv(), for retriving environment variables is deprecated (in later releases the deprecation was removed). The are currently several different libraries that for their own purposes has implemented frameworks around Runtime.exec() to handle the various issue outlined above. The proposed project should aim at coordinating and learning from these initatives to create and maintain a simple, reusable and well-tested package. Since some of the more problematic platforms are not readily available, it is my hope that the broad Apache community can be a great help. Scope of the package ------------------------------------ The package shall create and maintain a process execution package written in the Java language to be distributed under the ASF license. The Java code might also be complemented with scripts (e.g. Perl scripts) to fully enable execution on some operating systems. The package should aim for supporting a wide range of operating systems while still having a consistent API for all platforms. Identify the initial source for the package ------------------------------------ Several implementations exists and should be researched before finalizing the design: * Ant 1.X contains probably the most mature code within the exec task. This code has been stripped of the Ant specifics and cleaned up by Niklas Gustavsson and can be donated under the ASF license. * Ideas from http://ant.apache.org/ant2/actionlist.html#exec * plexus-utils has a similar but slimmer BSD-licensed implementation than Ant that can be reused Identify the base name for the package ------------------------------------ org.apache.commons.exec INITIAL COMMITTERS ------------------------------------ Brett Porter Stefan Bodewig Trygve Laugstol INITIAL CONTRIBUTORS ------------------------------------ Niklas Gustavsson Kev Jackson commons-exec-1.3-src/src/ 40755 0 0 0 12425540623 12363 5ustar 0 0 commons-exec-1.3-src/src/changes/ 40755 0 0 0 12425545060 13773 5ustar 0 0 commons-exec-1.3-src/src/main/ 40755 0 0 0 12425540623 13307 5ustar 0 0 commons-exec-1.3-src/src/main/assembly/ 40755 0 0 0 12425540624 15127 5ustar 0 0 commons-exec-1.3-src/src/main/java/ 40755 0 0 0 12425540623 14230 5ustar 0 0 commons-exec-1.3-src/src/main/java/org/ 40755 0 0 0 12425540623 15017 5ustar 0 0 commons-exec-1.3-src/src/main/java/org/apache/ 40755 0 0 0 12425540623 16240 5ustar 0 0 commons-exec-1.3-src/src/main/java/org/apache/commons/ 40755 0 0 0 12425540623 17713 5ustar 0 0 commons-exec-1.3-src/src/main/java/org/apache/commons/exec/ 40755 0 0 0 12425540624 20640 5ustar 0 0 commons-exec-1.3-src/src/main/java/org/apache/commons/exec/environment/ 40755 0 0 0 12425540624 23204 5ustar 0 0 commons-exec-1.3-src/src/main/java/org/apache/commons/exec/launcher/ 40755 0 0 0 12425540624 22441 5ustar 0 0 commons-exec-1.3-src/src/main/java/org/apache/commons/exec/util/ 40755 0 0 0 12425540624 21615 5ustar 0 0 commons-exec-1.3-src/src/media/ 40755 0 0 0 12425540622 13441 5ustar 0 0 commons-exec-1.3-src/src/site/ 40755 0 0 0 12425540624 13330 5ustar 0 0 commons-exec-1.3-src/src/site/apt/ 40755 0 0 0 12425545060 14113 5ustar 0 0 commons-exec-1.3-src/src/site/fml/ 40755 0 0 0 12425540624 14106 5ustar 0 0 commons-exec-1.3-src/src/site/resources/ 40755 0 0 0 12425540624 15342 5ustar 0 0 commons-exec-1.3-src/src/site/resources/images/ 40755 0 0 0 12425540624 16607 5ustar 0 0 commons-exec-1.3-src/src/site/xdoc/ 40755 0 0 0 12425540624 14265 5ustar 0 0 commons-exec-1.3-src/src/test/ 40755 0 0 0 12425540621 13340 5ustar 0 0 commons-exec-1.3-src/src/test/bin/ 40755 0 0 0 12425540623 14112 5ustar 0 0 commons-exec-1.3-src/src/test/java/ 40755 0 0 0 12425540621 14261 5ustar 0 0 commons-exec-1.3-src/src/test/java/org/ 40755 0 0 0 12425540621 15050 5ustar 0 0 commons-exec-1.3-src/src/test/java/org/apache/ 40755 0 0 0 12425540621 16271 5ustar 0 0 commons-exec-1.3-src/src/test/java/org/apache/commons/ 40755 0 0 0 12425540621 17744 5ustar 0 0 commons-exec-1.3-src/src/test/java/org/apache/commons/exec/ 40755 0 0 0 12425540623 20672 5ustar 0 0 commons-exec-1.3-src/src/test/java/org/apache/commons/exec/environment/ 40755 0 0 0 12425540623 23236 5ustar 0 0 commons-exec-1.3-src/src/test/java/org/apache/commons/exec/issues/ 40755 0 0 0 12425540623 22205 5ustar 0 0 commons-exec-1.3-src/src/test/java/org/apache/commons/exec/util/ 40755 0 0 0 12425540623 21647 5ustar 0 0 commons-exec-1.3-src/src/test/scripts/ 40755 0 0 0 12425540623 15031 5ustar 0 0 commons-exec-1.3-src/src/changes/changes.xml100644 0 0 36123 12425545060 16247 0ustar 0 0 commons-exec Siegfried Goeschl DefaultExecutor async execute prevents shutdown hooks running. Remove remaining raw types, unchecked conversions NPE in EnvironmentUtils.toString(map) No need to use System.class.getMethod("getenv",...) any more Update JUnit dependency to 4.11 Update to Java 5 Watchdog kills process immediately if timeout is too large. Applied the patch from Nickolay Martinov but the timeout disguises the fact that the process might be still running. Therefore added a sanity check in order to throw an exception if the the timeout for join() was exceeded. Fixed deadlock by calling the timeout observers outside of the synchronized block thereby removing a prerequisite of a deadlock. Also added a test case to demonstrate that this problem is fixed (which of course can not guarantee the absence of a dead lock). Set names for started threads. Tests fail on HP-UX, because it uses a different syntax for the ping command. "Write dead end" IOException when using Piped streams w/PumpStreamHandler. When encountering a PipedOutputStream we will automatically close it to avoid the exception. Race condition prevent watchdog working using ExecuteStreamHandler. Patch submittd by Kristian Rosenvold. OpenVMS now uses symbols instead of logicals for environment variables. Adding 'Argument' class and quote the arguments after expansion. Reverting changes of [EXEC-41] because the patch does not fix the problem. Also added test case for the broken patch. Added TutorialTest as a playground for new user and removed similar code from DefaultExecutorTest. String substitution handles now java.io.File instances in order to create a cross-platform file name. The 'forever.bat' accidentally overwrite the 'forever.txt' instead of appending. DefaultExecutor() now sets the working directory with the current working directory. Added 'DefaultExecutorTest#testStdInHandling' to show how commons-exec can feed the 'stdin' of a child process. Improved the documentation. Added a PumpStreamHandler.setAlwaysWaitForStreamThreads() which allows to skip joining with the pumper threads. Having said that - using that flag is for the desperate because it could leave up to three worker threads behind but there might be situations where this is the only escape. Process.waitFor should clear interrupt status when throwing InterruptedException Added 'DefaultExecuteResultHandler' Added a new section to the tutorial to show working with asynchronous processes. Thanks to Pablo for providing this documentation update. Because the ExecuteWatchdog is the only way to destroy asynchronous processes, it should be possible to set it to an infinite timeout, for processes which should not timeout, but manually destroyed under some circumstances. On a Mac, the unit tests never finish. Culprit is InputStreamPumper which sets its stop member in the run method; however, run might really be executed after the stopProcessing method is called if the process thread completes before the InputStreamPumper starts. Fixes NPE in DefaultExecutor.setExitValues(). Copies all data from an System.input stream to an output stream of the executed process. Removed useless synchronized statement in OpenVmsProcessingEnvironment.createProcEnvironment Using System.in for child process will actually hang your application - see JIRA for more details. Since there is no easy fix an IllegalRuntimeException is thrown when System.in is passed. Fixing a few findbugs issues. Handle null streams consistently. After a long discussion we decided to stick to following groupId "org.apache.commons" instead of "commons-exec". The Ant build now works even when junit is not on the classpath Fixed broken "groupId" from "org.apache.commons" to "commons-exec" Renamed EnvironmentUtil to EnvironmentUtils to align with other classes in this project and commons in general. Please note that this change could break existing clients (but would be rather unlikely). Make environment variables respect casing rules of platforms. Under Windows "PATH", "Path" and "path" would access the same environment variable whereas the real name is "Path". Invoking DefaultExecutor.execute(CommandLine command, Map environment) using a 'null' Map results in inheriting all environment variables of the current process while passing an empty map implies starting the new process with no environment variables. In short 'null' is not the same as an empty map. Added one additional test : DefaultExecutorTest.testExecuteWithFancyArg Using variable substitution within CommandLine broke the regression tests under Windows. Found also another bug when calling CommandLine.getExecutable() the result was not substituted at all. As a general rule we do variable substitution and file separator fixing on the command line executable and variable substitution but NO file separator fixing for the command line arguments. Added convinience method to add two parameters to the CommandLine using one method invocation. Implemented better regression test for OpenVMS affecting also the Executor and CommandLauncher interface. Added test scripts for OpenVMS - he seems to be the last human having access to an OpenVMS box ... :-) With the help of the Apache Commons community I added the first results of cross-OS testing. The regression tests now also works on Windows - so it should work now on Linux, Windows and Mac OS X Added DebugUtils to improve cross-platform testing. Removed commons-logging integration Made DefaultExecutor.launch() protected to enable mocking. Made ProcessDestroyer optional and pluggable when using Executor. CommandLine can now expand the given command line by a user-suppied map. This allows to execute something like "${JAVA_HOME}/bin/java -jar ${myapp}" Added methods to provide pre-quoted arguments. Exposing a ExecuteWatchdog.destroy() to kill an asynchrounous process manually. This formalizes a workaround described in the JIRA Extending exit value handling to support applications returning an error code. Cleaned up the source code to get rid of javadoc errors and unused imports. Added a few regression tests for the watchdog since they were missing. commons-exec-1.3-src/src/main/assembly/bin.xml100644 0 0 3155 12425540624 16522 0ustar 0 0 bin tar.gz zip false LICENSE.txt NOTICE.txt RELEASE-NOTES.txt target *.jar target/site/apidocs apidocs commons-exec-1.3-src/src/main/assembly/src.xml100644 0 0 4103 12425540623 16532 0ustar 0 0 src tar.gz zip ${artifactId}-${commons.release.version}-src build.xml findbugs-exclude-filter.xml LICENSE.txt NOTICE.txt pmd.xml pom.xml RELEASE-NOTES.txt STATUS src test/scripts/*.sh src 775 test/scripts/*.sh commons-exec-1.3-src/src/main/java/org/apache/commons/exec/CommandLine.java100644 0 0 34452 12425540624 24016 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.commons.exec; import java.io.File; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.StringTokenizer; import java.util.Vector; import org.apache.commons.exec.util.StringUtils; /** * CommandLine objects help handling command lines specifying processes to * execute. The class can be used to a command line by an application. * * @version $Id: CommandLine.java 1613094 2014-07-24 12:20:14Z ggregory $ */ public class CommandLine { /** * The arguments of the command. */ private final Vector arguments = new Vector(); /** * The program to execute. */ private final String executable; /** * A map of name value pairs used to expand command line arguments */ private Map substitutionMap; // N.B. This can contain values other than Strings /** * Was a file being used to set the executable? */ private final boolean isFile; /** * Create a command line from a string. * * @param line the first element becomes the executable, the rest the arguments * @return the parsed command line * @throws IllegalArgumentException If line is null or all whitespace */ public static CommandLine parse(final String line) { return parse(line, null); } /** * Create a command line from a string. * * @param line the first element becomes the executable, the rest the arguments * @param substitutionMap the name/value pairs used for substitution * @return the parsed command line * @throws IllegalArgumentException If line is null or all whitespace */ public static CommandLine parse(final String line, final Map substitutionMap) { if (line == null) { throw new IllegalArgumentException("Command line can not be null"); } else if (line.trim().length() == 0) { throw new IllegalArgumentException("Command line can not be empty"); } else { final String[] tmp = translateCommandline(line); final CommandLine cl = new CommandLine(tmp[0]); cl.setSubstitutionMap(substitutionMap); for (int i = 1; i < tmp.length; i++) { cl.addArgument(tmp[i]); } return cl; } } /** * Create a command line without any arguments. * * @param executable the executable */ public CommandLine(final String executable) { this.isFile=false; this.executable=toCleanExecutable(executable); } /** * Create a command line without any arguments. * * @param executable the executable file */ public CommandLine(final File executable) { this.isFile=true; this.executable=toCleanExecutable(executable.getAbsolutePath()); } /** * Copy constructor. * * @param other the instance to copy */ public CommandLine(final CommandLine other) { this.executable = other.getExecutable(); this.isFile = other.isFile(); this.arguments.addAll(other.arguments); if (other.getSubstitutionMap() != null) { final Map omap = new HashMap(); this.substitutionMap = omap; final Iterator iterator = other.substitutionMap.keySet().iterator(); while (iterator.hasNext()) { final String key = iterator.next(); omap.put(key, other.getSubstitutionMap().get(key)); } } } /** * Returns the executable. * * @return The executable */ public String getExecutable() { // Expand the executable and replace '/' and '\\' with the platform // specific file separator char. This is safe here since we know // that this is a platform specific command. return StringUtils.fixFileSeparatorChar(expandArgument(executable)); } /** * Was a file being used to set the executable? * * @return true if a file was used for setting the executable */ public boolean isFile() { return isFile; } /** * Add multiple arguments. Handles parsing of quotes and whitespace. * * @param addArguments An array of arguments * @return The command line itself */ public CommandLine addArguments(final String[] addArguments) { return this.addArguments(addArguments, true); } /** * Add multiple arguments. * * @param addArguments An array of arguments * @param handleQuoting Add the argument with/without handling quoting * @return The command line itself */ public CommandLine addArguments(final String[] addArguments, final boolean handleQuoting) { if (addArguments != null) { for (final String addArgument : addArguments) { addArgument(addArgument, handleQuoting); } } return this; } /** * Add multiple arguments. Handles parsing of quotes and whitespace. * Please note that the parsing can have undesired side-effects therefore * it is recommended to build the command line incrementally. * * @param addArguments An string containing multiple arguments. * @return The command line itself */ public CommandLine addArguments(final String addArguments) { return this.addArguments(addArguments, true); } /** * Add multiple arguments. Handles parsing of quotes and whitespace. * Please note that the parsing can have undesired side-effects therefore * it is recommended to build the command line incrementally. * * @param addArguments An string containing multiple arguments. * @param handleQuoting Add the argument with/without handling quoting * @return The command line itself */ public CommandLine addArguments(final String addArguments, final boolean handleQuoting) { if (addArguments != null) { final String[] argumentsArray = translateCommandline(addArguments); addArguments(argumentsArray, handleQuoting); } return this; } /** * Add a single argument. Handles quoting. * * @param argument The argument to add * @return The command line itself * @throws IllegalArgumentException If argument contains both single and double quotes */ public CommandLine addArgument(final String argument) { return this.addArgument(argument, true); } /** * Add a single argument. * * @param argument The argument to add * @param handleQuoting Add the argument with/without handling quoting * @return The command line itself */ public CommandLine addArgument(final String argument, final boolean handleQuoting) { if (argument == null) { return this; } // check if we can really quote the argument - if not throw an // IllegalArgumentException if (handleQuoting) { StringUtils.quoteArgument(argument); } arguments.add(new Argument(argument, handleQuoting)); return this; } /** * Returns the expanded and quoted command line arguments. * * @return The quoted arguments */ public String[] getArguments() { Argument currArgument; String expandedArgument; final String[] result = new String[arguments.size()]; for (int i=0; i getSubstitutionMap() { return substitutionMap; } /** * Set the substitutionMap to expand variables in the * command line. * * @param substitutionMap the map */ public void setSubstitutionMap(final Map substitutionMap) { this.substitutionMap = substitutionMap; } /** * Returns the command line as an array of strings. * * @return The command line as an string array */ public String[] toStrings() { final String[] result = new String[arguments.size() + 1]; result[0] = this.getExecutable(); System.arraycopy(getArguments(), 0, result, 1, result.length-1); return result; } /** * Stringify operator returns the command line as a string. * Parameters are correctly quoted when containing a space or * left untouched if the are already quoted. * * @return the command line as single string */ @Override public String toString() { return "[" + StringUtils.toString(toStrings(), ", ") + "]"; } // --- Implementation --------------------------------------------------- /** * Expand variables in a command line argument. * * @param argument the argument * @return the expanded string */ private String expandArgument(final String argument) { final StringBuffer stringBuffer = StringUtils.stringSubstitution(argument, this.getSubstitutionMap(), true); return stringBuffer.toString(); } /** * Crack a command line. * * @param toProcess * the command line to process * @return the command line broken into strings. An empty or null toProcess * parameter results in a zero sized array */ private static String[] translateCommandline(final String toProcess) { if (toProcess == null || toProcess.length() == 0) { // no command? no string return new String[0]; } // parse with a simple finite state machine final int normal = 0; final int inQuote = 1; final int inDoubleQuote = 2; int state = normal; final StringTokenizer tok = new StringTokenizer(toProcess, "\"\' ", true); final ArrayList list = new ArrayList(); StringBuilder current = new StringBuilder(); boolean lastTokenHasBeenQuoted = false; while (tok.hasMoreTokens()) { final String nextTok = tok.nextToken(); switch (state) { case inQuote: if ("\'".equals(nextTok)) { lastTokenHasBeenQuoted = true; state = normal; } else { current.append(nextTok); } break; case inDoubleQuote: if ("\"".equals(nextTok)) { lastTokenHasBeenQuoted = true; state = normal; } else { current.append(nextTok); } break; default: if ("\'".equals(nextTok)) { state = inQuote; } else if ("\"".equals(nextTok)) { state = inDoubleQuote; } else if (" ".equals(nextTok)) { if (lastTokenHasBeenQuoted || current.length() != 0) { list.add(current.toString()); current = new StringBuilder(); } } else { current.append(nextTok); } lastTokenHasBeenQuoted = false; break; } } if (lastTokenHasBeenQuoted || current.length() != 0) { list.add(current.toString()); } if (state == inQuote || state == inDoubleQuote) { throw new IllegalArgumentException("Unbalanced quotes in " + toProcess); } final String[] args = new String[list.size()]; return list.toArray(args); } /** * Cleans the executable string. The argument is trimmed and '/' and '\\' are * replaced with the platform specific file separator char * * @param dirtyExecutable the executable * @return the platform-specific executable string */ private String toCleanExecutable(final String dirtyExecutable) { if (dirtyExecutable == null) { throw new IllegalArgumentException("Executable can not be null"); } else if (dirtyExecutable.trim().length() == 0) { throw new IllegalArgumentException("Executable can not be empty"); } else { return StringUtils.fixFileSeparatorChar(dirtyExecutable); } } /** * Encapsulates a command line argument. */ class Argument { private final String value; private final boolean handleQuoting; private Argument(final String value, final boolean handleQuoting) { this.value = value.trim(); this.handleQuoting = handleQuoting; } private String getValue() { return value; } private boolean isHandleQuoting() { return handleQuoting; } } } commons-exec-1.3-src/src/main/java/org/apache/commons/exec/DaemonExecutor.java100644 0 0 3055 12425540624 24525 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.exec; /** * Runs daemon processes asynchronously. Callers are expected to register a {@link ProcessDestroyer} before executing * any processes. * * @since 1.3 */ public class DaemonExecutor extends DefaultExecutor { /** * Factory method to create a thread waiting for the result of an asynchronous execution. * * @param runnable * the runnable passed to the thread * @param name * the name of the thread * @return the thread */ @Override protected Thread createThread(final Runnable runnable, final String name) { final Thread t = super.createThread(runnable, name); t.setDaemon(true); return t; } } commons-exec-1.3-src/src/main/java/org/apache/commons/exec/DefaultExecuteResultHandler.java100644 0 0 11745 12425540624 27234 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.commons.exec; /** * A default implementation of 'ExecuteResultHandler' used for asynchronous * process handling. * * @version $Id: DefaultExecuteResultHandler.java 1636057 2014-11-01 21:14:00Z ggregory $ */ public class DefaultExecuteResultHandler implements ExecuteResultHandler { /** the interval polling the result */ private static final int SLEEP_TIME_MS = 50; /** Keep track if the process is still running */ private volatile boolean hasResult; /** The exit value of the finished process */ private volatile int exitValue; /** Any offending exception */ private volatile ExecuteException exception; /** * Constructor. */ public DefaultExecuteResultHandler() { this.hasResult = false; this.exitValue = Executor.INVALID_EXITVALUE; } /** * @see org.apache.commons.exec.ExecuteResultHandler#onProcessComplete(int) */ public void onProcessComplete(final int exitValue) { this.exitValue = exitValue; this.exception = null; this.hasResult = true; } /** * @see org.apache.commons.exec.ExecuteResultHandler#onProcessFailed(org.apache.commons.exec.ExecuteException) */ public void onProcessFailed(final ExecuteException e) { this.exitValue = e.getExitValue(); this.exception = e; this.hasResult = true; } /** * Get the {@code exception} causing the process execution to fail. * * @return Returns the exception. * @throws IllegalStateException if the process has not exited yet */ public ExecuteException getException() { if (!hasResult) { throw new IllegalStateException("The process has not exited yet therefore no result is available ..."); } return exception; } /** * Get the {@code exitValue} of the process. * * @return Returns the exitValue. * @throws IllegalStateException if the process has not exited yet */ public int getExitValue() { if (!hasResult) { throw new IllegalStateException("The process has not exited yet therefore no result is available ..."); } return exitValue; } /** * Has the process exited and a result is available, i.e. exitCode or exception? * * @return true if a result of the execution is available */ public boolean hasResult() { return hasResult; } /** * Causes the current thread to wait, if necessary, until the * process has terminated. This method returns immediately if * the process has already terminated. If the process has * not yet terminated, the calling thread will be blocked until the * process exits. * * @exception InterruptedException if the current thread is * {@linkplain Thread#interrupt() interrupted} by another * thread while it is waiting, then the wait is ended and * an {@link InterruptedException} is thrown. */ public void waitFor() throws InterruptedException { while (!hasResult()) { Thread.sleep(SLEEP_TIME_MS); } } /** * Causes the current thread to wait, if necessary, until the * process has terminated. This method returns immediately if * the process has already terminated. If the process has * not yet terminated, the calling thread will be blocked until the * process exits. * * @param timeout the maximum time to wait in milliseconds * @exception InterruptedException if the current thread is * {@linkplain Thread#interrupt() interrupted} by another * thread while it is waiting, then the wait is ended and * an {@link InterruptedException} is thrown. */ public void waitFor(final long timeout) throws InterruptedException { final long until = System.currentTimeMillis() + timeout; while (!hasResult() && System.currentTimeMillis() < until) { Thread.sleep(SLEEP_TIME_MS); } } }commons-exec-1.3-src/src/main/java/org/apache/commons/exec/DefaultExecutor.java100644 0 0 34350 12425540624 24730 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.exec; import java.io.File; import java.io.IOException; import java.util.Map; import org.apache.commons.exec.launcher.CommandLauncher; import org.apache.commons.exec.launcher.CommandLauncherFactory; /** * The default class to start a subprocess. The implementation * allows to *
    *
  • set a current working directory for the subprocess
  • *
  • provide a set of environment variables passed to the subprocess
  • *
  • capture the subprocess output of stdout and stderr using an ExecuteStreamHandler
  • *
  • kill long-running processes using an ExecuteWatchdog
  • *
  • define a set of expected exit values
  • *
  • terminate any started processes when the main process is terminating using a ProcessDestroyer
  • *
* * The following example shows the basic usage: * *
 * Executor exec = new DefaultExecutor();
 * CommandLine cl = new CommandLine("ls -l");
 * int exitvalue = exec.execute(cl);
 * 
* * @version $Id: DefaultExecutor.java 1636056 2014-11-01 21:12:52Z ggregory $ */ public class DefaultExecutor implements Executor { /** taking care of output and error stream */ private ExecuteStreamHandler streamHandler; /** the working directory of the process */ private File workingDirectory; /** monitoring of long running processes */ private ExecuteWatchdog watchdog; /** the exit values considered to be successful */ private int[] exitValues; /** launches the command in a new process */ private final CommandLauncher launcher; /** optional cleanup of started processes */ private ProcessDestroyer processDestroyer; /** worker thread for asynchronous execution */ private Thread executorThread; /** the first exception being caught to be thrown to the caller */ private IOException exceptionCaught; /** * Default constructor creating a default {@code PumpStreamHandler} * and sets the working directory of the subprocess to the current * working directory. * * The {@code PumpStreamHandler} pumps the output of the subprocess * into our {@code System.out} and {@code System.err} to avoid * into our {@code System.out} and {@code System.err} to avoid * a blocked or deadlocked subprocess (see{@link java.lang.Process Process}). */ public DefaultExecutor() { this.streamHandler = new PumpStreamHandler(); this.launcher = CommandLauncherFactory.createVMLauncher(); this.exitValues = new int[0]; this.workingDirectory = new File("."); this.exceptionCaught = null; } /** * @see org.apache.commons.exec.Executor#getStreamHandler() */ public ExecuteStreamHandler getStreamHandler() { return streamHandler; } /** * @see org.apache.commons.exec.Executor#setStreamHandler(org.apache.commons.exec.ExecuteStreamHandler) */ public void setStreamHandler(final ExecuteStreamHandler streamHandler) { this.streamHandler = streamHandler; } /** * @see org.apache.commons.exec.Executor#getWatchdog() */ public ExecuteWatchdog getWatchdog() { return watchdog; } /** * @see org.apache.commons.exec.Executor#setWatchdog(org.apache.commons.exec.ExecuteWatchdog) */ public void setWatchdog(final ExecuteWatchdog watchDog) { this.watchdog = watchDog; } /** * @see org.apache.commons.exec.Executor#getProcessDestroyer() */ public ProcessDestroyer getProcessDestroyer() { return this.processDestroyer; } /** * @see org.apache.commons.exec.Executor#setProcessDestroyer(ProcessDestroyer) */ public void setProcessDestroyer(final ProcessDestroyer processDestroyer) { this.processDestroyer = processDestroyer; } /** * @see org.apache.commons.exec.Executor#getWorkingDirectory() */ public File getWorkingDirectory() { return workingDirectory; } /** * @see org.apache.commons.exec.Executor#setWorkingDirectory(java.io.File) */ public void setWorkingDirectory(final File dir) { this.workingDirectory = dir; } /** * @see org.apache.commons.exec.Executor#execute(CommandLine) */ public int execute(final CommandLine command) throws ExecuteException, IOException { return execute(command, (Map) null); } /** * @see org.apache.commons.exec.Executor#execute(CommandLine, java.util.Map) */ public int execute(final CommandLine command, final Map environment) throws ExecuteException, IOException { if (workingDirectory != null && !workingDirectory.exists()) { throw new IOException(workingDirectory + " doesn't exist."); } return executeInternal(command, environment, workingDirectory, streamHandler); } /** * @see org.apache.commons.exec.Executor#execute(CommandLine, * org.apache.commons.exec.ExecuteResultHandler) */ public void execute(final CommandLine command, final ExecuteResultHandler handler) throws ExecuteException, IOException { execute(command, null, handler); } /** * @see org.apache.commons.exec.Executor#execute(CommandLine, * java.util.Map, org.apache.commons.exec.ExecuteResultHandler) */ public void execute(final CommandLine command, final Map environment, final ExecuteResultHandler handler) throws ExecuteException, IOException { if (workingDirectory != null && !workingDirectory.exists()) { throw new IOException(workingDirectory + " doesn't exist."); } if (watchdog != null) { watchdog.setProcessNotStarted(); } final Runnable runnable = new Runnable() { public void run() { int exitValue = Executor.INVALID_EXITVALUE; try { exitValue = executeInternal(command, environment, workingDirectory, streamHandler); handler.onProcessComplete(exitValue); } catch (final ExecuteException e) { handler.onProcessFailed(e); } catch (final Exception e) { handler.onProcessFailed(new ExecuteException("Execution failed", exitValue, e)); } } }; this.executorThread = createThread(runnable, "Exec Default Executor"); getExecutorThread().start(); } /** @see org.apache.commons.exec.Executor#setExitValue(int) */ public void setExitValue(final int value) { this.setExitValues(new int[] {value}); } /** @see org.apache.commons.exec.Executor#setExitValues(int[]) */ public void setExitValues(final int[] values) { this.exitValues = values == null ? null : (int[]) values.clone(); } /** @see org.apache.commons.exec.Executor#isFailure(int) */ public boolean isFailure(final int exitValue) { if (this.exitValues == null) { return false; } else if (this.exitValues.length == 0) { return this.launcher.isFailure(exitValue); } else { for (final int exitValue2 : this.exitValues) { if (exitValue2 == exitValue) { return false; } } } return true; } /** * Factory method to create a thread waiting for the result of an * asynchronous execution. * * @param runnable the runnable passed to the thread * @param name the name of the thread * @return the thread */ protected Thread createThread(final Runnable runnable, final String name) { return new Thread(runnable, name); } /** * Creates a process that runs a command. * * @param command * the command to run * @param env * the environment for the command * @param dir * the working directory for the command * @return the process started * @throws IOException * forwarded from the particular launcher used */ protected Process launch(final CommandLine command, final Map env, final File dir) throws IOException { if (this.launcher == null) { throw new IllegalStateException("CommandLauncher can not be null"); } if (dir != null && !dir.exists()) { throw new IOException(dir + " doesn't exist."); } return this.launcher.exec(command, env, dir); } /** * Get the worker thread being used for asynchronous execution. * * @return the worker thread */ protected Thread getExecutorThread() { return executorThread; } /** * Close the streams belonging to the given Process. * * @param process the Process. */ private void closeProcessStreams(final Process process) { try { process.getInputStream().close(); } catch (final IOException e) { setExceptionCaught(e); } try { process.getOutputStream().close(); } catch (final IOException e) { setExceptionCaught(e); } try { process.getErrorStream().close(); } catch (final IOException e) { setExceptionCaught(e); } } /** * Execute an internal process. If the executing thread is interrupted while waiting for the * child process to return the child process will be killed. * * @param command the command to execute * @param environment the execution environment * @param dir the working directory * @param streams process the streams (in, out, err) of the process * @return the exit code of the process * @throws IOException executing the process failed */ private int executeInternal(final CommandLine command, final Map environment, final File dir, final ExecuteStreamHandler streams) throws IOException { setExceptionCaught(null); final Process process = this.launch(command, environment, dir); try { streams.setProcessInputStream(process.getOutputStream()); streams.setProcessOutputStream(process.getInputStream()); streams.setProcessErrorStream(process.getErrorStream()); } catch (final IOException e) { process.destroy(); throw e; } streams.start(); try { // add the process to the list of those to destroy if the VM exits if (this.getProcessDestroyer() != null) { this.getProcessDestroyer().add(process); } // associate the watchdog with the newly created process if (watchdog != null) { watchdog.start(process); } int exitValue = Executor.INVALID_EXITVALUE; try { exitValue = process.waitFor(); } catch (final InterruptedException e) { process.destroy(); } finally { // see http://bugs.sun.com/view_bug.do?bug_id=6420270 // see https://issues.apache.org/jira/browse/EXEC-46 // Process.waitFor should clear interrupt status when throwing InterruptedException // but we have to do that manually Thread.interrupted(); } if (watchdog != null) { watchdog.stop(); } try { streams.stop(); } catch (final IOException e) { setExceptionCaught(e); } closeProcessStreams(process); if (getExceptionCaught() != null) { throw getExceptionCaught(); } if (watchdog != null) { try { watchdog.checkException(); } catch (final IOException e) { throw e; } catch (final Exception e) { throw new IOException(e.getMessage()); } } if (this.isFailure(exitValue)) { throw new ExecuteException("Process exited with an error: " + exitValue, exitValue); } return exitValue; } finally { // remove the process to the list of those to destroy if the VM exits if (this.getProcessDestroyer() != null) { this.getProcessDestroyer().remove(process); } } } /** * Keep track of the first IOException being thrown. * * @param e the IOException */ private void setExceptionCaught(final IOException e) { if (this.exceptionCaught == null) { this.exceptionCaught = e; } } /** * Get the first IOException being thrown. * * @return the first IOException being caught */ private IOException getExceptionCaught() { return this.exceptionCaught; } } ././@LongLink100644 0 0 151 12425545732 10261 Lustar 0 0 commons-exec-1.3-src/src/main/java/org/apache/commons/exec/environment/DefaultProcessingEnvironment.javacommons-exec-1.3-src/src/main/java/org/apache/commons/exec/environment/DefaultProcessingEnvironment.100644 0 0 21067 12425540624 31176 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.exec.environment; import java.io.BufferedReader; import java.io.IOException; import java.util.Comparator; import java.util.HashMap; import java.util.Map; import java.util.TreeMap; import org.apache.commons.exec.CommandLine; import org.apache.commons.exec.OS; /** * Helper class to determine the environment variable * for the OS. Depending on the JDK the environment * variables can be either retrieved directly from the * JVM or requires starting a process to get them running * an OS command line. * * @version $Id: DefaultProcessingEnvironment.java 1636056 2014-11-01 21:12:52Z ggregory $ */ public class DefaultProcessingEnvironment { /** the line separator of the system */ // private static final String LINE_SEPARATOR = System.getProperty("line.separator"); /** the environment variables of the process */ protected Map procEnvironment; /** * Find the list of environment variables for this process. * * @return a map containing the environment variables * @throws IOException obtaining the environment variables failed */ public synchronized Map getProcEnvironment() throws IOException { if (procEnvironment == null) { procEnvironment = this.createProcEnvironment(); } // create a copy of the map just in case that // anyone is going to modifiy it, e.g. removing // or setting an evironment variable final Map copy = createEnvironmentMap(); copy.putAll(procEnvironment); return copy; } /** * Find the list of environment variables for this process. * * @return a amp containing the environment variables * @throws IOException the operation failed */ protected Map createProcEnvironment() throws IOException { if (procEnvironment == null) { final Map env = System.getenv(); procEnvironment = createEnvironmentMap(); procEnvironment.putAll(env); } // No longer needed // if (procEnvironment == null) { // procEnvironment = createEnvironmentMap(); // final BufferedReader in = runProcEnvCommand(); // // String var = null; // String line; // while ((line = in.readLine()) != null) { // if (line.indexOf('=') == -1) { // // Chunk part of previous env var (UNIX env vars can // // contain embedded new lines). // if (var == null) { // var = LINE_SEPARATOR + line; // } else { // var += LINE_SEPARATOR + line; // } // } else { // // New env var...append the previous one if we have it. // if (var != null) { // EnvironmentUtils.addVariableToEnvironment(procEnvironment, var); // } // var = line; // } // } // // Since we "look ahead" before adding, there's one last env var. // if (var != null) { // EnvironmentUtils.addVariableToEnvironment(procEnvironment, var); // } // } return procEnvironment; } /** * Start a process to list the environment variables. * * @return a reader containing the output of the process * @throws IOException starting the process failed * @deprecated No longer needed */ @Deprecated protected BufferedReader runProcEnvCommand() throws IOException { // final ByteArrayOutputStream out = new ByteArrayOutputStream(); // final Executor exe = new DefaultExecutor(); // exe.setStreamHandler(new PumpStreamHandler(out)); // // ignore the exit value - Just try to use what we got // exe.execute(getProcEnvCommand()); // return new BufferedReader(new StringReader(toString(out))); return null; } /** * Determine the OS specific command line to get a list of environment * variables. * * @return the command line * @deprecated No longer needed */ @Deprecated protected CommandLine getProcEnvCommand() { // String executable; // String[] arguments = null; // if (OS.isFamilyOS2()) { // // OS/2 - use same mechanism as Windows 2000 // executable = "cmd"; // // arguments = new String[] {"/c", "set"}; // } else if (OS.isFamilyWindows()) { // // Determine if we're running under XP/2000/NT or 98/95 // if (OS.isFamilyWin9x()) { // executable = "command.com"; // // Windows 98/95 // } else { // executable = "cmd"; // // Windows XP/2000/NT/2003 // } // arguments = new String[] {"/c", "set"}; // } else if (OS.isFamilyZOS() || OS.isFamilyUnix()) { // // On most systems one could use: /bin/sh -c env // // // Some systems have /bin/env, others /usr/bin/env, just try // if (new File("/bin/env").canRead()) { // executable = "/bin/env"; // } else if (new File("/usr/bin/env").canRead()) { // executable = "/usr/bin/env"; // } else { // // rely on PATH // executable = "env"; // } // } else if (OS.isFamilyNetware() || OS.isFamilyOS400()) { // // rely on PATH // executable = "env"; // } else { // // MAC OS 9 and previous // // TODO: I have no idea how to get it, someone must fix it // executable = null; // } final CommandLine commandLine = null; // if (executable != null) { // commandLine = new CommandLine(executable); // commandLine.addArguments(arguments); // } return commandLine; } // /** // * ByteArrayOutputStream#toString doesn't seem to work reliably on OS/390, // * at least not the way we use it in the execution context. // * // * @param bos // * the output stream that one wants to read // * @return the output stream as a string, read with special encodings in the // * case of z/os and os/400 // */ // private String toString(final ByteArrayOutputStream bos) { // if (OS.isFamilyZOS()) { // try { // return bos.toString("Cp1047"); // } catch (final java.io.UnsupportedEncodingException e) { // // noop default encoding used // } // } else if (OS.isFamilyOS400()) { // try { // return bos.toString("Cp500"); // } catch (final java.io.UnsupportedEncodingException e) { // // noop default encoding used // } // } // return bos.toString(); // } /** * Creates a map that obeys the casing rules of the current platform for key * lookup. E.g. on a Windows platform, the map keys will be * case-insensitive. * * @return The map for storage of environment variables, never * {@code null}. */ private Map createEnvironmentMap() { if (OS.isFamilyWindows()) { return new TreeMap(new Comparator() { public int compare(final String key0, final String key1) { return key0.compareToIgnoreCase(key1); } }); } return new HashMap(); } } commons-exec-1.3-src/src/main/java/org/apache/commons/exec/environment/EnvironmentUtils.java100644 0 0 10612 12425540624 27511 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.commons.exec.environment; import java.io.IOException; import java.util.Map; import java.util.Map.Entry; //import org.apache.commons.exec.OS; /** * Wrapper for environment variables. * * @version $Id: EnvironmentUtils.java 1636056 2014-11-01 21:12:52Z ggregory $ */ public class EnvironmentUtils { private static final DefaultProcessingEnvironment PROCESSING_ENVIRONMENT_IMPLEMENTATION; static { // if (OS.isFamilyOpenVms()) { // PROCESSING_ENVIRONMENT_IMPLEMENTATION = new OpenVmsProcessingEnvironment(); // } else { PROCESSING_ENVIRONMENT_IMPLEMENTATION = new DefaultProcessingEnvironment(); // } } /** * Disable constructor. */ private EnvironmentUtils() { } /** * Get the variable list as an array. * * @param environment the environment to use, may be {@code null} * @return array of key=value assignment strings or {@code null} if and only if * the input map was {@code null} */ public static String[] toStrings(final Map environment) { if (environment == null) { return null; } final String[] result = new String[environment.size()]; int i = 0; for (final Entry entry : environment.entrySet()) { final String key = entry.getKey() == null ? "" : entry.getKey().toString(); final String value = entry.getValue() == null ? "" : entry.getValue().toString(); result[i] = key + "=" + value; i++; } return result; } /** * Find the list of environment variables for this process. The returned map preserves * the casing of a variable's name on all platforms but obeys the casing rules of the * current platform during lookup, e.g. key names will be case-insensitive on Windows * platforms. * * @return a map containing the environment variables, may be empty but never {@code null} * @throws IOException the operation failed */ public static Map getProcEnvironment() throws IOException { return PROCESSING_ENVIRONMENT_IMPLEMENTATION.getProcEnvironment(); } /** * Add a key/value pair to the given environment. * If the key matches an existing key, the previous setting is replaced. * * @param environment the current environment * @param keyAndValue the key/value pair */ public static void addVariableToEnvironment(final Map environment, final String keyAndValue) { final String[] parsedVariable = parseEnvironmentVariable(keyAndValue); environment.put(parsedVariable[0], parsedVariable[1]); } /** * Split a key/value pair into a String[]. It is assumed * that the ky/value pair contains a '=' character. * * @param keyAndValue the key/value pair * @return a String[] containing the key and value */ private static String[] parseEnvironmentVariable(final String keyAndValue) { final int index = keyAndValue.indexOf('='); if (index == -1) { throw new IllegalArgumentException( "Environment variable for this platform " + "must contain an equals sign ('=')"); } final String[] result = new String[2]; result[0] = keyAndValue.substring(0, index); result[1] = keyAndValue.substring(index + 1); return result; } } ././@LongLink100644 0 0 151 12425545732 10261 Lustar 0 0 commons-exec-1.3-src/src/main/java/org/apache/commons/exec/environment/OpenVmsProcessingEnvironment.javacommons-exec-1.3-src/src/main/java/org/apache/commons/exec/environment/OpenVmsProcessingEnvironment.100644 0 0 7324 12425540624 31161 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.exec.environment; //import java.io.BufferedReader; //import java.io.IOException; //import java.util.HashMap; //import java.util.Map; // //import org.apache.commons.exec.CommandLine; /** * Helper class to determine the environment variable * for VMS. * * @version $Id: OpenVmsProcessingEnvironment.java 1636056 2014-11-01 21:12:52Z ggregory $ * @deprecated No longer needed */ @Deprecated public class OpenVmsProcessingEnvironment extends DefaultProcessingEnvironment { /* * Hopefully removing super-class overrides won't cause Clirr error. * If necessary can just delegate to super-class. */ // /** // * Find the list of environment variables for this process. // * // * @return a map containing the environment variables // * @throws IOException the operation failed // */ // @Override // protected Map createProcEnvironment() throws IOException { // if (procEnvironment == null) { // final BufferedReader in = runProcEnvCommand(); // procEnvironment = addVMSenvironmentVariables(new HashMap(), in); // } // // return procEnvironment; // } // // /** // * Determine the OS specific command line to get a list of environment // * variables. // * // * @return the command line // */ // @Override // protected CommandLine getProcEnvCommand() { // final CommandLine commandLine = new CommandLine("show"); // commandLine.addArgument("symbol/global"); // the parser assumes symbols are global // commandLine.addArgument("*"); // return commandLine; // } // // /** // * This method is VMS specific and used by getProcEnvironment(). Parses VMS // * symbols from {@code in} and adds them to {@code environment}. // * {@code in} is expected to be the output of "SHOW SYMBOL/GLOBAL *". // * // * @param environment the current environment // * @param in the reader from the process to determine VMS env variables // * @return the updated environment // * @throws IOException operation failed // */ // private Map addVMSenvironmentVariables(final Map environment, // final BufferedReader in) throws IOException { // String line; // while ((line = in.readLine()) != null) { // final String SEP = "=="; // global symbol separator // final int sepidx = line.indexOf(SEP); // if (sepidx > 0) { // final String name = line.substring(0, sepidx).trim(); // String value = line.substring(sepidx+SEP.length()).trim(); // value = value.substring(1,value.length()-1); // drop enclosing quotes // environment.put(name,value); // } // } // return environment; // } } commons-exec-1.3-src/src/main/java/org/apache/commons/exec/ExecuteException.java100644 0 0 5367 12425540624 25074 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.commons.exec; import java.io.IOException; /** * An exception indicating that the executing a subprocesses failed. * * @version $Id: ExecuteException.java 1636056 2014-11-01 21:12:52Z ggregory $ */ public class ExecuteException extends IOException { /** * Comment for {@code serialVersionUID}. */ private static final long serialVersionUID = 3256443620654331699L; /** * The underlying cause of this exception. */ private final Throwable cause; /** * The exit value returned by the failed process */ private final int exitValue; /** * Construct a new exception with the specified detail message. * * @param message * The detail message * @param exitValue The exit value */ public ExecuteException(final String message, final int exitValue) { super(message + " (Exit value: " + exitValue + ")"); this.cause = null; this.exitValue = exitValue; } /** * Construct a new exception with the specified detail message and cause. * * @param message * The detail message * @param exitValue The exit value * @param cause * The underlying cause */ public ExecuteException(final String message, final int exitValue, final Throwable cause) { super(message + " (Exit value: " + exitValue + ". Caused by " + cause + ")"); this.cause = cause; // Two-argument version requires JDK 1.4 or later this.exitValue = exitValue; } /** * Return the underlying cause of this exception (if any). */ @Override public Throwable getCause() { return this.cause; } /** * Gets the exit value returned by the failed process * @return The exit value */ public int getExitValue() { return exitValue; } } commons-exec-1.3-src/src/main/java/org/apache/commons/exec/ExecuteResultHandler.java100644 0 0 3237 12425540624 25704 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.commons.exec; /** * The callback handlers for the result of asynchronous process execution. When a * process is started asynchronously the callback provides you with the result of * the executed process, i.e. the exit value or an exception. * * @see org.apache.commons.exec.Executor#execute(CommandLine, java.util.Map, ExecuteResultHandler) * * @version $Id: ExecuteResultHandler.java 1636056 2014-11-01 21:12:52Z ggregory $ */ public interface ExecuteResultHandler { /** * The asynchronous execution completed. * * @param exitValue the exit value of the sub-process */ void onProcessComplete(int exitValue); /** * The asynchronous execution failed. * * @param e the {@code ExecuteException} containing the root cause */ void onProcessFailed(ExecuteException e); } commons-exec-1.3-src/src/main/java/org/apache/commons/exec/ExecuteStreamHandler.java100644 0 0 5175 12425540624 25664 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.commons.exec; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; /** * Used by {@code Execute} to handle input and output stream of * subprocesses. * * @version $Id: ExecuteStreamHandler.java 1636064 2014-11-01 22:01:19Z ggregory $ */ public interface ExecuteStreamHandler { /** * Install a handler for the input stream of the subprocess. * * @param os * output stream to write to the standard input stream of the subprocess * @throws IOException * thrown when an I/O exception occurs. */ void setProcessInputStream(OutputStream os) throws IOException; /** * Install a handler for the error stream of the subprocess. * * @param is * input stream to read from the error stream from the subprocess * @throws IOException * thrown when an I/O exception occurs. */ void setProcessErrorStream(InputStream is) throws IOException; /** * Install a handler for the output stream of the subprocess. * * @param is * input stream to read from the error stream from the subprocess * @throws IOException * thrown when an I/O exception occurs. */ void setProcessOutputStream(InputStream is) throws IOException; /** * Start handling of the streams. * * @throws IOException * thrown when an I/O exception occurs. */ void start() throws IOException; /** * Stop handling of the streams - will not be restarted. Will wait for pump threads to complete. * * @throws IOException * thrown when an I/O exception occurs. */ void stop() throws IOException; } commons-exec-1.3-src/src/main/java/org/apache/commons/exec/ExecuteWatchdog.java100644 0 0 17125 12425540624 24711 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.commons.exec; import org.apache.commons.exec.util.DebugUtils; /** * Destroys a process running for too long. For example: * *
 * ExecuteWatchdog watchdog = new ExecuteWatchdog(30000);
 * Executer exec = new Executer(myloghandler, watchdog);
 * exec.setCommandLine(mycmdline);
 * int exitvalue = exec.execute();
 * if (Execute.isFailure(exitvalue) && watchdog.killedProcess()) {
 *     // it was killed on purpose by the watchdog
 * }
 * 
* * When starting an asynchronous process than 'ExecuteWatchdog' is the * keeper of the process handle. In some cases it is useful not to define * a timeout (and pass 'INFINITE_TIMEOUT') and to kill the process explicitly * using 'destroyProcess()'. *

* Please note that ExecuteWatchdog is processed asynchronously, e.g. it might * be still attached to a process even after the DefaultExecutor.execute * has returned. * * @see org.apache.commons.exec.Executor * @see org.apache.commons.exec.Watchdog * * @version $Id: ExecuteWatchdog.java 1612032 2014-07-20 06:30:44Z ggregory $ */ public class ExecuteWatchdog implements TimeoutObserver { /** The marker for an infinite timeout */ public static final long INFINITE_TIMEOUT = -1; /** The process to execute and watch for duration. */ private Process process; /** Is a user-supplied timeout in use */ private final boolean hasWatchdog; /** Say whether or not the watchdog is currently monitoring a process. */ private boolean watch; /** Exception that might be thrown during the process execution. */ private Exception caught; /** Say whether or not the process was killed due to running overtime. */ private boolean killedProcess; /** Will tell us whether timeout has occurred. */ private final Watchdog watchdog; /** Indicates that the process is verified as started */ private volatile boolean processStarted; /** * Creates a new watchdog with a given timeout. * * @param timeout * the timeout for the process in milliseconds. It must be * greater than 0 or 'INFINITE_TIMEOUT' */ public ExecuteWatchdog(final long timeout) { this.killedProcess = false; this.watch = false; this.hasWatchdog = timeout != INFINITE_TIMEOUT; this.processStarted = false; if (this.hasWatchdog) { this.watchdog = new Watchdog(timeout); this.watchdog.addTimeoutObserver(this); } else { this.watchdog = null; } } /** * Watches the given process and terminates it, if it runs for too long. All * information from the previous run are reset. * * @param processToMonitor * the process to monitor. It cannot be {@code null} * @throws IllegalStateException * if a process is still being monitored. */ public synchronized void start(final Process processToMonitor) { if (processToMonitor == null) { throw new NullPointerException("process is null."); } if (this.process != null) { throw new IllegalStateException("Already running."); } this.caught = null; this.killedProcess = false; this.watch = true; this.process = processToMonitor; this.processStarted = true; this.notifyAll(); if (this.hasWatchdog) { watchdog.start(); } } /** * Stops the watcher. It will notify all threads possibly waiting on this * object. */ public synchronized void stop() { if (hasWatchdog) { watchdog.stop(); } watch = false; process = null; } /** * Destroys the running process manually. */ public synchronized void destroyProcess() { ensureStarted(); this.timeoutOccured(null); this.stop(); } /** * Called after watchdog has finished. */ public synchronized void timeoutOccured(final Watchdog w) { try { try { // We must check if the process was not stopped // before being here if (process != null) { process.exitValue(); } } catch (final IllegalThreadStateException itse) { // the process is not terminated, if this is really // a timeout and not a manual stop then destroy it. if (watch) { killedProcess = true; process.destroy(); } } } catch (final Exception e) { caught = e; DebugUtils.handleException("Getting the exit value of the process failed", e); } finally { cleanUp(); } } /** * This method will rethrow the exception that was possibly caught during * the run of the process. It will only remains valid once the process has * been terminated either by 'error', timeout or manual intervention. * Information will be discarded once a new process is ran. * * @throws Exception * a wrapped exception over the one that was silently swallowed * and stored during the process run. */ public synchronized void checkException() throws Exception { if (caught != null) { throw caught; } } /** * Indicates whether or not the watchdog is still monitoring the process. * * @return {@code true} if the process is still running, otherwise * {@code false}. */ public synchronized boolean isWatching() { ensureStarted(); return watch; } /** * Indicates whether the last process run was killed. * * @return {@code true} if the process was killed * {@code false}. */ public synchronized boolean killedProcess() { return killedProcess; } /** * reset the monitor flag and the process. */ protected synchronized void cleanUp() { watch = false; process = null; } void setProcessNotStarted() { processStarted = false; } /** * Ensures that the process is started, so we do not race with asynch execution. * The caller of this method must be holding the lock on this */ private void ensureStarted() { while (!processStarted) { try { this.wait(); } catch (final InterruptedException e) { throw new RuntimeException(e.getMessage()); } } } } commons-exec-1.3-src/src/main/java/org/apache/commons/exec/Executor.java100644 0 0 17163 12425540624 23426 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.commons.exec; import java.io.File; import java.io.IOException; import java.util.Map; /** * The main abstraction to start an external process. * * The interface allows to *

    *
  • set a current working directory for the subprocess
  • *
  • provide a set of environment variables passed to the subprocess
  • *
  • capture the subprocess output of stdout and stderr using an ExecuteStreamHandler
  • *
  • kill long-running processes using an ExecuteWatchdog
  • *
  • define a set of expected exit values
  • *
  • terminate any started processes when the main process is terminating using a ProcessDestroyer
  • *
* * The following example shows the basic usage: * *
 * Executor exec = new DefaultExecutor();
 * CommandLine cl = new CommandLine("ls -l");
 * int exitvalue = exec.execute(cl);
 * 
* * @version $Id: Executor.java 1636056 2014-11-01 21:12:52Z ggregory $ */ public interface Executor { /** Invalid exit code. */ int INVALID_EXITVALUE = 0xdeadbeef; /** * Define the {@code exitValue} of the process to be considered * successful. If a different exit value is returned by * the process then {@link org.apache.commons.exec.Executor#execute(CommandLine)} * will throw an {@link org.apache.commons.exec.ExecuteException} * * @param value the exit code representing successful execution */ void setExitValue(final int value); /** * Define a list of {@code exitValue} of the process to be considered * successful. The caller can pass one of the following values *
    *
  • an array of exit values to be considered successful
  • *
  • an empty array for auto-detect of successful exit codes relying on {@link org.apache.commons.exec.Executor#isFailure(int)}
  • *
  • null to indicate to skip checking of exit codes
  • *
* * If an undefined exit value is returned by the process then * {@link org.apache.commons.exec.Executor#execute(CommandLine)} will * throw an {@link org.apache.commons.exec.ExecuteException}. * * @param values a list of the exit codes */ void setExitValues(final int[] values); /** * Checks whether {@code exitValue} signals a failure. If no * exit values are set than the default conventions of the OS is * used. e.g. most OS regard an exit code of '0' as successful * execution and everything else as failure. * * @param exitValue the exit value (return code) to be checked * @return {@code true} if {@code exitValue} signals a failure */ boolean isFailure(final int exitValue); /** * Get the StreamHandler used for providing input and * retrieving the output. * * @return the StreamHandler */ ExecuteStreamHandler getStreamHandler(); /** * Set a custom the StreamHandler used for providing * input and retrieving the output. If you don't provide * a proper stream handler the executed process might block * when writing to stdout and/or stderr (see * {@link java.lang.Process Process}). * * @param streamHandler the stream handler */ void setStreamHandler(ExecuteStreamHandler streamHandler); /** * Get the watchdog used to kill of processes running, * typically, too long time. * * @return the watchdog */ ExecuteWatchdog getWatchdog(); /** * Set the watchdog used to kill of processes running, * typically, too long time. * * @param watchDog the watchdog */ void setWatchdog(ExecuteWatchdog watchDog); /** * Set the handler for cleanup of started processes if the main process * is going to terminate. * * @return the ProcessDestroyer */ ProcessDestroyer getProcessDestroyer(); /** * Get the handler for cleanup of started processes if the main process * is going to terminate. * * @param processDestroyer the ProcessDestroyer */ void setProcessDestroyer(ProcessDestroyer processDestroyer); /** * Get the working directory of the created process. * * @return the working directory */ File getWorkingDirectory(); /** * Set the working directory of the created process. The * working directory must exist when you start the process. * * @param dir the working directory */ void setWorkingDirectory(File dir); /** * Methods for starting synchronous execution. The child process inherits * all environment variables of the parent process. * * @param command the command to execute * @return process exit value * @throws ExecuteException execution of subprocess failed or the * subprocess returned a exit value indicating a failure * {@link Executor#setExitValue(int)}. */ int execute(CommandLine command) throws ExecuteException, IOException; /** * Methods for starting synchronous execution. * * @param command the command to execute * @param environment The environment for the new process. If null, the * environment of the current process is used. * @return process exit value * @throws ExecuteException execution of subprocess failed or the * subprocess returned a exit value indicating a failure * {@link Executor#setExitValue(int)}. */ int execute(CommandLine command, Map environment) throws ExecuteException, IOException; /** * Methods for starting asynchronous execution. The child process inherits * all environment variables of the parent process. Result provided to * callback handler. * * @param command the command to execute * @param handler capture process termination and exit code * @throws ExecuteException execution of subprocess failed */ void execute(CommandLine command, ExecuteResultHandler handler) throws ExecuteException, IOException; /** * Methods for starting asynchronous execution. The child process inherits * all environment variables of the parent process. Result provided to * callback handler. * * @param command the command to execute * @param environment The environment for the new process. If null, the * environment of the current process is used. * @param handler capture process termination and exit code * @throws ExecuteException execution of subprocess failed */ void execute(CommandLine command, Map environment, ExecuteResultHandler handler) throws ExecuteException, IOException; } commons-exec-1.3-src/src/main/java/org/apache/commons/exec/InputStreamPumper.java100644 0 0 5002 12425540624 25241 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.commons.exec; import java.io.InputStream; import java.io.OutputStream; import org.apache.commons.exec.util.DebugUtils; /** * Copies all data from an System.input stream to an output stream of the executed process. * * @version $Id: InputStreamPumper.java 1557263 2014-01-10 21:18:09Z ggregory $ */ public class InputStreamPumper implements Runnable { public static final int SLEEPING_TIME = 100; /** the input stream to pump from */ private final InputStream is; /** the output stream to pmp into */ private final OutputStream os; /** flag to stop the stream pumping */ private volatile boolean stop; /** * Create a new stream pumper. * * @param is input stream to read data from * @param os output stream to write data to. */ public InputStreamPumper(final InputStream is, final OutputStream os) { this.is = is; this.os = os; this.stop = false; } /** * Copies data from the input stream to the output stream. Terminates as * soon as the input stream is closed or an error occurs. */ public void run() { try { while (!stop) { while (is.available() > 0 && !stop) { os.write(is.read()); } os.flush(); Thread.sleep(SLEEPING_TIME); } } catch (final Exception e) { final String msg = "Got exception while reading/writing the stream"; DebugUtils.handleException(msg ,e); } finally { } } public void stopProcessing() { stop = true; } } commons-exec-1.3-src/src/main/java/org/apache/commons/exec/launcher/CommandLauncher.java100644 0 0 6351 12425540624 26446 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.commons.exec.launcher; import java.io.File; import java.io.IOException; import java.util.Map; import org.apache.commons.exec.CommandLine; /** * Interface to shield the caller from the various platform-dependent * implementations. * * @version $Id: CommandLauncher.java 1636056 2014-11-01 21:12:52Z ggregory $ */ public interface CommandLauncher { /** * Launches the given command in a new process. * * @param cmd * The command to execute * @param env * The environment for the new process. If null, the environment * of the current process is used. * * @return the newly created process * @throws IOException * if attempting to run a command in a specific directory */ Process exec(final CommandLine cmd, final Map env) throws IOException; /** * Launches the given command in a new process, in the given working * directory. * * @param cmd * The command to execute * @param env * The environment for the new process. If null, the environment * of the current process is used. * @param workingDir * The directory to start the command in. If null, the current * directory is used * * @return the newly created process * @throws IOException * if trying to change directory */ Process exec(final CommandLine cmd, final Map env, final File workingDir) throws IOException; /** * Checks whether {@code exitValue} signals a failure on the current * system (OS specific). *

* Note that this method relies on the conventions of the OS, it * will return false results if the application you are running doesn't * follow these conventions. One notable exception is the Java VM provided * by HP for OpenVMS - it will return 0 if successful (like on any other * platform), but this signals a failure on OpenVMS. So if you execute a new * Java VM on OpenVMS, you cannot trust this method. *

* * @param exitValue the exit value (return code) to be checked * @return {@code true} if {@code exitValue} signals a failure */ boolean isFailure(final int exitValue); } commons-exec-1.3-src/src/main/java/org/apache/commons/exec/launcher/CommandLauncherFactory.java100644 0 0 3157 12425540624 27777 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.commons.exec.launcher; import org.apache.commons.exec.OS; /** * Builds a command launcher for the OS and JVM we are running under. * * @version $Id: CommandLauncherFactory.java 1556869 2014-01-09 16:51:11Z britter $ */ public final class CommandLauncherFactory { private CommandLauncherFactory() { } /** * Factory method to create an appropriate launcher. * * @return the command launcher */ public static CommandLauncher createVMLauncher() { // Try using a JDK 1.3 launcher CommandLauncher launcher; if (OS.isFamilyOpenVms()) { launcher = new VmsCommandLauncher(); } else { launcher = new Java13CommandLauncher(); } return launcher; } } commons-exec-1.3-src/src/main/java/org/apache/commons/exec/launcher/CommandLauncherImpl.java100644 0 0 3777 12425540624 27301 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.commons.exec.launcher; import java.io.File; import java.io.IOException; import java.util.Map; import org.apache.commons.exec.CommandLine; import org.apache.commons.exec.environment.EnvironmentUtils; /** * A command launcher for a particular JVM/OS platform. This class is a general * purpose command launcher which can only launch commands in the current * working directory. * * @version $Id: CommandLauncherImpl.java 1557338 2014-01-11 10:34:22Z sebb $ */ public abstract class CommandLauncherImpl implements CommandLauncher { public Process exec(final CommandLine cmd, final Map env) throws IOException { final String[] envVar = EnvironmentUtils.toStrings(env); return Runtime.getRuntime().exec(cmd.toStrings(), envVar); } public abstract Process exec(final CommandLine cmd, final Map env, final File workingDir) throws IOException; /** @see org.apache.commons.exec.launcher.CommandLauncher#isFailure(int) */ public boolean isFailure(final int exitValue) { // non zero exit value signals failure return exitValue != 0; } } commons-exec-1.3-src/src/main/java/org/apache/commons/exec/launcher/CommandLauncherProxy.java100644 0 0 3734 12425540624 27512 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.commons.exec.launcher; import java.io.IOException; import java.util.Map; import org.apache.commons.exec.CommandLine; /** * A command launcher that proxies another command launcher. Sub-classes * override exec(args, env, workdir) * * @version $Id: CommandLauncherProxy.java 1557338 2014-01-11 10:34:22Z sebb $ */ public abstract class CommandLauncherProxy extends CommandLauncherImpl { public CommandLauncherProxy(final CommandLauncher launcher) { myLauncher = launcher; } private final CommandLauncher myLauncher; /** * Launches the given command in a new process. Delegates this method to the * proxied launcher * * @param cmd * the command line to execute as an array of strings * @param env * the environment to set as an array of strings * @throws IOException * forwarded from the exec method of the command launcher */ @Override public Process exec(final CommandLine cmd, final Map env) throws IOException { return myLauncher.exec(cmd, env); } } commons-exec-1.3-src/src/main/java/org/apache/commons/exec/launcher/Java13CommandLauncher.java100644 0 0 4247 12425540624 27416 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.commons.exec.launcher; import java.io.File; import java.io.IOException; import java.util.Map; import org.apache.commons.exec.CommandLine; import org.apache.commons.exec.environment.EnvironmentUtils; /** * A command launcher for JDK/JRE 1.3 (and higher). Uses the built-in * Runtime.exec() command * * @version $Id: Java13CommandLauncher.java 1557338 2014-01-11 10:34:22Z sebb $ */ public class Java13CommandLauncher extends CommandLauncherImpl { /** * Constructor */ public Java13CommandLauncher() { } /** * Launches the given command in a new process, in the given working * directory * * @param cmd * the command line to execute as an array of strings * @param env * the environment to set as an array of strings * @param workingDir * the working directory where the command should run * @throws IOException * probably forwarded from Runtime#exec */ @Override public Process exec(final CommandLine cmd, final Map env, final File workingDir) throws IOException { final String[] envVars = EnvironmentUtils.toStrings(env); return Runtime.getRuntime().exec(cmd.toStrings(), envVars, workingDir); } } commons-exec-1.3-src/src/main/java/org/apache/commons/exec/launcher/OS2CommandLauncher.java100644 0 0 4775 12425540624 27002 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.commons.exec.launcher; import java.io.File; import java.io.IOException; import java.util.Map; import org.apache.commons.exec.CommandLine; /** * A command launcher for OS/2 that uses 'cmd.exe' when launching commands in * directories other than the current working directory. *

* Unlike Windows NT and friends, OS/2's cd doesn't support the /d switch to * change drives and directories in one go. *

* Please not that this class is currently unused because the Java13CommandLauncher * is used for 0S/2 * * @version $Id: OS2CommandLauncher.java 1557338 2014-01-11 10:34:22Z sebb $ */ public class OS2CommandLauncher extends CommandLauncherProxy { public OS2CommandLauncher(final CommandLauncher launcher) { super(launcher); } /** * Launches the given command in a new process, in the given working * directory. * * @param cmd * the command line to execute as an array of strings * @param env * the environment to set as an array of strings * @param workingDir * working directory where the command should run * @throws IOException * forwarded from the exec method of the command launcher */ @Override public Process exec(final CommandLine cmd, final Map env, final File workingDir) throws IOException { if (workingDir == null) { return exec(cmd, env); } final CommandLine newCmd = new CommandLine("cmd"); newCmd.addArgument("/c"); newCmd.addArguments(cmd.toStrings()); return exec(newCmd, env); } } commons-exec-1.3-src/src/main/java/org/apache/commons/exec/launcher/VmsCommandLauncher.java100644 0 0 13051 12425540624 27147 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.commons.exec.launcher; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import org.apache.commons.exec.CommandLine; import org.apache.commons.exec.util.StringUtils; /** * A command launcher for VMS that writes the command to a temporary DCL script * before launching commands. This is due to limitations of both the DCL * interpreter and the Java VM implementation. * * @version $Id: VmsCommandLauncher.java 1636056 2014-11-01 21:12:52Z ggregory $ */ public class VmsCommandLauncher extends Java13CommandLauncher { /** * Launches the given command in a new process. */ @Override public Process exec(final CommandLine cmd, final Map env) throws IOException { final CommandLine vmsCmd = new CommandLine( createCommandFile(cmd, env).getPath() ); return super.exec(vmsCmd, env); } /** * Launches the given command in a new process, in the given working * directory. Note that under Java 1.3.1, 1.4.0 and 1.4.1 on VMS this method * only works if {@code workingDir} is null or the logical * JAVA$FORK_SUPPORT_CHDIR needs to be set to TRUE. */ @Override public Process exec(final CommandLine cmd, final Map env, final File workingDir) throws IOException { final CommandLine vmsCmd = new CommandLine( createCommandFile(cmd, env).getPath() ); return super.exec(vmsCmd, env, workingDir); } /** @see org.apache.commons.exec.launcher.CommandLauncher#isFailure(int) */ @Override public boolean isFailure(final int exitValue) { // even exit value signals failure return exitValue % 2 == 0; } /* * Writes the command into a temporary DCL script and returns the * corresponding File object. The script will be deleted on exit. */ private File createCommandFile(final CommandLine cmd, final Map env) throws IOException { final File script = File.createTempFile("EXEC", ".TMP"); script.deleteOnExit(); PrintWriter out = null; try { out = new PrintWriter(new FileWriter(script.getAbsolutePath(),true)); // add the environment as global symbols for the DCL script if (env != null) { final Set> entries = env.entrySet(); for (final Entry entry : entries) { out.print("$ "); out.print(entry.getKey()); out.print(" == "); // define as global symbol out.println('\"'); String value = entry.getValue(); // Any embedded " values need to be doubled if (value.indexOf('\"') > 0) { final StringBuilder sb = new StringBuilder(); for (int i = 0; i < value.length(); i++) { final char c = value.charAt(i); if (c == '\"') { sb.append('\"'); } sb.append(c); } value=sb.toString(); } out.print(value); out.println('\"'); } } final String command = cmd.getExecutable(); if (cmd.isFile()) {// We assume it is it a script file out.print("$ @"); // This is a bit crude, but seems to work final String parts[] = StringUtils.split(command,"/"); out.print(parts[0]); // device out.print(":["); out.print(parts[1]); // top level directory final int lastPart = parts.length-1; for (int i=2; i< lastPart; i++) { out.print("."); out.print(parts[i]); } out.print("]"); out.print(parts[lastPart]); } else { out.print("$ "); out.print(command); } final String[] args = cmd.getArguments(); for (final String arg : args) { out.println(" -"); out.print(arg); } out.println(); } finally { if (out != null) { out.close(); } } return script; } } commons-exec-1.3-src/src/main/java/org/apache/commons/exec/launcher/WinNTCommandLauncher.java100644 0 0 4575 12425540624 27374 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.commons.exec.launcher; import java.io.File; import java.io.IOException; import java.util.Map; import org.apache.commons.exec.CommandLine; /** * A command launcher for Windows XP/2000/NT that uses 'cmd.exe' when launching * commands in directories other than the current working directory. * * @version $Id: WinNTCommandLauncher.java 1557338 2014-01-11 10:34:22Z sebb $ */ public class WinNTCommandLauncher extends CommandLauncherProxy { public WinNTCommandLauncher(final CommandLauncher launcher) { super(launcher); } /** * Launches the given command in a new process, in the given working * directory. * * @param cmd * the command line to execute as an array of strings * @param env * the environment to set as an array of strings * @param workingDir * working directory where the command should run * @throws IOException * forwarded from the exec method of the command launcher */ @Override public Process exec(final CommandLine cmd, final Map env, final File workingDir) throws IOException { if (workingDir == null) { return exec(cmd, env); } // Use cmd.exe to change to the specified directory before running // the command final CommandLine newCmd = new CommandLine("cmd"); newCmd.addArgument("/c"); newCmd.addArguments(cmd.toStrings()); return exec(newCmd, env); } } commons-exec-1.3-src/src/main/java/org/apache/commons/exec/LogOutputStream.java100644 0 0 12372 12425540624 24743 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.commons.exec; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; /** * Base class to connect a logging system to the output and/or * error stream of then external process. The implementation * parses the incoming data to construct a line and passes * the complete line to an user-defined implementation. * * @version $Id: LogOutputStream.java 1636056 2014-11-01 21:12:52Z ggregory $ */ public abstract class LogOutputStream extends OutputStream { /** Initial buffer size. */ private static final int INTIAL_SIZE = 132; /** Carriage return */ private static final int CR = 0x0d; /** Linefeed */ private static final int LF = 0x0a; /** the internal buffer */ private final ByteArrayOutputStream buffer = new ByteArrayOutputStream( INTIAL_SIZE); private boolean skip = false; private final int level; /** * Creates a new instance of this class. * Uses the default level of 999. */ public LogOutputStream() { this(999); } /** * Creates a new instance of this class. * * @param level loglevel used to log data written to this stream. */ public LogOutputStream(final int level) { this.level = level; } /** * Write the data to the buffer and flush the buffer, if a line separator is * detected. * * @param cc data to log (byte). * @see java.io.OutputStream#write(int) */ @Override public void write(final int cc) throws IOException { final byte c = (byte) cc; if (c == '\n' || c == '\r') { if (!skip) { processBuffer(); } } else { buffer.write(cc); } skip = c == '\r'; } /** * Flush this log stream. * * @see java.io.OutputStream#flush() */ @Override public void flush() { if (buffer.size() > 0) { processBuffer(); } } /** * Writes all remaining data from the buffer. * * @see java.io.OutputStream#close() */ @Override public void close() throws IOException { if (buffer.size() > 0) { processBuffer(); } super.close(); } /** * @return the trace level of the log system */ public int getMessageLevel() { return level; } /** * Write a block of characters to the output stream * * @param b the array containing the data * @param off the offset into the array where data starts * @param len the length of block * @throws java.io.IOException if the data cannot be written into the stream. * @see java.io.OutputStream#write(byte[], int, int) */ @Override public void write(final byte[] b, final int off, final int len) throws IOException { // find the line breaks and pass other chars through in blocks int offset = off; int blockStartOffset = offset; int remaining = len; while (remaining > 0) { while (remaining > 0 && b[offset] != LF && b[offset] != CR) { offset++; remaining--; } // either end of buffer or a line separator char final int blockLength = offset - blockStartOffset; if (blockLength > 0) { buffer.write(b, blockStartOffset, blockLength); } while (remaining > 0 && (b[offset] == LF || b[offset] == CR)) { write(b[offset]); offset++; remaining--; } blockStartOffset = offset; } } /** * Converts the buffer to a string and sends it to {@code processLine}. */ protected void processBuffer() { processLine(buffer.toString()); buffer.reset(); } /** * Logs a line to the log system of the user. * * @param line * the line to log. */ protected void processLine(final String line) { processLine(line, level); } /** * Logs a line to the log system of the user. * * @param line the line to log. * @param logLevel the log level to use */ protected abstract void processLine(final String line, final int logLevel); } commons-exec-1.3-src/src/main/java/org/apache/commons/exec/OS.java100644 0 0 20074 12425540624 22144 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.commons.exec; import java.util.Locale; /** * Condition that tests the OS type. * * @version $Id: OS.java 1556869 2014-01-09 16:51:11Z britter $ */ public final class OS { private static final String FAMILY_OS_400 = "os/400"; private static final String FAMILY_Z_OS = "z/os"; private static final String FAMILY_WIN9X = "win9x"; private static final String FAMILY_OPENVMS = "openvms"; private static final String FAMILY_UNIX = "unix"; private static final String FAMILY_TANDEM = "tandem"; private static final String FAMILY_MAC = "mac"; private static final String FAMILY_DOS = "dos"; private static final String FAMILY_NETWARE = "netware"; private static final String FAMILY_OS_2 = "os/2"; private static final String FAMILY_WINDOWS = "windows"; private static final String OS_NAME = System.getProperty("os.name") .toLowerCase(Locale.US); private static final String OS_ARCH = System.getProperty("os.arch") .toLowerCase(Locale.US); private static final String OS_VERSION = System.getProperty("os.version") .toLowerCase(Locale.US); private static final String PATH_SEP = System.getProperty("path.separator"); /** * Default constructor */ private OS() { } /** * Determines if the OS on which Ant is executing matches the given OS * family. * Possible values:
*
    *
  • dos
  • *
  • mac
  • *
  • netware
  • *
  • os/2
  • *
  • tandem
  • *
  • unix
  • *
  • windows
  • *
  • win9x
  • *
  • z/os
  • *
  • os/400
  • *
* * @param family * the family to check for * @return true if the OS matches */ private static boolean isFamily(final String family) { return isOs(family, null, null, null); } public static boolean isFamilyDOS() { return isFamily(FAMILY_DOS); } public static boolean isFamilyMac() { return isFamily(FAMILY_MAC); } public static boolean isFamilyNetware() { return isFamily(FAMILY_NETWARE); } public static boolean isFamilyOS2() { return isFamily(FAMILY_OS_2); } public static boolean isFamilyTandem() { return isFamily(FAMILY_TANDEM); } public static boolean isFamilyUnix() { return isFamily(FAMILY_UNIX); } public static boolean isFamilyWindows() { return isFamily(FAMILY_WINDOWS); } public static boolean isFamilyWin9x() { return isFamily(FAMILY_WIN9X); } public static boolean isFamilyZOS() { return isFamily(FAMILY_Z_OS); } public static boolean isFamilyOS400() { return isFamily(FAMILY_OS_400); } public static boolean isFamilyOpenVms() { return isFamily(FAMILY_OPENVMS); } /** * Determines if the OS on which Ant is executing matches the given OS name. * * @param name * the OS name to check for * @return true if the OS matches */ public static boolean isName(final String name) { return isOs(null, name, null, null); } /** * Determines if the OS on which Ant is executing matches the given OS * architecture. * * @param arch * the OS architecture to check for * @return true if the OS matches */ public static boolean isArch(final String arch) { return isOs(null, null, arch, null); } /** * Determines if the OS on which Ant is executing matches the given OS * version. * * @param version * the OS version to check for * @return true if the OS matches */ public static boolean isVersion(final String version) { return isOs(null, null, null, version); } /** * Determines if the OS on which Ant is executing matches the given OS * family, name, architecture and version * * @param family * The OS family * @param name * The OS name * @param arch * The OS architecture * @param version * The OS version * @return true if the OS matches */ public static boolean isOs(final String family, final String name, final String arch, final String version) { boolean retValue = false; if (family != null || name != null || arch != null || version != null) { boolean isFamily = true; boolean isName = true; boolean isArch = true; boolean isVersion = true; if (family != null) { if (family.equals(FAMILY_WINDOWS)) { isFamily = OS_NAME.indexOf(FAMILY_WINDOWS) > -1; } else if (family.equals(FAMILY_OS_2)) { isFamily = OS_NAME.indexOf(FAMILY_OS_2) > -1; } else if (family.equals(FAMILY_NETWARE)) { isFamily = OS_NAME.indexOf(FAMILY_NETWARE) > -1; } else if (family.equals(FAMILY_DOS)) { isFamily = PATH_SEP.equals(";") && !isFamily(FAMILY_NETWARE); } else if (family.equals(FAMILY_MAC)) { isFamily = OS_NAME.indexOf(FAMILY_MAC) > -1; } else if (family.equals(FAMILY_TANDEM)) { isFamily = OS_NAME.indexOf("nonstop_kernel") > -1; } else if (family.equals(FAMILY_UNIX)) { isFamily = PATH_SEP.equals(":") && !isFamily(FAMILY_OPENVMS) && (!isFamily(FAMILY_MAC) || OS_NAME.endsWith("x")); } else if (family.equals(FAMILY_WIN9X)) { isFamily = isFamily(FAMILY_WINDOWS) && (OS_NAME.indexOf("95") >= 0 || OS_NAME.indexOf("98") >= 0 || OS_NAME.indexOf("me") >= 0 || OS_NAME .indexOf("ce") >= 0); } else if (family.equals(FAMILY_Z_OS)) { isFamily = OS_NAME.indexOf(FAMILY_Z_OS) > -1 || OS_NAME.indexOf("os/390") > -1; } else if (family.equals(FAMILY_OS_400)) { isFamily = OS_NAME.indexOf(FAMILY_OS_400) > -1; } else if (family.equals(FAMILY_OPENVMS)) { isFamily = OS_NAME.indexOf(FAMILY_OPENVMS) > -1; } else { throw new IllegalArgumentException( "Don\'t know how to detect os family \"" + family + "\""); } } if (name != null) { isName = name.equals(OS_NAME); } if (arch != null) { isArch = arch.equals(OS_ARCH); } if (version != null) { isVersion = version.equals(OS_VERSION); } retValue = isFamily && isName && isArch && isVersion; } return retValue; } } commons-exec-1.3-src/src/main/java/org/apache/commons/exec/ProcessDestroyer.java100644 0 0 4107 12425540624 25121 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.commons.exec; /** * Destroys all registered {@link java.lang.Process} after a certain event, * typically when the VM exits * @see org.apache.commons.exec.ShutdownHookProcessDestroyer * * @version $Id: ProcessDestroyer.java 1636056 2014-11-01 21:12:52Z ggregory $ */ public interface ProcessDestroyer { /** * Returns {@code true} if the specified * {@link java.lang.Process} was * successfully added to the list of processes to be destroy. * * @param process * the process to add * @return {@code true} if the specified * {@link java.lang.Process} was * successfully added */ boolean add(Process process); /** * Returns {@code true} if the specified * {@link java.lang.Process} was * successfully removed from the list of processes to be destroy. * * @param process * the process to remove * @return {@code true} if the specified * {@link java.lang.Process} was * successfully removed */ boolean remove(Process process); /** * Returns the number of registered processes. * * @return the number of register process */ int size(); } commons-exec-1.3-src/src/main/java/org/apache/commons/exec/PumpStreamHandler.java100644 0 0 24314 12425540624 25217 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.commons.exec; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PipedOutputStream; import org.apache.commons.exec.util.DebugUtils; /** * Copies standard output and error of sub-processes to standard output and error * of the parent process. If output or error stream are set to null, any feedback * from that stream will be lost. * * @version $Id: PumpStreamHandler.java 1557263 2014-01-10 21:18:09Z ggregory $ */ public class PumpStreamHandler implements ExecuteStreamHandler { private static final long STOP_TIMEOUT_ADDITION = 2000L; private Thread outputThread; private Thread errorThread; private Thread inputThread; private final OutputStream out; private final OutputStream err; private final InputStream input; private InputStreamPumper inputStreamPumper; /** the timeout in ms the implementation waits when stopping the pumper threads */ private long stopTimeout; /** the last exception being caught */ private IOException caught = null; /** * Construct a new PumpStreamHandler. */ public PumpStreamHandler() { this(System.out, System.err); } /** * Construct a new PumpStreamHandler. * * @param outAndErr the output/error OutputStream. */ public PumpStreamHandler(final OutputStream outAndErr) { this(outAndErr, outAndErr); } /** * Construct a new PumpStreamHandler. * * @param out the output OutputStream. * @param err the error OutputStream. */ public PumpStreamHandler(final OutputStream out, final OutputStream err) { this(out, err, null); } /** * Construct a new PumpStreamHandler. * * @param out the output OutputStream. * @param err the error OutputStream. * @param input the input InputStream. */ public PumpStreamHandler(final OutputStream out, final OutputStream err, final InputStream input) { this.out = out; this.err = err; this.input = input; } /** * Set maximum time to wait until output streams are exchausted * when {@link #stop()} was called. * * @param timeout timeout in milliseconds or zero to wait forever (default) */ public void setStopTimeout(final long timeout) { this.stopTimeout = timeout; } /** * Set the InputStream from which to read the standard output * of the process. * * @param is the InputStream. */ public void setProcessOutputStream(final InputStream is) { if (out != null) { createProcessOutputPump(is, out); } } /** * Set the InputStream from which to read the standard error * of the process. * * @param is the InputStream. */ public void setProcessErrorStream(final InputStream is) { if (err != null) { createProcessErrorPump(is, err); } } /** * Set the OutputStream by means of which input can be sent * to the process. * * @param os the OutputStream. */ public void setProcessInputStream(final OutputStream os) { if (input != null) { if (input == System.in) { inputThread = createSystemInPump(input, os); } else { inputThread = createPump(input, os, true); } } else { try { os.close(); } catch (final IOException e) { final String msg = "Got exception while closing output stream"; DebugUtils.handleException(msg, e); } } } /** * Start the Threads. */ public void start() { if (outputThread != null) { outputThread.start(); } if (errorThread != null) { errorThread.start(); } if (inputThread != null) { inputThread.start(); } } /** * Stop pumping the streams. When a timeout is specified it it is not guaranteed that the * pumper threads are cleanly terminated. */ public void stop() throws IOException { if (inputStreamPumper != null) { inputStreamPumper.stopProcessing(); } stopThread(outputThread, stopTimeout); stopThread(errorThread, stopTimeout); stopThread(inputThread, stopTimeout); if (err != null && err != out) { try { err.flush(); } catch (final IOException e) { final String msg = "Got exception while flushing the error stream : " + e.getMessage(); DebugUtils.handleException(msg, e); } } if (out != null) { try { out.flush(); } catch (final IOException e) { final String msg = "Got exception while flushing the output stream"; DebugUtils.handleException(msg, e); } } if (caught != null) { throw caught; } } /** * Get the error stream. * * @return OutputStream. */ protected OutputStream getErr() { return err; } /** * Get the output stream. * * @return OutputStream. */ protected OutputStream getOut() { return out; } /** * Create the pump to handle process output. * * @param is the InputStream. * @param os the OutputStream. */ protected void createProcessOutputPump(final InputStream is, final OutputStream os) { outputThread = createPump(is, os); } /** * Create the pump to handle error output. * * @param is the InputStream. * @param os the OutputStream. */ protected void createProcessErrorPump(final InputStream is, final OutputStream os) { errorThread = createPump(is, os); } /** * Creates a stream pumper to copy the given input stream to the given * output stream. When the 'os' is an PipedOutputStream we are closing * 'os' afterwards to avoid an IOException ("Write end dead"). * * @param is the input stream to copy from * @param os the output stream to copy into * @return the stream pumper thread */ protected Thread createPump(final InputStream is, final OutputStream os) { final boolean closeWhenExhausted = os instanceof PipedOutputStream ? true : false; return createPump(is, os, closeWhenExhausted); } /** * Creates a stream pumper to copy the given input stream to the given * output stream. * * @param is the input stream to copy from * @param os the output stream to copy into * @param closeWhenExhausted close the output stream when the input stream is exhausted * @return the stream pumper thread */ protected Thread createPump(final InputStream is, final OutputStream os, final boolean closeWhenExhausted) { final Thread result = new Thread(new StreamPumper(is, os, closeWhenExhausted), "Exec Stream Pumper"); result.setDaemon(true); return result; } /** * Stopping a pumper thread. The implementation actually waits * longer than specified in 'timeout' to detect if the timeout * was indeed exceeded. If the timeout was exceeded an IOException * is created to be thrown to the caller. * * @param thread the thread to be stopped * @param timeout the time in ms to wait to join */ protected void stopThread(final Thread thread, final long timeout) { if (thread != null) { try { if (timeout == 0) { thread.join(); } else { final long timeToWait = timeout + STOP_TIMEOUT_ADDITION; final long startTime = System.currentTimeMillis(); thread.join(timeToWait); if (!(System.currentTimeMillis() < startTime + timeToWait)) { final String msg = "The stop timeout of " + timeout + " ms was exceeded"; caught = new ExecuteException(msg, Executor.INVALID_EXITVALUE); } } } catch (final InterruptedException e) { thread.interrupt(); } } } /** * Creates a stream pumper to copy the given input stream to the given * output stream. * * @param is the System.in input stream to copy from * @param os the output stream to copy into * @return the stream pumper thread */ private Thread createSystemInPump(final InputStream is, final OutputStream os) { inputStreamPumper = new InputStreamPumper(is, os); final Thread result = new Thread(inputStreamPumper, "Exec Input Stream Pumper"); result.setDaemon(true); return result; } } commons-exec-1.3-src/src/main/java/org/apache/commons/exec/ShutdownHookProcessDestroyer.java100644 0 0 15242 12425540624 27520 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.commons.exec; import java.util.Enumeration; import java.util.Vector; /** * Destroys all registered {@code Process}es when the VM exits. * * @version $Id: ShutdownHookProcessDestroyer.java 1636056 2014-11-01 21:12:52Z ggregory $ */ public class ShutdownHookProcessDestroyer implements ProcessDestroyer, Runnable { /** the list of currently running processes */ private final Vector processes = new Vector(); /** The thread registered at the JVM to execute the shutdown handler */ private ProcessDestroyerImpl destroyProcessThread = null; /** Whether or not this ProcessDestroyer has been registered as a shutdown hook */ private boolean added = false; /** * Whether or not this ProcessDestroyer is currently running as shutdown hook */ private volatile boolean running = false; private class ProcessDestroyerImpl extends Thread { private boolean shouldDestroy = true; public ProcessDestroyerImpl() { super("ProcessDestroyer Shutdown Hook"); } @Override public void run() { if (shouldDestroy) { ShutdownHookProcessDestroyer.this.run(); } } public void setShouldDestroy(final boolean shouldDestroy) { this.shouldDestroy = shouldDestroy; } } /** * Constructs a {@code ProcessDestroyer} and obtains * {@code Runtime.addShutdownHook()} and * {@code Runtime.removeShutdownHook()} through reflection. The * ProcessDestroyer manages a list of processes to be destroyed when the VM * exits. If a process is added when the list is empty, this * {@code ProcessDestroyer} is registered as a shutdown hook. If * removing a process results in an empty list, the * {@code ProcessDestroyer} is removed as a shutdown hook. */ public ShutdownHookProcessDestroyer() { } /** * Registers this {@code ProcessDestroyer} as a shutdown hook, uses * reflection to ensure pre-JDK 1.3 compatibility. */ private void addShutdownHook() { if (!running) { destroyProcessThread = new ProcessDestroyerImpl(); Runtime.getRuntime().addShutdownHook(destroyProcessThread); added = true; } } /** * Removes this {@code ProcessDestroyer} as a shutdown hook, uses * reflection to ensure pre-JDK 1.3 compatibility */ private void removeShutdownHook() { if (added && !running) { final boolean removed = Runtime.getRuntime().removeShutdownHook( destroyProcessThread); if (!removed) { System.err.println("Could not remove shutdown hook"); } /* * start the hook thread, a unstarted thread may not be eligible for * garbage collection Cf.: http://developer.java.sun.com/developer/ * bugParade/bugs/4533087.html */ destroyProcessThread.setShouldDestroy(false); destroyProcessThread.start(); // this should return quickly, since it basically is a NO-OP. try { destroyProcessThread.join(20000); } catch (final InterruptedException ie) { // the thread didn't die in time // it should not kill any processes unexpectedly } destroyProcessThread = null; added = false; } } /** * Returns whether or not the ProcessDestroyer is registered as as shutdown * hook * * @return true if this is currently added as shutdown hook */ public boolean isAddedAsShutdownHook() { return added; } /** * Returns {@code true} if the specified {@code Process} was * successfully added to the list of processes to destroy upon VM exit. * * @param process * the process to add * @return {@code true} if the specified {@code Process} was * successfully added */ public boolean add(final Process process) { synchronized (processes) { // if this list is empty, register the shutdown hook if (processes.size() == 0) { addShutdownHook(); } processes.addElement(process); return processes.contains(process); } } /** * Returns {@code true} if the specified {@code Process} was * successfully removed from the list of processes to destroy upon VM exit. * * @param process * the process to remove * @return {@code true} if the specified {@code Process} was * successfully removed */ public boolean remove(final Process process) { synchronized (processes) { final boolean processRemoved = processes.removeElement(process); if (processRemoved && processes.size() == 0) { removeShutdownHook(); } return processRemoved; } } /** * Returns the number of registered processes. * * @return the number of register process */ public int size() { return processes.size(); } /** * Invoked by the VM when it is exiting. */ public void run() { synchronized (processes) { running = true; final Enumeration e = processes.elements(); while (e.hasMoreElements()) { final Process process = e.nextElement(); try { process.destroy(); } catch (final Throwable t) { System.err.println("Unable to terminate process during process shutdown"); } } } } } commons-exec-1.3-src/src/main/java/org/apache/commons/exec/StreamPumper.java100644 0 0 11642 12425540624 24250 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.commons.exec; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.apache.commons.exec.util.DebugUtils; /** * Copies all data from an input stream to an output stream. * * @version $Id: StreamPumper.java 1557263 2014-01-10 21:18:09Z ggregory $ */ public class StreamPumper implements Runnable { /** the default size of the internal buffer for copying the streams */ private static final int DEFAULT_SIZE = 1024; /** the input stream to pump from */ private final InputStream is; /** the output stream to pmp into */ private final OutputStream os; /** the size of the internal buffer for copying the streams */ private final int size; /** was the end of the stream reached */ private boolean finished; /** close the output stream when exhausted */ private final boolean closeWhenExhausted; /** * Create a new stream pumper. * * @param is input stream to read data from * @param os output stream to write data to. * @param closeWhenExhausted if true, the output stream will be closed when the input is exhausted. */ public StreamPumper(final InputStream is, final OutputStream os, final boolean closeWhenExhausted) { this.is = is; this.os = os; this.size = DEFAULT_SIZE; this.closeWhenExhausted = closeWhenExhausted; } /** * Create a new stream pumper. * * @param is input stream to read data from * @param os output stream to write data to. * @param closeWhenExhausted if true, the output stream will be closed when the input is exhausted. * @param size the size of the internal buffer for copying the streams */ public StreamPumper(final InputStream is, final OutputStream os, final boolean closeWhenExhausted, final int size) { this.is = is; this.os = os; this.size = size > 0 ? size : DEFAULT_SIZE; this.closeWhenExhausted = closeWhenExhausted; } /** * Create a new stream pumper. * * @param is input stream to read data from * @param os output stream to write data to. */ public StreamPumper(final InputStream is, final OutputStream os) { this(is, os, false); } /** * Copies data from the input stream to the output stream. Terminates as * soon as the input stream is closed or an error occurs. */ public void run() { synchronized (this) { // Just in case this object is reused in the future finished = false; } final byte[] buf = new byte[this.size]; int length; try { while ((length = is.read(buf)) > 0) { os.write(buf, 0, length); } } catch (final Exception e) { // nothing to do - happens quite often with watchdog } finally { if (closeWhenExhausted) { try { os.close(); } catch (final IOException e) { final String msg = "Got exception while closing exhausted output stream"; DebugUtils.handleException(msg ,e); } } synchronized (this) { finished = true; notifyAll(); } } } /** * Tells whether the end of the stream has been reached. * * @return true is the stream has been exhausted. */ public synchronized boolean isFinished() { return finished; } /** * This method blocks until the stream pumper finishes. * * @exception InterruptedException * if any thread interrupted the current thread before or while the current thread was waiting for a * notification. * @see #isFinished() */ public synchronized void waitFor() throws InterruptedException { while (!isFinished()) { wait(); } } } commons-exec-1.3-src/src/main/java/org/apache/commons/exec/TimeoutObserver.java100644 0 0 2367 12425540624 24746 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.commons.exec; /** * Interface for classes that want to be notified by Watchdog. * * @see org.apache.commons.exec.Watchdog * * @version $Id: TimeoutObserver.java 1556869 2014-01-09 16:51:11Z britter $ */ public interface TimeoutObserver { /** * Called when the watchdog times out. * * @param w the watchdog that timed out. */ void timeoutOccured(Watchdog w); } commons-exec-1.3-src/src/main/java/org/apache/commons/exec/util/DebugUtils.java100644 0 0 5745 12425540624 24637 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.commons.exec.util; /** * Provides debugging support. * * @version $Id: DebugUtils.java 1636203 2014-11-02 22:26:31Z ggregory $ */ public class DebugUtils { /** * System property to determine how to handle exceptions. When * set to "false" we rethrow the otherwise silently catched * exceptions found in the original code. The default value * is "true" */ public static final String COMMONS_EXEC_LENIENT = "org.apache.commons.exec.lenient"; /** * System property to determine how to dump an exception. When * set to "true" we print any exception to stderr. The default * value is "false" */ public static final String COMMONS_EXEC_DEBUG = "org.apache.commons.exec.debug"; /** * Handles an exception based on the system properties. * * @param msg message describing the problem * @param e an exception being handled */ public static void handleException(final String msg, final Exception e) { if (isDebugEnabled()) { System.err.println(msg); e.printStackTrace(); } if (!isLenientEnabled()) { if (e instanceof RuntimeException) { throw (RuntimeException) e; } // can't pass root cause since the constructor is not available on JDK 1.3 throw new RuntimeException(e.getMessage()); } } /** * Determines if debugging is enabled based on the * system property "COMMONS_EXEC_DEBUG". * * @return true if debug mode is enabled */ public static boolean isDebugEnabled() { final String debug = System.getProperty(COMMONS_EXEC_DEBUG, Boolean.FALSE.toString()); return Boolean.TRUE.toString().equalsIgnoreCase(debug); } /** * Determines if lenient mode is enabled. * * @return true if lenient mode is enabled */ public static boolean isLenientEnabled() { final String lenient = System.getProperty(COMMONS_EXEC_LENIENT, Boolean.TRUE.toString()); return Boolean.TRUE.toString().equalsIgnoreCase(lenient); } } commons-exec-1.3-src/src/main/java/org/apache/commons/exec/util/MapUtils.java100644 0 0 6570 12425540624 24323 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.commons.exec.util; import java.util.HashMap; import java.util.Map; /** * Helper classes to manipulate maps to pass substition map to the CommandLine. This class is not part of the public API * and could change without warning. * * @version $Id: MapUtils.java 1636205 2014-11-02 22:32:33Z ggregory $ */ public class MapUtils { /** * Clones a map. * * @param source * the Map to clone * @param * the map key type * @param * the map value type * @return the cloned map */ public static Map copy(final Map source) { if (source == null) { return null; } final Map result = new HashMap(); result.putAll(source); return result; } /** * Clones a map and prefixes the keys in the clone, e.g. for mapping "JAVA_HOME" to "env.JAVA_HOME" to simulate the * behaviour of Ant. * * @param source * the source map * @param prefix * the prefix used for all names * @param * the map key type * @param * the map value type * @return the clone of the source map */ public static Map prefix(final Map source, final String prefix) { if (source == null) { return null; } final Map result = new HashMap(); for (final Map.Entry entry : source.entrySet()) { final K key = entry.getKey(); final V value = entry.getValue(); result.put(prefix + '.' + key.toString(), value); } return result; } /** * Clones the lhs map and add all things from the rhs map. * * @param lhs * the first map * @param rhs * the second map * @param * the map key type * @param * the map value type * @return the merged map */ public static Map merge(final Map lhs, final Map rhs) { Map result = null; if (lhs == null || lhs.size() == 0) { result = copy(rhs); } else if (rhs == null || rhs.size() == 0) { result = copy(lhs); } else { result = copy(lhs); result.putAll(rhs); } return result; } } commons-exec-1.3-src/src/main/java/org/apache/commons/exec/util/StringUtils.java100644 0 0 22722 12425540624 25071 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.commons.exec.util; import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.StringTokenizer; /** * Supplement of commons-lang, the stringSubstitution() was in a simpler * implementation available in an older commons-lang implementation. * * This class is not part of the public API and could change without * warning. * * @version $Id: StringUtils.java 1636204 2014-11-02 22:30:31Z ggregory $ */ public class StringUtils { private static final String SINGLE_QUOTE = "\'"; private static final String DOUBLE_QUOTE = "\""; private static final char SLASH_CHAR = '/'; private static final char BACKSLASH_CHAR = '\\'; /** * Perform a series of substitutions. *

* The substitutions are performed by replacing ${variable} in the target string with the value of provided by the * key "variable" in the provided hash table. *

*

* A key consists of the following characters: *

*
    *
  • letter *
  • digit *
  • dot character *
  • hyphen character *
  • plus character *
  • underscore character *
* * @param argStr * the argument string to be processed * @param vars * name/value pairs used for substitution * @param isLenient * ignore a key not found in vars or throw a RuntimeException? * @return String target string with replacements. */ public static StringBuffer stringSubstitution(final String argStr, final Map vars, final boolean isLenient) { final StringBuffer argBuf = new StringBuffer(); if (argStr == null || argStr.length() == 0) { return argBuf; } if (vars == null || vars.size() == 0) { return argBuf.append(argStr); } final int argStrLength = argStr.length(); for (int cIdx = 0; cIdx < argStrLength;) { char ch = argStr.charAt(cIdx); char del = ' '; switch (ch) { case '$': final StringBuilder nameBuf = new StringBuilder(); del = argStr.charAt(cIdx + 1); if (del == '{') { cIdx++; for (++cIdx; cIdx < argStr.length(); ++cIdx) { ch = argStr.charAt(cIdx); if (ch == '_' || ch == '.' || ch == '-' || ch == '+' || Character.isLetterOrDigit(ch)) { nameBuf.append(ch); } else { break; } } if (nameBuf.length() >= 0) { String value; final Object temp = vars.get(nameBuf.toString()); if (temp instanceof File) { // for a file we have to fix the separator chars to allow // cross-platform compatibility value = fixFileSeparatorChar(((File) temp).getAbsolutePath()); } else { value = temp != null ? temp.toString() : null; } if (value != null) { argBuf.append(value); } else { if (isLenient) { // just append the unresolved variable declaration argBuf.append("${").append(nameBuf.toString()).append("}"); } else { // complain that no variable was found throw new RuntimeException("No value found for : " + nameBuf); } } del = argStr.charAt(cIdx); if (del != '}') { throw new RuntimeException("Delimiter not found for : " + nameBuf); } } cIdx++; } else { argBuf.append(ch); ++cIdx; } break; default: argBuf.append(ch); ++cIdx; break; } } return argBuf; } /** * Split a string into an array of strings based * on a separator. * * @param input what to split * @param splitChar what to split on * @return the array of strings */ public static String[] split(final String input, final String splitChar) { final StringTokenizer tokens = new StringTokenizer(input, splitChar); final List strList = new ArrayList(); while (tokens.hasMoreTokens()) { strList.add(tokens.nextToken()); } return strList.toArray(new String[strList.size()]); } /** * Fixes the file separator char for the target platform * using the following replacement. * *
    *
  • '/' → File.separatorChar
  • *
  • '\\' → File.separatorChar
  • *
* * @param arg the argument to fix * @return the transformed argument */ public static String fixFileSeparatorChar(final String arg) { return arg.replace(SLASH_CHAR, File.separatorChar).replace( BACKSLASH_CHAR, File.separatorChar); } /** * Concatenates an array of string using a separator. * * @param strings the strings to concatenate * @param separator the separator between two strings * @return the concatenated strings */ public static String toString(final String[] strings, final String separator) { final StringBuilder sb = new StringBuilder(); for (int i = 0; i < strings.length; i++) { if (i > 0) { sb.append(separator); } sb.append(strings[i]); } return sb.toString(); } /** * Put quotes around the given String if necessary. *

* If the argument doesn't include spaces or quotes, return it as is. If it * contains double quotes, use single quotes - else surround the argument by * double quotes. *

* * @param argument the argument to be quoted * @return the quoted argument * @throws IllegalArgumentException If argument contains both types of quotes */ public static String quoteArgument(final String argument) { String cleanedArgument = argument.trim(); // strip the quotes from both ends while (cleanedArgument.startsWith(SINGLE_QUOTE) || cleanedArgument.startsWith(DOUBLE_QUOTE)) { cleanedArgument = cleanedArgument.substring(1); } while (cleanedArgument.endsWith(SINGLE_QUOTE) || cleanedArgument.endsWith(DOUBLE_QUOTE)) { cleanedArgument = cleanedArgument.substring(0, cleanedArgument.length() - 1); } final StringBuilder buf = new StringBuilder(); if (cleanedArgument.indexOf(DOUBLE_QUOTE) > -1) { if (cleanedArgument.indexOf(SINGLE_QUOTE) > -1) { throw new IllegalArgumentException( "Can't handle single and double quotes in same argument"); } return buf.append(SINGLE_QUOTE).append(cleanedArgument).append( SINGLE_QUOTE).toString(); } else if (cleanedArgument.indexOf(SINGLE_QUOTE) > -1 || cleanedArgument.indexOf(" ") > -1) { return buf.append(DOUBLE_QUOTE).append(cleanedArgument).append( DOUBLE_QUOTE).toString(); } else { return cleanedArgument; } } /** * Determines if this is a quoted argument - either single or * double quoted. * * @param argument the argument to check * @return true when the argument is quoted */ public static boolean isQuoted(final String argument) { return argument.startsWith(SINGLE_QUOTE) && argument.endsWith(SINGLE_QUOTE) || argument.startsWith(DOUBLE_QUOTE) && argument.endsWith(DOUBLE_QUOTE); } }commons-exec-1.3-src/src/main/java/org/apache/commons/exec/Watchdog.java100644 0 0 5725 12425540624 23351 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.commons.exec; import java.util.Enumeration; import java.util.Vector; /** * Generalization of {@code ExecuteWatchdog} * * @see org.apache.commons.exec.ExecuteWatchdog * * @version $Id: Watchdog.java 1636056 2014-11-01 21:12:52Z ggregory $ */ public class Watchdog implements Runnable { private final Vector observers = new Vector(1); private final long timeout; private boolean stopped = false; public Watchdog(final long timeout) { if (timeout < 1) { throw new IllegalArgumentException("timeout must not be less than 1."); } this.timeout = timeout; } public void addTimeoutObserver(final TimeoutObserver to) { observers.addElement(to); } public void removeTimeoutObserver(final TimeoutObserver to) { observers.removeElement(to); } protected final void fireTimeoutOccured() { final Enumeration e = observers.elements(); while (e.hasMoreElements()) { e.nextElement().timeoutOccured(this); } } public synchronized void start() { stopped = false; final Thread t = new Thread(this, "WATCHDOG"); t.setDaemon(true); t.start(); } public synchronized void stop() { stopped = true; notifyAll(); } public void run() { final long startTime = System.currentTimeMillis(); boolean isWaiting; synchronized (this) { long timeLeft = timeout - (System.currentTimeMillis() - startTime); isWaiting = timeLeft > 0; while (!stopped && isWaiting) { try { wait(timeLeft); } catch (final InterruptedException e) { } timeLeft = timeout - (System.currentTimeMillis() - startTime); isWaiting = timeLeft > 0; } } // notify the listeners outside of the synchronized block (see EXEC-60) if (!isWaiting) { fireTimeoutOccured(); } } } commons-exec-1.3-src/src/media/logo.xcf100644 0 0 211617 12425540622 15250 0ustar 0 0 gimp xcf fileêBBBgimp-image-grid(style solid) (fgcolor (color-rgba 0.000000 0.000000 0.000000 1.000000)) (bgcolor (color-rgba 1.000000 1.000000 1.000000 1.000000)) (xspacing 10.000000) (yspacing 10.000000) (spacing-unit inches) (xoffset 0.000000) (yoffset 0.000000) (offset-unit inches) ús’ TMÿ     Û5 gimp-text-layerô(text "TM") (font "Slogan") (font-size 10.000000) (font-size-unit pixels) (antialias yes) (language "en_US") (base-direction ltr) (color (color-rgb 0.000000 0.000000 0.000000)) (justify left) (box-mode dynamic) (box-unit pixels) (hinting yes) Z n ~šššÿüÿVýsÿþÿøÿÄÐÿþÿøÿ’O`†ÿþÿøÿ#ÉÐÿþÿøÿ¯•©ÿþÿøÿ=ÿ;ÿþÿþÿþÿêBApache Commons Execÿ     !gimp-text-layer(text "Apache Commons Exec") (font "Slogan") (font-size 40.000000) (font-size-unit pixels) (antialias yes) (language "en_US") (base-direction ltr) (color (color-rgb 0.000000 0.000000 0.000000)) (justify left) (box-mode dynamic) (box-unit pixels) (hinting yes) ëêB O[gêBW  w‚Y,#×ç÷'7G”ýëÿÿýí7þUÿÿþX7þ¸ÿÿþ»6ýýÿÿýþ 5þÿÿþ4ýàÿÿþÈÿÿýâ3þFÿÿüõõÿÿþHöA£Õñòט;þ©ÿÿü  ÿÿþ« ÿüÁÿÿý£ýùÿÿü==ÿÿýù ÿýÚÿÿýÊþpÿÿþÙþÙÿÿþq ÿõ®ÿþœ89œþÿÿþ³þÓÿÿþwþvÿÿþÔ ÿýûOýRüÿÿþXþ6ÿÿýûýûÿÿþ8ÿþyþ}ÿÿþÕþšÿÿþ°þ¯ÿÿþ›ÿýåýçÿÿþ<ý òÿÿþMþLÿÿýò ÿþþÿÿþƒþ`ÿÿýæýåÿÿþaÿþLþNÿÿþºþÃÿÿþ‡þ…ÿÿþÄÿþ þ"ÿÿþßþ'ÿÿþ%ý"þÿÿþ'ÿþ þÿÿþïþŠÿÿþÁþ¾ÿÿþ‹ÿþþÿÿþûýèÿÿýéÿþ þÿÿþïþQÿÿþQÿþ þ"ÿÿþßþ´ÿÿþ´ÿþLþNÿÿþº ýüÿÿþ2 þ/ÿÿýüÿþþÿÿþƒ þ{ÿÿþÎ þÌÿÿþzÿýåýçÿÿþ< ýÝÿÿþk þjÿÿýÜÿþxþ}ÿÿþÖ þAÿÿý÷ ý÷ÿÿþAÿýûOýQüÿÿþY þ¥ÿÿþ¤ þ¥ÿÿþ¤ÿõ®ÿþ›7 7œþÿÿþ´ ý÷ÿÿþ@ þBÿÿý÷ÿýÚÿÿýË þkÿÿýÛ ýÞÿÿþjÿüÂÿÿý¤þÎÿÿþyþ}ÿÿþÎÿöB£ÖòóÙš;/ÿ;ÿ;ÿ;ÿ;ÿ;ÿ;ÿ;ÿSqÿ;ÿ;ÿ;ÿ;ÿ;ÿ;ÿõq¯ßô÷ã¾{ôDËäøñ×Jÿò@§Ùöí̓<µþÿÿü÷‚ ýAÍÿÿýÚKÿü¹ÿÿüðÿ ÿþ£ ýpýÿ ÿÿýÑÿÿõÿþ»g.P½ÿÿþbþmÿÿõÞp* "\±ýÿÿð¨ÿêo"mòÿÿ¶(þ‚ÿÿýçý3ùÿÿýžý$´ÿýØü>ýÿ þ½ÿÿþOþ¸ÿÿý¯ÿýû-ý«ÿ þPÿÿþ’þ,ÿÿýöÿþ©ýVÿ þÿÿþÄþxÿÿþ¡ÿþUý&ÿ þÿÿþãþµÿÿþWÿþ"ý ÿø<½ãñýÿÿþòþÜÿÿþ%ÿþ ùÿ:Ðÿ ÿþþþîÿÿþÿ ûÿOúÿ ÿþûÿÿþÿ üÿòÿÿùçƒC ÿþïÿÿþÿ ýÿ†ÿÿýÐþ ÿÿþÝÿÿþ$ÿ ýÿÏÿÿþFþ'ÿÿþ´ÿÿþWÿ ýÿïÿÿþ þ^ÿÿþwÿÿþ¡ÿ ýÿúÿÿþþºÿÿþ*ÿÿýöÿ ýÿåÿÿþ9þFÿÿþ·ÿÿý¯ÿ ýÿ­ÿÿý»ý-êÿÿý1ùÿÿýý$³ÿ ýÿKÿÿöÀC +ƒöÿ­ÿÿþnÿÿõÞo) "[°ýÿÿ üÿ¯ÿÿýÚÿÿ ýuþÿ ÿÿ ûÿ ¬ÿÿüÂÿÿ ýGÓÿÿý×Jÿ þÿôG¨áøðÕ£Cÿÿ ôL—ÒéûïÓšFÿ þÿ?võB†¿ÖêúíÛ¹2ü}ïÿÿ2ýRíÿ ÿ1ý}þÿÿöø©d-.X/þ|ÿÿý 6ùEýÿÿýj7ý èÿÿþsõH“ÏèúìÓ–Fþmÿÿý¿ þK ý@ÏÿÿýÅ)ýáÿÿþ? ýù7ýiýÿ ÿýï>þ6ÿÿþÕ üÿÏþcÿÿ÷ü EZÔÿÿýìþuÿÿþ‹ ÿþ<ù(õÿÿï=ý°ÿÿþ²þ²ÿÿþT ÿþŽþ­ÿÿþIù àÿÿþ+þÑÿÿþ( ÿþ¿ú!ýÿÿ»þqÿÿþþäÿÿþ ÿþäþoÿÿþbþ*ÿÿþ¼þöÿÿþ ÿþóþ¬ÿÿþ0þ ÿÿþáþ÷ÿÿþ ÿþþþØÿÿüýþÿþôþäÿÿþ ÿþëÿÿþÑÿÿþ( ÿþûÿÿþ³ÿÿþS ÿþñÿÿþþvÿÿþŠ ÿþÞÿÿþ,þ6ÿÿþÔ ÿþºÿÿþcýáÿÿþ> ÿþzÿÿþ¯ þmÿÿý½ ÿþ,ÿÿýý%ý èÿÿþp ÿþ´ÿÿýÄùFýÿÿüfÿý.÷ÿÿý¶üHÂþ|ÿÿýÿþ_ÿÿóí‚8&V‘äÿÿý~þÿÿö÷¨b,-Vÿÿýaùÿ ÿýSîÿ ÿý3¼ÿÿüû­:ü~ïÿ ÿ ô4ÂáõùêÍž`õDˆÁØìûîÛ·?@ü~?;ÿüÛt 9ÿýßN8ý¨ñÿÿ:ú pîÿÿ;ü¶ÿ<ýGõn¸ÞôôÞ·möB¥ÖóõÑ„øNªáùñц ü~ôÿÿüó{ÿü¾ÿÿýì@ýÃÿÿ ý ³ÿ ÿý®ÿýÖÿÿúó*áÿÿ þ¦ÿÿùŸ: 9 ÿÿþ¡ÿö«ÿïu$eìÿÿó¿Íÿîu%dìÿ þVÿÿýýUýZþÿÿþRÿýßý3ûÿÿû¦ÿÝý2û þÔÿÿþ~þ†ÿÿþÑÿýý4þ¡ÿÿýü3þ¢þ>ÿÿýçý êÿÿþ=ÿþ­þQÿÿþ¬þQþ„ÿÿþþ“ÿÿþ‚ÿþWþ#ÿÿþVþ#þ¼ÿÿþMþPÿÿþºÿþ#þ ÿÿþ#þ þßÿÿþ!þ#ÿÿþÝÿþ þÿÿþ þþðÿÿþ þÿÿþîÿ ÿþüÿÿþþÿÿþûÿ ÿþðÿÿþ þÿÿþîÿ ÿþßÿÿþ!þ"ÿÿþÝÿ ÿþ¼ÿÿþMþOÿÿþºÿ ÿþƒÿÿþþ’ÿÿþÿ ÿ ýŒþ>ÿÿýæý éÿÿþ<ÿ ÿ üµÿþÔÿÿþ|þƒÿÿþÑÿ ÿ úlíÿÿþUÿÿýüRýWýÿÿþRÿ ÿ ý¤îÿÿþ¥ÿÿøþ8 8Ÿÿÿþ¡ÿ ÿ ÿýÞMý ³ÿ ÿý¯ÿ ÿ ÿüØq ü~ôÿÿüó{ÿ ÿ ý|; õo¸ßõõ߸n ÿ ÿJþöB¥ÖóõÑ„÷Nªáùñц òn¸ÞôôÞ·mîEÿü¾ÿÿýì@ýÃÿÿýîEü~ôÿÿúó{ÿõ/ÿýÖÿÿúó*áÿÿýõ/ý ³ÿ ÿþÅÿö«ÿïu$eìÿÿô¿Íÿîu%dìÿÿþÅþ¦ÿÿùŸ: 9 ÿÿþ5ÿýßý3ûÿÿû¦ÿÝý2ûÿÿþ5þVÿÿýýUýZþÿÿþ‰ÿýý4þ¡ÿÿýü3þ¢ÿÿþ‰þÔÿÿþ~þ†ÿÿþ¼ÿþ­þQÿÿþ¬þQÿÿþ¼þ>ÿÿýçý êÿÿþãÿþWþ#ÿÿþVþ#ÿÿþãþ„ÿÿþþ“ÿÿþòÿþ#þ ÿÿþ#þ ÿÿþòþ¼ÿÿþMþPÿÿþþÿþ þÿÿþ þÿÿþþþßÿÿþ!þ#ÿÿÿ ÿ ÿþðÿÿþ þÿÿÿ ÿ ÿþüÿÿþþÿÿÿ ÿ ÿþðÿÿþ þÿÿÿ ÿ ÿþßÿÿþ!þ"ÿÿÿ ÿ ÿþ¼ÿÿþMþOÿÿÿ ÿ ÿþƒÿÿþþ’ÿÿÿ ÿ ÿþ>ÿÿýæý éÿÿÿ ÿ ÿþÔÿÿþ|þƒÿÿÿ ÿ ÿþUÿÿýüRýWýÿÿÿ ÿ ÿþ¥ÿÿøþ8 8Ÿÿÿÿ ÿ ÿý ³ÿÿÿ ÿ ÿü~ôÿÿýó{ÿÿÿ ÿ ÿ õo¸ßõõ߸n@÷@§Ùöí̓ ôa¨Öîûó⸃/þÿü¹ÿÿýðKýhïÿÿýÌE ý®ÿýÑÿÿýù7þˆÿ ÿýÿ¡ÿö¨ÿêo"mòÿÿýÏþ@ÿÿôÊ^% 5oÄÿÿ ÿþRÿýØý>ýÿÿþ<þ¬ÿÿý©ý.¸ ÿþÑÿýû-þ«ÿÿþŽþæÿÿþ%ÿþ=ÿþ©þVÿÿþ¿þúÿÿþÿþ‚ÿþUþ&ÿÿþäþìÿÿþ&ÿþºÿþ"þ ÿÿþóþµÿÿý©ÿþÝÿþ þÿÿþþþGÿÿüÎaÿþîÿ ÿþƒÿÿúþÒ”Sÿþûÿ ÿýNÕÿÿûü¹Qÿþîÿ ÿû9‡ÆúÿÿýÈ" ÿþÝÿ ÿ û E‡×ÿÿýã ÿþºÿ ÿýFêÿÿþ ÿþÿ ÿþQÿÿþÞ ÿþ<ÿ ÿþÿÿþø ÿþÑÿ ÿþÿÿþä ÿþRÿ ÿüÇUý¤ÿÿþ¤ ýÿ¡ÿ ÿÿõî¡b0#]Êÿÿýû2 ý¯ÿ ÿ ÿýýf þÿ ÿ ÿý×Eÿ ÿñQ€©Êäõü÷鯔EP…ÿ,ÿ,ÿ,ÿ;ÿ;ÿ;ÿ.÷H“ÏèúìÓÿþ¡ÿÿþVþVÿÿþ¡ý@Ïÿÿÿý Øÿÿýñ"ý!ðÿÿýÙ ýiýÿÿÿý/øÿÿýËýÉÿÿýø0þcÿÿøü EZÿþjÿÿþþŒÿÿþlù(õÿÿï= ÿþ¬ÿÿúMIþÿÿþ¯þ­ÿÿþI ÿýßÿÿûíêÿÿýáú!ýÿÿ» ÿý7úÿÿýľÿÿýû;þoÿÿþb ÿ þuÿÿþ{þ¬ÿÿþ0 ÿý¶ÿÿý¼þØÿÿüýþÿýåÿÿýéþëÿ ÿÿþpÿÿþVþûÿ ÿÿýêÿÿþ­þñÿÿþ ÿýÃÿÿþ`þÞÿÿþ, ÿþ‹ÿÿýñ þºÿÿþc ÿýNþÿÿýÅõÿÿýÂþzÿÿþ¯ ÿý ïÿÿüãjÿÿþwþ,ÿÿýý% ÿýËÿÿúú9¶ÿÿýù0þ´ÿÿýÄ ÿþ•ÿÿþqýëÿÿýÔý.÷ÿÿý¶ÿþWÿÿþ®þRÿÿþþ_ÿÿùí‚8ÿý&òÿÿýÜþŸÿÿýþBýaùÿÿÿý Òÿÿý÷1ý ßÿÿýãý3¼ÿÿÿþŸÿÿþeý<ýÿÿþ¦ø4Âáõùê? € € €ðý–F ôDËäøñ×J ÿýÅ) ýAÍÿÿýÚK ÿýï>ýpýÿ ÿ þÔÿÿýìþmÿÿõÞp* "\±ýÿ ý°ÿÿþ²ý3ùÿÿýžý$´ ù àÿÿþ+þ¸ÿÿý¯þqÿÿþþ,ÿÿýöþ*ÿÿþ¼þxÿÿþ¡þ ÿÿþáþµÿÿþWþþÿÿþôþÜÿÿþ%ÿþîÿÿþÿþûÿÿþ#þïÿÿþ#þÝÿÿþ$#þ´ÿÿþW#þwÿÿþ¡#þ*ÿÿýö#þ·ÿÿý¯üHÂý1ùÿÿýý$³ ù&V‘äÿÿþnÿÿõÞo) "[°ýÿ ÿýuþÿ ÿ ÿüû­:ýGÓÿÿý×J ûÍž` ôL—ÒéûïÓšF×€€€€€€€€€€€€€€€€€€€€€€€€€€€€SSSSõ!z=êB Glow Layerÿ     !gimp-text-layer(text "Apache Commons Exec") (font "Slogan") (font-size 40.000000) (font-size-unit pixels) (antialias yes) (language "en_US") (base-direction ltr) (color (color-rgb 0.000000 0.000000 0.000000)) (justify left) (box-mode dynamic) (box-unit pixels) (hinting yes) ![êB!{nz†êB!ÇBˆcˆ€Ì¡ºÁrÞÿ ò&6FVfÝ3Ý/Ý-Ý+Ý)ÝÝÝÝ ÝßüàßßÝ$Ý ÝöÞáãäæäãáÞÝ"Ý ÝôÞâçêìíìêçâÞÝ!ÝÝôàåêãîðîãêåàÝ!ÝÝòÞâèëóúûúóëèâÞÝ ÝÝòßäëïùýþýùïëäßÝ ÝÝúàçíôüþþúüôíçàÝÝþÞßßÝÝúÞâêîøýýúøîêâÞÝÝüßààÞÞõàââäåääâáàÝÝÝðàåìòúýüûüýúòìåàÝÝëßáãåäãââäçêëííìêçäâßÝÝÝðáçíöüüù÷ùüüöíçáÝÝêáæëììêçèëêêìííìêéëçâßÝÝÝîßãëïùüúôòôúüùïëãßÝÝèßãëÚëíèîîëïóö÷øøöñëëçâÞÝÝÝîàæíóûû÷ðíð÷ûûóíæàÝÝèßäììøùöõòóôóòóõøúùõíëçáÝÝÝíÞâéí÷üúóíéíóúü÷íéâÝÝôßäíñûýûùõòïîîóïðõúúöìëåàÝÞÝìàäìðúüøïéåéïøüúñìäàÝÝåßåíóüþýúôîìèææéíïõúúôëèâÝÝÝìàçìõûûôíæâæíôûûõìçáÝÝåßäíóüþüøðëæâààâæëð÷ûùïìäßÝÝêßãêïøüùñêâàâêñùüøïêãÞÝÝåßäíôüýûôîæàÞÝÝÞàçíóúûôëçàÝÝêàæìóûû÷îçàÞàçî÷ûûóìæàÝÝôßäíôüýùðêâßÝÝôßãêðùû÷íéáÝÝêâèí÷üúóìäàÝßäìóúü÷íèâÝÝõßäíôüü÷îèàÝÝõàèí÷üùïëâÞÝèßäëðúüùñêãàßàãêñùüúñëäßÝÝõÞäíôüüöíæàÝÝõàæîõüúñëãßÝõàçíõûüøñêæääõæêð÷üûõíçàÝÝõÞäíôüüõíæàÝÝõàæíôûûòìäàÝôÞâêïøýüùôïíììõíïôùüýøïêâÝÝõÞäìôüüõîåßÝÝóßåîôûûóìäâÝÝôàæìòûýýûøõôóóéõøûýýûóìåàÝÝÞäìôüüõíåàÝÝóàæíôûûóìåæÝÝôâèíöüýýûúùùøøùêúûýýü÷íèáÝÝÞäìôüüöíæàÝÝôàæíöüúòëæèÝÝôßäëðùüüùöôóòòéóôöùüüùðëãÞÝÞäìôüü÷îçàÝÝôàèî÷üùñëæëÝÝôàçíôûüøóïíìííèìíïóøüûôìæàÝÞäìôüýùðêâÞÝÝóßãêðùüøîéæìÝÝôßâêí÷üúóíçåääÙåçíòúü÷îéâÝßãìôüýûôîæàÞÝÝÞàæíóúûõìçæìÝÝôàæìðúü÷îéâàßßÙàâéî÷üúñìäßßäìõüþüøðëæâààâæëðøûùðëääëÝÝôÞâéìôûúòíæàÝÝÚàæíóûûõíçàßäìõüþýúôïìèææéìïõúúôìèââéÝÝôàäëìøüøîëãßÝÝêßãëîøüøîëâàäìôüýûùöóïîîóðõúúöíëäààçÝÝõáçìîùúóìèâÝ ÝëâèìôûúðìåàäìôüýùöóôõóóòõøúùõíëçàÞßãÝÝôÞâéâî÷õëìæàÝ ÝÛàæìëö÷ðçæâäìôüü÷òïîñôö÷øøöñëëçâÞÝÝàÝÝôÞâéÉÞèäáéâÞÝ ÝíÞâéàæêãÖæâäìôüüõïêëëõíîîíêêëçâßÝÝýÞÝÝöáæêíîíêåàÝ ÝâàåéìíìèãàäìôûüõíæåçéëììëêçäáßÝÝþÝÝ÷ßâäææåãàÝ ÝëàãäåãáààäíôûûôíåààâãääüãâàÝÝþÝÝýÞßààþßÝÝßîàÞÝÝßäíóûûôìäßÝÝÞßßþÞÝÝ#ÝõßäíóûûóíäßÝÝ#ÝõßåíòûûòíåßÝÝ"ÝõßåíðúúðîåßÝÝÝ Ýõßåíê÷÷êíåàÝÝÝ ÝõßãëÖææÖëãßÝÝ Ý ÝõÞâçëííëçâÞÝÝÝ Ý÷ßâäææäâßÝ Ý#ÝþÞààþÞÝÝ'Ý*Ý+Ý,Ý.Ý1 ÝU8ö  4ô#08<80#2ò.KdtxtdM.0ð*Q~¢µ»¶£~R*/ð?vªÄÜâÜÄ«v?/ð (V”ÇçõøõçÇ”W( þî6n®ÚôüýüôÛ¯o6õ  îI†Âèùýþýùè‡Ië   +6994-$ì*_ŸÓñûýüýûñÓŸ_+å 185.',=RcqvuocR<%  ì1011Ø01>cÐïùõà´n62i¶çúýûðÕ¬{UBEX³ØðøóÛ®us¬ð (X˜Ëëø÷å¿B  Ø A¿å÷øëÈ‹K9j¶çúýûõçα•„…™·ÖëööéÇ\að:t²ØòùóØ«h.Ù.eªØóùò×¥aDm¶çùüùóìãÖÊÃÅÏÝëõöíÔ«m@J†ñ"P‹Ááõ÷éÊ“Q! Ú Q“Êê÷õá¸uNo¶çùûôêäæçæåæëñõõì׸‚H'3iñ)Z™¿àñîØ¹}@Ú?|¸Øîñ຀Uq¸æùúïÛÏÓßèíðññîäѸŒW+ Hñ (\”£È×л›a-Ú+`›ºÐ×È¢ySs·æùùêʬ¯¾Í×ÜÝÙÐì†Z1 (ò !K{¢¸½µœtE Û Crš±·ªŒ]Hr¹æùù迌w…œ¬´¶±¥sO.ò 3So~‚yeG% Û 'EaqwjQ8=rºæøùç»wLHWforpdR=&  ô +6@D=2! á .56.#4r»æøøæºp8""-461,# ö  ä   5t½æøøæ»r1  û ï6y¾åøøå½v3-ñ8y¾ã÷÷ã¾x50ñ6x¹ÙððÙ¹w71ó3j¨¸ÕÕ¸§k32ó'R„«ºº«„R'2ó 4VssV4 3õ (;EE;( 5÷  8û Ôø 6õ  '*'  3ô2N_d`N22ò+W © W+1ò?x³ØâÙ´y@1ñ $U•ÒñøñÒ—V% /ð3m±ã÷û÷ä±n3õ ðH‡ÈìóòóíɈHí  $'&$ ï )^¡ÙìãÚãìÚ¢_) ê#('':MY``YM:& î;w»ããÆ´Æãã»x;å1P`_N:=Vrˆ˜¡¡™ˆqT5  î R’ÏæÑ¢ˆ¢ÒæÐ“S! å Ov›Ÿ…osЧºÅÌÏÎÄ­Šc: ì0j¬Þâ»~`~»âÞ­j1å&_ÏÖ¾¥£²¸´°²½ËØ×À”d4 ìDƒÄå× ^@^ ×åÄ„Eå 'd«âïàÊ»ª’|oq~™»×ÝÂŽX)  ë '[žÖ寅D'D…ÆåÖŸ\' å 'd®æöíÔ®‚Z>00?]ˆ¹Üܶz@ ê8t·á߯j.-i®ßá¸t8å &c®ç÷ëÅ‹T,-VÇâÒšZ&  êNŽÍæÑ”O O”ÑæÍOå %c¯æôà«i22jªÛà´q5 è.f¨Üã½y87x½ãܨf-ó%c®åðÑ‘NôP‘ÏädžD è@~ÀäÚ¤^&  %]£ÙäÀ?ô%b®åëÃ};ô<~ÂäÒ•P Ú %W™ÔæËŒJ  I‹ÊæÔšW$ %b®äç¹p0ô1p¹äÚ X Ù3o³âæÁH+"!"+H€Àæâ´p3$b®äå³i) õ *i³ãß§\" ÙI‰ËíêÈ—rc``_cr—ÇêíËŠI$b®äå±f( õ 'g±ãá©^$ó *a¥ÝóñÞij¬ªªç«²ÄÝñóÝ¥a) $b®äå³h) õ *i³ãß§\).ô>{¾èòìá×ÒÏÏèÒ×áíóè¿z;#a®äç¹o0ô0p¹äÛ X,Bô #T•ÒëãË·­«ªªé­·ËãëÒ•S #a®åëÃ};ô<~ÁäÒ•P/Qó3m¯àäÄ•qeabbèadq”Ãäà¯l0#`®åðÑNôO‘ÏäÇ…D.ZóH†ÆåÖ¢c8($%%Ù$'8b¡Ö密D#`¯æôà«h02jªÛà´p6*[ñ +`¡ØåÃD   Ú CƒÃäס]% "`¯ç÷ëÅ‹S+,VÇâÒšW%#Vó>xºâÝ«i/Ú /i«Þâºw8 "`¯æöíÔ®‚Y=00>[‡¹ÜÝ·x=Iô %V’ÏæÏ’R ÛR’ÏæÏ‘P "`®åñâ˼ª’{op}™»×ÝÂŽV& 7ó6l¨Úà¹y=ÛDJMJD>5(  ç  *9HZhsvshZH9-    ç  -DFKMRRTTOMD>5-% ó *?Y|¥ÑòÿÿÝóÑ¥|[B0""/9BJRX]chmrxyyuodXMA5-((ó "5KhŒºáûÿÿÚûâºhP7*""(2@Rcpw}€†—¡¨¬«§œŽ|jXKA757õ (M[jt}…‘©ËìÿÿÖïÕ¸¦˜Šƒ{pfYOD<757< "*17997/*  ï  ,5@JS_n€žÅêÿÿðì˨~qf_VOF>50*%%è* "$''"  ï %*7AM]s’½æÿÿìè›j[PF>70*% ï  ð  (0]y’¦²¸¼»·­œƒc> 1r»æùù迊v…œ¬µµ®ž†:k–³ÃËÓÚÝÞÜÖ̾¤~S0‘(Kr–³ÅÐØÜÞÝØÐÇ»šk40p»æùùêÊ«¬½Ì×ÜÜ×̼V”¶ËÛåêîðññðëß̱„R' 'N}§Å×åíïððïîéàθ“P2o¹æùúîÚÌÏÝçíñòòìÜd¦ºÜææä䀛çìòõóèÏ®w@Gz¬Íãðóòíèåäåèçß¾ªc&1o¹æùûôèàáããäéðõ÷ò`¤¶ÏÓÎÇÂÁÆÑàïöõçÉ›[) 7k¤ËæôõïãÖËÆÆÊÐÔз©f&1n¹çùüøðæÛÏÆÄËÚëöùMˆ–´°žŠ~{„œ½Ûï÷óÛµv9 #QŽÃãôöïÜÆ©“‡ˆ“¥¸º—“R!1n¹çúýúñÞ£‹ƒ’´Öíø/UswkYG=;F`‹¿âô÷éÅŒH 1k­ÖñøòÞ¾’jNDEQf}‹‡f92o¹çúýùêÊ›jKCU¹àõ*8>;53128In¥ÖðøðÒU A…Àå÷÷èÉ–^6!,>LK9 0oºçúüõÞ°p=!,Y›Òð(9GS\ceip…«ÖðùôÚ¨_%Q˜Îîøôܱo7  1qºæùûñјS" A†Çì-Kj„—¤­°³µ½Íãóú÷à°e'"\¦ØóùïЙV$ È2r»æùúìÆ…@6zÀé9[ˆ«ÁÎ×Üßáâåêòùüùäµi+'d®ßöùëLJDä3s»æùùé¿x6 0s¼çb•¾Öåíðññèòôøüýùæ¶j*(i´â÷ùéÂ}:É3t»æùùç¼s2 /pºæ‘Áàðõóïêæäãåéòùüùæ·k,*i¶ãøøèÀy7É3t»æùùæ»q01r»æµÜò÷óçÙËÀº¸»Ëâóûùæ·k+(h´â÷ùéÁ}:É3t¼æøøæ»r0  0q»æÌíøõçͬ|ro}¡Ðîúùæ·k,%c®ßöùëLJCÈ3t¼æøøæ»r0  1r»æÚôùðÖ§rN908VËîúùæ·k,!Z¥ØóùïЙU$ €,3t¼æøøæ¼s1  1s¼æà÷ùìÉŠL&)U˜Óòûùç¸l-O—Îîøôܰo7  3t¼æøøæ¼t1  2t¼æá÷ùìȈG#!=r³àöüúç¹m+?ƒÀåö÷èÉ–^6->KK9 3u½æøøæ½u3  3u¼æÝöúðÔ iF;ImŸÎìúýúç¹n- .i«ÖñøòÞ¾‘jNCDPe|‹ˆi;6u¾æøøæ¾v3  3v¾æÓñúõäÇ¡†Œ¨Èâóûýúç»q0NÃãô÷ïÜÅ©’‡ˆ“¥·º—•V#6w¿æøøæ¿y55x¿æÁæöøòäÒÆÂÇÒßéòùüùæ¼t25i¤ÌçôõïãÖËÆÆÊÐÓз«j,5z¿åøøåÀ{88{¿å§Ñëö÷óíçääåäâéóúøã»t3Ey¬ÍäñôòíéåäåççÞ¾¬j,8x¾ã÷÷ã¿{99z¿ã€³ÐåïòòðíçÞÑÌÖåòñÙµs2%N}©ÆØæíðñðïíéàι˜X"2u¸ÙððÙ¹y76x¹ÙRƒ­ÃÑÚÞÜ×ÍÀ¯£³Ã×Ö¸¢d.*Kt˜µÆÑØÝÞÝØÐǺp=,e¦¸ÕÕ¸¨k20i¨¸.Ot’§³¸¶°¢ul€ ³³£~K" Â'>]|”§³¹¼¼¶«›…gB !L‚©ºº«„Q$ $Q„«&=VfruunaN>9JaqtiO.Ä,@Udrv|yul^I1 /TpsU22Us#.6994*!.8;3#ä#,4::<61'&:EE:(ç(:     ô  ÷  ü û þ û þ ÿr:ø  7÷ '--' 5õ5TddT44õ"Sv››vR" 4õ )bÎÎa( 4õ )e«áá«e( 4õ )e®ãã®d& ô û  û ò (e®ãã®b$í !&)(%"  ð #&)(&!Û &c®ãã®a&!%&!*8GT^bb^TF3"È *;LW_bb]QA/ %c®ãã¯c.%6IX^^VH4 $?Yo€œ¢£Ÿ“iL.Æ&?[s‡– £¡™ŠxcD% %c®ãä²mHSp‡˜¡ •‚gAi‰£´¿ÇÌÏÏ˾¤€Y2Ä.Nt•±ÂÊÍÎÌǽ­‘lB %b®ä滆t‡¤¹ÆÎÑÏ¿ž"U~«¹·±®®´¿ÎØÓ·‡W*Ã,S€«ËÔÏ·°¯²¹¼®‚X" %b®äę̈žª°¯¯¸ÇØßÐ"V{—”…uljpƒ¡ÃÛÙµ{D€¯ #L~²ÔÚÆ§Šxonvƒ”—{Z$ %b®åñàtnw‘·ÙäBVi\G6-*0Cd“ÄßÒœ_) 9p©ÕÝ×mM9/08I^kWF %b¯æõèÈœpL5.8V†½á !21& 3c¢Ô߸u9 $U‘ËáΚd9 ,9<( %b¯æôãµxD" ,]œÔ  ¥ E…ÅáɈH3m®ÝÞ²t; %b®æñÕ™W%BƒÅ  !#+E~ÀãÔ˜RB‚ÄãÒ—U$ þÌ %b®åìÆ‚A2rº $4DPX\^`cršÌêÝ¢Y O’ÒäÄ@ ô %c®äèºq2Ú *h³ 8Wq…”Ÿ¥¨ª¬´Èãñâ¨^# X Úäºs3 ô &c®äå³h) ó'd°Dn”±ÂÊÎÏÏéÐÔàïöå¬_##]§ßã´j,  õ &c®ãä°d' Ú%b®?s¥Ê×ÒÇ»³®¬¬³Çãóå­a#"_¨áã±g*  õ &c®ãã®c&Ú %c®bŸÐßЯ‘{mebbp—Ëìå®a##]§ßã³i,  õ &c®ãã®c%Ú%c®€Àá׬yR:-'#(@v¼èä®a# X Úäºs3 õ &c®ãã®c%Ú %c®—Ó寇K$ 3t½èä®a#O’ÒäÄ@ õ &c®ãã®c& Ù &c®£Ýåºq1@„Èìå®a$B‚ÃãÒ—U# þõ &c®ãã®c& à &c®¦ßå¹p0 'Zž×ñæ®b$3m®ÝÞ²t;   &d®ãã®d& à &d®žÚçÄ‚C $H»æõæ¯b%#T‘ËáΚd8  *9<( &d®ãã®d& à &d®ÌçÖ¥nD/,7Rw¤Íëöæ®c%9p©ÕÞÖlL8/08H]kWG (e®ãã®e( à (e®r±Üã̤ƒpmw‹¢µÇáñæ®d&  "L³ÕÚÆ§Šxnnu„“—{\& (e®ãã®f) æ )f®R‰¾ÚÞÒ¿³®±´¯¢ªËèá«e' ß+T­ÌÕÏø°¯²¹»®Y% (e«áá«g* æ )f«1^ˆ°ÈÑÑÍź¦‹v‚¬ÑÏ`' à-Qu—³ÃËÎÎËÆ¼¬mD'aÎÎc* æ )b3VsŒœ¢¡˜‡qVEW{œ›vO!á'A]v‰˜¡¤¡˜‰xbE' Rv››vS$ æ"Sv'=OZ`_YL9'0L``P2â +=MY`cb\P?04TddT5ç5T %''# ()#ð#'))&!÷&--' é '   û  û ù  ý ï51 .û  ý ,û ÷ *ë  $''$  í '.47741'    ë  *7FR[[TF9,"   æ  ,;Rk‚‚lT>/"        â(9On˜»Ì̼šsV@0% ø ù ÷%3FaŽ¿ÿÿíÁ’kO?3(  "%%÷"  ÷  "%%ô" "%0>Ts£ÖÿÿìÙ«€cQB70(" %*03799ö73-("  ö  %*0599ó730--3:H_°áÿÿÃ云udVMD<5- %-7<JYeouyyÙukaUF<0%"-9DOZfouyxvph]TMKQ]q’ÀèÿÿÃîÑ´¡–†€vma>KXlž¦¬­«¤™‰xdRA3(  (3AO`p€¥«ª©¢–†vh^]fz›ÅëÿÿÃñÛǾº¸µ°§™ˆRc~˜±ÃÐØÝßÜ×Í»¥‹pXF7-((-7DUl‚›±ÃÏØÝÝÜÔʹ£‹wmq‚ŸÉìÿÿÃõæÜÛÝàáßØÌ¸f†ªÉáóúþÿÿþü÷èÒ¶”vZH<55AHXn„‚lT@7007@Tl‚DOYfqx{}|vspoqqpj_M>2(" "(09DO[fpuyxvpf[OC95007>IT[[TF9/(%%(/9FT05>FMRUUVSQQPPMJF>7,"Ò"(09AFMRTTQMH@92*%"%(,479971*""*17 %*039<<:7ø5/*"÷ %*0599ù70-("ç $''$  $ "%%((%÷"   ç  "%((%%"ü  ö ü  ú ÷      û         ü  þ  ™¸Ý3 Ý1 Ý.Ý-Ý+Ý*ÝÝÝ ÝÝþÞßßÝÝ ÝùßàââääååäÝ ÝøßàãæèêëííþëÝÝ ÝõÞàãçêìêêìíîîýíëÝÝ ÝõÞáåéìêíòõö÷÷ýöõÝÝÝóÞâæëêîô÷øöôóññýòôÝ Ý Ýîàæëëòøù÷òîíìíîíììÝ Ýß ÝÝòàäëëóùùõïíëéçææüçéßÝ ÝòßàââääåääââàÞÝÝòßâéëòùùôîíçäâààüâãàÝÝùàâæèêëííùëêçæâàÝÝòàæìîøúöïëæâàÞÝÝûÞéäàÝÝ÷ÞàäèìéêìîîøìêéìèãàÝÝóÞâéëõûùðíæáÞÝÝûéêãàÝÝìàæêêìñõ÷÷ø÷÷õòëêêäàÝÝôàåìïùûõîéâÞÝÝûðëèâÝÝêàåëêðöø÷õóóôöøù÷ïêéãàÝ ÝõàçëôûúòíæàÝÝïøíëäàÝÝßãêêòøøõðîîöïò÷úøïëçâÝ ÝõâéìöûøïêâÞÝÝîûôëçàÝÝàçëñøùôïëèææõéîñøú÷ìëäßÝ ÝõÞãëíùû÷íèâÝ Ýîü÷íéáÝÞãêí÷úöðêåáààõãçîôúúòëçàÝ ÝõßäëðúûõíçàÝ Ýïüùïëâßàåìóúùóíæáßßôáåêñøû÷ëéâÞÝ ÝõßäìñúûôìæàÝ Ýàüúñìãßáèí÷ûùóìæåäããääæëñøüùíëäßÝ ÝõßäíñûûôíæßÝ ÝðüûòìãßâéïùüúõðîììõíðôùüúïíäßÝ ÝõßäíñûûôíæßÝ ÝûðóìäàâëòúýüùöôóóòòóöõøûýûïíåàÝ ÝõßäìñúûôìæàÝ Ýûñóìäàãìóûýýûúùùøøù÷úûûøëìåàÝ ÝõßäëðúûõíçàÝ ÝûñôìäàãìóûýüùöôóòòùñìÛëãßÝ ÝõÞãëîùû÷íèáÝ ÝûðôìäàãìóûýùôðíììííûìêæáÝ Ýõâéì÷ûøïêâÞÝÝûòôìäàâëòúüøñêæä äüãàÞÝ ÝõàçëôûúòíæàÝÝûðôìäßâéðùüøñéãßßÞÞßþÞÝÝôàåìïùûõîéâÞÝÝûñôìäßáèî÷üúòëäßÝÝóÞâêëöûùðíæáÞÝÝûðóìäßàåìóûûõîèâßÝÝúÞààáàÝÝòàæìîøúöïëæâàÞÝÝáÞûûóíäßßãëîøûùòîçäààßààâãæèèäàÝÝòßâéëòùùôîíçäâààëáâûûóíäßÝàçëñùû÷ñîêçææöçéëíãÄéãßÝÝòàåëëóùùõïíëéçææëçéûûòíäßÝÞãêìòùú÷óïîííöìëëéæÓìåàÝÝÛàæëëòøùöòîíìíîíììúúðíäßÝÝàåëëð÷ùøöôòññ÷òóòëÕìåàÝÝóÞâæëêîô÷øöôóññ÷òô÷÷êìäßÝÝøàåêëìñõ÷÷öõóðêãâéãßÝÝþÝÝõÞáæêìêíòõö÷÷÷öõææ×ëãÞÝÝøàãèëêêìîîöíëéèììéäàÝÝ ÝõÞàãçêìêêìíîîøíëííëçáÝÝùàâäçêëíí÷ìëéçåâàÞÝÝ ÝøßàãæèêëííùëææäâßÝÝðÞàáâäååæåääâáàÞÝÝ Ýùßàââääååäà ÝýÞßààßþÞÝ ÝÝüÞßßààß"Ý7Ý5Ý 3Ý 0Ý-ÝÝÝ ÝÝ Ý€94ü þ1ò ",367:764/ð "0@Sbktwyyun.ï2Mf~”¤¯¶º¼»·¯-î(Ceˆ¥»ÇÏÖÚÞÞÝÛÖ,ò*Oxž¾ÏÜæëîïððýïíë*R€­ÉÜëðñïëçåäåçê ú ú è%K~°ÎåñóïåÚÐÉÃÃÅÉÐ ú#-477ù3-#ç Au«ÎèôôêÚÉ´Ÿ†„†’¡4ì-?UdnvxvpdU?*  å1`›ÈåôõêÔ¸”t]MDBEM_eB$ê'>]y’¥±·º¸±¦‘yY9  Ì F€»ÝóöíÖ³„X9(,œpC'Kq—´ÄÏØÜÞÜØÐò’jD" î,_žÎì÷óß¼‡Q- ì Ä j7 %Kz§Ã×äëîððõïìäÕÀžoA ï:w¶Üô÷ìΚ\,ààÂR! @u©ÊáîñîêæåèíñóîÞÄœf9 ñ L‹Äè÷õâ»z>àñׯn2/cŸÈäññèÛÌÃÁÆÓãïõñݾR& ñ &ZÏïøòاc- ßøèÈDE…¾àòóæÐ²”z† ÃßñöïÔ­p7ò *e©×óøîΗR ßùðКQ$+`¤ÔïõìÓ¨xTC?Ge•ÆæõöåÁ‰M ñ 0m±ÞõøëLjFßùôÚ¦]/=y»äõô㿉ZA62:Ox¯ÛòøîÏž^( ñ2q¶á÷øé€>ßù÷à¯c6KŽËîøó༒xkggjrбÙñùôÙ­j3ñ4r¹ãøøè¿z9ïùøã´gøòæ¶lBd­âøýüùõòññóòóõøøòصs;ñ 0m±ÞõøëLjFøòæ¶kDf±ãùüùóêåââöäåãÙº¡f0ò *e©ØóøîΔP øðæ·kDe¯âøûôäξ·µ··ó¸¹º»¼º³ŸxJ# ñ &ZÏïøòاc- øáæ·lBaªßöúðÖ¬„pjjlmooqrstpaF*ñ L‹Äè÷õâ»z=øâæ¶l>X ØôùñÖ¡g>/**++-/2331. ï:wµÝô÷ëÍ™[,øâæ·l:M‘Íïùõß±p9  î,_ŸÎì÷óÞ»…O( Þ øøæ¹m6?{½å÷øêÊ•[2*9DC8% Ë F»ÝóöíÖ³‚X9((øøæºn3/b¦ÕñøôàÀ“iK>79CRf{Š…nD! Ë1`›ÉåôõéÔ·”t[MCADN]øøæ»p1"F‡¿âô÷ðÞÆª‘‚}‹š­½»›j4 Ì Bv«ÎèôôêÚȳŸ…ƒ‡Ÿøøå¼s/,ažÊåóöðåØÌÄÁÂÇÎÔØÔº²|@ Ì%K~°ÎåñóïåÚÐÉÃÃÄÈÏ÷÷ã½t2=r§ÊáïóòîêæääåçêéÞ½²x@ Û*R­ÉÝëðñïëçåäåçêððÙ·r0 !Gx¤ÃÖäìïððôïíêåÛ˸œh4 ò*OxŸ¾ÏÜæëîïððÞïíÕÕ¸¦d, %Fk’°ÂÏ×ÜÞÞÝØÒÊõštG# Ð(Ceˆ¥»ÇÐÖÛÝÞÝÚÕºº©K  ;Xu¡¯¶»½ºµ¬ |aE*Ñ2Mf”¥¯¶º¼»·¯pT/ (=N_lvy{xtk`OA. ê "0AScnsy{yunEE:&î (39<<:81+í ",369<961 ü ú ü û "¶ü  3ó !%'((%"0ñ ,àåȆEOŽÆÙ¼ƒL' :m«×Ú­n5 ô"XžØãºs4àæÔ—Q-h«ØÓ¡`.  "MŽËáăF ô$^¤Ýã´k. ïåÜ¢Y =~ÁáΔW2%""ô#-K…ÄäÒ”T! ô%`¨àã²h+ ðäà¨]" JÐèÔ§|f__`õevÏêÜ¢]& ô%`¨àã±g+ ðãâ¬`" SÛñæÎ·¬ªªõ¬´Èáïߥc) ô$^¥Ýã´k. ãò­`" Y¦áôðâÖÐÏÏõÐÒØàáМ`( ô"XžØãºs4ãò®`" !\¨âòäʵ¬ªª÷«­«vO" ôP’ÑãÂ~=ãð®`" Z§àìÏudaabbcdú`N0 ôDƒÅãÍŽMãò®`" V ÛçÂI+##$%ù&'&  ó6qµàØ£a* ãñ®`" M”񾂠D  ü  ô (^Ôà»|@ãð®a# ?‚ÄäÔ›W# ûóG‚¿àÑœa0ãä®b# /k®Ýà¶w=   Í0dÑÝ¿ŠW. ãã®b$ RËâÒ h:   .;<* Î Cx°Õ×·ˆ]:% ãã®c%7m¨ÔßÇœqP:/+-4BSgq[L$ Í(R„µÔÔ»•sXD7/-07Cãã®d&I|¯ÓÛʬzniktž_- Î.W„°ÎÓÆ®—ƒvmlmuáá«e' (P|¨ÈÔÑź±®®±·¾¿®€\*Ð/T{ ½ÍÏǽµ°®°´»ÎÎa' )Lq’®ÀÉÍÎÎËÆ¿´¢‰iD è*Gh…Ÿ´¿ÇËÍÎÍÊÄ››vQ!ê#>ý<9ñ %*3HU_ipwz}~}xu  æ %0FMRUUñRMF>7-% ó *>So“»Üøÿÿæü÷ñíêìïõTD9-%" "(-9DOXfou{{áwofXMA5*   %5Kg‹³ÙøÿÿÓüñäÙÏÉÅÆÊÑt`OA50-07AO]o€‘Ÿ§­®­¨Ÿ‘€mYH<-  ô -AZ}¦ÏòÿÿÑúèÖô§ŸœœŸ§Ÿ„iVH?X|§Ó÷ÿÿäýìÒµ™„uh`[YY]ñÑ­‹tffl}˜·ÕïýÿÿóýìϬ…eH5% õ  0Fdйãþÿÿõ÷ݽ›ƒl`OIDBBóÿï̧‹}{…œ»Ûöÿ ÿéðϦ}[D-   "5Mm™ÈñÿÿæþëͨŠo[K?50--0ÿþâÀ ž¹Ùöÿÿøýøôóõúþÿÿêê×nO7%  %:Tw¤ÔùÿÿôüãÀ™{bK:0%"  ÿ÷òÒ´¡¢µÒïÿÿöúðéäãæíõþÿÿêüÛ°[A* *<[¯ÜýÿÿôøÛ¶qTB0"ÿ÷ûßò´ÊåüÿÿõûñæÞÙ×Úâì÷ÿÿëîÄ’gF0  *D]„µâþÿÿôôÔ«†fK7(  ÿøýçοÄÙòÿÿóþöíãÛØ×ÙÞèóýÿÿìùÑ qM5" -DaˆºäÿÿññЦ€bF3"  ÿÿùìÕÈÏäúÿÿóý÷ðêåââãæëôûÿÿìýÛ¨wR5% -FcмæÿÿõïÌ£~`D0  ÿùïÚÏ×ëþÿÿúþûøõóòòûóõùýÿÿìþß­xT9% -FcмæÿÿõïÌ£~`D0  ÿúñßÔÝïÿÿí߬xQ7" -DaˆºäÿÿññЦ€bF3"  ÿÿúòà×àòÿÿì×¥qJ5" *D]„µâþÿÿôôÔ«†fK7(  ÿúòàØáòÿÿìÆ•fC- *<[¯ÜýÿÿôøÛµqT?0"ÿúòàØáòÿÿÜýú÷óñîíììëëêéæÝʧ{Y>( %:Tw¤ÔùÿÿõüãÀ™{bK:0%  ÿúòàÖÞðÿÿÜüôëãÜ×ÓÐÍÌÊÉý³ƒdH5"  "5Mm™Èñÿÿñþëͨˆo[K?50--0ÿÿùòßÔÚìþÿÿÛüñãÕÊÁ¹´±¬ª¦¡˜Ž}gO<*   0Fdйãþÿÿòöݽ›ƒl`OIDBBDÿÿùðÜÏÓæûÿÿèþóãÒö®¨¢š•‘ˆ~mZF7% õ *>X|§Ó÷ÿÿòýëѳ˜„uh`[YY]ÿÿùïØÈÊÝôÿÿÛøéׯ»°§¢›˜—‘…qZC2"  "5Mk‘¾åþÿÿóúçÏ· ‘„|wvx{ÿÿøîÔÀ¿ÏçýÿÿÛþóåÕȼµ±¯°²³±¤‡dE/   -AZ}¦ÏòÿÿôùèÕò§žœ›¦ÿÿøìζ²¼ÖñÿÿÛýôéÞÕÏÍÍÑÕÙãò¤qI1   %5KgŠ³ÙøÿÿõüñäÙÏÈÄÅÉÑÿÿ÷éǪ¡¨ÀÛöÿÿìûõðììîóùþÿÿµ|K/  ó *>So“»Üøÿÿ÷ü÷ñìêëïõÿÿö佞“¤¿Üöÿ ÿ÷³yK/ ò "0DZt–»Øóÿ ÿôÙ¯}ˆŸ¹Öîüÿ ÿâøØžjA,  %3FZt”²Îåøÿ ÿǘxjfl}“®ÇÛíøüþÿÿþýùðÞÆ¦|T7$  (5FXo‰£¼ÑáðøüþÿÿÙþûÌ̽yaTTV_o‚™¯ÁÏØÝßÞÜ×Í¿¬”w[B. à (3DRey£µÄÏ×ÜßàßÛÕ„nXHA?BHQ`o¦¬¯®¬¤šŒ|fSA1$ Æ %050-05:FMZeow{||yukaWJ;/" Ù "*5>HU_ipwz}~}xt9971,%" %*09AFMRUUñOJD<5*" ñ %*3>ý<9ñ  "%((ó%"   î  %%(**((%  ù ö  ÷ þ  þ    þ     þ €€þÝ=Ý:Ý8Ý6 Ý4 Ý3 Ý2ÝÝ ÝýÞÝÝ ÝâýàßÝÝÝùêçæäáßÝ8Ý÷êéíêçäàÞÝ6Ý÷ôðëèìêåàÝ6ÝöõöõñçâéãßÝ5ÝöìïóõðÝíåàÝ5ÝöìîëììÞîæàÝÝ÷ÞßßààßßÞÝÝþÞßßþÞÝÝßõÞåçëìÞÌìåàÝÝóßàâãäååäãâàßÝÝößààÞÞßàââääüâàÞÝÝîàâãäåääâßáåéë¿éãÞÝÝïÞàãæéëìííìëéæãàÞÝÝôÞáãåäãââäçêììçëéæâàÞßáåèëìííëêÝÞàâåæãàÝÝíßâæêëêëíïïíìéëêæâßÝÝáàæëììêçèëêéìîîìêëèäáâçëéêìîîìéÝÝûÞàáàÝÝ÷ßâçìêïôö÷÷÷öôïêìçâÞÝÝòÞãêÛëíçïîêïóöøøôõïìéæèêèïóöøøþõÝÝëáçìëôøù÷õóóõ÷ùøôëìçàÝÝõÞäììøùöõðñòòôô÷úûøòîìíëðòòûô÷úúÝÝÝàåëëõúùõðïîîïðõùúõëëäàÝÝßäíñûýûøôïîîíïñõúûùôóððîíîîïðõúÝÝÇÞâèëóúúõïíéææéíïõúúóëèáÝÝßäíóüþüøñîêçæçëðöûüú÷ôïíëçæçëðöÝÝÇàåìîùû÷ðëæâààâæëï÷ûùîìãßÝßäíôüþüõîêäààáæëòúýüúóîéäààáæìñÝÝÇàçëôûúóíçàÞÝÝÞáçîóúûôëçàÝßäìôüýúòìäàÝÝÞâèïøýýúñëäàÝÝÞâéîÝÝõâêì÷ûùðêãßÝÝêßäëðùû÷íèáÝßäìôüüøïèâÝÝõàæíöüýøïèâÝÝüàæîÝÝõßãëîùû÷îèáÝÝëáèî÷ûùïëâÞßäìôüüöîæàÝÝõßåíõüüöîæàÝÝüßæíÝÝõßäìðúûõîæàÝÝëàæíõüúñëãÞßäìôüüôíæàÝÝõßäíôüüôíæàÝÝüßäíÝÝõßäíñûûôíæàÝÝëàæíôûûòìãßßäìôûüôíäßÝÝõßäíôüüôíäßÝÝüßäíÝÝõßäíñûûôîæßÝÝëßåîôûûòìãßßäìôûûôíäßÝÝõßäíóûûôíäßÝÝüßäíÝÝõßäìòûûôíæàÝÝëàæíôûûòìãßßäìôûûóíäßÝÝõßäíóûûóíäßÝÝüßäíÝÝõßäìðúûõîæàÝÝëàæíõüúñëãÞßäìôûûóíäßÝÝõßäíóûûóíäßÝÝüßäíÝÝòàßÞßâëîùû÷îèáÝÝëáèî÷ûùïëâÞßäìôûûóíäßÝÝõßäíóûûóíäßÝÝêßäíÝÝàâääâàâéí÷ûùðêãßÝÝêßãêðùû÷íèáÝßäíóûûóíäßÝÝõßäíóûûóíäßÝÝÑßäíßáäèêÈçâáçëôûúóíçàÞÝÝÞáçíóúûôëçàÝßäíóûûóíäßÝÝõßäíóûûóíäßÝÝÑßäíäçëìàÒêãàäìîùû÷ðëæâààâæëï÷ûùîìãßÝßäíóûûóíåßÝÝõßåíóûûóíåßÝÝÑßåíìîëìíáìãàâèëóúúõïíéææéíïõúúóëèáÝÝßäíóûûòíåßÝÝõßåíòûûòíåßÝÝêßåíìïóõñßëãßàäëìõúùõðîîéïðõùúõëëäàÝÝßäíòûûòîåßÝÝõßåîòûûòîåßÝÝÞßåîõöõñèäèáÝÝàæìëôøù÷õóóõ÷ùøôëëçàÝÝõßäíðúúðîæßÝÝõßåîðúúðîæßÝÝêßåîôðëèìéãàÝÝÞâçìêïôö÷÷÷öôïêìçâÞÝÝõßäíê÷÷éíæàÝÝõßåíé÷÷éíæàÝÝõßåíêéíêçãàÝÝíßâæêëéëíîîíëéëêæâßÝÝõÞãëÖææÖëãßÝÝõßãëÖææÖëãßÝÝößãëêçæãáßÝÝïÞàãæéëìííìëéæãàÞÝÝ÷áçëííëçâÝÝ÷âçëííëçâÝÝùâçââàßÝÝóßàâãäååäãâàßÝÝ÷ßâäææäâßÝÝ÷ßâäææäâßÝÝüßâÞÝ ÝýÞßààýßÞÝ ÝàþÞÝÝþÞààþÞÝÝþÞÝ„ÝÝÝÝÝݨ@û :ù+$ 8÷cTE2# 6ö£”jQ9# 5õÏÆ¼¦mK) 4õêäÙÍÀ£yG#4õîïîçÕ¾Ÿg0þ ôØáêíæÇµy:õ  õ  Ü  ´ÇÓÝàɺ~;  *169961+  Ä   +6763( "-6994,v’±Çį°v7 "6H[jrwwrj[H3#€  185.(,=Rcqvtk[F,% .U¤½ËÕÚÝÝÚÕ˽¤~V1 +e¦¸ÕÕ¸¨k20i¨¸ÕÕ¸¨k20i¨£”jO4  *Hk…œ¬µ¹¹µ¬œ…gH* "Mƒ©º¼«„Q$ $Q„«¼¼«„Q$ $Q„bT@/"  "6H\jswwsj\J3#Ù0TssU22UssU22U+$ ï  *179971+  õ&:EE;(õ(;EE;(ø( õ  ÷  ÷  ý þþ û û  €ü;ù8øI;- 7÷†ubK5!6ö½°š‚hH)5öÅËȸ—pF 5ö“¨½È»Š^* 5öWn‰¥¯e. õ ü  ýï %6Rs‚r\* ñ  %((%  Ù  $&&# $''# 'A[MCï 2DR]bb]RC2 Ã"('':MZ`^WF0  )>P[a_WG /3$.Kg‘¢¢‘gK. Â0O`_O:]‰ºÛÚ´x?%d®ãã®e( õ (e®ãã®e( Ñ (e“¨»ÇºŠX! 'V‹¿ÙÕ»˜}qq~™»ÖÙ¾ŠU'  &e®ãã®f) õ )f®ãã®f) Ñ )fÄÊÇ·—n@2_¹ÑÓÉ»³³¼ÉÔѹŒ_3 'e«áá«g* õ )f«áá«g* Þ )f¼¯šfE% 5]¢ºÇÌÎÎÌÇ»¢\4õ&aÎÎc* õ )bÎÎc* Þ )b…sbJ4/Lh~‘¢¢‘hK. õ Rv››vS$ õ"Sv››vS$ õ"SI;+ ï"2DR]bb]RD2 õ4TdeT5õ5TeeT5÷5ñ  %((%  ÷'--' ÷ '--' ú  ü  ü ù  ù  þ1K€þ=:8  6÷ 4ó"  2ò50*%  1óMD>7-%   ñkdUJ@5*    òš‹|kZJ;,   ó̾«–}dM9,       þ    îöìÚÇ«ŠgM7*ù ö ÿãþ󨵋aC2%  "%%((%%"   ö "%%"þ ü ""%%ý" ÿÿøýã«xO;-((à*0399<<973-(""%(-035599ü530--ü03377ý0ûÿÿѾ‡[C7557>FKOSUUSOHD<3*""(/59>DFHKORTTRMKFBBØDFHMOQQMFÚæõþÿÿÂŒ`JDBHMXcmtz}}ztkaUH>3*%%€ï(2;BJRX]ahmrx{zwqkc][[]aiowxxth°¾Îà÷ÿµ…`RPQ]kz‹˜¤«°°«¤˜‡wfUH<5339FTcpw}~ƒ—¡¨­­¨ “‡}yw}‡’Ÿ§¬ª£˜ƒŽž¯»Þ™t]X[fw¥ºÊÖÜßßÜÖʺ¤Œt_PFDFOay“¤©ª©­¸ÈÓÛÞÞÚÑÁ±¡˜›¥µÄÒÚÝÝ×Ì_hq~ˆ†we^bo‚œ»ÒæõüþÿÿþüõæÒ¸š~i[VYg§Æ×ÜØÕÖàïúýÿÿýøéׯ¼¿ÌÜðúþÿÿýøFHQV]^][_lƒ¢Âßøÿÿô÷ÞÁ¡‚qhl~ŸÊÿÿüðñüÿÿùôäÛÞëüÿÿñ359>CKOVf}›Áãüÿ ÿõû⢉}~´Ýÿÿýûþÿÿû÷ñóþÿÿò"%(/7>KYp¸Ýûÿÿùý÷òò÷ýÿÿöûß½Ÿ Áçÿÿúúôòöüÿÿèûþÿÿúôñõûÿÿ %-:K_~¤Ïôÿÿ÷ùíãÜÜãíúÿÿ÷õÕ¶ ªÊìÿÿøõêâßäïúÿÿèþÿþóçßÝâíùÿ *:MhŒ¸áþÿÿõüëÙÉÀÀÉÙìüÿÿ÷þåȰ©´Ðîÿÿöøè×ÌÉÑàñþÿÿëöæÖÊÇÌÜïý *:Qs›ÉñÿÿõòÜij©©³ÅÝòÿÿøóÖ¼²»ÔïÿÿõþïÛÆº·ÀÓéúÿÿêþíØÂ·²¼Íåù *::DKXix‹™¤¬°°¬¤™ˆwfXH?:75-*(*2;IT[[RF9/(%%(/9FR[[RF9/(%%(/9FMF>70("  %-3[¤ÙôùïΔOO•Ïçøøå¸k*+k¹æùùéÀx6 /p»çùùé¿x6 0r¼çøøåµkBb¬ßöùëÆ…@@…Ææøøæ¹l++k¹æùùç¼s2/oºæùùç¼s3/pºæøøæ¶lDf±â÷øéÀz89|Àæøøæ¹l++k¹æùùæ»q/ .p»æùùæ»q0 /r»æøøæ¶lDi³ãøøè¿x57w¿æøøæ¹l++k¹æøøæ»r0  0q»æøøæ»r0  0q»æøøæ·lDf±â÷øéÀz89{Àæøøæ¹l++k¹æøøæ»r0  1r»æøøæ»r0  1r»æøøæ·lBa¬ßöùëÆ…@@…Ææøøæºl++l¹æøøæ¼s1  1s¼æøøæ¼s1  1s¼æøøæ¶l@Z£ÙôùîΔOO•Ïæøøæºl,,lºæøøæ¼t1  2t¼æøøæ¼t1  2t¼æøøæ·lP[a_WG2ì 2DR]bb]RC2 fD%Û1O`_O:]‰ºÛ®ãã®e&&e®ãã®f) õ )f®ãã®f) Ñ )f®ãã®d% &U‹¿ÙÕ»˜}qq~™»ÖÙ«áá«e' &d«áá«g* õ )f«áá«g* Ñ )f«áá«e' 1_¹ÑÓÉ»³³¼ÉÔѹÎÎa'&`ÎÎc* õ )bÎÎc* Ñ )bÎÎa' 5\¢ºÇÌÎÎÌÇ»¢v››vQ Qv››vS$ õ"Sv››vS$ Ñ"Sv››vQ!/Lh~‘¢¢‘hKTddS33SddT5õ5TeeT5õ5TddS4ë!2DR]bb]RD2 '--&÷&--' ÷ '--' ÷ '--&í  %((%   ù  ù  ù  ü  ü dT  þ     þ         ú ö ú  û ÷  ÷ "%%"þ ü ""%%÷"   ê "%%((%%"-% ô"%(-035599ü530--ü03377ø0*% Ô"(-379<<973-(B90(""(/59>DFHKORTTRMKFBB€.DFHMOQQMFB90( "*3HUcmtz}}ztkaUˆt`OD755<>CMV^[TF9/(%%(/9FR[[RF9/(%%(/9FT[[TI>73037AKUcmtz}{ztkaU799ø72-*-2799ß71*""*147741*""*179974,%""ï(-3ÝþÝVÝþÞßßþÞÝ ÝßþÞÝÝößààÞÞßàáãääüâàßÝÝúßàâãäååúäââàßÝ ÝýàÞÝÝìÞáãåäãââäèêìíìëêçãàÝÝøÞàãæèëìííøëêèæãàÞÝ ÝüæâßÝÝëàæëììêççëêéìîîìéëéäàÝÝíàåêëêëíïîîìêèéíéåàÝ ÝûìçâÞÝÝòÞãêÛêíçîíêîóöøøùõîéêãàÝÝùàåëéîô÷÷ööôñìâáêãßÝ ÝûëìçàÝÝõÞäììøùöôðñòòéô÷úûøðëèáÝÝàãêêóùúøöôòññòúëÕìæàÝ ÝîõëëäàÝÝßäíñûýûøóïîîìðõúûøíëãßÝàçêñúûøóïíí÷ìëéäÑìæàÝ ÝËúóëèáÝÝßäíóüþüøñîêçæçëðöûûôëçàßâéì÷ûùóîêçæåæçêìæÃêãßÝ ÝÕûùîìãßÝßäíôüýüõîéäààáæíñúü÷íéâßãëïúü÷ðéãàßààùâåçèäáÝ ÝÖúûôëçàÝßäìôüýúñëäàÝÝßâéï÷üùïëâßãìñûüöðçáßÝÝàýáàÝ Ýîùû÷íèáÝßäìôüüøïèâÝÝêàæîöüúñìãßãëðúü÷ðéãàßÝÝî÷ûùïëâÞßäìôüüöîæàÝÝæàæíôüûòìäßâéíøûùóîêæäâààÞÝÝîõüúñëãÞßäìôüüôíæàÝÝäßäíôûûóìäßàçëòùûøòîíìêèæãáàÝÝîôûûòìãßßäìôûüôíäßÝÝâßäíóûûóìäßßãéêòøùøõòïíììëèåâàÝ ÝîôûûòìãßßäìôûûôíäßÝÝíßäíóûûôíäßÝàäêëíóö÷÷ööóðíëìçãàÝ ÝîôûûòìãßßäìôûûóíäßÝÝàßäíóûûóíäßÝÝàãèìëìïñôö÷ø÷óìêèãßÝ ÝîõüúñëãÞßäìôûûóíäßÝÝõßäíóûûóíäßÝÝíßáãçéëììîñõùúöìêçàÝ Ýî÷ûùïëâÞßäìôûûóíäßÝÝõßäíóûûóíäßÝÝîßàâãåçêíðõúûõéêâÞÝ Ýîùû÷íèáÝßäíóûûóíäßÝÝõßäíóûûóíäßÝÝñÞßàâæëñøüùìëäßÝ ÝîúûôëçàÝßäíóûûóíäßÝÝïßäíóûûóíäßÝÞááàÞÝÝôßãèð÷üúîìäßÝ ÝîûùîìãßÝßäíóûûóíåßÝÝßßåíóûûóíäßàãæçæãâààßßàãéð÷üùíìäßÝ ÝîúóëèáÝÝßäíóûûòíåßÝÝßßåíòûûóíäàáèÐåíëéçæååæêîóùû÷êêãßÝ ÝîõëëäàÝÝßäíòûûòîåßÝÝíßåîòûûòíåàãìàìííììííõîïò÷úùðêçâÝ ÝëýçàÝÝõßäíðúúðîæßÝÝíßåíðúúðíåàãìæô÷öõóòòõôöøùøñéêäàÝ ÝûìçâÞÝÝõßäíê÷÷éíæàÝÝíßåíé÷÷ëìäàãëÜîôö÷÷øø÷øöóìêêåàÝ ÝüæâßÝÝõÞãëÖææÖëãßÝÝíßãëÖççØëãßáçæçéëíîïïöîíêêìèäàÞÝ ÝýàÞÝÝ÷áçëííëçâÝÝïâçëííëæàÝÞâæèêëìííùëêèæâàÝÝ÷ßâäææäâßÝÝïßâäææãáÞÝÝÞàââääååäâýàßÝÝàþÞÝÝþÞààÝûÞßßàßßüàßÞÝJÝ;Ý:Ý8Ý6Ý 3Ý ÝÝÝ2 Ý“Óþþõ  ü ù  ý ë   +3661+! í %/67:;96.' ü#é 185.(,:Odquvm^J4ë3HYfqwyzwpfYG4# ËI* +KfrqdWZrޤ±·¶°Ÿ†dA" (Cd‚˜©³º¼»¸²¨—hI* Ê~V1G{¡³´¦•–¬ÀÍ×ÜÜ×̼œoA %LwžºÉÓÚÞßÞÚÕÍÆ¹žyM# Ê´ˆV+ (`Ÿ¹ÖÚÍÇÆÎÜçíñòòìÜÄžg5 Ey«ÈÜéïðñððîëçÞͺŸj: ÊÓ¶„K! -m²ÙñôíäÞàããäéðõ÷òàÁO 0f¥ËæòõòíèåãäæèèÞ¾³}C ÊëѬp7.qºãøû÷ðæÛÏÇÅÌÛëöùñ×®k4"E†Àãõ÷ñäÔÈÁÀÃÊÑÕѸ³~C ÊöçÇ“Q!/q»æúýúñÞÄ¥…’´ÖíøøèÃ…E/VžÑðùôãȤ‰{x‚‘¥¶º™k8 ÊøóÚ°l1-mºçúýùêËmLDU¹àõùðЙS8b¬ÜõùïÔ£mJ:6!,Y›ÒðùôÚ¦_>f¯à÷ùíÍ’V0(5CG9' ËóøïÏ—M#/l¸æùûñÒ˜S# A†Çìù÷à¯f>a¬ÝöùïÔ¢mG/"  ÌïùóØ¥X'.k¸æùúìÆ…A6zÀéùøãµi=XÒñùôãÇ¢‚jXH:,# Ëëùöß­`+/k·æùùéÀx6 0s¼çùøå·l9Fƒ¿ãô÷ñãÒÁ° Ž|fQ9'  Êéù÷â²d./k·æùùç¼s2/pºæøøæ¸l31`žÈäñôñëäÛÒȼ«’uT4  Êèøøã´h./k·æùùæ»q01r»æøøæ¹n0 ;n¢Ä×åìïðîìèàÖÆ±Žc; Ééø÷â²e./k¸æøøæ»r0  0r»æøøæºn-=h¯ÂÏÙáçìðñïçÕ½“`1Éëùöß­`,/k¹æøøæ»r0  1r»æøøæºo- 1Ol…›­»ÆÓàìóõî׸…J! ÉïùóØ¥X'/l¹æøøæ¼s1  1s¼æøøæ»p.  "2BTcv‰¡»Õêö÷ìË `, ÉóùïЗM#/m¹æøøæ¼t1  2t¼æøøæ»p/!*5F]…´ÜòùôÙ±o6÷Êè‚@/o»æøøæ½u3  3u½æøøæ»p3+=A8,"&;bœÑïùöÞ¶t8ÉøóÚ¯l0-p»æøøæ¾v3  3v¾æøøæ»s:8[{…{gSC85;Lp¥ÕðùõÚ²p4ÉöçÈ“Q /r½æøøæ¿y55x¿æøøæ¼uBQŠžº¼®œŠ}wyˆ¤ÇãôøïѦd-ÉëѬo61u¾åøøåÀ{88{¿åøøå½wId¨ÄÜÞØÏȾ¿ÇÓãðöóàÀŽS$ ÉÓ¶ƒK! 2v¾ã÷÷ã¿{98z¿ã÷÷ã»wLk¯ÐëñïëèåääçìñôñâȤn7Ù´ˆV-0s¸ÙððÙ¹y76x¹ÙððÙµpGb¢¿àëïðññôðïíæ×ħyI$ Ê~V1 +e¦¸ÕÕ¸¨k20i§¸ÕÕ¸¡b9M¬ÃÏÖÚÝßàßÜØÐŵ—sL) ËH* "Mƒ©º¼«„Q$ $Q„©º¹§|G%.U}–§¯µº¼¼»·°¤’z]A& ü#Ò0TssU22Up~}lL)-BXepuxz{ytmcSA- ý õ&:EE;(í(:DB5  ',669::÷92,#÷  î  ù û þ  Qý  ý ú  û þí  $&'" ï $'((&# ýë"('&;MZ`_WH4í0AQZ`cc_WK=, û. é1O`_O;;Uqˆ™¡ •‚gE&ë*Gd{Žš¢¥£“ƒs_E) û\4ÒNv›Ÿ…no‡¤¹ÆÎÑÏ¿žtH! ,T{Ÿ¹ÇÌÎÎÍɹ¨lG Ê_3%^ÏÖ½¢©°¯¯¸ÇØßÐ¥p; "N€±ÑØÐÁ¶¯­¯´º½®^, ʾ‰U' %c«âîÝuow‘·ÙäÍ”X% 7o«×àʦ‡tjimx‡–š|_. ËÚ³w?%c®æõèÈqM6.8V†½áà³r6J‹ÊäÓ¢nI3+)/9K_mXK$ ËáјY& $b®æôãµyE" ,]œÔåȆE XÙæÃ€C *9<, ÌÜß´q5$b®æñÕ™W%BƒÅæÔ—P ![¤Þå»t4  ÍÐãÆ…C#b®åìÆ‚A2rºåÜ¢Y XŸÚæÃ€C íÂäÒ”P#a®äèºq2ä *h³äà¨^" JŒËäÓ£nH/# í¹äÚ¡W#a®äå³h) ã'd°ãâ¬`# 6p¬ÖÞÉ¥…mYJ;.   î³ãß§\ #a®ãä°d' á%b®ãã­b# K~®ÌÔ;­œŒzhT>)  î±ãá¨^"#a®ãã®c&à %c®ãã®b$)Nu—±ÀÉËÈÁ·§“xZ9  î³ãß§\!#a®ãã®c%à%c®ãã®b$#=Zq†™¨¶ÁËÏÉ´‘i> î¹äÚ¡X#b®ãã®c%ß %c®ãã®b$ &5FWfv‹¢½ÒÙÅ—c3 îÂäÒ”P#b®ãã®c& õ &c®ãã®c%ì  *7Ib‡´Úà¿I îÏ䯆D$b®ãã®c& õ &c®ãã®c%ì -UÊæÔ™X% îÜß´q5$c®ãã®d& î &d®ãã®c%  ó :z¿æÜ¡_' îáÑ™Y& %c®ãã®d& ß &d®ãã®c% #8:-! DÃå×›Z$ îÚ´x?%d®ãã®e( ß (e®ãã®c% B]phTC5-((2Hm¢ÒâljM U'  &e®ãã®f) ß )f®ãã®d&"Y‡¨¤“‚vlgjs†¥ÈÝÓ¦n: îŒ_3 'e«áá«g* ß )e«áá«e&%_—ÆÏȾ¶°­¯µ¿ÍÔ̪{L%  û\4õ&aÎÎc* í )bÎÎ`&P~­ÁÈËÎÏÏõÍʳ—uN* û. õ Rv››vS$ á"Rv››vO 6[v†’š¡¥§¥ —ˆu]A& ýõ4TdeT5â5TdcS1/?KS[`bdc_WK<, þ÷'--' ä &-,% "%')()&"ù  ù  ú  û ¿þ<<þ ü þ ý    ü        ù   ø ú  ù ø ö    ö "%%ø"   ø"%((õ%"  è  ""%(-035599ø70-("÷"(-359<<ô970*%  Û %3*" (/59>AFHKORTQMFB90*%  è%*33*%%Î(2;BJRV[_fmrwxwrk_TF<3--05>FR_jsz{|{xpeZL>2'  -fUH<5339FTcpw}~ƒŠ–¡¨«ª¤˜‡ubRH??BHSew‡—£«®¯®¨Ÿ‘€lXC4$ ’  0Œt_PFDFOay“¤©ª©­·ÆÑÚÝÝÖ˸ …o]TOVas‰¡¸ÉÔÜßàÞÚÓųš{]B.    3¸š~i[VYg¤Æ×ÜØÓÕßïúýÿÿý÷å̯xlhl}•´ÏäôûþÿÿàþûöåË©~U7$  "5ÞÁ¡‚qhl~ÊÿÿüïðüÿÿôñÔ²“€}†œºÚõÿ ÿäûÜ lB,  "5û⢉}~´ÝÿÿýûþÿÿöïÏ®˜“ž·Ùùÿ ÿæ³yI-  "5ÿûß½ž Áçÿÿ÷þÿÿúôòõûÿÿ÷þãĬ¦²ÐñÿÿÛþúõðìíðõüÿÿ³zI-  "7ÿÿõÕ¶ ªÊìÿÿ÷þôéàÞäîùÿÿøóÖ¼³ÂßüÿÿÚþõìáÙÓÏÏÑÕÛïžkD,  "7ÿÿþåȰ©´ÐîÿÿöøçÖÉÉÏßðþÿÿùûáÇ¿ÍçÿÿäúíßÑļ´±®®ªœ~[>'  "7ÿÿøóÖ¼²»ÔïÿÿõþïÙŹ¶¾ÏæúÿÿùþèÑÅÑêÿÿäøêÙʽ±§ž˜ˆzcK7'  "7ÿÿøúàźÀÖðÿÿõúæÌµ©§°ÂßõÿÿúìÔÈÒèÿÿäúíÞÏÁ·ªŸ“†|m[F7%  "7ÿÿøýçÎÀÄØðÿÿõöÞ¿¨ž£º×òÿÿùîÖÈÎãýÿÿäþõëßÔɽ­ ‘l[K7*  "7ÿÿøþëÑÃÅÙðÿÿõòÖ·Ÿ’›°ÑïÿÿùïÖÄÆØóÿÿìþúòëãØÌ½«•hTA0" û "7ÿÿùìÕÄÆÙðÿÿõïѰ–ŠŠ”¬ÎîÿÿøïÖÀ»Èàùÿÿïþûõìßл€gK9( û "7ÿÿùíÕÄÇÙðÿÿõîΪ‘„‚¨ËíÿÿöîÔº°¶ÉÞôþÿÿìüóßÄ¢~]D0   "7ÿÿùìÔÄÆÙðÿÿõíË¥‹€€Š¤ÉìÿÿóîÒµ§¥°ÂÔäòúýÿÿîýèÅšrQ9%  "5ÿÿøþëÑÁÄ×ïÿÿõìÉ£ˆ||†¡ÉìÿÿïîѲŸ™¦µÄÒÝçîöûþÿÿïþ㶇_B*  "5ÿÿøýçÍ¿ÁÖïÿÿõëÇ „{{„ Çëÿÿîíΰ›’‘”Ÿ«µÁÍ×ßèòúÿÿðøÍ˜hF0  "5ÿÿøúàź¾ÕîÿÿõëÅŸ‚vv‚žÅëÿÿííί›‘‘“–¦®¸ÁÌ×äñüÿÿðþØ¥rM3" "5ÿÿøóÖ¼°¸ÑíÿÿõêÜ~uu~œÃêÿÿíìͯŸ›Ÿ ¢£§¬²¼ÄÏÝìùÿÿçݪuM7" "5ÿÿþåȱ§²Îìÿÿõé˜}pp}˜Âéÿÿíì̲¦¬º¿¿¼º¹½ÃÉÔàïúÿÿæþÚ¦tM3"  3ÿÿõÕ¶¢ªÉêÿÿõç½”wllw”¿èÿÿíë̳°Ã÷ëâÝÙÕÔÖÛãìõþÿÿæúÑmJ0   0ÿûß¿Ÿ‘‘ Ãçÿÿõäºqffqºåÿÿúéɲ·Òÿÿöû÷òïîðôúþÿÿæë¾ŒbB-  -üãã‹~‚•¸âÿÿõ಄h]]h†²áÿÿúåí´Õÿ ÿåôϤwU9(  *ÞÁ¡†rlq„«×ÿÿõÖ¤x_TT_x¤Öÿÿúܶ¡ªÊÿ ÿãþðÒ®†bD0   %¸š~k`[_r”Áÿÿõ¿ŽiRFFRhŽÀÿÿôǤ‘•°Óìöûýþÿÿ€ýúðÞÈ«‰hM9(   ŽtaQKIM]vš¼ÌË»™sVD<5-*(*2;IT[[RF9/(%%(/9FT^`[RJHHMU_hrx}ñ}ypfZOA7*  â 3*%  "*179971*""*179;;õ7559>DJOUXZZðXSOFA9-% á " $''$  $'**%%ç(*037<>>A>><50*%  ú   üü  úú "%(**(ô"  ô      þö           2 “ÅÝ)Ý$Ý"Ý!Ý Ý Ý&ÝÝüßààßßàþßÝ ÝÝúßáãåæååæüäâßÝ'Ýûáæëìíí îûëçâÞÝ%ÝøßãëÛìñòññðïøîìäÎëåàÝ%Ýößäììøûûúùøø÷ùõðÛíæàÝ%ÝõßåíñûýûøôòññðïøîìåÏëäàÝ%ÝößåíóüüøôïííîüëçáÝÝßÝõßåíóüüöïèåääåæôãáÞÝÝÞßààßÞÝÝýÞßààþßÝÝêÞàââääåääÝÝßäíóûüôíåàßßýàßÝÝ÷àãåææäâàÝÝ÷àâäææåãàÝÝùàâæèêëííòëÝÝßäíóûûôìäßÝ ÝõàäéìîîìèäàÝÝõàãèìîîìéãßÝÝøàäèìéêìîîòìÝÝßäíóûûôìãÞÝ ÝÍáæÃÕæëççêãßÝÝßãéççëæÖÅåàÝÝàåêêìñõ÷÷ø÷÷ÝÝßäíôûûôìäßÝ ÝÊàåéáòø÷ïìèâßßâçìï÷øòãéäàÝàåëêðöø÷õóóôöÝÝßäíôûüõíåàßÞÞßßýàÞÝÝÞÞãéêïùûøïìæááæìïøûùïêèáÞßãêêòøøõðîîòïÝÝßäíôüüöïèåääåæÙãáÞÝÝàäëìõûû÷ïëææëï÷ûûõìêãßÞàçëñøùôïëèææñéÝÝßäíôüýøôïíìííîûíëçáÝÝßàæìî÷üûõïëëïõûüøîìæàÝßãëí÷úöðêåáààÃãÝÝßäíôüýüøõóòòññðïïîìåÐëãÞÝÝÞâçíñùüúõòòõúüùñíçáÝÝàæìòúùóíæáßßòáÝÝßäíôüþýûúùøø÷ùõðÜíåßÝÝÂßâèíôûüúøøúüûôíèâÞÝÝáèí÷ûùóìæåäããääÝÝßäíôüýüøõóòññððïïîìåÎëãßÝÝïàãêî÷üýüüýü÷ïêãàÝÝöâêïùüúõðîììÝôßäíôüýøôïíìííîüëçâÝÝñàåëòùýþþýùñìåàÝÝôãëñúýüùöôóóòòòóÝÝßäíôüüöïèåääåæüäâßÝÝóáçîöüþþûöîçáÝÝôÞãìòûýýûúùùøøÝõßäíôûüôíåàßßàþÞÝÝóàæíõûþýúôìäàÝÝôÞäìòûýüùöôóòòÝõßäíôûûôìäßÝÝòÞâçïöüþþûôíæàÝÝóÞãìòûýùôðíììííÝõßäíóûûôìäÞÝÝñàåìòúýþþü÷ðéâÞÝÝöãëñúüøñêæääÝõßäíóûûôìäÞÝÝùàäëï÷üýýúûôíçáÝÝôâêïùüøðéãßßÞÞÝõßäíóûûôìäÞÝÝîàãéîõûüûùúüüùðìåàÝÝõáèí÷üúòëäßÝÝõßäíóûûôìäßÝÝßÞâçíóúüúöóôøûû÷îêãßÝÝàæëóûûõîèâßÝÝõßåíóûüôíåàßßàþßÝÝÎÞáçíïùüúõïìíòøüúôíèâÞÝßãëîøûùòîçäààßàÝÝßåíóüüõïèåääåæÙãàÞÞàæëí÷ûûöïêæçíóúüùðíæàÝÝàçëñùû÷ñîêçææÝößåíóüüøôïííîØíëæààäêìôûû÷ïëåáâèíõûûöìëäàÝßãêëòùú÷óïîííÝõßåíñûýûøôòññðïÉîìæÒëãâèëîùûøðìçàßàäëí÷ûúñêéâÞÝàåëëð÷ùøöôòññÝÝßäììøûûúøø÷Ùöðßìææêâñø÷ðìèâÞÝÝàçìíöøóãèäàÝÝàåêëìñõ÷÷ÝøßãëÛìñòññðïïîìåÒëåæÈÖæëçæêäàÝÝôßâèèæëçÖÅæàÝÝøàãèëêêìîîþíÝÝûáæëìííîòíëçâãèìîîìéäàÝÝõàãèìîîìéäàÝÝùàâäçêëííÝúßáãåæååæôãâààâäææäâàÝÝ÷àâäææåãáÝÝöÞàáâäååæåÝÝüßààß ßàþßÝÝùÞßààßÞÝÝýÞßààþßÝÝýÞßàà€Ý Ý Ý ÝÝÝ€Eýþþ )ø ÷ &÷%09<<988ò9:<<>?BCC9. $ù.Lfuzz{~õ€‚…†‚v]: #ö$K|¢¶¼¾¾½½¾¿ôÀÁÂÃþ®[+#ö0e¢»Ùãääââ÷áÞÓ³®v;"ô6tµÙòø÷õóññøïæÇ·~=ô:x¼ãøüøðèäââõáÞÓ³ªp6  þ ü á8z¾æùûòá˾º¹»¼½¿ÀÁ½ª…O$ û õ ú#-477€Ð36w½æùúëÌž}qprtvyz~€{kM+):A@8,  ,9AC=/! ,?Udnvxvp6u¼æùùè½{H1-.023689:7/ ;_t€s[;  <[s€u`= %=]y’¥±·º¸±5t»æùùæ¸l/  2d“¯¼¼±—n> y‘¸ÔÛÒÀd10dœÀÒÛÔ¸r9%Ix¥Ã×äëîðð€ï3t»æùùæ·l/   ;v­ÈçòðßÃT..TÂßðóçÉ©l4%Au¨Êáîñîêæåèí3s»æùùè¼zF0--02368:7, ,^šÅáôøòܸ~QP}·ÜòøôáÑR,3bžÈäññèÛÌÃÁÆÓ3r»æùúìËœ{ooptvz{}{kK)=t«ÐëøøïÔ¬ªÔîøøìϦj6(G‡¾àòóæÐ²”z† 3rºæùûòáʼ¸·º»½¿ÁÁ¼¨‚J!J¶Øðù÷êд´Ðê÷ùñÙ´{A"/b¥ÔïõìÓ¨xTC?Ge3rºçúüùòéäââÆáÞÓ³¨i.(U‹ÀàôùöéÜÛéöùôᾈN%=|¼äõô㿉ZA62:O3rºçúýüøôòññÇïæÇµw3 1_—Çç÷úöññöú÷èÈ–Y*K‘Ëîøó༒xkggjr3rºçúüùòéäââ×áÞÓ³ªm29h£ÑíùûúúûùîѤh3 "X¡×óúöèÔÁ·³³Âµ¶3rºæùûòáʼ¸¸»½¿ÀÂÃþ¬‰R  ?w±Üóûýýûóܲw> %b¬ÞöüúôëåãââÅ3r»æùúìË|pptvz}€„€rU2&QÈëùýýùêÆŒO#  'h²âøýüùõòññå3s»æùùè½{H2/0368<>?>3'âD€Àèøýý÷ã¶u: *kµãùüùóêåââæ3t»æùùæ¸m1  à(U’Êìúýýøæ¼|A *i³âøûôäξ·µ··î¸3t»æøøæ¸k, Í CzµÞôüýýúïÑ_- %e®ßöúð׬„pjjlmo4t»æøøæ¸k*  Ê =n¨Óîùûûüû÷åÀˆN" "[¤ØôùñÖ¡g>/**++4t¼æøøæ¸l, ý€26džËé÷ú÷ôõùúòÚ³w@ N–Îïùõß±p95u¼æùùæ¹o1  -Z‘ÃãõùõêàäðøøíѤh3>€¿å÷øêÊ•[26v¼æùùè¾|I3/13589<>=:/(Q‡»ÜòùöèϺÃÝòùöæÇ•X(.fªÕñøôàÀ“iK>796w½æùúëÍŸrrtvz{~€{fI*)F{±Õïøøìѧˆ•ÁãõùóÞ¼„I$$HŠÀâô÷ðÞÆª‘‚}8z¾æùûòáÌ¿»º»½¿¿ÁÂÂÁº¥{MDn¥Îé÷ùðذxVe›Ìê÷øîÔ®p:"1cžÊåóöðåØÌÄÁÂ:x¼ãøüøðèäââÈáÞÓ³ lf“Âàôøóß½„L/=o­ÖïøöäǘW)#>r§Êáïóòîêæää6tµÙòø÷õóññØïæÇ¯{{©ÇæòñáÆ—[,"J†½ÛïóéÊ­p5%Gx¤ÃÖäìïððôï0e¢»ÙãääââÉáÞÓ³¤w~·ÓÛÓ¤m:-^–¿ÏÚÕ¹’w8$Ek’°ÂÏ×ÜÞÞÝ$K|¢¶¼¾¾½½¾¿ýÀÁÂÂꦂ^f‹ª¹¼³šqA 8i”±½¼°“d4 :Xu¡¯¶»½º.Lfuzz{~Ç€‚ƒ}kQ:AYp}~v`A$ 9Zr€‚zdC  (;N_lvy{x%09<<988é9:<<=?A?>5#)9@@8, ó ):CC=0#õ (39<<:ø ø  ü ö  ü ýþý   Äý  ú  'ú"(*))*÷+,.-( %ú1Oaeefg÷hjjgW9%÷ Ov«¬«ª ªù¨štW) %ö '_Ñáß×ÑÏÏù̼c. %õ (d«âðàŲ«ªªù¨štV& %ó (e®åìÉ–qdcdeeõfggijfU6ü  Þ (d®äæ¶p<(#%%&'())*,+$ ÷  å #&(&# &c®ãä¯c'  þ  ò(-,& õ&,-(è *~ÁáΔW2%""ò# %b®æòãdz«ªªù¨štV& â #L…¿âìèèì㿆M# L‘ÐèÔ§|f__`ç %b®åìÉ–pdbcdefghjjgV7ã)Y–Îí÷öíΗ[*VžÛñæÎ·¬ªªè %c®äæ¶p;'#%&'))*+--& ñ8q´ã÷÷â°o6õ"[¦áôðâÖÐÏÏé &c®ãä¯c' ñ +c¨ÞöôØžY% õ#^¨âòäʵ¬ªªõ &c®ãã®`#ñ9tµä÷õÜ¥a+ó#]§àìÏudaabbõ &c®ãã®a#ã,]™Ñïø÷èÀ‚F X ÛçÂI+##$ò% &c®ãã®a#á&Q‰ÂäîíïîÚªm6O”񾂠D õ &c®ãã®b#ß F|µÞçÙËÑãçΗ\*B‚ÄäÔ›W# õ &c®ãã®a#Ý;n¨ÖæÕ¯“Ãáá¿…M" 2l®Ýà¶w= ó &c®ãä¯d(  þ  €¸ 2cšÎåÛ±{Yf—ËåÛ¯t>!SËâÒ h:  (d®äæ¶p=($%&'())*+,+"+VŒÃâὄL.:j§×æÑžd27n¨ÔßÇœqP:/+- )e®åìÉ–qecdeeffghiieR1#K€·ÞäÈ’X)D}¸ßãÄ‹V'  I|¯ÓÛʬznik (d«âðàŲ«ªªÉ¨štP#>q¦ÕäÒ¡g4 &UÆâÛ±zE(P|¨ÈÔÑź±®® '_Ñáß×ÑÏÏÊ̼]+.Y†¸ÓΨuA4gœÈÔ¾Œ^.)Lq’®ÀÉÍÎÎË Ov«¬«ª ªÍ¨štP)1Nx™¢”tL% AnŽ¡š{P3#95/*  õ"/;DOX]accað_]ZXQLC91'  õ"2@Tfu~…ˆŠŠìˆ‡…ƒ|wodVE4' õ /@[x•¨³¸º»»ºì¶µ²°ª£–dI1$   Ú (;Vy¥ÆÚãæççææååäãâáàÝØÍ´a@.    ú ú0Hh”Æÿÿó®wL7(    ø "%((ù%9TwªÛÿÿó»V;0*%" üü÷ %*059<<ù9>Z‚µäÿÿì±}YC<752/*(%" "%(*,,ü*%"  ÷%*09>FMRUUùRDaмèÿÿìûöñíêèçæäâáÞÙϸ•oVJFFûC@<933ý7<@@ð>;72/-05?HRbp€‘Ÿ§­®­¨Kh’ÃëÿÿÃôâÏ¿´ª£ž˜’ˆwnaY[g{™—Œ|md``dmzŒ—™ŒyeUPTaoƒ›±ÃÐÚÝàÞÚMj”ÅìÿÿÃòÞÇ´¦›’Š„}wqjb]V[f£ÀÐÕÏ¿¨“{}’¨¾ÏÕÐÂ¥…nglz“®ÉÞðùýþÿÿýPl˜ÅìÿÿëóÞŲ£•‹‚vpjd]YV[o•èÿÿõïÒ·¤˜˜£·Òïÿÿõꟃ|†›¹×ïýÿÿúPn˜Æìÿÿêóßɵ¨’Š‚}unf]YV^q—Èüÿÿ÷îØÃ··ÃØîÿÿöüЩ‘‘¡½ÜöÿÿúQn˜ÇíÿÿêõäÑ÷¬¤ž˜‘Š‚xnc]_n»èÿÿ÷þîÝÑÑÝíþÿÿ÷ìÇ©›¢»ÚöÿÿôýøôóõúQq›ÉíÿÿéøîâÙÑËÅÁ¼º³¬ŸŽyhakƒªÔ÷ÿÿùýðççðüÿÿ÷øÚ»¥¤´ÒïÿÿóúðéäãæíQq›ÉîÿÿèüøóïìêèæäâßÚлšwefx—¾âüÿÿûüööûÿÿöýæÊ°¦¬ÄãüÿÿòûñæÞÙ×ÚâQq›Éîÿÿö´…icl†¨Ïîÿÿýÿ÷ð׺§¦µÓðÿÿñþöíãÛØ×ÙÞQq›Éîÿÿõ½‰g]dw—ºÝöÿÿö÷áÄ®¢¨¾Ýúÿÿñý÷ðêåââãæQq›Éîÿÿô±€bV]l…§ËèûÿÿõüêÒ¶¤ŸªÄåýÿÿúþûøõóòòùóQq›ÉîÿÿåüøóïìéæäâàÝØÍ·’kTMTf}˜»ÝóþÿÿôþòݪªÈéþÿ ÿúQq›ÉíÿÿåøíàÖÎÆÁ»·²®¦™†lTHFN^u‘°ÐëúÿÿõúêÓ·£™›ªÊìÿ ÿúQn˜Çíÿÿäõâμ¯£›’Œ…wm^QC>BK[u­Îèøþÿÿôþ÷æÌ³ •™«Êíÿ ÿúPn˜ÆìÿÿåòÛÁ«™‹wnhaZRHB<:?K^v‘³Óìúÿÿõøçδ •™©Êëÿÿñýú÷óñîíììPn˜Åìÿÿæñ׺¢€shb[TMFA:7:BOd}œ¾ÞóÿÿõüíÖº£™™§ÈêÿÿñüôëãÜ×ÓÐÍPl–ÅìÿÿæðÖ·ŸŠzmd[TOID?<Z‚µäÿÿúÁ¥¨ÄèÿÿöþîÚÈ¿ÅÓçüÿÿöîÈ¥‘‘¢¿Üöÿÿú9TwªÛÿÿúÊ­¯Ïûÿÿõð×¾«¤©¶ÎéþÿÿôýѤˆ€‰Ÿ¹Öîüÿÿú0Hh”ÆÿÿûÁ¥«êÿÿôñѵŒ†Œ–®Êéÿÿ¤ë›{mp~•®ÇÛíøüþÿÿþ(;Vy¥ÆÚãæççææååäãâáàÞÚÒ¿£‘”¬ÄÒÕп¨zqloz‡ »ÍÔÐÁ¥ƒg\[bq„š¯ÁÏØÝßÞÜ /@[x•¨³¸º»»ºÅ¶µ²±­¨Ž~su‚’œž™‹zi]VRVYgu†•›—Œw_OFHKT`q‚¦¬¯®¬"2@Tfu~…ˆŠŠÃˆ‡…ƒ‚}zumdZUW[dhhf_UKD?>@CCã@950-**-39>@@>;7/*%%(*39AFMRUUò  (27<972--/û*(" ê "%(,,*'" "%*059<<õ  %(*-00-î*(%%"  ýò "%((÷   þ       úû             €6ÝÝ Ý ÝÝ Ý"Ý#Ý#Ý$ÝþßÝÝßþÞÝÝâýàÞÝ ÝúÞàáâäååäüâàßÝÝúêçåâàÝÝùàâæçêëííùëéæäàÞÝÝùêéìèãàÝÝìÞàäèìêêìíîìêççíêæàÞÝÝøõòëêêäàÝÝøàæêêìòõ÷÷ööõóíãàêäßÝÝ÷øù÷ïêèãßÝÝõàæëëñ÷ùøöóññøòñëÕíæàÝÝ÷ò÷úøïëçàÝÝêàãêëòùú÷ñîíîîíêèâÏíæàÝÝßîñøú÷ìëãÞÝÝáçëñùú÷ðîêçææçêíç¾êäàÝÝêçîôúúòëæàÝßãëíøûøñíçäàà÷áâæèèæâßÝÝêåêñøû÷ìèáÞàæëóúûôîèâßÝÝùßàââáàÝÝëæëñøüùïëâßáèì÷ûùðëäßÝÝìíðôùüúñëãßâêïùû÷îèâÝÝìóõøûýûðìãàãëñúüõíçàÝÝùîúûûøíìãàäìòûûôíæàÝÝòðñíßéâàäìòûûôîæßÝÝíñìéäàßäìòûûôíæàÝÝäñãâàÝÞãëðúûõîçàÝÝþÞßßþÞÝÝöâêîùû÷îèâÝÝ Ýõâèì÷ûùðëäßÝÝÝúÞààáßÝÝôàçëóúûôîèâßÝÝùßàââáàÝÝêàâãæççäàÝÝßäëíøûøðíçäàà÷áâæèèæâßÝÝ÷çéëíäÈéãÝÝêáçëñùú÷ðîêçææçêíç¾êäàÝÝßìëëéæÕìäÞÝÝàäêëóùú÷ñîíîîíëèâÏíæàÝÝöñòóòìÖìãÞÝÝõàæëêñøùøöôññøòñëÕíæàÝÝ÷õóðêãâèâÝÝøàæëêìòö÷÷ööõòíãàêäßÝÝ÷ëéèììéäàÝÝìÞáäèìêêìîîíëèèíêåàÞÝÝøìëéçåâàÝÝùàâæèêìííøìêéæäàÞÝÝäûâáàÞÝÝúÞàââäååäüâàßÝÝßþÞÝÝýÞßààßþÞÝÝ$Ý#Ý#Ý"Ý ÝÝÝ Ý Ý ÝÝ 2þû  ô   ú-#ð#-499;61' ødU?* ì,?Qbovzyul^I8! ÷¦‘xY9ë'>]y’¦²¸¼»·­ˆkK(ÞÐñ‘jB 'Kr–³ÅÐØÜÞÝØÐȼ¢|J( ÞìäÕÀn>%N{§Å×åíïððïîéàμ¡l:ÞñóîÞÄšb1 Dy¬Íãðóòíèåäåèçß¾µEÞãïõñݽˆI 2h£ËæôõïãÖËÆÆÊÐÔзµEÞÃßñöïÓ¨f. KŒÁãôöïÜÆ©“‡ˆ“¦¹¼—¢q>Þ•Ææõöå¿@.fªÖñøòÞ¾’jNDEQg‘zV. Þx¯ÛòøîΖQ*?¿å÷÷èÉ–^6!-@SWL5ߊ±ÙñùôØ¥\4P”Íîøôܱo7  !&'é¿Ðåôú÷ß®e?\£ØóùïЙV$ û êåéòùû÷à²hBe­ßöùëLJDêòóõøøòتcBk³â÷ùéÂ}:âìäåãÙº•U>kµãøøè¿y7긺º»¹¯—j<6j³â÷ùéÁ}:êoprqpiV9 ,e®ßöùëLJCé-/131-&&\¦ØóùïЙU$ û ß R˜Îîøôܰo7  !&Þ*9@?/ C…Àåö÷èÉ–^6->QWL5ÞCRf{‡€a71k¬ÖñøòÞ¾‘jNCDPf~‘zV. Þ‹š¬¼º›”W##PŽÃãô÷ïÜÅ©’‡ˆ“¦¸¼˜¢q>ÞÇÎÔØÔº«l*6j¥ÌçôõïãÖËÆÆÊÐÔзµEÞåçêéÞ½­l/ Ez¬ÍäñôòíéåäåççÞ¾´EÞíêåÛË·—\% %N}©ÆØæíðñðïíéàλ¡l:ÞØÒÊó˜o?*Lt˜µÆÑØÝÞÝØÐǼ¢zJ( öµ¬Ÿ{_B$ ë'>]|”§³¹¼¼¶¬œ‡kK*ötk`O@,ì,@Udrv|zul^L4! ø81+ ð#,4::<61' ú  ô   þþrü û  û  ú ð #&)(&! ùL;) î *;LW_bb]QA1  øˆsY7-% (09AFMRTTQMH@7/" ÚofXMA5*" %-9DOZfouyxvpfZL>2' ÙŸ‘€m[K>3*((-5AO`p€¥«ª©¢”„oZE4$ ÙÑð—}gSF:77& ýì÷ÿÿ÷ðѵ¨«ÄãýÿÿêýïÛÆ´¦œ˜™ššŒqO3" üèóýÿÿøúÞ³»ÔñÿÿêôÞê–†|solf\L9& üëôûÿÿøýæË¼Çßúÿÿéýéί”obVOJE>1& üõùýÿÿøþêÏÂÎæýÿÿêù࿟„p^OD<7/*" ÿùêÑÇÒêþÿÿêõÙµ“ybOB5-(" ÿúåÍÅÒìÿÿëñÓ¯ŒpYF7-%  ÿúØÃ¿ÒíÿÿëðÒ­ŠoWD5(" óìëëêèâÕ³·ÎëÿÿëñÓ¯ŒpYF7-%  òÌËÉÇý²§¢¬ÇçþÿÿêõÙ´“ybOB5-(" ò¬ª¨¤ œ–’“¡¾âýÿÿêùྟ„p^OD:7/*" ò›–•‘Š…‚ˆ–´Ùùÿÿéýêί”obVOJE>0& ò›š™˜†€~Œ¦ËïÿÿêôÞꕆ{soke\L9& ñ¯°²µµ«—ƒz€—ºßýÿÿêýïÛÆ´¥›—™ššŒqO3" ñÍÑÖÚäó­Šuw…¥ÌïÿÿêýðãÕÌÅÅÉÍÔë—e>& ðîóùþÿÿ¼pju²×öÿÿëþúòíêìòúÿÿ°vG+ ÿõ¹‡h_fx•¸Ú÷ÿ ÿõ²vG- ÿñøÙ£xZQVcy–¹×ñþÿÿóüÝ¡jB) ÙýùðÞǨ^KDFP_v®ÉÞðúýþÿÿýøêÍ«X9$ Ù×ÍÀ¬–y`K>572("  (09DO[fpuyxvpfZM>2' ÚOJD<5*" (09AFMRTTQMH@7/" ÷930*%÷ %*0599ó70*%  ÷%"    ì "%((%%  ù  ú ø ø          &ÝP€€&P€€€€€€€€€€€€€€€€€€€€€€€€SSSSõ!z=êB Backgroundÿ     EêBekwƒêB±½ÉÕáíù)5AMYeÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ €ÿ €ÿ €ÿ€ÿ€ÿ€ÿ€ÿ€ÿ€ÿ€ÿ€ÿ€ÿ€ÿ€ÿ€ÿ€ÿ€ÿ€ÿ€ÿ€ÿ€ÿ€ÿ€ÿ€ÿSÿSÿSÿõ!z=commons-exec-1.3-src/src/site/apt/commandline.apt100644 0 0 11334 12425540624 17227 0ustar 0 0 ~~ ~~ Licensed to the Apache Software Foundation (ASF) under one or more ~~ contributor license agreements. See the NOTICE file distributed with ~~ this work for additional information regarding copyright ownership. ~~ The ASF licenses this file to You under the Apache License, Version 2.0 ~~ (the "License"); you may not use this file except in compliance with ~~ the License. You may obtain a copy of the License at ~~ ~~ http://www.apache.org/licenses/LICENSE-2.0 ~~ ~~ Unless required by applicable law or agreed to in writing, software ~~ distributed under the License is distributed on an "AS IS" BASIS, ~~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ~~ See the License for the specific language governing permissions and ~~ limitations under the License. ~~ ~~ -------- Apache Commons Exec - Building the command line -------- -------- 20 August 2010 -------- Building the command line You have two ways to create the command line to be executed * parsing the entire command line string * building the command line incrementally * General Considerations No matter which approach you are using commons-exec does change your command line arguments in the following two cases * when the executable contains forward or backward slashes * when a command line argument contains an unquoted string The following executable arguments ---------------------------------------- ./bin/vim ---------------------------------------- will be translated under Windows to ---------------------------------------- .\\bin\\vim ---------------------------------------- * Parsing the entire command line string Parsing the command line string is easy to use but you might run into problems when tackling complex scenarios. Therefore this functionality was deprecated in the {{{http://ant.apache.org/manual/Tasks/exec.html}Ant Exec task}}. Let's have a look at few examples you would like to stick to parsing entire command line strings ** Spaces in command line arguments Here we would like to invoke a batch file which contains spaces in the path ---------------------------------------- cmd.exe /C c:\was51\Web Sphere\AppServer\bin\versionInfo.bat ---------------------------------------- Due to the space in the file name we have to quote the file name either with single or double quotes otherwise it falls apart into two command line arguments and . ---------------------------------------- String line = "cmd.exe /C 'c:\\was51\\Web Sphere\\AppServer\\bin\\versionInfo.bat'"; ---------------------------------------- * Building the Command Line Incrementally This is the recommended approach and caters also for pre-quoted command line argument. ** A simple example Now we would like to build the following command line ---------------------------------------- runMemorySud.cmd 10 30 -XX:+UseParallelGC -XX:ParallelGCThreads=2 ---------------------------------------- using the following code snippet ---------------------------------------- CommandLine cmdl = new CommandLine("runMemorySud.cmd"); cmdl.addArgument("10"); cmdl.addArgument("30"); cmdl.addArgument("-XX:+UseParallelGC"); cmdl.addArgument("-XX:ParallelGCThreads=2"); ---------------------------------------- ** A complex example Now let's have a look at the following command line found somewhere in the internet ---------------------------------------- dotnetfx.exe /q:a /c:"install.exe /l ""\Documents and Settings\myusername\Local Settings\Temp\netfx.log"" /q" ---------------------------------------- The following code snippet builds the command line using pre-quoted arguments and variable expansion ---------------------------------------- File file = new File("/Documents and Settings/myusername/Local Settings/Temp/netfx.log"); Map map = new HashMap(); map.put("FILE", file); cmdl = new CommandLine("dotnetfx.exe"); cmdl.setSubstitutionMap(map); cmdl.addArgument("/q:a", false); cmdl.addArgument("/c:\"install.exe /l \"\"${FILE}\"\" /q\"", false); ---------------------------------------- * For the Desperate When crafting a command line it would be really helpful to see what happens to your command line arguments. The following scripts can be invoked to print your command line arguments for Unix ---------------------------------------- while [ $# -gt 0 ] do echo "$1" shift done ---------------------------------------- and for Windows ---------------------------------------- :Loop IF [%1]==[] GOTO Continue @ECHO "%1" SHIFT GOTO Loop :Continue ---------------------------------------- commons-exec-1.3-src/src/site/apt/index.apt100644 0 0 5471 12425545060 16034 0ustar 0 0 ~~ ~~ Licensed to the Apache Software Foundation (ASF) under one or more ~~ contributor license agreements. See the NOTICE file distributed with ~~ this work for additional information regarding copyright ownership. ~~ The ASF licenses this file to You under the Apache License, Version 2.0 ~~ (the "License"); you may not use this file except in compliance with ~~ the License. You may obtain a copy of the License at ~~ ~~ http://www.apache.org/licenses/LICENSE-2.0 ~~ ~~ Unless required by applicable law or agreed to in writing, software ~~ distributed under the License is distributed on an "AS IS" BASIS, ~~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ~~ See the License for the specific language governing permissions and ~~ limitations under the License. ~~ ~~ -------- Apache Commons Exec -------- -------- 12 November 2008 -------- Apache Commons Exec * Rationale Executing external processes from Java is a well-known problem area. It is inheriently platform dependent and requires the developer to know and test for platform specific behaviors, for example using cmd.exe on Windows or limited buffer sizes causing deadlocks. The JRE support for this is very limited, albeit better with the Java SE 1.5 ProcessBuilder class. Reliably executing external processes can also require knowledge of the environment variables before or after the command is executed. In J2SE 1.1-1.4 there is not support for this, since the method, <<>>, for retrieving environment variables is deprecated. There are currently several different libraries that for their own purposes have implemented frameworks around <<>> to handle the various issues outlined above. The proposed project should aim at coordinating and learning from these initiatives to create and maintain a simple, reusable and well-tested package. Since some of the more problematic platforms are not readily available, it is our hope that the broad Apache community can be a great help. * Scope of the package The package shall create and maintain a process execution package written in the Java language to be distributed under the ASF license. The Java code might also be complemented with scripts (e.g. Perl scripts) to fully enable execution on some operating systems. The package should aim for supporting a wide range of operating systems while still having a consistent API for all platforms. * Releases Version v1.3 (current), is JDK 1.5 compatible - {{{http://commons.apache.org/exec/download_exec.cgi}Download now!}}. Version v1.2, is JDK 1.3 compatible. Version v1.1, is JDK 1.3 compatible. For previous releases, see the {{{http://archive.apache.org/dist/commons/exec/}Apache Archive}}. commons-exec-1.3-src/src/site/apt/technical.apt100644 0 0 2337 12425540624 16656 0ustar 0 0 ~~ ~~ Licensed to the Apache Software Foundation (ASF) under one or more ~~ contributor license agreements. See the NOTICE file distributed with ~~ this work for additional information regarding copyright ownership. ~~ The ASF licenses this file to You under the Apache License, Version 2.0 ~~ (the "License"); you may not use this file except in compliance with ~~ the License. You may obtain a copy of the License at ~~ ~~ http://www.apache.org/licenses/LICENSE-2.0 ~~ ~~ Unless required by applicable law or agreed to in writing, software ~~ distributed under the License is distributed on an "AS IS" BASIS, ~~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ~~ See the License for the specific language governing permissions and ~~ limitations under the License. ~~ ~~ -------- Apache Commons Exec Technical Details -------- -------- 16 August 2010 -------- Apache Commons Exec * An Implementation Overview Looking at commons-exec can be a bit daunting the first time therefore an overview of the implementation helps. ** DefaultExecutor The main class is <> where you defined the command line of the sub-process to be executed. commons-exec-1.3-src/src/site/apt/tutorial.apt100644 0 0 20222 12425540624 16600 0ustar 0 0 ~~ ~~ Licensed to the Apache Software Foundation (ASF) under one or more ~~ contributor license agreements. See the NOTICE file distributed with ~~ this work for additional information regarding copyright ownership. ~~ The ASF licenses this file to You under the Apache License, Version 2.0 ~~ (the "License"); you may not use this file except in compliance with ~~ the License. You may obtain a copy of the License at ~~ ~~ http://www.apache.org/licenses/LICENSE-2.0 ~~ ~~ Unless required by applicable law or agreed to in writing, software ~~ distributed under the License is distributed on an "AS IS" BASIS, ~~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ~~ See the License for the specific language governing permissions and ~~ limitations under the License. ~~ ~~ -------- Apache Commons Exec Tutorial -------- -------- 15 September 2010 -------- Apache Commons Exec * The First Encounter At this point we can safely assume that you would like to start some subprocesses from within your Java application and you spent some time here to do it properly. You look at Commons Exec and think "Wow - calling Runtime.exec() is easy and the Apache folks are wasting their and my time with tons of code". Well, we learned it the hard way (in my case more than once) that using plain Runtime.exec() can be a painful experience. Therefore you are invited to delve into commons-exec and have a look at the hard lessons the easy way ... * Taming Your First Process Let's look at a real example - we would like to print PDF documents from within your Java application. After googling a while it turns out to be a minor headache and using Adobe Acrobat seems to be a good option. The command line under Windows should look like "AcroRd32.exe /p /h file" assuming that the Acrobat Reader is found in the path. +---------------------------------------------------------------------------- String line = "AcroRd32.exe /p /h " + file.getAbsolutePath(); CommandLine cmdLine = CommandLine.parse(line); DefaultExecutor executor = new DefaultExecutor(); int exitValue = executor.execute(cmdLine); +---------------------------------------------------------------------------- You successfully printed your first PDF document but at the end an exception is thrown - what happend? Oops, Acrobat Reader returned an exit value of '1' on success which is usually considered as an execution failure. So we have to tweak our code to fix this odd behaviour - we define the exit value of "1" to be considered as successful execution. +---------------------------------------------------------------------------- String line = "AcroRd32.exe /p /h " + file.getAbsolutePath(); CommandLine cmdLine = CommandLine.parse(line); DefaultExecutor executor = new DefaultExecutor(); executor.setExitValue(1); int exitValue = executor.execute(cmdLine); +---------------------------------------------------------------------------- * To Watchdog Or Not To Watchdog You happily printed for a while but now your application blocks - your printing subprocess hangs for some obvious or not so obvious reason. Starting is easy but what to do with a run-away Acrobat Reader telling you that printing failed due to a lack of paper?! Luckily commons-exec provides a watchdog which does the work for you. Here is the improved code which kills a run-away process after sixty seconds. +---------------------------------------------------------------------------- String line = "AcroRd32.exe /p /h " + file.getAbsolutePath(); CommandLine cmdLine = CommandLine.parse(line); DefaultExecutor executor = new DefaultExecutor(); executor.setExitValue(1); ExecuteWatchdog watchdog = new ExecuteWatchdog(60000); executor.setWatchdog(watchdog); int exitValue = executor.execute(cmdLine); +---------------------------------------------------------------------------- * Quoting Is Your Friend Well, the code worked for quite a while until a new customer complained that no documents are printed. It took half a day to find out that the following file 'C:\\Document And Settings\\documents\\432432.pdf' could not be printed. Due to the spaces and without further quoting the command line fell literally apart into the following snippet +---------------------------------------------------------------------------- > AcroRd32.exe /p /h C:\Document And Settings\documents\432432.pdf +---------------------------------------------------------------------------- As a quick fix we added double quotes which tells commons-exec to handle the file as a single command line argument instead of splitting it into parts. +---------------------------------------------------------------------------- String line = "AcroRd32.exe /p /h \"" + file.getAbsolutePath() + "\""; CommandLine cmdLine = CommandLine.parse(line); DefaultExecutor executor = new DefaultExecutor(); executor.setExitValue(1); ExecuteWatchdog watchdog = new ExecuteWatchdog(60000); executor.setWatchdog(watchdog); int exitValue = executor.execute(cmdLine); +---------------------------------------------------------------------------- * Build the Command Line Incrementally The previous problem stems from the fact that commons-exec tried to split a single command line string into a string array considering single and double quotes. At the end of the day this is error-prone so we recommend building the command line incrementally - according to the same reasoning the Ant documentation does not recommend passing a single command line to the target (see deprecated command attribute for {{{http://ant.apache.org/manual/CoreTasks/exec.html}exec}} task) +---------------------------------------------------------------------------- Map map = new HashMap(); map.put("file", new File("invoice.pdf")); CommandLine cmdLine = new CommandLine("AcroRd32.exe"); cmdLine.addArgument("/p"); cmdLine.addArgument("/h"); cmdLine.addArgument("${file}"); cmdLine.setSubstitutionMap(map); DefaultExecutor executor = new DefaultExecutor(); executor.setExitValue(1); ExecuteWatchdog watchdog = new ExecuteWatchdog(60000); executor.setWatchdog(watchdog); int exitValue = executor.execute(cmdLine); +---------------------------------------------------------------------------- Please note that we are passing an 'java.io.File' instance for expanding the command line arguments - this allows to convert the resulting file name on the fly to match your OS. * Unblock Your Execution Up to now we have a working example but it would not be good enough for production - because it is blocking. Your worker thread will block until the print process has finished or was killed by the watchdog. Therefore executing the print job asynchronously will do the trick. In this example we create an instance of 'ExecuteResultHandler' and pass it to the 'Executor' instance in order to execute the process asynchronously. The 'resultHandler' picks up any offending exception or the process exit code. +---------------------------------------------------------------------------- CommandLine cmdLine = new CommandLine("AcroRd32.exe"); cmdLine.addArgument("/p"); cmdLine.addArgument("/h"); cmdLine.addArgument("${file}"); HashMap map = new HashMap(); map.put("file", new File("invoice.pdf")); commandLine.setSubstitutionMap(map); DefaultExecuteResultHandler resultHandler = new DefaultExecuteResultHandler(); ExecuteWatchdog watchdog = new ExecuteWatchdog(60*1000); Executor executor = new DefaultExecutor(); executor.setExitValue(1); executor.setWatchdog(watchdog); executor.execute(cmdLine, resultHandler); // some time later the result handler callback was invoked so we // can safely request the exit value int exitValue = resultHandler.waitFor(); +---------------------------------------------------------------------------- * Get Your Hands Dirty A tutorial is nice but executing the tutorial code is even nicer. You find the ready-to-run tutorial under {{{http://commons.apache.org/exec/xref-test/org/apache/commons/exec/TutorialTest.html}src/test/java/org/apache/commons/exec/TutorialTest.java}}. commons-exec-1.3-src/src/site/fml/faq.fml100644 0 0 10356 12425540624 15477 0ustar 0 0 General How mature is it?

The code was ported from Apache Ant and extensively tested on various platforms. So there is no reason not to use it and it is very likely better than any home-grown library.

How do I create a complex command line using single and double quotes?

It is recommended to use CommandLine.addArgument() instead of CommandLine.parse(). Using CommandLine.parse() the implementation tries to figure out the correct quoting using your arguments and file names containing spaces. With CommandLine.addArgument() you can enable/disable quoting depending on your requirements. Having said that this is the recommended approach using Ant anyway.

Are child processes automatically killed?

This functionality is largely depend on the operating system - on Unix it works mostly and under Windows not at all (see Bug 4770092). In terms of stability and cross-platform support try to start your applications directly and avoid various wrapper scripts.

Does commons-exec support java-gcj?

Well - one out of 55 regression tests fails. The EnvironmentUtilTest.testGetProcEnvironment() test fails because it detects no environment variables for the current process but there must be one since we require JAVA_HOME to be set. Not sure if this is a plain bug in java-gcj-4.2.1 or requires a work around in commons-exec

How to test commons-exec on my environment?

Assuming that you have an environment not listed on the test matrix and want to make sure that everything works fine you can run easily run the regression tests. Make a SVN checkout and run 'ant test-distribution' to create the test distribution in './target'. On a production box downloading the ready-to-run test distribution might be even more handy ( http://people.apache.org/~sgoeschl/download/commons-exec/). Unpack the 'zip' or 'tar.gz' file and start the tests. Independent from the result we very much appreciate your feedback ... :-)

Why is the regression test broken on my Unix box

Please check if the shell scripts under "./src/test/script" are executable - assuming that they are not executable the "testExecute*" and "testExecuteAsync*" test will fail. We try very hard to keep the executable bit but they have somehow the tendency to to be lost ...

commons-exec-1.3-src/src/site/resources/download_exec.cgi100644 0 0 240 12425540624 20712 0ustar 0 0 #!/bin/sh # Just call the standard mirrors.cgi script. It will use download.html # as the input template. exec /www/www.apache.org/dyn/mirrors/mirrors.cgi $*commons-exec-1.3-src/src/site/resources/images/logo.png100644 0 0 67660 12425540624 20411 0ustar 0 0 ‰PNG  IHDRêB˜U• bKGDÿÿÿ ½§“ pHYs  šœtIMEÝ 9(UŽ› IDATxÚì½Ù—dÇyà÷‹¸q÷\jéK‘"$ŽÊ#yfhόǖ|tüàGÿ~´ÏŸcf¬1E‘”(’ H€ÐÝÕ][nw¿ŸâfVVuõR@ ¨Šsª3³ªó޸߾‡áz]¯ëu½®×õº^¿‘K_ƒàz]¯ëu½®×õºVÔ×ëz]¯ëu½®×õºVÔ×ëz]¯ëu½®×µ¢¾^×ëz]¯ëu½®×µ¢¾^×ëz]¯ëu½®—¹Áõúm^bí ÿ ‚k@]¯ëu½~c—ºnÏúíUBÿÐsa²ý·çÀæZq_¯k¹òŠÌ5/ýæ)êkïåKd¤õï.ï?˜?“ Ÿ/ƒÙSp¹ðùšV¯×?{åüi”ö3øæšŸ¾DEý"y-?etñ÷¸þ–Ãû…ð¸øú<š^/ƒÝ5^¯î2å¥ö³ä͵Üÿrõ9d>KH^ ÁWÏPÖúÏÏRD[pVAð[ ï‹tvëÏâܳÍš.µ>«õûkZ½^ÿŒdÊ9>ºLa¿¤vŽw®yéËUÔr‰P¼Thn+Œ‹È»¨À¯×•”’´íye´FêZñDÑ¥ŒòOÞÏ4X¶•s×}ï­á¤õ‚´öï£è·v×ëz]I¦gEý’Ûö Áuíß·Íæïk+JE±xIaˆ‚Wª¬Ÿ™§}×z®ùª½Ä(é5¬i[\U"]ãqàE­x'™‡¹s¨0<‹lò Ÿå¥Š´>'á² ©kOƒU…Ô®®ÁõHÛ }¶{*T§Tài1IQ&BÅ1:Í<& r ìÖ´úÒ!«ÏW¼Ç«ä‘ßô½}ÿdÐóøÈóNT¥ç«®ó¿ßŽF9·‰H]RaÆl _•fC@EÑ—ê }²êóº‡ùLHn[\]oìVK¤©‹¬=CDyÄÅ)z4F% Ê9ô”õU[®Ê4W¹þÅhÁ+WÌÏó¤× U•¸r‰«ÐW8[Š:D…#t3BgcÏXIâÿv‰U»í‰¿ª½nB÷¢p©ëÍ+ ¤®ÚÃEšé*ĵ`;D,8 J@˜¥T˜@¡Ó :Α¦B¥9ºËQYvö ŸÒ#ø4´òYiýóT,¿-{û2ðò¼û¼°­ðÂw?« ÚðÓ¹Õ)W¸ªBÊÂËò®ƒ¾¿<½¶VÔëÔ‘Ö¨8†0DÇ)*ÍP]ƒJ2ôhì¿w‰ÌÿRœŸW$«¾(yh>r/*é²Ä-æ¸ÕWžâš%ÒU ”F…):£³]è{t>òÆ\ª¬_Vy½ôú”×}!€¯@hWmRÛ{”ÓÞÅ ·šc‹C\w‚È‘AQ«ÕŒzé:´µgã綬Z¶¢ç<Çs[Á>ì?5#l+éÊ ) ¯ ‹®\á–3\5Cºg  Ft tHàPFM‹§<1дÊp]†6ct½ƒn¦Ð·h¹ œ¶•õU™ñ9pxéÞïÏk]0Ú®jD~‘{{!}~þÜðò²ð}ÞÞŸÅCWà¯Kyiˆ„ºù W,°«c¤˜áê%ÒVH× ý–G½åI+¥ Ð^Æã=ê&DÅ ®ÏÑým§hg½¬¿LY?ç^I?÷ç «®BsW¡·W¢¨å’¢©*d¹Ä-æØÙ!vµV DÕ(,"ªNpõ]- š`om”‡hý”•õ, ¼°eà²l<¥”^xýgTSËÅ¢«2ûó*ã/ß=•mÛMˆ×Kìê×âÔäD¢R×H±Bši-XNÐÖn<ëÂà¥^Æ ¹ÂÞŸûOeA_TÒkº(°³S¤X`‹\uŠs3ÐÄ-¤@ªQ‘A‡ñ`ý+'Hg¡©qm…ê–8»@ê¡F”ñ]œ±»Û‹„ì³håyp~­?ëÿ^ÃçÐ÷3•Èóøã7lo/ ·«òð§ÁË«€ïö~n—È õ5^ÊiØ’ánµôJzþ[>ÁuÇ+jDu`ÜùtÙð€s+åáª5*ŒP&F‘!vŠ45‚%X×)‘y™Ó¶guK/2h®ÐòûyȪO-·¯ñðuuú’°£WÒÇô§qíÄKØQ¨‘A™z¢Bf%¶B)øéí"3k/õV.z•—çbXfšÙªÔ]߇ €¹xýíŠõç]÷Òk¾€Ð.«P~î}Ö{tî,[cͰÝcÔnÇ_ÿõÿÉkï~ |üïñçßù÷¸Õ!ÔJ"pÊïqýEH×ö]›áóEæ¾ÒÞ/Àé¢Ap¥(Äݹ¢À-—¸Ù)nyâ Äú 0j`À(£q-­mqt ¥ b,âå’€0 IÃ)*¤òÙ-¨Â{z] sQ =—ÒÊ&/ Ï/‚÷s•ÌÅbºKpÄ3ðò¿·Kxø•âåŠ2èeŸá…{¿¬Íõ¤^6Ê·]ï²®+*WØÅ!¶xŒSOP»²ÈZ*dÐÊjˆÚ wSÊÿJiÔðŠ@(§®Äµm€ªÐ:Tκhs ƒgà÷e¢—zà¯PV½Yþñ2ÎËK)ê§¼é¡ÈÀ-—¸Õ {òW<ÆÅ'°ðáß²ÿ•·0ሾ[qüðCÞº÷ Ô“cX•¥ D±/>ˆ¢3`_flïöï`S•ø”Õ þÚpÖJé)Kéâõ‡*âg^w-´×…CUð³B¢O!u]‰ü¼û¬-ÿ5 ÿÇ®,p«nuŠ˜%Ä!oÿñ7¹÷@HÔ#ÍWûÐ.ÿ¾ê{T]û(‚0|ú9¶˜æ)þ0º´Â §¡åi]z±(ë…á¥áúçrÒEá•ôüˆ~y€k#ɵìæ,ûë–¤;wȳ]t˜£u:\Þp®Ãõ5®[ÑÇÏ0Æ0™dPV¸úÕE¨6C‚1á™’àsn Ûs0ÞfÖ‹ ëÓÐú¶—¸Î^„ã%BÿŽ.Ûßs„Ó—¶·mú|–ŒXw ¯_^^¾ÏÙû¥aûmôÞºè­]ªÄÖ†ïj‰+Nqý j×òýøxóÛß$ÛÝCk…èÏÐEU´ù,àzè[Çâ䄟ÿàgüÏÿÓÿ†Ô+¤+‘*A‚èœqv®k›^žå¹^µ¼h8?Gž_UV]j\E–¿ŒÎx ïúå=êmâl[¤(²ÄÎŽqÅ1®;‚†& yãOÿŒñ½‰Žvqíœlÿ¿Ð<> I;ÜêU¤Ø(G%)2TË §¬¾5 .#â52œóùðíüI`6Që{lê£l·$lZž,bûó¹™áºk%·¹öZx ½·ÏŒB\rÿ<ýÓùŸõþ×Hl[Î.K¯¨Ê%’(=b¼»G4~€|w‹´+ì"„*‚V¼]¨4E' D± Ã3Ž…_´øŸ£ÍÞ/Zý—µ< ÔWjÍÛ¦·u.mwo”tw€¤3ô„Â8zY‘½þU¢ô.Zôý’¾™#õŠÞ6›ªUDQ†Ž§äé-Ò½ŽfyÀÃï“©œý4Ä5st3At¼QÔCÒ¹­¿ö©×¥´†þÙ‡JòsàY‚z]u{Î˺@/yJà]æ Ë…ï©(F*Ižj§y _ÆÞ.i™»Œ>ŸÙš·æß//ZoàûÔ}.‹–=§­ðo­¯û¼u™ð?·ç®óå ©–ˆZ@ñæ·¿Éíwÿ‚(\ë8[âú§ ±Ëb}ß‘L˜Í}ðÔµHS鑺ö8麧”ئÿz›F¶ñwјێ0\„çGŸFV­£ƒ<ßVîçŠz_V–?ƒ–/VÁ¦Ð÷SÞçZ`Ö5n¹ŠšŽ‘d…žfH¢ÈïüÑä]´ã’%¹[1_>AÙ{´„âŒpIŽÊsô@ÀÛ!×m@¸ªôïûþì÷kBÃA? µÈF¡кí&ñÊi#.zEëgªJ¿¶FêÊ cÛˆoåÚÌÐf¸^ŠÊósŠNm+ëµ7¸ÝúP×CurØÎ·²­Ÿc-$ô@Û»lY©ë–§(FEÉYËS×mÚžÔÚ«Ùb„çåõ7Êú͹æ1’ÎPwSVªÁìî1¹õ.Ú¤ôõÅÑز$p£B„8¬4ô2£“ ŠI¦÷ˆó;Lï>øÛ¿âÆ·^‡¶ÁµJg8eÎE8¤m~ß°H'À ¤{AÚð,Â>Eº­°/D7ÞêEgÌ„eÿ<ÛÖËÈ®»º¬ÚnÏÜJ¡žã…«Êò8è ñEuë(/×ùd^Ö›–‹ÞMYÕǧ8»@Å-.îN‰²7Ð:¡É‰²û„Ó=l;G¥®\ ?º(8ÞT"o+j·Z"u鉸©Ïú´»é[p"=¨¡÷­7€Â ´(C‡9*É‘t„ÊGèAYŸYHÍ „ª¡5a´…ÿl;ßÒâ¯&(“â¢=š¢ëÊ_7ÏÏ#÷¢µ\¸b5´HSàÚúÚ zz@¡ :ôa†2 *ˆQ¢ÏŠ?ÖJ?ì@Z!Vƒ·‚ëV-‚E(qj޶ D:N±&A¯rT—@ŸªL- dµÄ­ŽqÕc$ž¡n‡º&º}üÖ·¨OÞ£=yH¤ qÕ!‹©,Ò9, ´Bdž8 IÇ)$1Åñ–ö#Äd¨ BÚ3œí½aÒ Ji¤k=SÖ®ó-`¸ÎÃ`-H”ö×ã3ZÉÆ¾M%˽bئAk}ïjSù{] u\ôÍyZwÖÓ‹ <«¥c”Ž|®P âSzDq-2Ä”2¨ÈÓ—NƨlŒNós ð°oê߈½é|tæ‘l Ϊ•Ŧ5ÏÕËÏ/keÝ÷ˆm|  êA,¢ÄçpUˆ2!*ÊQa†Î'è$ÛÀw; uå•I±ÂÕK\W‚m¾/×”ò¹ß0FG™‡O3FÚ ºmQ}~VU½Ný]ôÔ.˯®#uͺCÂa­#œ«i‹÷DˆšW4(«½” ô°'ååòÔÚ@f¸ìóÎÞב%¨.B5ð‘…æB[^^wNÎÉ€Þ+?ןå7JÞx§,¤ñgÛ{æ,„=bzTè@yVWNC¢º§G¨rBI3ß„¯5ˆóíÍ ×®pÕ)ÒÏq}R!ºe½š¶^QS…(•£õ×ì$»èÁÂ^km[²›œêr៧˜ùgïWˆ+ÝøçÐ[¹7¢m ’¢š ¥3)´ FËàQ'íÀ|áFK+·¥Á *°Ö¨$Þ„÷D ´ ®ËÑõÔÃ6ßAê•ÎÂhÖzæZã¢^"Õ)®["8j”îcQ(oÌ¸é ºKpUŽ §ù>ºk m|õ9/Ñšw1Õ2T³»bŽ+qÌPS¡fgüÖ‚(~ˆ;yBÚôô±§ê\‚"òBTk$ˆ,’50nÉ÷2Òl̇ï¿ÇG?ÿˆoÿ:¼®AZD ®Záڥǟ]!zpÚ¢”¼E .@UJÐ*ÇUtºƒ”coÅñ™A×µg ¦]ž§õÞy…£Ús´.Æ‚e¤S¨>‚.B¹Ä ô@#AA a‡˜‚~Ó2‰P‡(ÉÐå]ì"ù*þÚKi\SþFìMêÚ÷æ­@X;x¡¥o ­Þr"Å‚´C‚¢¡:Zyƒ§ ‰PMî#‹åA6EÅ^YŸ-®.på)ÒÌqR ®Õ Ú¢‚¡¥P)P%!®OÑ2Bɱ%p;_U}Yî‚,ÖÆÆ0Y2´[^«WÐ/?Á­´ïý9¨}a˜I|„Ä cü ¥Ð+£tähRo Ε޳VÈ–pƒQ£Tl¢0>†î½S±5âjo éµ¢ŽPfpdt쥉/›[ΑnàÓ+È*îTS¤oŒ· /to‘-VW’åbSh´ÝAì.bo¬ñµ=7Wm®\DÖ¶Ð4¾°©Z!ý 5r°“£â“¾î‘R„“­2´ÙÁ¤¯£ÓÀÞõøY­p«:›zE¦õ™¯J¤ZaWO°åÄÍ»D¤C\ã­,e!5 PãÒmÌÆ “Æ[U¬fèz‚4+t½GÐí¡ÊÒ[Jš¡çv‰ëA/pÉ B‘B‡¡/@r‚8ñ £*rE_ÏЋ9ÒÖ{YºïÑ]wæ±w®,}±Æê»ÒÖ¨xËXl+\;Ãu§8;W tˆ´>,¬Ä 5V¨qŒJ#ï ˆó-x«™/q§UDÐÞvËj j r‰ñt¶þ^µBŠ%¶Zàº%º)òÐ4Å>šÐ7¿9{kt’o8‡Tƒñ֜⺜Y@Ò~þxéZÀB 'ŒcTbÐÆ "¾-²¬¢Ä–3T»Dª:ÙAE)Ê„C4¯ØÜC̉HAg!*2¨p‹‘A¹¸¶FÙ\•ó|_Gè!纙 y™W}±Š½ï‡4ß™ÒQ.qý éf85‡°~9YUÍ¡™ÙºÝGêÚokøm"‹³3yøR²¼‚¶ÂÙúj‹Òøèæ‹ðõÒõv®f',KOèõa Mo Ú{íâúmñ#³OÛ¿O”ÿ&Ú!Ú}®ø=ÑȪÀV t¹D­rtà†¢ W.qËClýÑG0í!6>²]Ô¸U‰Ò 5ÓŠª/½‡-Ãã¨ñ4&käø·,E…T:Ûõy*Õ!A…S'® ³XP”+zëCNz]° @tN eU‡œá?ù 뼕ÝuÇ~Mã;´Ùî g0¶¨˜––FˆPÖM¤ëÑV‘$)£i ‹7w¨2B:çïs±5ÃC£ÑÆ ³„àÞJhUB#5bjŸ/QàT‡Šãñ=¯p'5®ªšnÈ­ [àä ç0q¨˜Ê6tÔ8šP¢pt¨@ˆ¦!Y`Ó%ý²F¯*èÏÂN[ó¸¬vý~ * \=óE/E%5£;ß ŠïÐ7O¨O>$izìG§ÈA€v»èpLýD¼hÈãi~õá47 ‹éºG9Å¿ýî_BBCëpÕ:êrŠè’¨!6‹¨lƒ¥éÐ&œ*°¨Q@6 Ê9>ÄUt~D£J&>Çæ,®_âì ÎP;‚$­—-nY¢”BM&´ʾZŸîݤŽl”¢Â%òðçè½uwJåZ)^¡µ¥Õ¢Ba|{‚žWȬŕ­V%»>Ÿ¬8Û[ºDíô~oÅ·7wÒÀöÞ¢Ø×^t R/¼"•c$/Q»úÕãå’g—Uƒ ÓŒF9Šn‰r!ZÏcÒ¡"Åx4BÏÜñc¤ôáT£ƒHëæ8=‡t‰ÚU0‰)m…¥B´"À`Å÷þ»nˆT8!›LI H5G\€ëcÞf>ýö"¹îœ7t†ŸM­ÁÖMçsʽ@!¨…†.‚4C‘£H½bÕ‘7‚ƒ$B£HPCÊClºA‚IJH{Tä©Ü¢†`n ÏQ6ôû -˜™v¨…žÄ¨$öqÓøtVÑ êºé;\·BäIV°#¨iBå^BVíät]VȪÒû_‘—çÒÔ^IoË×åXE’äLb…4+Äú¨ˆjG¼¾ÌUŠÈèºM(Ô—Ü/‘¸#ØÍé ä“û@H_þ‚öôׄÑ1]»B«=LöÑämªðW${#ìñê®Z¢Ë±÷B‡jD)¸Õ ΡöZ¾÷ƒ¿âþï ©–ñÚ×þ®·Ìäûä;_'LwÐQŽÖ!àèë9ÕìæGÇŒnQªÄôȪCÚ΋ {ˆKdZ2ïN™ÎH&ùþmÒtÐ&® εôÕÅ“_@W3¾3Â=™!…CfØ¡ºzmñוGìò ¶ŒÊW¨}E“TnEº‡Ñä.ÆŒ6­CÎYœ«±ÕœÕì1G>`OØÍ÷ý}ÐÞë+7ãFã{M„JmŠl.¶æm¬É‹uëùæuí äúÊ{LÓÔ$Ó·M½ø€°wp‚&œî0Úý:a¾ƒI&çpY~òc¢›)&îP³•Eؽœ£Õ!éäûoæ{˜hìC‹®£]=bõÉOˆsCL‡{| … u‹ŽF>2Å 2áû?ük^ûý¯~á{ëÏöV6>߇Æõ"K—ÝÏ /é•8¾ÿÃÿüô³w§‡èÉ”ñ½¯>ÇÄáyƒCÆ( ü`p; êNÌR5ˆ²d÷Þ"ÊoÂzïn(•íú®¤«,gyøð!»é>û£ég~ÀH›¡læùéeá µ|áÚ3ʹ =ˆÓ(«Q.@©È× J”ŠQ* ZpÝ0ŶHPðÿ¯ÿƒhOñÆïýÙ(§ž3¦Œ§;«àTC;8:Q 7-z³ÔŽùÉœdºO¹*xð¿¤9rüwßù¨¢F Wù–ÕqåeU¬©ä ²joDö¸ã㡦¥G’Ÿï´43œB¶ò÷¸‚,ÿà“_0Í÷¸9N|¨ÜÕ>Šs ¾.†¿Í•‹ÈêÚ÷òVKj Œs‚Q‚‰ïâ\C»üY.éÚGH4¢ N^ÃÄ·1£1ÒU¨ÑW—¨z…« /¼÷]µÄ-Oqɦ¼õGßäöïýt8¢]þœ(Ùgùèä÷ÞA)ÒW4‹9ZÙQ~‹dúÑôMêÉ/X}ô#F·Æ¨nƒ+Ň3#ÀÔh?þáùêwþ„|w¥+ŽèŠŸ Ât3ºM¶÷ ’éÛ”‡?föñ/Ù¹9ñ¹¥rÈ­õU7Cè¬ñc>û'ÍáVHizÔxÄÞ?ÅD/8Ê#ºê”¾+½òÕf$£[¸;šŸ~ï{üù¿ø.b¯D” -!N(Õ&¿‡²ŠêôÉÍ»$H³ ë¸tŒß"J_'ºùÑè5æþr˜Qƒ[Áª÷¡)­©`ŽLKÔ­˜"ìaœ²sûÛ˜h„kWôÍ!v¾±¨0Ƥ»DÙM’Ék¤{‡Ì?ùn¤‰Å¡ª»È6U·›Ö¼ËƬ…H×yï©«qR@âèèIöîb¢}\¿ _<$î,ýqƒjÆè`J0¾žîìì F#T–õÓ?ÕÜ{Ë¿îÕw@ƒëV¸fîÃh“u;cn—䯕d÷«è ¤oNè«l½ô É“î“íý.Éôw¨Oßgþà—LÂ>Fu5¢2ï)é, ² ož£õŸÆ7(>ú[ÒÛwÐ:Á53šnFŸæDùm¢ü5¢›w‰F·)>þa| s³Ä’°œ‘ß~ “æÃ÷Néã³ï™›w‰Fw9ýà¯P: ,+\u•Ch¼£—ÈtŽJ¾¼½i¥ Ê [¡êMJáT‰„sÔösÄËâR¼˜hŸâ“¿%¹y ¦¸f…ý³¯ IDATAÓ-èÓ1Ñe<†ÃL ìâV•߆-²ßÜLXÈ’ôÎëä·¿GôÝ’¾< ¯fØnhÒ1Ú¤ŒöÞ@Høñ÷ÿ?þ͟߇zˆì!WíºiA•³éYúü(2¢,¢­ÿÛ\àC×aÒøÂ2¥A™!¯>\§·ž–¬å»ÿã¿ãƒƒŸrûío‘ßü:®_1ÿèo°6D-æØãÃ}л#Üþ.˜ž7ßü.:S<~·ª¹ÿí·‘ƒ%²0¸ºó)¹Q‹¾•PÄîÓɪ±&² rpŒ[Y¤¨Ñ&Cp¾6'˜Ãd‰º_Y–Û;šŸ|ï{|÷_݇zÈÓór§L›«‘­çLKU ít‰š„4Ò‘í}mÆôõ#Ú“1‹‚þñÌí×h±DÓcLr—x÷mÊÙßMcä´Ä5KÜj‰ÒÕ –lYàê11Ùhhü&ºƒIv±õfr—îôiæ„Êj_$äêG”‹G˜É-²½o‘íÿZ,>ø;&·r\¹‚™Âµ$DÕâ"\k)žùGÂøw¨ü„xo[/º–(4h@· «×ßû¢ü-vßj9þéÿM´›cèFáºÐÞPËJ´©{›î¦ØÃ9TÛ×yq‰Œô­1 »z5x©[½ ^>Á¤#šÓc‚¦*¥ÄÎèêýèÛÏØ5¸&@M,:×4aD¸ƒñë†6;´Åû4G?óÑëˆP¡Çª†ÖÎ(›šå¼¤©:δ"WWÐ[¡nqrNoøTšB 0ò#w% p)èÈi]ù|tP£‚tˆt>4Þ5>Vü9qÃ÷ß¡)Ÿ0Þ%Ê¿~'`ñÁ"½·‹:]`WK!Ø£_Û¡2 »ïük¢ükôõcÚò1÷:\áN-²T $µ—U¡ûŒ²*E­æ¸å ºsˆ”>E¦WÈt…¾RêŽà%ey]RV §§§”E3tB\ _æ*EdÒ4¸Ê‰-|ÁÒÞI¢ü _¨W=@Šžþá!öãc°ÄôÕLr—(ƒ*ù zLÿø5_⪹G´]·Ãøvâ°˜0F›mÆnãÚC\yBÐ ¦j°OѯP ' ñ}zŽ(ùÙÿ†d÷›ôwO¨O7ŸCíÐ’Q0ÜqÃíñmÒ @ŽgØÙ[V^IAïe˜7îÑñ I¦ß"¿ý.Íñ'0Íàð™Ï±]€ò!óB‚2îèóŒ`œ2¾÷´™Ð.ÿ‘úñû¤.ÀÎp‹Û ˜•Dd£”ÑdQ0á—ÿõh@ÙØW–êæâ:ßr¤c´™à\C_ÎHÈàðw²À¶j¼~”¢þìæŸß"»óÝÁ!f$¸' (ZÐ Ñ%ÁXÓcôH“ßû6Z‡”‡.kÂÙûèþÔ÷“†è›Ì¯ÓØŸ MˆIßbòæ2ûùß0ÙÍ|á`=ÃÕ{¾ ¿û¹¿a¸#ûTÊeÝ·ÜÕˆjÑqˆS–(¹1.žúˆuÑ ÚH}ËÍxâ[n² =™øv‹ C6Æ@Ûú¼Ò¸ÞïCúÖ[Ñj;Pé7ÉnüþÐö}dvJ¼ª°‡ôËô8!¾s“ŽÇÔX²Lvã[ØzFýä1ÑÜñšÕ‚ÄtÍ@ëцÖutW}D_œ2 räøÈÓJÛAjîì¢ä5jýc²ÛÿšhüutÓ· Âé š'ŒÂ)êôw2£oZH‚»{¨Û÷¨õÈnÿ+¢ü>Ù×莎 r‡;^¡š!7VHWƒrçøð ßÛá1Abqn « ·èiLe,éÝW…—4Ù ð²+~‰-—äÁxlóì¯ßžæ±öÑL.8)Á*D“:vNnÓ—Óžüœ iqŸ<Àôµøjù,E²1£ñ#&üüä=hH2Œf¾ºÂö}ÊçÞX§Òtœ¡'ú^ºBµ ŒC…-D€é lA—Æƾ†Ü{ø.CIè=ïN#®%+ŽzöFwöˆòw½~JõáˆÞÞCì PoïцÂèÞ»Dù;@G=ÿ)¦nˆV=ö ‚™FjiƒÞUô“ô³Ëª÷þ†É^J8Ç-ªO}Z,/Pè² 5^Z–çãœñä&Óp‡÷þë¾#Içþä¾(>KO|ª¢Ï("“rèõ“%L  5ñîmO¼}A}üA ýǧ¸Oj'˜[¯Qÿ’hü t´O¸s‡®ú=VÈÒ·~hù‰s¾Ò¹[7üŸyŒ qXúêÊŠàtAÿ‹'È‹4CegºÀV_¹…í{Úô—$ÓwÉnþ§'Ð{9öÉ ,K¤òíbá¿}÷Ïà“]YÁ²ÄÍk¤ðý¢è;=ÆÍ„ï~•îäC¢ô.&¾EvûmšO~M”:Üñ݆¸Àr¾HdZ¢÷r jvïý)&¹I[|Hõä}⺧ÿÕ'ðÄ"UAî{-³© R)Ò$ç/þÝÿŠ”ƒ‚QµÜ õP5­Î¸Švù1‘‹q>Áýâwâ|—YÖÀ²%|7¤¥ÃMc’7‰¦÷Y=z€I5âVÞ« @íö¨ý›Ôªarï;˜p—úôïÑu ?¡{ïöA …ø6 ãÐ7g¸² üݯÑ¿‡¹w“hüñ÷éN+L2Lµ«WÀö,?sÉXE× ÓŒÄBà Ô±A£¡‹cE€†Ê‚$è0Ag~Äf Íúç˜ȵ'¿;K×U·âJ/öFô¦bzó[h“SÏŒ›ÌVtï?B÷Háq!ÙwZ|í.XÚô×$Óo’ß~—ã“’9îQ‰œ,‘Vƒ­¡ñ´¯¶CŽ®¢]þšPbäÁCì/Op'jç+`O+‚Ààhq»˜è0£ß…Õ{ˆmHÂ<|Hÿ¡§Z‡Je‹1!m駘ì>ñî}–G‡dY€ÓÒ Õ†/ù"ö6¯/ÝÛêè`d™#m‹ŠR…Þߧ톗s<&òàöƒSܱø‚ X6Ïä±pl Xú™ó:@¥1:?I€¾zˆîöWÐÿä9et@½¦šl2á/þû¿„Òì@…„W:†õi­}6Fë3z ¾ ß÷F VPg‘)­‡¡ Ú·ViãCâU«*ˆöUÙ]„Ô"3²7F`Ò=²Ý? ™~‹þÎ1.|L½æa=Ý!Ü»I²û.ZêùßS?~Ÿ¬7¸OfȬTÐAÚ¡÷v)_…¬ºù>ÝQ9ÜÑŠ;ˆ{‚½= }^–7OÞ'zž,¯C¤4›ò—ÿËÿ޲ct4ñs2†VÛ±^ØžuqŠÍ¹"²bå[²ºD z'¥Ó–túZ'´Õ/å9=Å>*‘£T³’kúæ€(ÿ Ñô-VO>Áì¦Ø£–+\£Ýz€Ï®Û¼2ržéÛ#šÓ_azè}ˆýÄ¢Š%Ce^Ý"}ƒ ~oL{ò>Qþ6&¾C¼w‡æácÂLp®DjƒjChê¤õg:7Ïw4=4zë§(Ù›œ o>@e©–ä6Ñø.uð!¤‘ W­|ßf`‘x‰Ê,Q$»70ù›àZêãŸÙûÑ'¸:T9B;èlŠRÙP5¡zƒêÂa €FèÀhTPÀzȉښî:úú»œaæsܯN‘G ÊØçÏËtØ'¨$¥­0É}L¼IˆJ†žP놯›EÄ»c¢ü œ+±å‚fEûàöÑ™ 4å ñm8ÇØ[PéôÝ1QþUÒwXžþ&7þð‹n"±žîô¼“˜†!.âzÀú^Í0éð§ íéœÎ ô#z=ׇØc^Ï娇“|ØVÖë¡1]‰à[ÑiI÷îbâ;¸¾ =yŸ ܯŸà>v°HPn Áªhð1Ñ·F4'ï= ¦7îÒ<<Àä Ñ Ò([”ˆoëÙD%úö·<Á,´#–!ØLS쟠Fcúê1ÑÈùACÎBÓ¢‹’þ£òHÁ*BIˆ¬j\`q{§gôÕ¢ìmLzsh»1ˆê«PÕyE-g•©ŸûÞN!½lo!t~$¥Rè<£ é//çxl1§ÿõ)ò@`e@bTÙà‚þÙ<–öHàûƒ•Ò(­Âm’¡`l…v–n¾Bf-Ì Ò+$ À”KC› Mˆ%¨QŽŠs_Ìõ*–Ú<õˆdü-êå賫ØL&s›Y‡=›JVù©d¿øÁÏøþí_"¶C97Œ~ÍQuŠ;Ybå˜ôí}ʇ?ÄÄ{DÙ[d·þˆRþ á; ÐIMvëO¼×ZþŠÕö!öÃäHa wHdÑ#°YD¸›½Yµ:ú>ñÈ@°B\8tÒÅÉîî9Ynž'ËuŠ&£%E‘¡Ã1:ž¢âÑYÿôz4lyÒO‘s¤_ÂÄù"²,$Jïâèè¿Fµ÷è9é=`Â÷èµ?¥_ü“ß'Jïd ô*]À¢ÄU ß+èü ÜYû‘ozp }ýW•¨£cÜa‡.”ËQÑx¾%R)Üa:ž!zŠëŽÐùWˆ¦¯S<>€Ì P¯@"¨5´tˆnQc‡L”Ÿ–cA+ƒ=jªP0qŒ£Aëï¡Ãûé ߦøpŒÊ":Õ2Úy ­3úúc\¹ ˜­ƒµÊÐjíŒöP£1:KQi aàfh9“´Ç5r6ð!ÐgšNÀ•ôͺu¸ãÌê-)¨‘Ê7¯ÐÖáê™ Fÿ ‘zœëP"èG¶wíàª1aŒ³ÄšàvŠL|TÂ3¸øôiˆÒ– JÁhbò[8ã…-¿Ïzôë:­^ÐJâÔGXDéM5>΢•ÆY…ˆ ·ö7–ÿ63lOÚ>hcû~]çT5¨4¤ÓŽñôu0)®xà…þñ ÷¤GU Š*ÌÎh°\!Ç rtêi°9B§o_£Ð`l|»Š³Ã°}–tÞ쫇Ð8ìá f *Ïìh¸) X¶Ð[úz†s Gߢ,¸ãäÄA•¢]‚ Œ…Z¬póš \sê…„!$»ú ,ÊÙ/foP~oîüÞtBìéF¤÷´?ÞÁ)KúEàÅm={s€îîhœÒdh’áÙC¨ËóxÌ(Ä UÅÎ÷F{øLÐf„Ó§èÉ·S!-¨ZéQtUkˆŒ7Fµñr"óÕáJéW ©Õ0,†èQþMLpgÛM í³f}oÏùV±P¡ú\¡ Õ)Øn‰6‡˜{{”ßü9Å$¯“Ýþ3lû€,º…I^ǵǔOþSîÁ܃f1Êj A‡'´º{e²ŠP£³œú™ gtô—ËòG j‘z%½-Ë'#ßR‡G¨$FçcTœy{=þSÏú¾¬ˆ¬Xú©Lº@MZÕ“îm&ôí íì#tÛÑ-aÕy"[¶¸Ã%aÛÑÎ>"Ú?ÅDûÄûoQ-†™ä°BšÊTù|$­W>â6Ôà\E_=Aµ™H¡ý„¡tÇ*¤ qàŠ™­½ }}D”ïù!)ièó¼C¤óaÞÜÂT¡§!ŒFè4‚8ôG"SóT¬Ð“1fçmˆ2Ðct´ƒŽÌ ä: è*$v(Ý¡Ò1`²[ µßçp'+(íŒwÑÓ]ôtêÇË%‰ç—a“«k°åÙ áZ#Jq+uCnúå·l ‰ýÕp´­*b¡q('¾2‡Öà £ý¸Bi!40Š‘Pa²;h3B‡áô-¬hŸ ¯:Ÿ{Z«Xí+ÒUbv&»÷!œ€ÎÑÑ®è Öøq‘ëŸ2Fwá½|6Ù´}ÐË0×[{E•0ÎÓÐ×G(ëy e€b„N¦>ç´Eƒ²êqóµ?¢¯Ÿ`òw0É>!ÐÇ 9pf8'{=ÊãR[‡[4дÎPñh}*ÁÙÊt-ç‡ñ8Á-ZhC”IÑÊòТ:Tc= ôµna†ñ™ ÓøbÝÆ€¾¨½õÏÜ›ÒÝ0}°ó‘’,BâÁXð"½Cf…Ç‹Ë_ ^ά”ͳ++þÙ;_…­Tæe…2^É?‹ÇÂÀ³¬¬J¬ÑôÕ:Úä÷¨ÍC‚·ÞA©··D5Ð× DÕ8kÐ}vHQ4Œ|Tm5¹x4ëx˹×>¡-~B{ú1¶*p½Ã]œï}ÉœïƒÁ7aˆj©,¾µ®£– ìG3‚8 S–:ÿÙíI”}—¼¹1\?£>ýîðs¼¤ÿÕu£ºÈÓ™i!T#‘~e²JÇ1ľ€Ý*t£¢gÈòÒ€£ÓgÈòh8üh}Rœœ;øc[Y¿pÖ·\rLع"²¦@º9äµ;AbM”ßàšTß#ËS/ä"й‚XyÅ»²„R‘A‡çñb\ÙCgüA Ÿ/k¥%Ï{vƒ Rt2ò´Üˆ©×<›Ç´B •BN*ÂÉÅÿG‡{˜hhïw¨úŸ!÷î`nßE—²ª¢ƒÊú®ë¶V¨Ðà’U•þÜ„®ûÿÛ{ÓË’óÎï÷ĉ³ß%onUÕÕÝÅnv“âÒE‹#kÓÀ36dŒ5²à/!èkècè߆,ÃÀˆCLÈ’-.Ýͥת®-÷»œ=Â/"îÍ›7—ÊÊ®.ÖD¡»‹÷œç<ÏÏöÿ»Ïòzš–­E„nB9þ9AÓ¢gSÔ¤tÆV– /Oä©n¤[¼¾ù{P(qŽ‚„…" Ô)L÷邇è$ ~ô+tïÉp½ìvŸzúÊû¿BÏjº÷Ã#Mì ¿xtÃH]zëY骥w@˜h¢{¨‰3^­+D”u ±E÷´í! ²›èá¦ãý€Ù)1ÕÔ…wL Ú+Ï›¤Ã´¥;‘×k"$q¬Pb¤Ž\~Ù ÆÒµ%Æ”J‘ÀŸÌU‡MZd¼1¢ÙêQë–ds›|p õ‡±¯ QÞ`¨ B%[¨hÛ Õ ÙÕü»œ¶ ™¬²H F©Ô/¾‚‹i,ÒHâH2TêY|æ'°¥~ßE­€rì?Î@ ¢N’)«Z«\աĮڠ3®Ó¶N‰˜ùÊu÷³–E¶RÖaøFJç\^o ³×Qj€éÏÀ˜3iî”ò£AÆÐÖ÷©‹ûT‡GØ4wˆEaŒ„ñq«Ôû)*º9£’Ò€C ²rà'Q†Ò)V *¬t¾ÚÔƒù·í1„ÏGŸâž§xêú˜p¡iÜ}¤íN¼J¹^Ó–^Qw`"‡ÌäQÏN¬A4ÒT(ƒ[ƒÌ×`€h•ÎÉp5?}–,ƒ¤žP´¬2(QtfÉ¿YºN‚ЭÐåæMÐ"‚4¾=Í«-9.M´]‹Ì½üóæf?‡¹ÙÀKÚÓs³Þ·Çvî¯tˆ±ó¼ær1^.< ¹¬†y/xwïµ3+.8µ²Ç0 ¥Æî¶D›-Ón‡±úùͯ£ÂuÒíß§ž>¤ß§•‰r‚uEˆ&¨ìa‰!­Å4& åiƒíœ)pDèRQïåÝ”vrstHýî/°*hBGL”$ÎE±shÂÐSF&^_äH°† ×2—ÖŒ¬sªt‚˜[„؇0x€^ÿõÑûDù(½(Úv‡úàÂNÑ~ts·€éÐÎC ÊùY-‹9<+]U‘7¹;\ˆBBíþx]nº\ž¨ËeÉPãideçû Þô…9êÇ„¼š94]ŒROÀñZobh’-‚Q¯¶k7±•]ä—%Q¨AŸptâ!¨­úD£/2}üp”C|€ÏP­S –1fÁ¨³l¬EÄ)6+ ’…ž¯ÇûtNŠõŠ¢[({%¾‹Awгwú4ëf3zå;èt Ó•´åõô¡c¡ê*¬é *ΈF¯¸Å%KˆncÛ9-5ÎSA‰õÕ®HI!˜î¤šWPÎ=L‰"÷ïÞ”¥wÄ3ά¶bÌâp³ Ôñâ^¶jGP;ÆY)uõë1ßwHªÑNߥÞÿ¶˜`ëîÌżºÜû˜Ö0Ûßã“·ßeû7°’!:u´r>´z²\PÞ*Nè”rtFAc0u‹é&(6ÐaƒŽ–ÓÌAy ¤,ÙÙæôšËíYsÊBOžbËÒ³ü´ÇðŠà0­•>™Ÿ‡3üiu :ƒgP"n Ï.´ø¾óoî—Vdɲ,ÏB外ŒvÛËÒ爎¯SÚ±±ùÚøƒ…U%œÊg®ü·µç8\ŸÏÜèB„ÈÕ‹œ»>^`QgÈ¥›(ž\žøî:Âs÷+ï >&‚.Æ æ“½×T;ûìîý=ÙæMÂÞ6:^C§›Î+o§4Õ!ÅÑ#ŒÂ0!ÙÐØý3Þ6 ›eĈ7Ø é À2ƒKûbõ]ÍÐãæ~ù¨CµÏ,‡49f[Kü+N\þ5 +œB…д'ö¸ˆ†F\è¤@Úš@gSø§·˜vŸ@õhgav'0QH $Îù±Ò:”…Ìž®*÷÷¸ÿö»¬½ò´Ú#‡ËOèr ¦3çër¯ÛFzY‡?E:B_Ø;]–ž¢ðEdÔÐÀh€dQú*¨Š– ~‰º> M2—ZN»!H”‚(y ¥ú€&J_¥È~Œl€ a¯rž’Ts¢¯o $;÷@ÄÿsY¡Î "k– [w 7DlEpc¶0zí»èômuŸâñÏ0Ó)R5HÓ¡:ÇŠ£‹‚~K=}—D¯ h¾©BóJÜZŒ÷lí6„±9ö2ü;°®]Aç:—ÉU²àk‰À“•ˆ£g"çÖ,)Dãá4;0êÙo ®ŠŽ&®ÁÊqDa~9•¡Xgà¬"Ó›l~õ;ØA©5$Ê’ Ïh'™{Õþô¹ _G™WUH¦iË]tz•Œ°¤Ÿ@<²p”‡ã#TšbÃÐ-©®sHhËÏZå¯N\ª¦*É ŒAÙÐÉPyΑáäØó[]ƒxÊX»²ŇWd('“~vY–atR–F#Ö\.¸n¾æ BkçÝ<©èhÙH-ÿösœ›„¡‹’]b}ÚyxÖª“r±ÆZ<'¹œ·Çtž+™_¿?ñDŒT!ì¶tŒ‰¶#Ò­ÕÎÓÇH qL˜­£Ó5âáÒÑ›˜vFuø>$ß.µhf*ɱiM¾:——ÚGæŽÅ|ò»ŸÀú.¤ ‘®‡Dë(ˆd¨ ó$#‘çuöû4Μ׎ÚÔΣ#]ç#H-è•)¦&tÝÌyÄj¥bÚvâ©=56H++êÏ;e†«é*Aá+ñÀ ™²ö…obîM‘*rΦ˜¥g,érìñÁî,]î#y¶®—úü`4—Å%µ¾°wº®kQU`Û)6(‘aD£,Ñú«¨hÃçŽg@„Ž_EmlƒiNØ—^ ]/ 1˜Òøhƒxýåø=‚a„I ˜´ «Zç‘.+ åÚ:‰•;Q5%¶œ-”‰mJÇmt‹¶Ã IDATk™Ó J)Ú¶r½»]‹„ ë}ê #å÷Ñù+˜zr÷ç„eM÷à݃=ÌaI[4._–Apgä^hí¦_ïÞ¹ð­Ï£ëR×bL"Eé̳ºˆkáªkLU¸ÜMQ`µÆ(å(3—rÔ¶m^ÞóM cé½ó`Î*æ½Ò‹Pq<~ 5úÏv ¦-0ºÀT»t{Ó~ôÝû±G 6r÷×Úµ‘i¯h=_­ã{u²—`ˆRToͦ§Š)–+±E)çU‡Î[“0u8ÀEA¸P t¸ŽŠBÔZ“yG=AMÆtP_¼A^…]´ÖžÎs6ÆG.wÛu® ¨mýy©Bé¥GfXåIRêrQqkëùl]Lá1ãm[¸ç¶bä¸ PÔÙr9O–AàòÈrQ;ã:¬†îé+ƒ5àó˜Û“Ö§?wÛ¶t]…1z!qrÁQá>o¹,ÞáÂé¢Uޏ"r½ç;5fÖ`vvÑ=Ѓé%Ðv4ÓO)ƒHŽ^&¼F”ÿKÂþ-ö~õÿ2\´¦<Ä”k¨jèÖúÐå ‚(ÌIÙ‹X"’ºþß(G%Ž ’(rûsùOèÒ[‹Cw×ù´Rí8¼)!k‘[Á+/ÓHCðe”Þô‘Ò[Ù&M¸‹º½…9ØÅîv N§¢u©ܽ;uRWí_RWyTËÅÊh¨˜„ÐøT#¶3t+ºÜÊÁu¹Zr¸dî(,ë÷%.ê³(.†úÜÞé¦ñÆÌñž¦ ²‘cCˆúw@E˜ú.õô]êÃhgGØÆœ*á_ÞBÎDÃ;Dùï¢û¯b£_¡¶‡tŸÌ°{•3tÁÒ wiÕ=È4&(QEáz]­ ?ۦĶ6nPiˆUr\äÒBÓ"M zУÉB¢þ«(S÷PEIûÑ4?ÿó A ¶t½²jÓÎJôšœ«ÐD‡§ì«[[GÕ­£ã!•º‡êGÕ˜Ù UM±GG˜…GbPI‚ÕÁ)R”Å Èt+‚y]ÃÕ‰ÖîÛªs”õ×A0eƒ©÷Ý̨ˆ®,ô£ó)Hg‘@!±òíd«p Ô‚öNâÔ°{CTo•n Òžã{“dœ×6¥ÔbÓK˜8áòˆÐj&ȶ££-‚þMÚò>²a§˜jŸnìÛØZGA:§7=A{è1¾mçj$¨&˜n‚µ3¬iôaÕ`ƒiQÑ:ìQ+,Àµk *f‹S۔خ‚¤uÕ¨ Âxà¢eÍ[UŽì£µ.”¯9ß8%Ëy­ÂE²\½nþ}B¬rÁyh~ýüz~ssGOXŸ¸ŠéªÆ4‘[Ÿ^.¥@ذÁ%Ö>G¹ÌÝEï ÜÂ*â(LŒ—0.è‚ °zÉ è…èõµ5ªǔ¦ Ûú#²Ñ[˜× Ž~õSFy[M¹Ì¼.c HÈ^t¸÷i5{aÔÎk$pQƒ0ò‡l}ìIëг®ù̼@s‰×ÞV3ÇKÏž ¿xƒ: Ho|½ærÉæ±KSªœdøêþ'È­G¦m±Ó‘Ö¯°¸=ZÉ ]Õ—×U 9*íÞQ"èÑÆ§¸Œ£¾‚.§i\ËRÕ7±OEycýTíY'ª`»Î…½ÛÚ-5CyF0ÈÐÉMhÇ”‡ÿ;=BГÂõù‰:_ù<µµtê ã>e=&ý:¹IÐbj…Z×tKìLy€ æž§§”JÑé6Uø.ÁZ.™`ÇSL,-ÈN¼CF#ŒV®œRc0Ó™+V‰bT££‘o»ÙCššöþæ^½o±¥£%L’Ü-$#_ÄÒ,Š‘½ÍÖÓKg±eƒ´švö¾‚N·)ÃwQ£]ö¦cL‘8å¶kQå ;ï£ç\¨fQe»æ5!ê8ï‹i¬­Žû‹Ï¹ÆQajh—;ªçÀwÐñe kì‚i ÔD®ú9ò}Jèòä*EtæzIãžc ÃS¹é'ÉùßÍï™$¨¤G7M¡Ž`\¢T@}øzk‹dø:Gû÷Hnm`§±1•‚‹­†Î³:‹æÒ¶˜nAåÀ^‚›hj‡tÖ€-jT–ÒV{èì:Û¦ ~‹æynõÒyí‹~Ýpy‹ GtB{¸Ó¶Ü…N9JÉÎ)x ¬“ÓY^ëy²ìÔ…²á¶CC…´å¯éÚ#A'¯¢¢d7¾ÅÑÑ÷‰_»Å}ì§%¶r 9b¶lÑ@^MWÊõ9u|ð ÚÄUgyÑ ½àéty[a«©»åû¨Í1­ƒ°ö:n™‹ú,¯ZŸYíí‰LUÃ(Æ-2Š)iÈG¯£TJ[~Jõà׳‚ö×b÷[bø‡ˆoñèÜI6h‘õýÆš^ŠNï “—ˆ6^§Øÿ1áfŽ”˜£ ¡Ã9™GP1:yÉÁCnÔÖ.fZbÆ‚Tµó¨uYƒÚÐÈæÈAô…›˜¶¢>¼‹jÁ–ÐXŸüW¾ºlïÄà{(ý¢ÈÍœàæ º8DÇ7Ae ¦+'lí+Y¶30鈶4ÕÁÇDï¡£MT6pÅ6·1U…™@ LZ¤›`šÕ„†Hx失µ®öl4<ÙcÑgxÔv®DätþLÍ[¦"hæ°BuŠjïC’áWPѪ7‚ÚÜÙ‡é><h:P>ï.~UE@’‚ä ‰B±Zª=‘g)3/(sðŸ)’å¨évz„=Ú%]Ë8zðzð2:Ü"Ù|æñGè;#ŒÙÇîíašÖ…ÂÛž'}}€uQUa†Ë6Iø§ÿ÷ü‹o|ÛÑr–`Çj”QÞ%én"iŒlŒP[tG¶1Hã0Ø­ª ¯¶"dc IT¼ mA=¾‡ê€qƒtÚá#ëÆõ/Ÿ¥Ü/#Ë«®s<>ça‰ï,PBžóÜ.ZŸB#0®P\,—Ö¾`r™‡¾ÅÊ&-*ñŒx•ãDÇR+l`+‡ÿ%“CI·ݸ©÷}}ì¥=l§4‹H›½,>Áè‰÷T+ýZ2¿¯òص9‰qEZj¡¢MâÑ(Ç¿@a›®yˆy4Ã¥óâƒÜ ^Û¢ Éú›(í˜~ªÝû$MK³?ó0:¾²Ý(5@'#½‡Úì£nÕ •`neè/ÝÀ †èÁ w`P±OåˆûŸò•~Ñ"‚èÊ0Þß!Ýþ˜¨ÿ&ÉÆW˜ÿDüêMèÀã¦h±¶@™11Æj”ò=ºAŠ-bBW§8.`8GŠà«qåø´oJàÌp¦«HÕˆ·/Ç]¶Ìöv¨·?&ê‰dýkL'ÿ@øÅ×Á~2ÃXÄv‡\lÒ!™†¾A •$è¼Ql°Ê‡µÏR‚Aàèób²0t©€¬G¯aëCºÙÙ›‘¬GL?ý1ýÛL4üm5¡â7BÚûØý±+Š4c¤\1J Γ‘b‹ô¥˜,áÃ÷ÅLÏQÀ,ÀLâN1Þ¹O¶õ):}™hý êê‚;[Øæ!ö~-œAÌ 7CÔm»þ%w°-îRì< oíÔúlíÈt‚îœ|î%dyÕ5pŽ!¸5† ,¢xþs;o}*íæcsÔwÂtç>í¹rñºáE‘ 8#­,*1¨u` Ð@Õ!G­ë˶ȴAB(€ÜÕjXQˆrENÆضó½ïÇ‘’EÎü áîE7‰R§¦«PŽ´(TXlÖ@;Åj0Òº‚Á&FTìªþMàBâv°­¥vž~ƒO `õY·¨—7˜é–µÛŒN^¢­w™=ø'RÏ>D’œZ ºOÒÿ:Ñè-êñ#:ѯ4˜¶‚½ºÈ!èkªeze]"}Ä…¢¥´H¡œÞ•ÕUØY‹nìÓër´«Ï’¡ïY J‡X`µÀx8' ®ÏƒlÄ3ªXjdMS–hthÛ#нˆl€Ùm‘ràŠ…Â>*ñ྽ÈV•c½iÆØâ»×Þ ¨ö> ~m^¢}Œlçð°‚£k—IB Ó›ÐÿÓ评t›{Øq夆9êæÝp€¬£ó/bÚ’Ùî/‘Ò`:Z4`§5&U´ÅCtr¾BBðú®¢ïÆ´ iDpc»9¢ éàeçM/ŽþÔ:Že1¾§4PЀÙ/HÒãOÂðÎ:½Mºý&åÃ_éUÌú.æ°BÚVwÔ¨~Šô"ŠzÊ÷ÿÏ¿ã¿ÿïþvVcE/*=Ä+ ³ é§„NÙH¹žC|1E£±g\·Ø¼a„Šp§ÕB0;S¢|ñÝ3|m€Ž¶‰o|•òþ/ˆ¾ü&fcµ7ÂWˆ © y„ä÷988äÿŸÿÀÿðoÿ×›¬º“Õ*ç$çÅe>ô-yU QÕv2Ãîe–i·Ç4ü1ùö7É6ߢTïQØO‰^»‰Ú.°G3gD›‹'¤jAž1­+Êöˆµ×^£©k$ÕÎk°L;Ìî˜p;cúðçô_å¯Ó®=Æ  ¿Òv1GÎ ¨~Dpk‹¦ßG7ˆò;˜vÌôáÏ ;ÁìN¡ÐˆJHacqK+‡–KÉ2tUÓæ\·8øéBåqhA›SFçsÛEë3ŠêÕ—é”Ä71¦¦~êÒb¦“ ÑRîyá÷åèUøâ*ß.çå¼`ÏŠ2T¿Enç(]BíR˜„Ðë»2ЮH˪ "Dbl ]‚-ÅEfeŒ ävŸ™jè½ü:c*ÊÝŸÒíî<Þ¥ùô!’§¯½Fqï'è/l “—Èn}‹ÃÙ÷IoobËlçÒØÔ­…Ç¢—GWÓUýò!‡ûüÿáûü›ý?b÷¢b„Ó ]±ØÞŒäVþôº¼S4‡üûÿãçßýOÿ+¦¦‡{‹aYIC/‡¿õùÝÆõ2ä ££þ|áÕ‡t“™6Ø*rXÁé*_Còž/Í׋Â5›b&ûtM€-ŽIItÔÕ}’üËDý/p|Lº¹F7ášFÁèæ¸ÊÔ„®ØLÔ)4Mgà$ŽAGKÕ…;ý†¡+ Yæp}À uP®tv¯F*:eßû!ý—þˆ( n…T»ï`·G›#”qÛÖZ BEKk Åô1eÓmçHª hNF–{9WrÔ'¼ê$Aå9¶ì£ê l[a‹ûpŸü¥”éƒû˜¦"ß~‹dô%T:¢Ú{ŸÎt±F‹vTAˆ1-ÆZ í[¯ß$‰×©Æ»´]í*4 @÷ Óؽ‚d=`üð.Aú3²ÑWIÖÞ¢ä*:‚×3´uïdÄR=Ü$Yû˜ŽÙÞ/(ÜeÐÅtûe‡ÄNëGÊyL*8®¼¬,ƒà”,¯zÝ| HA8Ð+Ïqn­O¢R GÞÚ7$›êœ˹ïà‹ÉBåØ¿ÖÖßܤfì3%ÌAÚ'¸¹†¶²ðULF ]¯½†Ò´Å}Æ÷Þ& 28²Š5Ì\/ó9@vi¿‰7Òâû|m.¥8¨œ¨ÿ2ARÁ—övé[”ÔIæ,ñúoÞÜŽrÓ»?Å–+dr#¡ŒC¢Í-’á×AiÊý·)îÿšdÚÒþvs¿rÊÉ6¸Álç§ônÐéÒ[_còÑ?Ó{ySa7À–`Æîè~I+æjºjö˜²kHnäk¤ç±KŠª”E:Ú#v4fö”º|—ýý}¢ݸº¯¦tŽ‹o½êõâøˆH\µŸ‰Œ²¨p¶Qì¾¶v<#`ýMT¶E0Ü@õzHšº‡zæ-3™8 ù™3¼v\£åþûDñt¸Ž"lO£†)ÝQåÃ_KMŒfF;{ß¡M aN§t¦ÆØ$ Ȇdù t¼…ÁPî¾Í䣷éIŠýt& "¹+V›(’V8¼ÿ AöS²Í¯¥¯¢ndÔ“i¦ûØÆ}J{œß}”i©§¿F©Æ”´MK„Cå‘^ô•€cB¤ìÎ!ÙK “Gh›пù tz“Þ­íl—¶:`VMÜnVdäýâ>î>Àc÷¹0[yE!´m‹ñ¹©¶mt¨vy]¦H”úî6ƒmR¬Ž hÛæÄuGA§ïŒ¾A2|“¢—Šñ­£ GØ6†Ja•¤ŸAW;Pú}x"iâø'”‹dvm‡Ý“ÝŠž^—G^—Ûî ܧ…‡˜A´‚@$c÷Ñ=ÂímµG;þ„ñ§ï³­»êØhHлA0ØF ×Pý¾Ïo©EÓ·¤)…tcåÂ'Í!‘ Ù»û[t|õÁ„Lö¥*š¸\¢’%RŽ)mq éЭe²ó!Aoƒpí–÷ˆÓ£R9þˆbïšÇ䪰‡* y„•êó¨dðÊÃßþ”fú˜tý T4@g/£¢mL=¦PÜ¥ï3ܺI{ðE±7Sw*ßß#‹¶¤jû¨tˆ‰Ûm ¥ÆT‚}xD;¢8œ²sð÷¤·‰ûîÝ£dDdpÞ^[ÒT‡”™<¾ÏWÞü¶4.ï£Sˆ:D÷a»QL÷÷è?`¼¿G?¿D=”é9Ãë•A‚õ°&`¼ÿpqÝt^rÃUe÷{H“( …ë+~T’n…4AÇþo~H´¶N¤©/›9jÝS†7û/ˆ\ú¨¨£ï?Z\WìïÑ‹6ArT¨\ĦjØ¿wáí_¯ ãn¢ó›¨¥Š.c:O±¹Oóø=&ï’IJÚŰbÖ|ä"šIºhº0­4("Tœa%…V˜ÍvéO?ñ–× ÓWH¢ã"VÎÀXZþ{Ï 5Ù9„D£"‹ Cl/â“ËÍ·þ+L×QŽÅø“"®öáv_£ì:k¬jaf°gdùûüˆ!:Ù@§Ü}÷]^Ýø"ÁH!aKåöh1þ̺êë_ý&¶‘x‘ƵQa€‚)ûàjºük¿÷¶ê:Æ'Õœk¨ý)̵²ÄH’£ÔŒŸüð'ÜúÒ-¦»TÓr#½!ÖŽúÛù Ôp5¢²lUm}9aèr_Z`jé¬cÖªÆ>Þÿ¿Hòã8xçß|õ«®Œ>è–'Tpq“)æÞÇdANs0avð6öy"e=HEG¤ èap¢¤yæð®Å`™b§cxX±vsDùø€ƒ‡ÿˆ”V#˜¦Eªš4HÈT޹{Ÿ¦?æã_ÿ‚ác¬å“·ßcëþ[æ190(sïßÔÈ4¤+L¡1ÆÄ}K²Ö§ÜÝáðñ}IŠ"ŸnÀÓßAöxýÖa&0‹`€dèÖ}©¡´üöG¿¤¬Ü&º÷³÷¸ý_¿zˆdTÜGOÊQ*¬®0R"UÃ?ú%µ¿îÓŸ½ÇÍq ¥×ᚣ 4ª«1MŽ-1ƄÊázJ}8ezðFŒÇG>v˜mãàB ÙÊ7Щ†2„:C⡃’ 9XW5ó~Cߪ|ë‰FÑMBLùûø™MéèåTû»Lv:XW­%˜ÊúîPšÍd;©àqƒT9Ê‘,‡X»÷ªÆ˜&Â`»ý˜. ™}ò>F~ë^t®ÓA A#Ø%RôQá’ QQîˆ+l‹i‘ý³’åU®SÀÝŸ½ÇÍ?¼¹XgÒÅØ qly•â}ÿ[óœçvb}F#GZc{ñªam挵y±äBYñÁ~I»ôÛßü.¢2×¶H€¾òæ·¨'3¦Å»®%Ì·zÊ0ÆSab:lcI‚ˆQ0ÀT؉Bué ‚Þ&*Í‘>‡çX–`tmºˆ@ÖÃT}¤ EÅÇ?û%Ùh¥Ä¥[s®>Qƒ°Ä õè“ûpçë&Và?ýßÿ5‚~Æt÷cÊñ>}“KŽ9ˆÇ s8ආ¨ÆNf°S 4ÿðoÉÖoP–>~ÀG?þ„õ/ÿ­s†âÚÓæ˜é¦›^MWÅ”©3T´  ‘+RöéÜn`ëóèàétùËo"e€T¢sç´gG>V£b­µv¹Ú»(÷ôdŒïÑÝÃt0áØU~K‹m:˜´Øi„t#‚xÕß@õÜjqMîE9*°ãÆU£g1j«ïJÖœÇnðŒR¦:Äš#Œ=ÄF3H ’)$ }…¬g2Öµ¥µÖÑïuÚÑ ë¨x‹ ßBõ7#·N|ŠDÎà‹>i;ÿç|}N§Øé”î`;=¢›î¹w3®e.n ±Š1œÌøD±nWÄ@* &ClßVÂJg.ÜuضÆG˜êÓ`£)Ä’ ’ FœJ]c‹;³PDHÛC…ëñÕ[s5Jamë¿í>69‚¼u²Te÷t²œ¯§½.ò¥háHÁ8…®çŠÉ¤†`ýÂqЧکû§]gŸin'×§XÇÛŒÁÓÊN1Í‘“K8†¤yqä’5(WÈRì^‡=Šžt6U×צקŽaˆ1Ó4PµPX(4JPÙ ‚þÁ`„­ëà•½µOZÞGGG˜ƒ]Ú½Oé&÷0òéuØL ð}Ó 19®¾_*Œsˆ^°‹‚V9xl°ožY¤ïZ5­²Î.UŽ—|’9xR‡¿`:Œ–Ø|†¬dͧdÐØÆÂL#³1h"0‚m*L}„5GX9ÂFÅåtUmÁ„H—¢Ô:J¯£â¹ˆÉ<2l¦Ìô€n¶wy]Þ¤QÐ%(»†JodÞfæTž;{EçêA½Š¯,sÈÆ0tÞ‡ÔIDAT´Ù„©&p ðÎB‚‰Â!’­äHš ×|ÏkrRÂð¸(HP@7‹0e‚`&S°5fVc€"AT Au¼(Œ¢1Ö÷; æ¡ÅîÖ¨½Û7î#…¡k]0!ÊÕCÒ¾«FÏ.Ïh˜Sc¦G˜f€íÆØñ;)±ªu9oð|¯RZŽs¬Žl»p]0Bå#‡ºÕ.Ám×a“â)sÌ4Gª¶:Â6…«H ;¬-]„KQ*uHlÁ‘°ï©ô´“S› m‚5™C+j¿wDõÜ\’u–s0šªL`Ú;›`§¾uÅäˆî!ƒ!J<’ò¨h5ª`f‡H=ÄvhÆN lÐys\ئ¹‚¨Q9*[waÅt„ʆ¨$sòr¡ËEùêy| ÉGÍ¡*ƒÀ¤fÜÃ}§¸‹)”%ö¨Æ*׃*Á …Õ`3 ¢â¡ g&}— ÕÑ¢ÍÅ3T–cŠžûÓN\?wQbT R"â±¥­€ÕˆqHjJõõ]Ô?MÎÃ’mƒT1¶M0m‚-—Ú‰¤w5Y^å:kÝA…ÔQóIîåi0vŠeŒ®PäêëìªïdrDeH>@…CWŸ! ÛµØf€šõ0Õ (—évV9žV#6Fe)’ŪpˆiõÔ!“Qù°{ç¸ãçxûÖ!ÊY£lâÃë=$ô× ]Ä-ŠÎä9>¡ç#W,*I‚d=‚vËÑ9γ¿‹Ý›8>vãÐí*xݼÔDkßÖxíÛÓ2W…ÞE¨ t¬u=(±ªvŽR"mæØÇ†='_;®%0¦c™aËvjlè3’ žÿY$wØ­«ž6Õ[M0å!¶»ï{Y]•¬!zHÐórM²E?8]qìÞ9NŸ¬Ë €À3³eH¸†ŠGŽŠ3ìÜÈÇ…¡ïEYîËž¥ªÌ\¥­Ô.o­"$Ì]N3ë¡Ò ÉódØ‹Fî%ò0ójÃ0ÁV¤;AÔS¬)0¢‘ ^€ ,G¿]œE½ ‰œ-û® CÄÆNØqŠ„© KE©;tÄÉéÜyÞG•Sï5ޱM55b™¨æí »ÅhÅ àŽÈÝ?]C¥TÚsÜØžMG<DZÄ1¶ÌÝ<Ê5L9Å6STSx‚Î8ø6 G—!q•äHœ¹o6¨+¤Í°Ík ·¡Q!öœ\âlq`^¸â‘ªm&'¯SsßÔÃ'ð°eš£š [Ž›ZS8JÒ®Ãze(â§»O‚hÇÕ«zC·Nzýc(½%c}^qÙ™ùê%Š8å ͈<'t¹†™Q~~ÖÔÐ9ÅG7GVòýâ¢=q„JˆN¬iœ:¥½2Ì2‡Ÿ<ÍP{†)Çþ4`w(ƒu(O®S‡‹œõݦORGc:oŸ1©2l#eï„,U€N/%KÚÓ•O}Ýb ˜Î÷æÆ(ºù{e†˜¶pFĸ²§YgŸyn«ëÓ+ó¹Ñ±m‹Í\ëž©g/”\l3Á¶¥[{ÊU‰»¾cïå·Ãªh ×ÂÔ•g¾u-W í÷•üWQŽÄ9*wi Õë»tEêßcyŸœµ§æ¨Æ8=¿ÐÑjÚsß°+°MåñÏÍé:&™cú+F£C‡Ÿ­B·÷û‹ }kŒ7b,éÐñy©§Ì\Ò;mƒ2#L=[»º"1þ@¹z…8wßSél©jw°.×°ÍìétUÚCÒ*[Ñã~NÊ;±O­Ë£Ü9Œ™·yî L.§õ e8÷^æaë4C)…¨› °M} K'ʽ\ºJÓ•¥^½EOØœ¶pN¢§Ø¢‡ ‡˜°@ÉӺɠÀ†í©^@×áxeš£dƒ [G²>ªŸû FG¡è(Ø’ÅIyAܽ„i.um†Ø²@Õ~¯ñŠ}ž× ‚°?ÖCþÔ]kOí»üPš- 4>I\E»GزeŽ*K‡1=Þ¢7:p^ºû†ñqUæü´?÷Ò»[gNvvY.‘¿îdA‰t›‡¿·­§¯ \‹Ùd‰aJ²Ì1L•=ÔòÜíÉ"Ñþ;‡*rÑ•å‹hË2«\‚îí”±^ÁÈÅØ&Ç…˹•¥«ì¯e%«°«óÖ!ßR'‘W®Q|œº9oéa“ĵf=L9:ù ŽéîD{ å{ë“t±GX!‘$ÁV.*`ëúJ²¤ëP¾ºx^¨÷ÔkÀÎ ICW?7„ ÒõÜÞ~7sómM%Çës)µFæ¾*‹J.‹w˜ú}¥ñ¢ ªsüç¶­¡©ÿ}T)\èÖ"f´Ê{Çûj)7}Çñ‰}´ÜúÈš×i!&¢fSlU¸Cúœ hÎuÁ¸tÜž:ÇÌ–Ð{ž>¦!Åœæ(PÁñoux:L_ר¦v°Éóï?ß—>¶AsfN~Q¤Ø¦-Ë«ë*¯Çïj\žÚ& ¶¼‚.]‘Ÿêõ˜ßçF>.,&;OêÛ& €õ9Û€`Õ‹^MŒŸuÏ @¢›å˜É‰f˜ «\è'CRÒ'ze±Éèõ ô5ÜD ‡.ÖŸeþx77Î+dÝ‹MU×Þåîß}¨÷CÕ2|âü½„“ïŸì‰ý<üï=M~L­Ø4¹í°C|œ†˜¿ÃÊ7uù¦ž'–è–ÂÈú$ÿéÒÂÇ·9¹w=ãºeBó¥ÜÞñ·:cî«€ÿ‹4,Ú?–ýêaî „éç—-³mÍï]×Þæ¨ùçÈx]wBÙ,¾K Oâ–ç·ôíÄ_/Iâßé]{ ´Ë(s9,ß¾ñWï†Ø.{¶²|Êë–÷õ)žc°m³Ò÷þüævÖú\>/¨y_T¹,ëÍÕ u›Gh›ãµºÔ[+J9¯óŒõºØW+ž´<)¥´¤“•RØ(Fâ6ï3-Œ9 ¤²0œKßbŽ+±ú¾vÅà/Ù‘åƒñBozù¹oØ.Z‚“×.Cq.™îéuÕœ4ã =.˺ÜìKëòÏ(/ý$¯e® wuá,+ÜóNgÝS)çuÅñÑžèÜTXu„ gg÷0!’ôþ*ß"nº¶°^ÏçÕòÒ&<µÂð¤!ZÚØ«Œ3§H#–è³;K‘Ì7ªÿ5Æ•ù˜/Äåg+xØKó·K\Õ27¤«§Ýóz(çPuóyœwÝr>kõ[3÷Sà%óï³¼èϪD½$'ë V­ùÆñ­['ÖiÓÏkAȰ¤læüÇçÌóÂo†. °¤V×˹2 Ã ï»ØcÏZ–OqÝ oiYÁž÷»ç8·†tÕKô‘ŸV.Ë{dɨËR׉ýtF¨yÁ¶ôöÕ…z^©%Ô\¸ÇÏÔ‹Ë{iG|på Y¬Ú“SÎÈÜîœuÐXY‹ûϯ{ºjU¶ËkèRº|9‚8:\Ò“>?G½âµ,¨ÒV ÎN}ä ÊË÷œ‡Òæ¡ðº^pÛ Àtj8ÄÒ`9tÕtV3]êEœîïÑÏn!qŸ`8B¥}Ô`à<êì8O~¦Ò]ýèKí>óPײç%O`§:Áò´zXYùNviS.+€K)ÁØ¿Õ/gœOÍmYK‹ù¢ëNÜ㢹ŸsŸsrgÌíÒä>«ï²ºN—Ùh–eyÎF?ožgÍm~Ïy!Ωg\Æ}F™|î×ézáï~Gïtjÿ— —ÕÐÊïÎ5JÏp_«ç—ŒÉb—¡É\5¼«s]•ÕŠ Ï,x[ÒqgQužû¼•ë>‹®:ó;οUš^M—_Òf>±ú,¯…e/î"ó¼°Õø²‘¯ëS„-¶­°vÛHÕœêa¼ùG·Qñ*^'èo †#×’-åÊŸôÁÏ1¢«Â~’;ó½Ï9ÉνêSÏ»„B:kÁœò(.#—%Ù^öºÕË¡¼'}«ÕïÉ…yïzù½äIó{Ò<Ï3—}Æ%ï{U™|^×'—§ÞÿŸ÷;³OÉP.§¾áòþº„aVûêÜý3¢­F#.».¡ /c3XÙkç9NOºî©ôúßôYéò+ËËZk/:éRÖº/ñÀ÷‡ êÚÅø}¬9Ø¥?ÆT1j÷d?¥ïßTf»þA54Òg´=q¬¼ïeØ…F|õrÁó.µ9/3ÿ§5~W¹î ßê¢CÅg5ЗZWW•çsü/Œ,/±¯Ÿúw¿Ëwz‘årÕµ|ÉÃôUöÕyûæIûéitÕe¡‚Ÿú>½~™õ 8EOómTŸþþÖ""|ï{ßãÏÿüÏÿ×ý×üÕ_ýsó|®¡¾Ò¹ÊY2Ö¦,]#þtâ€Q¦1ÍÖŽ}Y¿ï–¾)È·\ÛOÞ;nKX)¸Š§ðYÆSV®xïËÜã¼¹\:ŒõŒ¿Õça ŸjŽ—44OšçgùÏ[&Ÿ—,_´wú¼Öæïôû^b½>«=uî|¯úW˜×g•ëÓêÇg¡«®ò¥5ËfWDøÎw¾Ã~ðD„¦iøö·¿ÍÛo¿½ø~–“¾jèrÞ* ’d©‘W²_äg÷a¦×_ìô‰$ýy¡­g¸8>kØö2Ï“Ï`L>¹_vÞÏÓ0?ÕŸ‘²{…ð4…r¿KY>Y|ž×}^kóy¾ƒ=/lúœôñÓì™çµ&^t]u™ç\æÞßúÖ·øÛ¿ý[þôOÿ”¿ù›¿áOþäOxûí·ïqú¹x@óªë®s=°u)f޽ª®,(¾Ó÷0ªÔ¡ðœð¤¯X¤t=®Çõ¸×ãz|îX‘Sõo~óþâ/þ‚þð‡üÁü÷wÇ+¯¼òt¡ïçb¬ç¹‘y?¡ïK»¨óD>z¥Gûz\ëq=®Çõø/ÁP[kù³?û3^zé%vvvøÞ÷¾wâwú…™ýí™­Ë/:/w¿JÑØõ¸×ãz\ëñ‚¿üË¿ä»ßý.ÿðÿpÚ¸¿õ«ž%¶¤ùŸ2êËÞó3jù¹×ãz\ëq=~õE¿{a õ)c½d Ï-©m?×ãz\ëq=®ÇïÔ¸¿H†ú\ƒ½ìU_µOïz\ëq=®Çõ¸6ÔÏÁ`_èëq=®Çõ¸׆úz\ëq=®Çõ¸/Âøÿ±|;ƒÎ¯:IEND®B`‚commons-exec-1.3-src/src/site/site.xml100644 0 0 3456 12425540624 15123 0ustar 0 0 Apache Commons Exec /images/logo.png /index.html commons-exec-1.3-src/src/site/xdoc/download_exec.xml100644 0 0 15520 12425540624 17742 0ustar 0 0 Download Apache Commons Exec Commons Documentation Team

We recommend you use a mirror to download our release builds, but you must verify the integrity of the downloaded files using signatures downloaded from our main distribution directories. Recent releases (48 hours) may not yet be available from the mirrors.

You are currently using [preferred]. If you encounter a problem with this mirror, please select another mirror. If all mirrors are failing, there are backup mirrors (at the end of the mirrors list) that should be available.

[if-any logo][end]

Other mirrors:

The KEYS link links to the code signing keys used to sign the product. The PGP link downloads the OpenPGP compatible signature from our main site. The MD5 link downloads the checksum from the main site.

commons-exec-1.3-bin.tar.gz md5 pgp
commons-exec-1.3-bin.zip md5 pgp
commons-exec-1.3-src.tar.gz md5 pgp
commons-exec-1.3-src.zip md5 pgp

Older releases can be obtained from the archives.

commons-exec-1.3-src/src/site/xdoc/issue-tracking.xml100644 0 0 13367 12425540624 20066 0ustar 0 0 Commons Exec Issue tracking Commons Documentation Team

Commons Exec uses ASF JIRA for tracking issues. See the Commons Exec JIRA project page.

To use JIRA you may need to create an account (if you have previously created/updated Commons issues using Bugzilla an account will have been automatically created and you can use the Forgot Password page to get a new password).

If you would like to report a bug, or raise an enhancement request with Commons Exec please do the following:

  1. Search existing open bugs. If you find your issue listed then please add a comment with your details.
  2. Search the mailing list archive(s). You may find your issue or idea has already been discussed.
  3. Decide if your issue is a bug or an enhancement.
  4. Submit either a bug report or enhancement request.

Please also remember these points:

  • the more information you provide, the better we can help you
  • test cases are vital, particularly for any proposed enhancements
  • the developers of Commons Exec are all unpaid volunteers

For more information on subversion and creating patches see the Apache Contributors Guide.

You may also find these links useful:

commons-exec-1.3-src/src/site/xdoc/mail-lists.xml100644 0 0 22536 12425540624 17212 0ustar 0 0 Commons Exec Mailing Lists Commons Documentation Team

Commons Exec shares mailing lists with all the other Commons Components. To make it easier for people to only read messages related to components they are interested in, the convention in Commons is to prefix the subject line of messages with the component's name, for example:

  • [exec] Problem with the ...

Questions related to the usage of Commons Exec should be posted to the User List.
The Developer List is for questions and discussion related to the development of Commons Exec.
Please do not cross-post; developers are also subscribed to the user list.

Note: please don't send patches or attachments to any of the mailing lists. Patches are best handled via the Issue Tracking system. Otherwise, please upload the file to a public server and include the URL in the mail.

Please prefix the subject line of any messages for Commons Exec with [exec] - thanks!

Name Subscribe Unsubscribe Post Archive Other Archives
Commons User List

Questions on using Commons Exec.

Subscribe Unsubscribe Post mail-archives.apache.org markmail.org
www.mail-archive.com
news.gmane.org
Commons Developer List

Discussion of development of Commons Exec.

Subscribe Unsubscribe Post mail-archives.apache.org markmail.org
www.mail-archive.com
news.gmane.org
Commons Issues List

Only for e-mails automatically generated by the issue tracking system.

Subscribe Unsubscribe read only mail-archives.apache.org markmail.org
www.mail-archive.com
Commons Commits List

Only for e-mails automatically generated by the source control sytem.

Subscribe Unsubscribe read only mail-archives.apache.org markmail.org
www.mail-archive.com

Other mailing lists which you may find useful include:

Name Subscribe Unsubscribe Post Archive Other Archives
Apache Announce List

General announcements of Apache project releases.

Subscribe Unsubscribe read only mail-archives.apache.org markmail.org
old.nabble.com
www.mail-archive.com
news.gmane.org
commons-exec-1.3-src/src/site/xdoc/testmatrix.xml100644 0 0 22647 12425540624 17343 0ustar 0 0 Commons Exec Test Matrix Siegfried Goeschl

The following tables contains the test results of running the comons-exec regression tests on different OS/JVMs

Operating System JVM Status Reporter
Linux (2.6.34.7-56.fc1, x86, 64 bit) java version "1.6.0_20"
Java(TM) SE Runtime Environment (build 1.6.0_20-b02)
Java HotSpot(TM) 64-Bit Server VM (build 16.3-b01, mixed mode)
Passed James Carman
Linux (2.6.35-gentoo-r9, x86, 64 bit) java version "1.6.0_21"
Java(TM) SE Runtime Environment (build 1.6.0_21-b06)
Java HotSpot(TM) 64-Bit Server VM (build 17.0-b16, mixed mode)
Passed Jörg Schaible
Linux (2.6.35-gentoo-r9, x86, 64 bit) java version "1.5.0_22"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_22-b03)
Java HotSpot(TM) 64-Bit Server VM (build 1.5.0_22-b03, mixed mode)
Passed Jörg Schaible
Linux (2.6.35-gentoo-r9, x86, 64 bit) java version "1.4.2-03"
Java(TM) 2 Runtime Environment, Standard Edition (build Blackdown-1.4.2-03)
Java HotSpot(TM) 64-Bit Server VM (build Blackdown-1.4.2-03, mixed mode)
Failed
DefaultExecutorTest#testEnvironmentVariables
DefaultExecutorTest#testAddEnvironmentVariables
Jörg Schaible
Linux (2.6.35-gentoo-r9, x86, 64 bit) java version "1.5.0"
Java(TM) 2 Runtime Environment, Standard Edition (build pxa64dev-20100813 (SR12 FP1 ))
IBM J9 VM (build 2.3, J2RE 1.5.0 IBM J9 2.3 Linux amd64-64
j9vmxa6423-20100808 (JIT enabled)
Passed Jörg Schaible
Linux (2.6.35-gentoo-r9, x86, 64 bit) java version "1.6.0"
Java(TM) SE Runtime Environment (build pxa6460sr8fp1-20100624_01(SR8 FP1))
IBM J9 VM (build 2.4, JRE 1.6.0 IBM J9 2.4 Linux amd64-64
jvmxa6460sr8ifx-20100609_59383 (JIT enabled, AOT enabled)
Passed Jörg Schaible
Linux (2.6.35-gentoo-r9, x86, 64 bit) java version "1.6.0_18"
OpenJDK Runtime Environment (IcedTea6 1.8.1) (Gentoo build 1.6.0_18-b18)
OpenJDK 64-Bit Server VM (build 16.0-b13, mixed mode)
Passed Jörg Schaible
Linux (2.6.35-gentoo-r9, x86, 64 bit) java version "1.5.0"
JamVM version 1.5.4
Copyright (C) 2003-2010 Robert Lougher GPL2
Execution Engine: inline-threaded interpreter
Compiled with: gcc 4.4.3
Failed
DefaultExecutorTest#testExecuteAsyncWithTimelyUserTermination
Jörg Schaible
Operating System JVM Status Reporter
Mac OS X (Darwin Kernel Version 13.0.0) java version "1.7.0_45"
Java(TM) SE Runtime Environment (build 1.7.0_45-b18)
Java HotSpot(TM) 64-Bit Server VM (build 24.45-b08, mixed mode)
Passed Emmanuel Keller
Mac OS X (Darwin Kernel Version 10.4.0) java version "1.6.0_20"
Java(TM) SE Runtime Environment (build 1.6.0_20-b02)
Java HotSpot(TM) 64-Bit Server VM (build 16.3-b01, mixed mode)
Passed James Carman
Mac OS X (Darwin Kernel Version 10.4.0) java version "1.5.0_24"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_24-b02-357-10M3065)
Java HotSpot(TM) Client VM (build 1.5.0_24-149, mixed mode, sharing)
Passed Simon Tripodi
Operating System JVM Status Reporter
Windows 7 Professional 64 bit java version "1.6.0_20"
Java(TM) SE Runtime Environment (build 1.6.0_20-b02)
Java HotSpot(TM) 64-Bit Server VM (build 16.3-b01, mixed mode)
Passed James Carman
Windows 7 Enterprise java version "1.6.0_21" Passed Niall Pemberton
Windows 7 Enterprise java version "1.5.0_22-b03" Passed Niall Pemberton
Windows 7 Enterprise java version "1.4.2_19-b04" Passed Niall Pemberton
Windows 7 Enterprise java version "1.3.1_18-b01" Passed Niall Pemberton
Windows Vista Business java version "1.6.0_21"
Java(TM) SE Runtime Environment (build 1.6.0_21-b07)
Java HotSpot(TM) 64-Bit Server VM (build 17.0-b17, mixed mode)
Passed Gary Gregory
Operating System JVM Status Reporter
OpenVMS V8.3 (AlphaServer ES40 - 4 CPUs) Fast VM (build 1.5.0-4, build J2SDK.v.1.5.0:03/31/2008-15:26, native threads, jit_150) Fails tests which try to terminate a subprocess
  • DefaultExecutorTest#testExecuteAsyncWithTimelyUserTermination
  • DefaultExecutorTest#testExecuteAsyncWithTooLateUserTermination
  • DefaultExecutorTest#testExecuteWatchdogSync - test hangs
  • DefaultExecutorTest#testExecuteWatchdogAsync
  • DefaultExecutorTest#testExecuteAsyncWithProcessDestroyer
  • DefaultExecutorTest#testExec41WithoutStreams
Sebastian Bazley
OpenVMS V8.3-1H1 (Integrity HP rx2600 (1.30GHz/3.0MB) - 2 CPUs) Java HotSpot(TM) Server VM (build 1.5.0-2 12/02/2006-21:30 IA64, mixed mode) Fails tests which try to terminate a subprocess
  • DefaultExecutorTest#testExecuteAsyncWithTimelyUserTermination
  • DefaultExecutorTest#testExecuteAsyncWithTooLateUserTermination
  • DefaultExecutorTest#testExecuteWatchdogSync - test hangs
  • DefaultExecutorTest#testExecuteWatchdogAsync
  • DefaultExecutorTest#testExecuteAsyncWithProcessDestroyer
  • DefaultExecutorTest#testExec41WithoutStreams
Sebastian Bazley
commons-exec-1.3-src/src/test/bin/testme.bat100644 0 0 2012 12425540623 16173 0ustar 0 0 @ECHO OFF REM REM Licensed to the Apache Software Foundation (ASF) under one or more REM contributor license agreements. See the NOTICE file distributed with REM this work for additional information regarding copyright ownership. REM The ASF licenses this file to You under the Apache License, Version 2.0 REM (the "License"); you may not use this file except in compliance with REM the License. You may obtain a copy of the License at REM REM http://www.apache.org/licenses/LICENSE-2.0 REM REM Unless required by applicable law or agreed to in writing, software REM distributed under the License is distributed on an "AS IS" BASIS, REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. REM See the License for the specific language governing permissions and REM limitations under the License. REM mkdir target "%JAVA_HOME%\bin\java" -cp .\lib\junit-3.8.1.jar;.\lib\commons-exec-${project.version}-tests.jar;.\lib\commons-exec-${project.version}.jar org.apache.commons.exec.TestRunnercommons-exec-1.3-src/src/test/bin/testme.dcl100644 0 0 2347 12425540623 16202 0ustar 0 0 $!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! $! $! Licensed to the Apache Software Foundation (ASF) under one or more $! contributor license agreements. See the NOTICE file distributed with $! this work for additional information regarding copyright ownership. $! The ASF licenses this file to You under the Apache License, Version 2.0 $! (the "License"); you may not use this file except in compliance with $! the License. You may obtain a copy of the License at $! $! http://www.apache.org/licenses/LICENSE-2.0 $! $! Unless required by applicable law or agreed to in writing, software $! distributed under the License is distributed on an "AS IS" BASIS, $! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. $! See the License for the specific language governing permissions and $! limitations under the License. $! $!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! $! $! Run the test suite $! $ create/directory [.target] $ java "-Dorg.apache.commons.exec.lenient=false" "-Dorg.apache.commons.exec.debug=false" - -cp "./lib/junit-3.8.1.jar:./lib/commons-exec-${project.version}-tests.jar:./lib/commons-exec-${project.version}.jar" - "org.apache.commons.exec.TestRunner"commons-exec-1.3-src/src/test/bin/testme.sh100644 0 0 2106 12425540623 16043 0ustar 0 0 #!/bin/sh # # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # chmod ug+x ./src/test/scripts/*.sh mkdir target $JAVA_HOME/bin/java -Dorg.apache.commons.exec.lenient=false -Dorg.apache.commons.exec.debug=false -cp ./lib/junit-3.8.1.jar:./lib/commons-exec-${project.version}-tests.jar:./lib/commons-exec-${project.version}.jar org.apache.commons.exec.TestRunnercommons-exec-1.3-src/src/test/java/org/apache/commons/exec/CommandLineTest.java100644 0 0 51352 12425540623 24706 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.commons.exec; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.File; import java.util.HashMap; import java.util.Map; import org.apache.commons.exec.util.StringUtils; import org.junit.Test; /** * @version $Id: CommandLineTest.java 1636048 2014-11-01 20:55:54Z ggregory $ */ public class CommandLineTest { @Test public void testExecutable() { final CommandLine cmdl = new CommandLine("test"); assertEquals("[test]", cmdl.toString()); assertArrayEquals(new String[]{"test"}, cmdl.toStrings()); assertEquals("test", cmdl.getExecutable()); assertTrue(cmdl.getArguments().length == 0); } @Test public void testExecutableZeroLengthString() { try { new CommandLine(""); fail("Must throw IllegalArgumentException"); } catch (final IllegalArgumentException e) { // Expected } } @Test public void testExecutableWhitespaceString() { try { new CommandLine(" "); fail("Must throw IllegalArgumentException"); } catch (final IllegalArgumentException e) { // Expected } } @Test public void testNullExecutable() { try { new CommandLine((String)null); fail("Must throw IllegalArgumentException"); } catch (final IllegalArgumentException e) { // Expected } } @Test public void testAddArgument() { final CommandLine cmdl = new CommandLine("test"); cmdl.addArgument("foo"); cmdl.addArgument("bar"); assertEquals("[test, foo, bar]", cmdl.toString()); assertArrayEquals(new String[]{"test", "foo", "bar"}, cmdl.toStrings()); } @Test public void testAddNullArgument() { final CommandLine cmdl = new CommandLine("test"); cmdl.addArgument(null); assertEquals("[test]", cmdl.toString()); assertArrayEquals(new String[]{"test"}, cmdl.toStrings()); } @Test public void testAddArgumentWithSpace() { final CommandLine cmdl = new CommandLine("test"); cmdl.addArgument("foo"); cmdl.addArgument("ba r"); assertEquals("[test, foo, \"ba r\"]", cmdl.toString()); assertArrayEquals(new String[]{"test", "foo", "\"ba r\""}, cmdl.toStrings()); } @Test public void testAddArgumentWithQuote() { final CommandLine cmdl = new CommandLine("test"); cmdl.addArgument("foo"); cmdl.addArgument("ba\"r"); assertEquals("[test, foo, 'ba\"r']", cmdl.toString()); assertArrayEquals(new String[]{"test", "foo", "'ba\"r'"}, cmdl.toStrings()); } @Test public void testAddArgumentWithQuotesAround() { final CommandLine cmdl = new CommandLine("test"); cmdl.addArgument("\'foo\'"); cmdl.addArgument("\"bar\""); cmdl.addArgument("\"fe z\""); assertEquals("[test, foo, bar, \"fe z\"]", cmdl.toString()); assertArrayEquals(new String[]{"test", "foo", "bar", "\"fe z\""}, cmdl.toStrings()); } @Test public void testAddArgumentWithSingleQuote() { final CommandLine cmdl = new CommandLine("test"); cmdl.addArgument("foo"); cmdl.addArgument("ba'r"); assertEquals("[test, foo, \"ba'r\"]", cmdl.toString()); assertArrayEquals(new String[]{"test", "foo", "\"ba\'r\""}, cmdl .toStrings()); } @Test public void testAddArgumentWithBothQuotes() { final CommandLine cmdl = new CommandLine("test"); try { cmdl.addArgument("b\"a'r"); fail("IllegalArgumentException should be thrown"); } catch (final IllegalArgumentException e) { // OK, expected } } @Test public void testAddArguments() { final CommandLine cmdl = new CommandLine("test"); cmdl.addArguments("foo bar"); assertEquals("[test, foo, bar]", cmdl.toString()); assertArrayEquals(new String[]{"test", "foo", "bar"}, cmdl.toStrings()); } @Test public void testAddArgumentsWithQuotes() { final CommandLine cmdl = new CommandLine("test"); cmdl.addArguments("'foo' \"bar\""); assertEquals("[test, foo, bar]", cmdl.toString()); assertArrayEquals(new String[]{"test", "foo", "bar"}, cmdl.toStrings()); } @Test public void testAddArgumentsWithQuotesAndSpaces() { final CommandLine cmdl = new CommandLine("test"); cmdl.addArguments("'fo o' \"ba r\""); assertEquals("[test, \"fo o\", \"ba r\"]", cmdl.toString()); assertArrayEquals(new String[]{"test", "\"fo o\"", "\"ba r\""}, cmdl .toStrings()); } @Test public void testAddArgumentsArray() { final CommandLine cmdl = new CommandLine("test"); cmdl.addArguments(new String[] {"foo", "bar"}); assertEquals("[test, foo, bar]", cmdl.toString()); assertArrayEquals(new String[]{"test", "foo", "bar"}, cmdl.toStrings()); } @Test public void testAddArgumentsArrayNull() { final CommandLine cmdl = new CommandLine("test"); cmdl.addArguments((String[]) null); assertEquals("[test]", cmdl.toString()); assertArrayEquals(new String[]{"test"}, cmdl.toStrings()); } /** * A little example how to add two command line arguments * in one line, e.g. to make commenting out some options * less error prone. */ @Test public void testAddTwoArguments() { final CommandLine userAddCL1 = new CommandLine("useradd"); userAddCL1.addArgument("-g"); userAddCL1.addArgument("tomcat"); userAddCL1.addArgument("foo"); final CommandLine userAddCL2 = new CommandLine("useradd"); userAddCL2.addArgument("-g").addArgument("tomcat"); userAddCL2.addArgument("foo"); assertEquals(userAddCL1.toString(), userAddCL2.toString()); } @Test public void testParseCommandLine() { final CommandLine cmdl = CommandLine.parse("test foo bar"); assertEquals("[test, foo, bar]", cmdl.toString()); assertArrayEquals(new String[]{"test", "foo", "bar"}, cmdl.toStrings()); } @Test public void testParseCommandLineWithQuotes() { final CommandLine cmdl = CommandLine.parse("test \"foo\" \'ba r\'"); assertEquals("[test, foo, \"ba r\"]", cmdl.toString()); assertArrayEquals(new String[]{"test", "foo", "\"ba r\""}, cmdl.toStrings()); } @Test public void testParseCommandLineWithUnevenQuotes() { try { CommandLine.parse("test \"foo bar"); fail("IllegalArgumentException must be thrown due to uneven quotes"); } catch (final IllegalArgumentException e) { // Expected } } @Test public void testParseCommandLineWithNull() { try { CommandLine.parse(null); fail("IllegalArgumentException must be thrown due to incorrect command line"); } catch (final IllegalArgumentException e) { // Expected } } @Test public void testParseCommandLineWithOnlyWhitespace() { try { CommandLine.parse(" "); fail("IllegalArgumentException must be thrown due to incorrect command line"); } catch (final IllegalArgumentException e) { // Expected } } /** * A command line parsing puzzle from Tino Schoellhorn - ImageMagix expects * a "500x>" parameter (including quotes) and it is simply not possible to * do that without adding a space, e.g. "500x> ". */ @Test public void testParseComplexCommandLine1() { final HashMap substitutionMap = new HashMap(); substitutionMap.put("in", "source.jpg"); substitutionMap.put("out", "target.jpg"); final CommandLine cmdl = CommandLine.parse("cmd /C convert ${in} -resize \"\'500x> \'\" ${out}", substitutionMap); assertEquals("[cmd, /C, convert, source.jpg, -resize, \"500x> \", target.jpg]", cmdl.toString()); } /** * Another command line parsing puzzle from Kai Hu - as * far as I understand it there is no way to express that * in a one-line command string. */ @Test public void testParseComplexCommandLine2() { final String commandline = "./script/jrake cruise:publish_installers " + "INSTALLER_VERSION=unstable_2_1 " + "INSTALLER_PATH=\"/var/lib/ cruise-agent/installers\" " + "INSTALLER_DOWNLOAD_SERVER=\'something\' " + "WITHOUT_HELP_DOC=true"; final CommandLine cmdl = CommandLine.parse(commandline); final String[] args = cmdl.getArguments(); assertEquals(args[0], "cruise:publish_installers"); assertEquals(args[1], "INSTALLER_VERSION=unstable_2_1"); // assertEquals(args[2], "INSTALLER_PATH=\"/var/lib/ cruise-agent/installers\""); // assertEquals(args[3], "INSTALLER_DOWNLOAD_SERVER='something'"); assertEquals(args[4], "WITHOUT_HELP_DOC=true"); } /** * Test the following command line * * cmd.exe /C c:\was51\Web Sphere\AppServer\bin\versionInfo.bat */ @Test public void testParseRealLifeCommandLine_1() { final String commandline = "cmd.exe /C \"c:\\was51\\Web Sphere\\AppServer\\bin\\versionInfo.bat\""; final CommandLine cmdl = CommandLine.parse(commandline); final String[] args = cmdl.getArguments(); assertEquals("/C", args[0]); assertEquals("\"c:\\was51\\Web Sphere\\AppServer\\bin\\versionInfo.bat\"", args[1]); } /** * Create a command line with pre-quoted strings to test SANDBOX-192, * e.g. "runMemorySud.cmd", "10", "30", "-XX:+UseParallelGC", "\"-XX:ParallelGCThreads=2\"" */ @Test public void testComplexAddArgument() { final CommandLine cmdl = new CommandLine("runMemorySud.cmd"); cmdl.addArgument("10", false); cmdl.addArgument("30", false); cmdl.addArgument("-XX:+UseParallelGC", false); cmdl.addArgument("\"-XX:ParallelGCThreads=2\"", false); assertArrayEquals(new String[]{"runMemorySud.cmd", "10", "30", "-XX:+UseParallelGC", "\"-XX:ParallelGCThreads=2\""}, cmdl.toStrings()); } /** * Create a command line with pre-quoted strings to test SANDBOX-192, * e.g. "runMemorySud.cmd", "10", "30", "-XX:+UseParallelGC", "\"-XX:ParallelGCThreads=2\"" */ @Test public void testComplexAddArguments1() { final CommandLine cmdl = new CommandLine("runMemorySud.cmd"); cmdl.addArguments(new String[] {"10", "30", "-XX:+UseParallelGC", "\"-XX:ParallelGCThreads=2\""}, false); assertArrayEquals(new String[]{"runMemorySud.cmd", "10", "30", "-XX:+UseParallelGC", "\"-XX:ParallelGCThreads=2\""}, cmdl.toStrings()); } /** * Create a command line with pre-quoted strings to test SANDBOX-192, * e.g. "runMemorySud.cmd", "10", "30", "-XX:+UseParallelGC", "\"-XX:ParallelGCThreads=2\"" * Please not that we re forced to add additional single quotes to get the test working - * don't know if this is a bug or a feature. */ @Test public void testComplexAddArguments2() { final CommandLine cmdl = new CommandLine("runMemorySud.cmd"); cmdl.addArguments("10 30 -XX:+UseParallelGC '\"-XX:ParallelGCThreads=2\"'", false); assertArrayEquals(new String[]{"runMemorySud.cmd", "10", "30", "-XX:+UseParallelGC", "\"-XX:ParallelGCThreads=2\""}, cmdl.toStrings()); } /** * Test expanding the command line based on a user-supplied map. */ @Test public void testCommandLineParsingWithExpansion1() { CommandLine cmdl; final HashMap substitutionMap = new HashMap(); substitutionMap.put("JAVA_HOME", "/usr/local/java"); substitutionMap.put("appMainClass", "foo.bar.Main"); substitutionMap.put("file1", new File("./pom.xml")); substitutionMap.put("file2", new File(".\\temp\\READ ME.txt")); final HashMap incompleteMap = new HashMap(); incompleteMap.put("JAVA_HOME", "/usr/local/java"); // do not pass substitution map cmdl = CommandLine.parse("${JAVA_HOME}/bin/java ${appMainClass}"); assertTrue(cmdl.getExecutable().indexOf("${JAVA_HOME}") == 0 ); assertArrayEquals(new String[]{"${appMainClass}"}, cmdl.getArguments()); // pass arguments with an empty map cmdl = CommandLine.parse("${JAVA_HOME}/bin/java ${appMainClass}", new HashMap()); assertTrue(cmdl.getExecutable().indexOf("${JAVA_HOME}") == 0 ); assertArrayEquals(new String[]{"${appMainClass}"}, cmdl.getArguments()); // pass an complete substitution map cmdl = CommandLine.parse("${JAVA_HOME}/bin/java ${appMainClass}", substitutionMap); assertTrue(cmdl.getExecutable().indexOf("${JAVA_HOME}") < 0 ); assertTrue(cmdl.getExecutable().indexOf("local") > 0 ); assertArrayEquals(new String[]{"foo.bar.Main"}, cmdl.getArguments()); // pass an incomplete substitution map resulting in unresolved variables cmdl = CommandLine.parse("${JAVA_HOME}/bin/java ${appMainClass}", incompleteMap); assertTrue(cmdl.getExecutable().indexOf("${JAVA_HOME}") < 0 ); assertTrue(cmdl.getExecutable().indexOf("local") > 0 ); assertArrayEquals(new String[]{"${appMainClass}"}, cmdl.getArguments()); // pass a file cmdl = CommandLine.parse("${JAVA_HOME}/bin/java ${appMainClass} ${file1} ${file2}", substitutionMap); assertTrue(cmdl.getExecutable().indexOf("${file}") < 0 ); } /** * Test expanding the command line based on a user-supplied map. The main * goal of the test is to setup a command line using macros and reuse * it multiple times. */ @Test public void testCommandLineParsingWithExpansion2() { CommandLine cmdl; String[] result; // build the user supplied parameters final HashMap substitutionMap = new HashMap(); substitutionMap.put("JAVA_HOME", "C:\\Programme\\jdk1.5.0_12"); substitutionMap.put("appMainClass", "foo.bar.Main"); // build the command line cmdl = new CommandLine("${JAVA_HOME}\\bin\\java"); cmdl.addArgument("-class"); cmdl.addArgument("${appMainClass}"); cmdl.addArgument("${file}"); // build the first command line substitutionMap.put("file", "C:\\Document And Settings\\documents\\432431.pdf"); cmdl.setSubstitutionMap(substitutionMap); result = cmdl.toStrings(); // verify the first command line // please note - the executable argument is changed to using platform specific file separator char // whereas all other variable substitution are not touched assertEquals(StringUtils.fixFileSeparatorChar("C:\\Programme\\jdk1.5.0_12\\bin\\java"), result[0]); assertEquals("-class", result[1]); assertEquals("foo.bar.Main", result[2]); assertEquals("\"C:\\Document And Settings\\documents\\432431.pdf\"", result[3]); // verify the first command line again but by // accessing the executable and arguments directly final String executable = cmdl.getExecutable(); final String[] arguments = cmdl.getArguments(); assertEquals(StringUtils.fixFileSeparatorChar("C:\\Programme\\jdk1.5.0_12\\bin\\java"), executable); assertEquals("-class", arguments[0]); assertEquals("foo.bar.Main", arguments[1]); assertEquals("\"C:\\Document And Settings\\documents\\432431.pdf\"", arguments[2]); // build the second command line with updated parameters resulting in a different command line substitutionMap.put("file", "C:\\Document And Settings\\documents\\432432.pdf"); result = cmdl.toStrings(); assertEquals(StringUtils.fixFileSeparatorChar("C:\\Programme\\jdk1.5.0_12\\bin\\java"), result[0]); assertEquals("-class", result[1]); assertEquals("foo.bar.Main", result[2]); assertEquals("\"C:\\Document And Settings\\documents\\432432.pdf\"", result[3]); } @Test public void testCommandLineParsingWithExpansion3() { final CommandLine cmdl = CommandLine.parse("AcroRd32.exe"); cmdl.addArgument("/p"); cmdl.addArgument("/h"); cmdl.addArgument("${file}", false); final HashMap params = new HashMap(); params.put("file", "C:\\Document And Settings\\documents\\432432.pdf"); cmdl.setSubstitutionMap(params); final String[] result = cmdl.toStrings(); assertEquals("AcroRd32.exe", result[0]); assertEquals("/p", result[1]); assertEquals("/h", result[2]); assertEquals("C:\\Document And Settings\\documents\\432432.pdf", result[3]); } /** * Test the toString() method. * * @throws Exception the test failed */ @Test public void testToString() throws Exception { CommandLine cmdl; final HashMap params = new HashMap(); // use no arguments cmdl = CommandLine.parse("AcroRd32.exe", params); assertEquals("[AcroRd32.exe]", cmdl.toString()); // use an argument containing spaces params.put("file", "C:\\Document And Settings\\documents\\432432.pdf"); cmdl = CommandLine.parse("AcroRd32.exe /p /h '${file}'", params); assertEquals("[AcroRd32.exe, /p, /h, \"C:\\Document And Settings\\documents\\432432.pdf\"]", cmdl.toString()); // use an argument without spaces params.put("file", "C:\\documents\\432432.pdf"); cmdl = CommandLine.parse("AcroRd32.exe /p /h '${file}'", params); assertEquals("[AcroRd32.exe, /p, /h, C:\\documents\\432432.pdf]", cmdl.toString()); } /** * Test that toString() produces output that is useful for troubleshooting. * * @throws Exception the test failed */ @Test public void testToStringTroubleshooting() throws Exception { System.out.println("testToStringTroubleshooting"); // On HP-UX quotes handling leads to errors, // also usage of quotes isn't mandatory on other platforms too // so it probably should work correctly either way. final CommandLine cmd1 = new CommandLine("sh").addArgument("-c") .addArgument("echo 1", false); final CommandLine cmd2 = new CommandLine("sh").addArgument("-c") .addArgument("echo").addArgument("1"); System.out.println("cmd1: " + cmd1.toString()); System.out.println("cmd2: " + cmd2.toString()); assertTrue("toString() is useful for troubleshooting", !cmd1.toString().equals(cmd2.toString())); } @Test public void testCopyConstructor() { final Map map = new HashMap(); map.put("bar", "bar"); final CommandLine other = new CommandLine("test"); other.addArgument("foo"); other.setSubstitutionMap(map); final CommandLine cmdl = new CommandLine(other); assertEquals(other.getExecutable(), cmdl.getExecutable()); assertArrayEquals(other.getArguments(), cmdl.getArguments()); assertEquals(other.isFile(), cmdl.isFile()); assertEquals(other.getSubstitutionMap(), cmdl.getSubstitutionMap()); } } commons-exec-1.3-src/src/test/java/org/apache/commons/exec/DefaultExecutorTest.java100644 0 0 75123 12425540622 25624 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.commons.exec; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FileReader; import java.io.IOException; import java.util.HashMap; import java.util.Map; import org.apache.commons.exec.environment.EnvironmentUtils; import org.junit.After; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Ignore; import org.junit.Test; /** * @version $Id: DefaultExecutorTest.java 1636057 2014-11-01 21:14:00Z ggregory $ */ public class DefaultExecutorTest { /** Maximum time to wait (15s) */ private static final int WAITFOR_TIMEOUT = 15000; private final Executor exec = new DefaultExecutor(); private final File testDir = new File("src/test/scripts"); private final File foreverOutputFile = new File("./target/forever.txt"); private ByteArrayOutputStream baos; private final File testScript = TestUtil.resolveScriptForOS(testDir + "/test"); private final File errorTestScript = TestUtil.resolveScriptForOS(testDir + "/error"); private final File foreverTestScript = TestUtil.resolveScriptForOS(testDir + "/forever"); private final File nonExistingTestScript = TestUtil.resolveScriptForOS(testDir + "/grmpffffff"); private final File redirectScript = TestUtil.resolveScriptForOS(testDir + "/redirect"); private final File printArgsScript = TestUtil.resolveScriptForOS(testDir + "/printargs"); // private final File acroRd32Script = TestUtil.resolveScriptForOS(testDir + "/acrord32"); private final File stdinSript = TestUtil.resolveScriptForOS(testDir + "/stdin"); private final File environmentSript = TestUtil.resolveScriptForOS(testDir + "/environment"); // private final File wrapperScript = TestUtil.resolveScriptForOS(testDir + "/wrapper"); // Get suitable exit codes for the OS private static int SUCCESS_STATUS; // test script successful exit code private static int ERROR_STATUS; // test script error exit code @BeforeClass public static void classSetUp() { final int statuses[] = TestUtil.getTestScriptCodesForOS(); SUCCESS_STATUS=statuses[0]; ERROR_STATUS=statuses[1]; // turn on debug mode and throw an exception for each encountered problem System.setProperty("org.apache.commons.exec.lenient", "false"); System.setProperty("org.apache.commons.exec.debug", "true"); } @Before public void setUp() throws Exception { // delete the marker file this.foreverOutputFile.getParentFile().mkdirs(); if (this.foreverOutputFile.exists()) { this.foreverOutputFile.delete(); } // prepare a ready to Executor this.baos = new ByteArrayOutputStream(); this.exec.setStreamHandler(new PumpStreamHandler(baos, baos)); } @After public void tearDown() throws Exception { this.baos.close(); foreverOutputFile.delete(); } // ====================================================================== // Start of regression tests // ====================================================================== /** * The simplest possible test - start a script and * check that the output was pumped into our * {@code ByteArrayOutputStream}. * * @throws Exception the test failed */ @Test public void testExecute() throws Exception { final CommandLine cl = new CommandLine(testScript); final int exitValue = exec.execute(cl); assertEquals("FOO..", baos.toString().trim()); assertFalse(exec.isFailure(exitValue)); assertEquals(new File("."), exec.getWorkingDirectory()); } @Test public void testExecuteWithWorkingDirectory() throws Exception { final File workingDir = new File("./target"); final CommandLine cl = new CommandLine(testScript); exec.setWorkingDirectory(workingDir); final int exitValue = exec.execute(cl); assertEquals("FOO..", baos.toString().trim()); assertFalse(exec.isFailure(exitValue)); assertEquals(exec.getWorkingDirectory(), workingDir); } @Test(expected = IOException.class) public void testExecuteWithInvalidWorkingDirectory() throws Exception { final File workingDir = new File("/foo/bar"); final CommandLine cl = new CommandLine(testScript); exec.setWorkingDirectory(workingDir); exec.execute(cl); } @Test public void testExecuteWithError() throws Exception { final CommandLine cl = new CommandLine(errorTestScript); try{ exec.execute(cl); fail("Must throw ExecuteException"); } catch (final ExecuteException e) { assertTrue(exec.isFailure(e.getExitValue())); } } @Test public void testExecuteWithArg() throws Exception { final CommandLine cl = new CommandLine(testScript); cl.addArgument("BAR"); final int exitValue = exec.execute(cl); assertEquals("FOO..BAR", baos.toString().trim()); assertFalse(exec.isFailure(exitValue)); } /** * Execute the test script and pass a environment containing * 'TEST_ENV_VAR'. */ @Test public void testExecuteWithSingleEnvironmentVariable() throws Exception { final Map env = new HashMap(); env.put("TEST_ENV_VAR", "XYZ"); final CommandLine cl = new CommandLine(testScript); final int exitValue = exec.execute(cl, env); assertEquals("FOO.XYZ.", baos.toString().trim()); assertFalse(exec.isFailure(exitValue)); } /** * Start a asynchronous process which returns an success * exit value. * * @throws Exception the test failed */ @Test public void testExecuteAsync() throws Exception { final CommandLine cl = new CommandLine(testScript); final DefaultExecuteResultHandler resultHandler = new DefaultExecuteResultHandler(); exec.execute(cl, resultHandler); resultHandler.waitFor(2000); assertTrue(resultHandler.hasResult()); assertNull(resultHandler.getException()); assertFalse(exec.isFailure(resultHandler.getExitValue())); assertEquals("FOO..", baos.toString().trim()); } /** * Start a asynchronous process which returns an error * exit value. * * @throws Exception the test failed */ @Test public void testExecuteAsyncWithError() throws Exception { final CommandLine cl = new CommandLine(errorTestScript); final DefaultExecuteResultHandler resultHandler = new DefaultExecuteResultHandler(); exec.execute(cl, resultHandler); resultHandler.waitFor(2000); assertTrue(resultHandler.hasResult()); assertTrue(exec.isFailure(resultHandler.getExitValue())); assertNotNull(resultHandler.getException()); assertEquals("FOO..", baos.toString().trim()); } /** * Start a asynchronous process and terminate it manually before the * watchdog timeout occurs. * * @throws Exception the test failed */ @Test public void testExecuteAsyncWithTimelyUserTermination() throws Exception { final CommandLine cl = new CommandLine(foreverTestScript); final ExecuteWatchdog watchdog = new ExecuteWatchdog(Integer.MAX_VALUE); exec.setWatchdog(watchdog); final DefaultExecuteResultHandler handler = new DefaultExecuteResultHandler(); exec.execute(cl, handler); // wait for script to run Thread.sleep(2000); assertTrue("Watchdog should watch the process", watchdog.isWatching()); // terminate it manually using the watchdog watchdog.destroyProcess(); // wait until the result of the process execution is propagated handler.waitFor(WAITFOR_TIMEOUT); assertTrue("Watchdog should have killed the process", watchdog.killedProcess()); assertFalse("Watchdog is no longer watching the process", watchdog.isWatching()); assertTrue("ResultHandler received a result", handler.hasResult()); assertNotNull("ResultHandler received an exception as result", handler.getException()); } /** * Start a asynchronous process and try to terminate it manually but * the process was already terminated by the watchdog. This is * basically a race condition between infrastructure and user * code. * * @throws Exception the test failed */ @Test public void testExecuteAsyncWithTooLateUserTermination() throws Exception { final CommandLine cl = new CommandLine(foreverTestScript); final DefaultExecuteResultHandler handler = new DefaultExecuteResultHandler(); final ExecuteWatchdog watchdog = new ExecuteWatchdog(3000); exec.setWatchdog(watchdog); exec.execute(cl, handler); // wait for script to be terminated by the watchdog Thread.sleep(6000); // try to terminate the already terminated process watchdog.destroyProcess(); // wait until the result of the process execution is propagated handler.waitFor(WAITFOR_TIMEOUT); assertTrue("Watchdog should have killed the process already", watchdog.killedProcess()); assertFalse("Watchdog is no longer watching the process", watchdog.isWatching()); assertTrue("ResultHandler received a result", handler.hasResult()); assertNotNull("ResultHandler received an exception as result", handler.getException()); } /** * Start a script looping forever (synchronously) and check if the ExecuteWatchdog * kicks in killing the run away process. To make killing a process * more testable the "forever" scripts write each second a '.' * into "./target/forever.txt" (a marker file). After a test run * we should have a few dots in there. * * @throws Exception the test failed */ @Test public void testExecuteWatchdogSync() throws Exception { if (OS.isFamilyOpenVms()) { System.out.println("The test 'testExecuteWatchdogSync' currently hangs on the following OS : " + System.getProperty("os.name")); return; } final long timeout = 10000; final CommandLine cl = new CommandLine(foreverTestScript); final DefaultExecutor executor = new DefaultExecutor(); executor.setWorkingDirectory(new File(".")); final ExecuteWatchdog watchdog = new ExecuteWatchdog(timeout); executor.setWatchdog(watchdog); try { executor.execute(cl); } catch (final ExecuteException e) { Thread.sleep(timeout); final int nrOfInvocations = getOccurrences(readFile(this.foreverOutputFile), '.'); assertTrue(executor.getWatchdog().killedProcess()); assertTrue("killing the subprocess did not work : " + nrOfInvocations, nrOfInvocations > 5 && nrOfInvocations <= 11); return; } catch (final Throwable t) { fail(t.getMessage()); } assertTrue("Killed process should be true", executor.getWatchdog().killedProcess() ); fail("Process did not create ExecuteException when killed"); } /** * Start a script looping forever (asynchronously) and check if the * ExecuteWatchdog kicks in killing the run away process. To make killing * a process more testable the "forever" scripts write each second a '.' * into "./target/forever.txt" (a marker file). After a test run * we should have a few dots in there. * * @throws Exception the test failed */ @Test public void testExecuteWatchdogAsync() throws Exception { final long timeout = 10000; final CommandLine cl = new CommandLine(foreverTestScript); final DefaultExecuteResultHandler handler = new DefaultExecuteResultHandler(); final DefaultExecutor executor = new DefaultExecutor(); executor.setWorkingDirectory(new File(".")); executor.setWatchdog(new ExecuteWatchdog(timeout)); executor.execute(cl, handler); handler.waitFor(WAITFOR_TIMEOUT); assertTrue("Killed process should be true", executor.getWatchdog().killedProcess() ); assertTrue("ResultHandler received a result", handler.hasResult()); assertNotNull("ResultHandler received an exception as result", handler.getException()); final int nrOfInvocations = getOccurrences(readFile(this.foreverOutputFile), '.'); assertTrue("Killing the process did not work : " + nrOfInvocations, nrOfInvocations > 5 && nrOfInvocations <= 11); } /** * [EXEC-68] Synchronously starts a short script with a Watchdog attached with an extremely large timeout. Checks * to see if the script terminated naturally or if it was killed by the Watchdog. Fail if killed by Watchdog. * * @throws Exception * the test failed */ @Test public void testExecuteWatchdogVeryLongTimeout() throws Exception { final long timeout = Long.MAX_VALUE; final CommandLine cl = new CommandLine(testScript); final DefaultExecutor executor = new DefaultExecutor(); executor.setWorkingDirectory(new File(".")); final ExecuteWatchdog watchdog = new ExecuteWatchdog(timeout); executor.setWatchdog(watchdog); try { executor.execute(cl); } catch (final ExecuteException e) { assertFalse("Process should exit normally, not be killed by watchdog", watchdog.killedProcess()); // If the Watchdog did not kill it, something else went wrong. throw e; } } /** * Try to start an non-existing application which should result * in an exception. * * @throws Exception the test failed */ @Test(expected = IOException.class) public void testExecuteNonExistingApplication() throws Exception { final CommandLine cl = new CommandLine(nonExistingTestScript); final DefaultExecutor executor = new DefaultExecutor(); executor.execute(cl); } /** * Try to start an non-existing application asynchronously which should result * in an exception. * * @throws Exception the test failed */ @Test public void testExecuteAsyncWithNonExistingApplication() throws Exception { final CommandLine cl = new CommandLine(nonExistingTestScript); final DefaultExecuteResultHandler handler = new DefaultExecuteResultHandler(); exec.execute(cl, handler); Thread.sleep(2000); assertNotNull(handler.getException()); assertTrue(exec.isFailure(handler.getExitValue())); } /** * Invoke the error script but define that the ERROR_STATUS is a good * exit value and therefore no exception should be thrown. * * @throws Exception the test failed */ @Test public void testExecuteWithCustomExitValue1() throws Exception { exec.setExitValue(ERROR_STATUS); final CommandLine cl = new CommandLine(errorTestScript); exec.execute(cl); } /** * Invoke the error script but define that SUCCESS_STATUS is a bad * exit value and therefore an exception should be thrown. * * @throws Exception the test failed */ @Test public void testExecuteWithCustomExitValue2() throws Exception { final CommandLine cl = new CommandLine(errorTestScript); exec.setExitValue(SUCCESS_STATUS); try{ exec.execute(cl); fail("Must throw ExecuteException"); } catch (final ExecuteException e) { assertTrue(exec.isFailure(e.getExitValue())); } } /** * Test the proper handling of ProcessDestroyer for an synchronous process. * * @throws Exception the test failed */ @Test public void testExecuteWithProcessDestroyer() throws Exception { final CommandLine cl = new CommandLine(testScript); final ShutdownHookProcessDestroyer processDestroyer = new ShutdownHookProcessDestroyer(); exec.setProcessDestroyer(processDestroyer); assertTrue(processDestroyer.size() == 0); assertTrue(processDestroyer.isAddedAsShutdownHook() == false); final int exitValue = exec.execute(cl); assertEquals("FOO..", baos.toString().trim()); assertFalse(exec.isFailure(exitValue)); assertTrue(processDestroyer.size() == 0); assertTrue(processDestroyer.isAddedAsShutdownHook() == false); } /** * Test the proper handling of ProcessDestroyer for an asynchronous process. * Since we do not terminate the process it will be terminated in the * ShutdownHookProcessDestroyer implementation. * * @throws Exception the test failed */ @Test public void testExecuteAsyncWithProcessDestroyer() throws Exception { final CommandLine cl = new CommandLine(foreverTestScript); final DefaultExecuteResultHandler handler = new DefaultExecuteResultHandler(); final ShutdownHookProcessDestroyer processDestroyer = new ShutdownHookProcessDestroyer(); final ExecuteWatchdog watchdog = new ExecuteWatchdog(Integer.MAX_VALUE); assertTrue(exec.getProcessDestroyer() == null); assertTrue(processDestroyer.size() == 0); assertTrue(processDestroyer.isAddedAsShutdownHook() == false); exec.setWatchdog(watchdog); exec.setProcessDestroyer(processDestroyer); exec.execute(cl, handler); // wait for script to start Thread.sleep(2000); // our process destroyer should be initialized now assertNotNull("Process destroyer should exist", exec.getProcessDestroyer()); assertEquals("Process destroyer size should be 1", 1, processDestroyer.size()); assertTrue("Process destroyer should exist as shutdown hook", processDestroyer.isAddedAsShutdownHook()); // terminate it and the process destroyer is detached watchdog.destroyProcess(); assertTrue(watchdog.killedProcess()); handler.waitFor(WAITFOR_TIMEOUT); assertTrue("ResultHandler received a result", handler.hasResult()); assertNotNull(handler.getException()); assertEquals("Processor Destroyer size should be 0", 0, processDestroyer.size()); assertFalse("Process destroyer should not exist as shutdown hook", processDestroyer.isAddedAsShutdownHook()); } /** * Invoke the test using some fancy arguments. * * @throws Exception the test failed */ @Test public void testExecuteWithFancyArg() throws Exception { final CommandLine cl = new CommandLine(testScript); cl.addArgument("test $;`(0)[1]{2}"); final int exitValue = exec.execute(cl); assertTrue(baos.toString().trim().indexOf("test $;`(0)[1]{2}") > 0); assertFalse(exec.isFailure(exitValue)); } /** * Start a process with redirected streams - stdin of the newly * created process is connected to a FileInputStream whereas * the "redirect" script reads all lines from stdin and prints * them on stdout. Furthermore the script prints a status * message on stderr. * * @throws Exception the test failed */ @Test public void testExecuteWithRedirectedStreams() throws Exception { if (OS.isFamilyUnix()) { final FileInputStream fis = new FileInputStream("./NOTICE.txt"); final CommandLine cl = new CommandLine(redirectScript); final PumpStreamHandler pumpStreamHandler = new PumpStreamHandler(baos, baos, fis); final DefaultExecutor executor = new DefaultExecutor(); executor.setWorkingDirectory(new File(".")); executor.setStreamHandler(pumpStreamHandler); final int exitValue = executor.execute(cl); fis.close(); final String result = baos.toString().trim(); assertTrue(result, result.indexOf("Finished reading from stdin") > 0); assertFalse("exitValue=" + exitValue, exec.isFailure(exitValue)); } else if (OS.isFamilyWindows()) { System.err .println("The code samples to do that in windows look like a joke ... :-( .., no way I'm doing that"); System.err.println("The test 'testExecuteWithRedirectedStreams' does not support the following OS : " + System.getProperty("os.name")); return; } else { System.err.println("The test 'testExecuteWithRedirectedStreams' does not support the following OS : " + System.getProperty("os.name")); return; } } /** * Start a process and connect stdout and stderr. * * @throws Exception the test failed */ @Test public void testExecuteWithStdOutErr() throws Exception { final CommandLine cl = new CommandLine(testScript); final PumpStreamHandler pumpStreamHandler = new PumpStreamHandler(System.out, System.err); final DefaultExecutor executor = new DefaultExecutor(); executor.setStreamHandler(pumpStreamHandler); final int exitValue = executor.execute(cl); assertFalse(exec.isFailure(exitValue)); } /** * Start a process and connect it to no stream. * * @throws Exception * the test failed */ @Test public void testExecuteWithNullOutErr() throws Exception { final CommandLine cl = new CommandLine(testScript); final PumpStreamHandler pumpStreamHandler = new PumpStreamHandler(null, null); final DefaultExecutor executor = new DefaultExecutor(); executor.setStreamHandler(pumpStreamHandler); final int exitValue = executor.execute(cl); assertFalse(exec.isFailure(exitValue)); } /** * Start a process and connect out and err to a file. * * @throws Exception the test failed */ @Test public void testExecuteWithRedirectOutErr() throws Exception { final File outfile = File.createTempFile("EXEC", ".test"); outfile.deleteOnExit(); final CommandLine cl = new CommandLine(testScript); final FileOutputStream outAndErr = new FileOutputStream(outfile); try { final PumpStreamHandler pumpStreamHandler = new PumpStreamHandler(outAndErr); final DefaultExecutor executor = new DefaultExecutor(); executor.setStreamHandler(pumpStreamHandler); final int exitValue = executor.execute(cl); assertFalse(exec.isFailure(exitValue)); assertTrue(outfile.exists()); } finally { outAndErr.close(); } } /** * A generic test case to print the command line arguments to 'printargs' script to solve * even more command line puzzles. * * @throws Exception the test failed */ @Test public void testExecuteWithComplexArguments() throws Exception { final CommandLine cl = new CommandLine(printArgsScript); cl.addArgument("gdal_translate"); cl.addArgument("HDF5:\"/home/kk/grass/data/4404.he5\"://HDFEOS/GRIDS/OMI_Column_Amount_O3/Data_Fields/ColumnAmountO3/home/kk/4.tif", false); final DefaultExecutor executor = new DefaultExecutor(); final int exitValue = executor.execute(cl); assertFalse(exec.isFailure(exitValue)); } /** * The test script reads an argument from {@code stdin} and prints * the result to stdout. To make things slightly more interesting * we are using an asynchronous process. * * @throws Exception the test failed */ @Test public void testStdInHandling() throws Exception { // newline not needed; causes problems for VMS final ByteArrayInputStream bais = new ByteArrayInputStream("Foo".getBytes()); final CommandLine cl = new CommandLine(this.stdinSript); final PumpStreamHandler pumpStreamHandler = new PumpStreamHandler(this.baos, System.err, bais); final DefaultExecuteResultHandler resultHandler = new DefaultExecuteResultHandler(); final Executor executor = new DefaultExecutor(); executor.setStreamHandler(pumpStreamHandler); executor.execute(cl, resultHandler); resultHandler.waitFor(WAITFOR_TIMEOUT); assertTrue("ResultHandler received a result", resultHandler.hasResult()); assertFalse(exec.isFailure(resultHandler.getExitValue())); final String result = baos.toString(); assertTrue("Result '" + result + "' should contain 'Hello Foo!'", result.indexOf("Hello Foo!") >= 0); } /** * Call a script to dump the environment variables of the subprocess. * * @throws Exception the test failed */ @Test public void testEnvironmentVariables() throws Exception { exec.execute(new CommandLine(environmentSript)); final String environment = baos.toString().trim(); assertTrue("Found no environment variables", environment.length() > 0); assertFalse(environment.indexOf("NEW_VAR") >= 0); } /** * Call a script to dump the environment variables of the subprocess * after adding a custom environment variable. * * @throws Exception the test failed */ @Test public void testAddEnvironmentVariables() throws Exception { final Map myEnvVars = new HashMap(); myEnvVars.putAll(EnvironmentUtils.getProcEnvironment()); myEnvVars.put("NEW_VAR","NEW_VAL"); exec.execute(new CommandLine(environmentSript), myEnvVars); final String environment = baos.toString().trim(); assertTrue("Expecting NEW_VAR in "+environment,environment.indexOf("NEW_VAR") >= 0); assertTrue("Expecting NEW_VAL in "+environment,environment.indexOf("NEW_VAL") >= 0); } @Test public void testAddEnvironmentVariableEmbeddedQuote() throws Exception { final Map myEnvVars = new HashMap(); myEnvVars.putAll(EnvironmentUtils.getProcEnvironment()); final String name = "NEW_VAR"; final String value = "NEW_\"_VAL"; myEnvVars.put(name,value); exec.execute(new CommandLine(environmentSript), myEnvVars); final String environment = baos.toString().trim(); assertTrue("Expecting "+name+" in "+environment,environment.indexOf(name) >= 0); assertTrue("Expecting "+value+" in "+environment,environment.indexOf(value) >= 0); } // ====================================================================== // === Long running tests // ====================================================================== /** * Start any processes in a loop to make sure that we do * not leave any handles/resources open. * * @throws Exception the test failed */ @Test @Ignore public void _testExecuteStability() throws Exception { // make a plain-vanilla test for (int i=0; i<100; i++) { final Map env = new HashMap(); env.put("TEST_ENV_VAR", Integer.toString(i)); final CommandLine cl = new CommandLine(testScript); final int exitValue = exec.execute(cl,env); assertFalse(exec.isFailure(exitValue)); assertEquals("FOO." + i + ".", baos.toString().trim()); baos.reset(); } // now be nasty and use the watchdog to kill out sub-processes for (int i=0; i<100; i++) { final Map env = new HashMap(); env.put("TEST_ENV_VAR", Integer.toString(i)); final DefaultExecuteResultHandler resultHandler = new DefaultExecuteResultHandler(); final CommandLine cl = new CommandLine(foreverTestScript); final ExecuteWatchdog watchdog = new ExecuteWatchdog(500); exec.setWatchdog(watchdog); exec.execute(cl, env, resultHandler); resultHandler.waitFor(WAITFOR_TIMEOUT); assertTrue("ResultHandler received a result", resultHandler.hasResult()); assertNotNull(resultHandler.getException()); baos.reset(); } } // ====================================================================== // === Helper methods // ====================================================================== private String readFile(final File file) throws Exception { String text; final StringBuilder contents = new StringBuilder(); final BufferedReader reader = new BufferedReader(new FileReader(file)); while ((text = reader.readLine()) != null) { contents.append(text) .append(System.getProperty( "line.separator")); } reader.close(); return contents.toString(); } private int getOccurrences(final String data, final char c) { int result = 0; for (int i=0; i env = new HashMap(); assertArrayEquals(new String[0], EnvironmentUtils.toStrings(env)); env.put("foo2", "bar2"); env.put("foo", "bar"); final String[] envStrings = EnvironmentUtils.toStrings(env); final String[] expected = new String[]{"foo2=bar2", "foo=bar"}; // ensure the result does not depend on the hash ordering Arrays.sort(expected); Arrays.sort(envStrings); assertArrayEquals(expected, envStrings); } /** * Test to access the environment variables of the current * process. Please note that this test does not run on * java-gjc. * * @throws IOException the test failed */ @Test public void testGetProcEnvironment() throws IOException { final Map procEnvironment = EnvironmentUtils.getProcEnvironment(); // we assume that there is at least one environment variable // for this process, i.e. $JAVA_HOME assertTrue("Expecting non-zero environment size", procEnvironment.size() > 0); final String[] envArgs = EnvironmentUtils.toStrings(procEnvironment); for (int i=0; i 0); // System.out.println(envArgs[i]); } } /** * On Windows platforms test that accessing environment variables * can be done in a case-insensitive way, e.g. "PATH", "Path" and * "path" would reference the same environment variable. * * @throws IOException the test failed */ @Test public void testGetProcEnvironmentCaseInsensitiveLookup() throws IOException { // run tests only on windows platforms if (!OS.isFamilyWindows()) { return; } // ensure that we have the same value for upper and lowercase keys final Map procEnvironment = EnvironmentUtils.getProcEnvironment(); for (final Entry entry : procEnvironment.entrySet()) { final String key = entry.getKey(); final String value = entry.getValue(); assertEquals(value, procEnvironment.get(key.toLowerCase(Locale.ENGLISH))); assertEquals(value, procEnvironment.get(key.toUpperCase(Locale.ENGLISH))); } // add an environment variable and check access EnvironmentUtils.addVariableToEnvironment(procEnvironment, "foo=bar"); assertEquals("bar", procEnvironment.get("FOO")); assertEquals("bar", procEnvironment.get("Foo")); assertEquals("bar", procEnvironment.get("foo")); } /** * Accessing environment variables is case-sensitive or not depending * on the operating system but the values of the environment variable * are always case-sensitive. So make sure that this assumption holds * on all operating systems. * * @throws Exception the test failed */ @Test public void testCaseInsensitiveVariableLookup() throws Exception { final Map procEnvironment = EnvironmentUtils.getProcEnvironment(); // Check that case is preserved for values EnvironmentUtils.addVariableToEnvironment(procEnvironment, "foo=bAr"); assertEquals("bAr", procEnvironment.get("foo")); } /** * Tests the behavior of the EnvironmentUtils.toStrings() * when using a {@code null} key given to the map. */ @Test public void testToStringWithNullKey() { final Map env = new HashMap(); env.put(null, "TheNullKey"); final String[] strings = EnvironmentUtils.toStrings(env); assertEquals(1, strings.length); assertEquals("=TheNullKey", strings[0]); } /** * Tests the behavior of the EnvironmentUtils.toStrings() * when using a {@code null} value given to the map. */ @Test public void testToStringWithNullValue() { final Map env = new HashMap(); env.put("key", null); final String[] strings = EnvironmentUtils.toStrings(env); assertEquals(1, strings.length); assertEquals("key=", strings[0]); } } commons-exec-1.3-src/src/test/java/org/apache/commons/exec/issues/Exec33Test.java100644 0 0 4135 12425540623 25042 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.exec.issues; import static org.junit.Assert.assertFalse; import java.io.File; import org.apache.commons.exec.CommandLine; import org.apache.commons.exec.DefaultExecutor; import org.apache.commons.exec.Executor; import org.apache.commons.exec.PumpStreamHandler; import org.apache.commons.exec.TestUtil; import org.junit.Test; /** * Test the patch for EXEC-33 (https://issues.apache.org/jira/browse/EXEC-33) * * PumpStreamHandler hangs if System.in is redirect to process input stream . * * @version $Id: Exec33Test.java 1557130 2014-01-10 14:23:40Z britter $ */ public class Exec33Test { private final Executor exec = new DefaultExecutor(); private final File testDir = new File("src/test/scripts"); private final File testScript = TestUtil.resolveScriptForOS(testDir + "/test"); @Test public void testExec33() throws Exception { final CommandLine cl = new CommandLine(testScript); final PumpStreamHandler pumpStreamHandler = new PumpStreamHandler(System.out, System.err, System.in); final DefaultExecutor executor = new DefaultExecutor(); executor.setStreamHandler(pumpStreamHandler); final int exitValue = executor.execute(cl); assertFalse(exec.isFailure(exitValue)); } } commons-exec-1.3-src/src/test/java/org/apache/commons/exec/issues/Exec34Test.java100644 0 0 7212 12425540623 25042 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.exec.issues; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import java.io.File; import org.apache.commons.exec.CommandLine; import org.apache.commons.exec.DefaultExecuteResultHandler; import org.apache.commons.exec.DefaultExecutor; import org.apache.commons.exec.ExecuteWatchdog; import org.apache.commons.exec.Executor; import org.apache.commons.exec.TestUtil; import org.junit.Test; /** * EXEC-34 https://issues.apache.org/jira/browse/EXEC-34 * * @version $Id: Exec34Test.java 1636056 2014-11-01 21:12:52Z ggregory $ */ public class Exec34Test { private final Executor exec = new DefaultExecutor(); private final File testDir = new File("src/test/scripts"); private final File pingScript = TestUtil.resolveScriptForOS(testDir + "/ping"); /** * * Race condition prevent watchdog working using ExecuteStreamHandler. * The test fails because when watchdog.destroyProcess() is invoked the * external process is not bound to the watchdog yet. * * @throws Exception the test failed */ @Test public void testExec34_1() throws Exception { final CommandLine cmdLine = new CommandLine(pingScript); cmdLine.addArgument("10"); // sleep 10 secs final ExecuteWatchdog watchdog = new ExecuteWatchdog(Integer.MAX_VALUE); final DefaultExecuteResultHandler handler = new DefaultExecuteResultHandler(); exec.setWatchdog(watchdog); exec.execute(cmdLine, handler); assertTrue(watchdog.isWatching()); watchdog.destroyProcess(); assertTrue("Watchdog should have killed the process",watchdog.killedProcess()); assertFalse("Watchdog is no longer watching the process",watchdog.isWatching()); } /** * Some user waited for an asynchronous process using watchdog.isWatching() which * is now properly implemented using {@code DefaultExecuteResultHandler}. * * @throws Exception the test failed */ @Test public void testExec34_2() throws Exception { final CommandLine cmdLine = new CommandLine(pingScript); cmdLine.addArgument("10"); // sleep 10 secs final ExecuteWatchdog watchdog = new ExecuteWatchdog(5000); final DefaultExecuteResultHandler handler = new DefaultExecuteResultHandler(); exec.setWatchdog(watchdog); exec.execute(cmdLine, handler); handler.waitFor(); assertTrue("Process has exited", handler.hasResult()); assertNotNull("Process was aborted", handler.getException()); assertTrue("Watchdog should have killed the process", watchdog.killedProcess()); assertFalse("Watchdog is no longer watching the process", watchdog.isWatching()); } } commons-exec-1.3-src/src/test/java/org/apache/commons/exec/issues/Exec36Test.java100644 0 0 20501 12425540623 25060 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.exec.issues; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import java.io.ByteArrayOutputStream; import java.io.File; import java.util.HashMap; import java.util.Map; import org.apache.commons.exec.CommandLine; import org.apache.commons.exec.DefaultExecutor; import org.apache.commons.exec.Executor; import org.apache.commons.exec.OS; import org.apache.commons.exec.PumpStreamHandler; import org.apache.commons.exec.TestUtil; import org.junit.After; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; /** * Test EXEC-36 see https://issues.apache.org/jira/browse/EXEC-36 * * @version $Id: Exec36Test.java 1564600 2014-02-05 01:17:47Z ggregory $ */ public class Exec36Test { private final Executor exec = new DefaultExecutor(); private final File testDir = new File("src/test/scripts"); private final File printArgsScript = TestUtil.resolveScriptForOS(testDir + "/printargs"); private ByteArrayOutputStream baos; @Before public void setUp() throws Exception { // prepare a ready to Executor this.baos = new ByteArrayOutputStream(); this.exec.setStreamHandler(new PumpStreamHandler(baos, baos)); } @After public void tearDown() throws Exception { this.baos.close(); } /** * * Original example from Kai Hu which only can be tested on Unix * * @throws Exception the test failed */ @Test public void testExec36_1() throws Exception { if (OS.isFamilyUnix()) { CommandLine cmdl; /** * ./script/jrake cruise:publish_installers INSTALLER_VERSION=unstable_2_1 \ * INSTALLER_PATH="/var/lib/ cruise-agent/installers" INSTALLER_DOWNLOAD_SERVER='something' WITHOUT_HELP_DOC=true */ final String expected = "./script/jrake\n" + "cruise:publish_installers\n" + "INSTALLER_VERSION=unstable_2_1\n" + "INSTALLER_PATH=\"/var/lib/ cruise-agent/installers\"\n" + "INSTALLER_DOWNLOAD_SERVER='something'\n" + "WITHOUT_HELP_DOC=true"; cmdl = new CommandLine(printArgsScript); cmdl.addArgument("./script/jrake", false); cmdl.addArgument("cruise:publish_installers", false); cmdl.addArgument("INSTALLER_VERSION=unstable_2_1", false); cmdl.addArgument("INSTALLER_PATH=\"/var/lib/ cruise-agent/installers\"", false); cmdl.addArgument("INSTALLER_DOWNLOAD_SERVER='something'", false); cmdl.addArgument("WITHOUT_HELP_DOC=true", false); final int exitValue = exec.execute(cmdl); final String result = baos.toString().trim(); assertFalse(exec.isFailure(exitValue)); assertEquals(expected, result); } else { System.err.println("The test 'testExec36_1' does not support the following OS : " + System.getProperty("os.name")); return; } } /** * Test a complex real example found at * http://blogs.msdn.com/b/astebner/archive/2005/12/13/503471.aspx * * The command line is so weird that it even falls apart under Windows * * @throws Exception the test failed */ @Test public void testExec36_2() throws Exception { String expected; // the original command line // dotnetfx.exe /q:a /c:"install.exe /l ""\Documents and Settings\myusername\Local Settings\Temp\netfx.log"" /q" if (OS.isFamilyWindows()) { expected = "dotnetfx.exe\n" + "/q:a\n" + "/c:\"install.exe /l \"\"\\Documents and Settings\\myusername\\Local Settings\\Temp\\netfx.log\"\" /q\""; } else if (OS.isFamilyUnix()) { expected = "dotnetfx.exe\n" + "/q:a\n" + "/c:\"install.exe /l \"\"/Documents and Settings/myusername/Local Settings/Temp/netfx.log\"\" /q\""; } else { System.err.println("The test 'testExec36_3' does not support the following OS : " + System.getProperty("os.name")); return; } CommandLine cmdl; final File file = new File("/Documents and Settings/myusername/Local Settings/Temp/netfx.log"); final Map map = new HashMap(); map.put("FILE", file); cmdl = new CommandLine(printArgsScript); cmdl.setSubstitutionMap(map); cmdl.addArgument("dotnetfx.exe", false); cmdl.addArgument("/q:a", false); cmdl.addArgument("/c:\"install.exe /l \"\"${FILE}\"\" /q\"", false); final int exitValue = exec.execute(cmdl); final String result = baos.toString().trim(); assertFalse(exec.isFailure(exitValue)); if (OS.isFamilyUnix()) { // the parameters fall literally apart under Windows - need to disable the check for Win32 assertEquals(expected, result); } } /** * Some complex real-life command line from * http://blogs.msdn.com/b/astebner/archive/2005/12/13/503471.aspx */ @Test @Ignore public void _testExec36_4() throws Exception { CommandLine cmdl; final String line = "./script/jrake " + "cruise:publish_installers " + "INSTALLER_VERSION=unstable_2_1 " + "INSTALLER_PATH=\"/var/lib/cruise-agent/installers\" " + "INSTALLER_DOWNLOAD_SERVER='something'" + "WITHOUT_HELP_DOC=true"; cmdl = CommandLine.parse(line); final String[] args = cmdl.toStrings(); assertEquals("./script/jrake", args[0]); assertEquals("cruise:publish_installers", args[1]); assertEquals("INSTALLER_VERSION=unstable_2_1", args[2]); assertEquals("INSTALLER_PATH=\"/var/lib/cruise-agent/installers\"", args[3]); assertEquals("INSTALLER_DOWNLOAD_SERVER='something'", args[4]); assertEquals("WITHOUT_HELP_DOC=true", args[5]); } /** * Some complex real-life command line from * http://blogs.msdn.com/b/astebner/archive/2005/12/13/503471.aspx */ @Test @Ignore public void _testExec36_5() { CommandLine cmdl; final String line = "dotnetfx.exe" + " /q:a " + "/c:\"install.exe /l \"\"c:\\Documents and Settings\\myusername\\Local Settings\\Temp\\netfx.log\"\" /q\""; cmdl = CommandLine.parse(line); final String[] args = cmdl.toStrings(); assertEquals("dotnetfx.exe", args[0]); assertEquals("/q:a", args[1]); assertEquals("/c:\"install.exe /l \"\"c:\\Documents and Settings\\myusername\\Local Settings\\Temp\\netfx.log\"\" /q\"", args[2] ); } /** * Test the following command line * * C:\CVS_DB\WeightsEngine /f WeightsEngine.mak CFG="WeightsEngine - Win32Release" */ @Test @Ignore public void _testExec36_6() { final String commandline = "C:\\CVS_DB\\WeightsEngine /f WeightsEngine.mak CFG=\"WeightsEngine - Win32Release\""; final CommandLine cmdl = CommandLine.parse(commandline); final String[] args = cmdl.getArguments(); assertEquals("/f", args[0]); assertEquals("WeightsEngine.mak", args[1]); assertEquals("CFG=\"WeightsEngine - Win32Release\"", args[2]); } } commons-exec-1.3-src/src/test/java/org/apache/commons/exec/issues/Exec41Test.java100644 0 0 13524 12425540623 25063 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.exec.issues; import static org.junit.Assert.assertTrue; import java.io.File; import org.apache.commons.exec.CommandLine; import org.apache.commons.exec.DefaultExecutor; import org.apache.commons.exec.ExecuteException; import org.apache.commons.exec.ExecuteWatchdog; import org.apache.commons.exec.OS; import org.apache.commons.exec.PumpStreamHandler; import org.apache.commons.exec.TestUtil; import org.junit.Test; /** * Test the patch for EXEC-41 (https://issues.apache.org/jira/browse/EXEC-41). * * @version $Id: Exec41Test.java 1557130 2014-01-10 14:23:40Z britter $ */ public class Exec41Test { private final File testDir = new File("src/test/scripts"); private final File pingScript = TestUtil.resolveScriptForOS(testDir + "/ping"); /** * * When a process runs longer than allowed by a configured watchdog's * timeout, the watchdog tries to destroy it and then DefaultExecutor * tries to clean up by joining with all installed pump stream threads. * Problem is, that sometimes the native process doesn't die and thus * streams aren't closed and the stream threads do not complete. * * @throws Exception the test failed */ @Test public void testExec41WithStreams() throws Exception { CommandLine cmdLine; if (OS.isFamilyWindows()) { cmdLine = CommandLine.parse("ping.exe -n 10 -w 1000 127.0.0.1"); } else if ("HP-UX".equals(System.getProperty("os.name"))) { // see EXEC-52 - option must appear after the hostname! cmdLine = CommandLine.parse("ping 127.0.0.1 -n 10"); } else if (OS.isFamilyUnix()) { cmdLine = CommandLine.parse("ping -c 10 127.0.0.1"); } else { System.err.println("The test 'testExec41WithStreams' does not support the following OS : " + System.getProperty("os.name")); return; } final DefaultExecutor executor = new DefaultExecutor(); final ExecuteWatchdog watchdog = new ExecuteWatchdog(2 * 1000); // allow process no more than 2 secs final PumpStreamHandler pumpStreamHandler = new PumpStreamHandler(System.out, System.err); // this method was part of the patch I reverted // pumpStreamHandler.setAlwaysWaitForStreamThreads(false); executor.setWatchdog(watchdog); executor.setStreamHandler(pumpStreamHandler); final long startTime = System.currentTimeMillis(); try { executor.execute(cmdLine); } catch (final ExecuteException e) { // nothing to do } final long duration = System.currentTimeMillis() - startTime; System.out.println("Process completed in " + duration + " millis; below is its output"); if (watchdog.killedProcess()) { System.out.println("Process timed out and was killed by watchdog."); } assertTrue("The process was killed by the watchdog", watchdog.killedProcess()); assertTrue("Skipping the Thread.join() did not work", duration < 9000); } /** * Test EXEC-41 with a disabled PumpStreamHandler to check if we could return * immediately after killing the process (no streams implies no blocking * stream pumper threads). But you have to be 100% sure that the subprocess * is not writing to 'stdout' and 'stderr'. * * For this test we are using the batch file - under Windows the 'ping' * process can't be killed (not supported by Win32) and will happily * run the given time (e.g. 10 seconds) even hwen the batch file is already * killed. * * @throws Exception the test failed */ @Test public void testExec41WithoutStreams() throws Exception { final CommandLine cmdLine = new CommandLine(pingScript); cmdLine.addArgument("10"); // sleep 10 secs final DefaultExecutor executor = new DefaultExecutor(); final ExecuteWatchdog watchdog = new ExecuteWatchdog(2*1000); // allow process no more than 2 secs // create a custom "PumpStreamHandler" doing no pumping at all final PumpStreamHandler pumpStreamHandler = new PumpStreamHandler(null, null, null); executor.setWatchdog(watchdog); executor.setStreamHandler(pumpStreamHandler); final long startTime = System.currentTimeMillis(); try { executor.execute(cmdLine); } catch (final ExecuteException e) { System.out.println(e); } final long duration = System.currentTimeMillis() - startTime; System.out.println("Process completed in " + duration +" millis; below is its output"); if (watchdog.killedProcess()) { System.out.println("Process timed out and was killed."); } assertTrue("The process was killed by the watchdog", watchdog.killedProcess()); assertTrue("Skipping the Thread.join() did not work, duration="+duration, duration < 9000); } } commons-exec-1.3-src/src/test/java/org/apache/commons/exec/issues/Exec44Test.java100644 0 0 5420 12425540623 25042 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.exec.issues; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import java.io.File; import org.apache.commons.exec.CommandLine; import org.apache.commons.exec.DefaultExecuteResultHandler; import org.apache.commons.exec.DefaultExecutor; import org.apache.commons.exec.ExecuteWatchdog; import org.apache.commons.exec.Executor; import org.apache.commons.exec.TestUtil; import org.junit.Test; /** * Test EXEC-44 (https://issues.apache.org/jira/browse/EXEC-44). * * @version $Id: Exec44Test.java 1557130 2014-01-10 14:23:40Z britter $ */ public class Exec44Test { private final Executor exec = new DefaultExecutor(); private final File testDir = new File("src/test/scripts"); private final File foreverTestScript = TestUtil.resolveScriptForOS(testDir + "/forever"); /** * * Because the ExecuteWatchdog is the only way to destroy asynchronous * processes, it should be possible to set it to an infinite timeout, * for processes which should not timeout, but manually destroyed * under some circumstances. * * @throws Exception the test failed */ @Test public void testExec44() throws Exception { final CommandLine cl = new CommandLine(foreverTestScript); final DefaultExecuteResultHandler resultHandler = new DefaultExecuteResultHandler(); final ExecuteWatchdog watchdog = new ExecuteWatchdog(ExecuteWatchdog.INFINITE_TIMEOUT); exec.setWatchdog(watchdog); exec.execute(cl, resultHandler); // wait for script to run Thread.sleep(5000); assertTrue("The watchdog is watching the process", watchdog.isWatching()); // terminate it watchdog.destroyProcess(); assertTrue("The watchdog has killed the process", watchdog.killedProcess()); assertFalse("The watchdog is no longer watching any process", watchdog.isWatching()); } } commons-exec-1.3-src/src/test/java/org/apache/commons/exec/issues/Exec49Test.java100644 0 0 11570 12425540623 25072 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.exec.issues; import java.io.ByteArrayOutputStream; import java.io.PipedInputStream; import java.io.PipedOutputStream; import org.apache.commons.exec.CommandLine; import org.apache.commons.exec.DefaultExecuteResultHandler; import org.apache.commons.exec.DefaultExecutor; import org.apache.commons.exec.Executor; import org.apache.commons.exec.OS; import org.apache.commons.exec.PumpStreamHandler; import org.junit.Test; /** * Test EXEC-44 (https://issues.apache.org/jira/browse/EXEC-44). * * @version $Id: Exec49Test.java 1557406 2014-01-11 14:19:34Z sebb $ */ public class Exec49Test { private final Executor exec = new DefaultExecutor(); /** * The issue was detected when trying to capture stdout/stderr with a PipedOutputStream and * then pass that to a PipedInputStream. The following code will produce the error. * The reason for the error is the PipedOutputStream is not being closed correctly, * causing the PipedInputStream to break. * * @throws Exception the test failed */ @Test public void testExec49_1() throws Exception { if (OS.isFamilyUnix()) { final CommandLine cl = CommandLine.parse("/bin/ls"); cl.addArgument("/opt"); // redirect stdout/stderr to pipedOutputStream final PipedOutputStream pipedOutputStream = new PipedOutputStream(); final PumpStreamHandler psh = new PumpStreamHandler(pipedOutputStream); exec.setStreamHandler(psh); // start an asynchronous process to enable the main thread System.out.println("Preparing to execute process - commandLine=" + cl.toString()); final DefaultExecuteResultHandler handler = new DefaultExecuteResultHandler(); exec.execute(cl, handler); System.out.println("Process spun off successfully - process=" + cl.getExecutable()); int x; final PipedInputStream pis = new PipedInputStream(pipedOutputStream); while ((x = pis.read()) >= 0) { // System.out.println("pis.available() " + pis.available()); // System.out.println("x " + x); } pis.close(); handler.waitFor(10000); handler.getExitValue(); // will fail if process has not finished } } /** * The issue was detected when trying to capture stdout with a PipedOutputStream and * then pass that to a PipedInputStream. The following code will produce the error. * The reason for the error is the PipedOutputStream is not being closed correctly, * causing the PipedInputStream to break. * * @throws Exception the test failed */ @Test public void testExec49_2() throws Exception { if (OS.isFamilyUnix()) { final CommandLine cl = CommandLine.parse("/bin/ls"); cl.addArgument("/opt"); // redirect only stdout to pipedOutputStream final PipedOutputStream pipedOutputStream = new PipedOutputStream(); final PumpStreamHandler psh = new PumpStreamHandler(pipedOutputStream, new ByteArrayOutputStream()); exec.setStreamHandler(psh); // start an asynchronous process to enable the main thread System.out.println("Preparing to execute process - commandLine=" + cl.toString()); final DefaultExecuteResultHandler handler = new DefaultExecuteResultHandler(); exec.execute(cl, handler); System.out.println("Process spun off successfully - process=" + cl.getExecutable()); int x; final PipedInputStream pis = new PipedInputStream(pipedOutputStream); while ((x = pis.read()) >= 0) { // System.out.println("pis.available() " + pis.available()); // System.out.println("x " + x); } pis.close(); handler.waitFor(10000); handler.getExitValue(); // will fail if process has not finished } } } commons-exec-1.3-src/src/test/java/org/apache/commons/exec/issues/Exec57Test.java100644 0 0 6330 12425540623 25047 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.exec.issues; import static org.junit.Assert.fail; import java.io.File; import java.io.IOException; import org.apache.commons.exec.CommandLine; import org.apache.commons.exec.DefaultExecutor; import org.apache.commons.exec.ExecuteException; import org.apache.commons.exec.OS; import org.apache.commons.exec.PumpStreamHandler; import org.junit.Test; /** * Test EXEC-57 (https://issues.apache.org/jira/browse/EXEC-57). * * @version $Id: Exec57Test.java 1557263 2014-01-10 21:18:09Z ggregory $ */ public class Exec57Test { private final File testDir = new File("src/test/scripts"); /** * * DefaultExecutor.execute() does not return even if child process terminated - in this * case the child process hangs because the grand children is connected to stdout & stderr * and is still running. As work-around a stop timeout is used for the PumpStreamHandler * to ensure that the caller does not block forever but if the stop timeout is exceeded * an ExecuteException is thrown to notify the caller. * * @throws Exception the test failed */ @Test public void testExec_57() throws IOException { if (!OS.isFamilyUnix()) { System.err.println("The test 'testSyncInvocationOfBackgroundProcess' does not support the following OS : " + System.getProperty("os.name")); return; } final CommandLine cmdLine = new CommandLine("sh").addArgument("-c").addArgument(testDir + "/invoker.sh", false); final DefaultExecutor executor = new DefaultExecutor(); final PumpStreamHandler pumpStreamHandler = new PumpStreamHandler(System.out, System.err); // Without this timeout current thread will be blocked // even if command we'll invoke will terminate immediately. pumpStreamHandler.setStopTimeout(2000); executor.setStreamHandler(pumpStreamHandler); final long startTime = System.currentTimeMillis(); System.out.println("Executing " + cmdLine); try { executor.execute(cmdLine); } catch (final ExecuteException e) { final long duration = System.currentTimeMillis() - startTime; System.out.println("Process completed in " + duration +" millis; above is its output"); return; } fail("Expecting an ExecuteException"); } } commons-exec-1.3-src/src/test/java/org/apache/commons/exec/issues/Exec60Test.java100644 0 0 10130 12425540623 25052 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.commons.exec.issues; import static org.junit.Assert.assertTrue; import java.io.File; import org.apache.commons.exec.CommandLine; import org.apache.commons.exec.DefaultExecutor; import org.apache.commons.exec.ExecuteException; import org.apache.commons.exec.ExecuteWatchdog; import org.apache.commons.exec.Executor; import org.apache.commons.exec.TestUtil; import org.junit.Test; /** * Test EXEC-60 (https://issues.apache.org/jira/browse/EXEC-60). * * @version $Id: Exec60Test.java 1557130 2014-01-10 14:23:40Z britter $ */ public class Exec60Test { private final Executor exec = new DefaultExecutor(); private final File testDir = new File("src/test/scripts"); private final File pingScript = TestUtil.resolveScriptForOS(testDir + "/ping"); /** * Possible deadlock when a process is terminating at the same time its timing out. Please * note that a successful test is no proof that the issues was indeed fixed. */ @Test public void testExec_60() throws Exception { final int start = 0; final int seconds = 1; final int offsetMultiplier = 1; final int maxRetries = 180; int processTerminatedCounter = 0; int watchdogKilledProcessCounter = 0; final CommandLine cmdLine = new CommandLine(pingScript); cmdLine.addArgument(Integer.toString(seconds + 1)); // need to add "1" to wait the requested number of seconds final long startTime = System.currentTimeMillis(); for (int offset = start; offset <= maxRetries; offset++) { // wait progressively longer for process to complete // tricky to get this test right. We want to try and catch the process while it is terminating, // so we increase the timeout gradually until the test terminates normally. // However if the increase is too gradual, we never wait long enough for any test to exit normally final ExecuteWatchdog watchdog = new ExecuteWatchdog(seconds * 1000 + offset * offsetMultiplier); exec.setWatchdog(watchdog); try { exec.execute(cmdLine); processTerminatedCounter++; // System.out.println(offset + ": process has terminated: " + watchdog.killedProcess()); if (processTerminatedCounter > 5) { break; } } catch (final ExecuteException ex) { // System.out.println(offset + ": process was killed: " + watchdog.killedProcess()); assertTrue("Watchdog killed the process", watchdog.killedProcess()); watchdogKilledProcessCounter++; } } final long avg = (System.currentTimeMillis() - startTime) / (watchdogKilledProcessCounter+processTerminatedCounter); System.out.println("Processes terminated: " + processTerminatedCounter + " killed: " + watchdogKilledProcessCounter + " Multiplier: " + offsetMultiplier + " MaxRetries: " + maxRetries + " Elapsed (avg ms): " + avg); assertTrue("Not a single process terminated on its own", processTerminatedCounter > 0); assertTrue("Not a single process was killed by the watch dog", watchdogKilledProcessCounter > 0); } } commons-exec-1.3-src/src/test/java/org/apache/commons/exec/LogOutputStreamTest.java100644 0 0 5732 12425540623 25617 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.commons.exec; import static org.junit.Assert.assertFalse; import java.io.File; import java.io.OutputStream; import org.junit.After; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; /** * Test the LogOutputStream. * * @version $Id: LogOutputStreamTest.java 1557265 2014-01-10 21:47:50Z ggregory $ */ public class LogOutputStreamTest { private final Executor exec = new DefaultExecutor(); private final File testDir = new File("src/test/scripts"); private OutputStream systemOut; private final File environmentScript = TestUtil.resolveScriptForOS(testDir + "/environment"); @BeforeClass public static void classSetUp() { // turn on debug mode and throw an exception for each encountered problem System.setProperty("org.apache.commons.exec.lenient", "false"); System.setProperty("org.apache.commons.exec.debug", "true"); } @Before public void setUp() throws Exception { this.systemOut = new SystemLogOutputStream(1); this.exec.setStreamHandler(new PumpStreamHandler(systemOut, systemOut)); } @After public void tearDown() throws Exception { this.systemOut.close(); } // ====================================================================== // Start of regression tests // ====================================================================== @Test public void testStdout() throws Exception { final CommandLine cl = new CommandLine(environmentScript); final int exitValue = exec.execute(cl); assertFalse(exec.isFailure(exitValue)); } // ====================================================================== // Helper classes // ====================================================================== private class SystemLogOutputStream extends LogOutputStream { private SystemLogOutputStream(final int level) { super(level); } @Override protected void processLine(final String line, final int level) { System.out.println(line); } } } commons-exec-1.3-src/src/test/java/org/apache/commons/exec/StandAloneTest.java100644 0 0 3647 12425540623 24534 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.commons.exec; import static org.junit.Assert.assertTrue; import java.io.File; import org.junit.BeforeClass; import org.junit.Test; /** * Placeholder for mailing list question - provided a minimal test case * to answer the question as sel-contained regression test. * * @version $Id: StandAloneTest.java 1556900 2014-01-09 17:54:51Z britter $ */ public class StandAloneTest { @BeforeClass public static void classSetUp() { System.setProperty("org.apache.commons.exec.lenient", "false"); System.setProperty("org.apache.commons.exec.debug", "true"); } @Test public void testMe() throws Exception { if (OS.isFamilyUnix()) { final File testScript = TestUtil.resolveScriptForOS("./src/test/scripts/standalone"); final Executor exec = new DefaultExecutor(); exec.setStreamHandler(new PumpStreamHandler()); final CommandLine cl = new CommandLine(testScript); exec.execute(cl); assertTrue(new File("./target/mybackup.gz").exists()); } } } commons-exec-1.3-src/src/test/java/org/apache/commons/exec/TestUtil.java100644 0 0 4034 12425540623 23410 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.commons.exec; import java.io.File; import junit.framework.AssertionFailedError; /** * @version $Id: TestUtil.java 1557263 2014-01-10 21:18:09Z ggregory $ */ public final class TestUtil { private TestUtil() { } public static File resolveScriptForOS(final String script) { if (OS.isFamilyWindows()) { return new File(script + ".bat"); } else if (OS.isFamilyUnix()) { return new File(script + ".sh"); } else if (OS.isFamilyOpenVms()) { return new File(script + ".dcl"); } else { throw new AssertionFailedError("Test not supported for this OS"); } } /** * Get success and fail return codes used by the test scripts * @return int array[2] = {ok, success} */ public static int[] getTestScriptCodesForOS() { if (OS.isFamilyWindows()) { return new int[]{0,1}; } else if (OS.isFamilyUnix()) { return new int[]{0,1}; } else if (OS.isFamilyOpenVms()) { return new int[]{1,2}; } else { throw new AssertionFailedError("Test not supported for this OS"); } } } commons-exec-1.3-src/src/test/java/org/apache/commons/exec/TutorialTest.java100644 0 0 13341 12425540623 24317 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.commons.exec; import static org.junit.Assert.fail; import java.io.File; import java.io.IOException; import java.util.HashMap; import java.util.Map; import org.junit.Test; /** * An example based on the tutorial where the user can can safely play with *
    *
  • blocking or non-blocking print jobs *
  • with print job timeouts to trigger the {@code ExecuteWatchdog} *
  • with the {@code exitValue} returned from the print script *
* * @version $Id: TutorialTest.java 1636056 2014-11-01 21:12:52Z ggregory $ */ public class TutorialTest { /** the directory to pick up the test scripts */ private final File testDir = new File("src/test/scripts"); /** simulates a PDF print job */ private final File acroRd32Script = TestUtil.resolveScriptForOS(testDir + "/acrord32"); @Test public void testTutorialExample() throws Exception { final long printJobTimeout = 15000; final boolean printInBackground = false; final File pdfFile = new File("/Documents and Settings/foo.pdf"); PrintResultHandler printResult; try { // printing takes around 10 seconds System.out.println("[main] Preparing print job ..."); printResult = print(pdfFile, printJobTimeout, printInBackground); System.out.println("[main] Successfully sent the print job ..."); } catch (final Exception e) { e.printStackTrace(); fail("[main] Printing of the following document failed : " + pdfFile.getAbsolutePath()); throw e; } // come back to check the print result System.out.println("[main] Test is exiting but waiting for the print job to finish..."); printResult.waitFor(); System.out.println("[main] The print job has finished ..."); } /** * Simulate printing a PDF document. * * @param file the file to print * @param printJobTimeout the printJobTimeout (ms) before the watchdog terminates the print process * @param printInBackground printing done in the background or blocking * @return a print result handler (implementing a future) * @throws IOException the test failed */ public PrintResultHandler print(final File file, final long printJobTimeout, final boolean printInBackground) throws IOException { int exitValue; ExecuteWatchdog watchdog = null; PrintResultHandler resultHandler; // build up the command line to using a 'java.io.File' final Map map = new HashMap(); map.put("file", file); final CommandLine commandLine = new CommandLine(acroRd32Script); commandLine.addArgument("/p"); commandLine.addArgument("/h"); commandLine.addArgument("${file}"); commandLine.setSubstitutionMap(map); // create the executor and consider the exitValue '1' as success final Executor executor = new DefaultExecutor(); executor.setExitValue(1); // create a watchdog if requested if (printJobTimeout > 0) { watchdog = new ExecuteWatchdog(printJobTimeout); executor.setWatchdog(watchdog); } // pass a "ExecuteResultHandler" when doing background printing if (printInBackground) { System.out.println("[print] Executing non-blocking print job ..."); resultHandler = new PrintResultHandler(watchdog); executor.execute(commandLine, resultHandler); } else { System.out.println("[print] Executing blocking print job ..."); exitValue = executor.execute(commandLine); resultHandler = new PrintResultHandler(exitValue); } return resultHandler; } private class PrintResultHandler extends DefaultExecuteResultHandler { private ExecuteWatchdog watchdog; public PrintResultHandler(final ExecuteWatchdog watchdog) { this.watchdog = watchdog; } public PrintResultHandler(final int exitValue) { super.onProcessComplete(exitValue); } @Override public void onProcessComplete(final int exitValue) { super.onProcessComplete(exitValue); System.out.println("[resultHandler] The document was successfully printed ..."); } @Override public void onProcessFailed(final ExecuteException e) { super.onProcessFailed(e); if (watchdog != null && watchdog.killedProcess()) { System.err.println("[resultHandler] The print process timed out"); } else { System.err.println("[resultHandler] The print process failed to do : " + e.getMessage()); } } } }commons-exec-1.3-src/src/test/java/org/apache/commons/exec/util/MapUtilTest.java100644 0 0 5655 12425540623 25035 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.commons.exec.util; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import java.util.HashMap; import java.util.Map; import org.apache.commons.exec.environment.EnvironmentUtils; import org.junit.Test; /** * @version $Id: MapUtilTest.java 1564600 2014-02-05 01:17:47Z ggregory $ */ public class MapUtilTest { /** * Test copying of map */ @Test public void testCopyMap() throws Exception { final HashMap procEnvironment = new HashMap(); procEnvironment.put("JAVA_HOME", "/usr/opt/java"); final Map result = MapUtils.copy(procEnvironment); assertTrue(result.size() == 1); assertTrue(procEnvironment.size() == 1); assertEquals("/usr/opt/java", result.get("JAVA_HOME")); result.remove("JAVA_HOME"); assertTrue(result.size() == 0); assertTrue(procEnvironment.size() == 1); } /** * Test merging of maps */ @Test public void testMergeMap() throws Exception { final Map procEnvironment = EnvironmentUtils.getProcEnvironment(); final HashMap applicationEnvironment = new HashMap(); applicationEnvironment.put("appMainClass", "foo.bar.Main"); final Map result = MapUtils.merge(procEnvironment, applicationEnvironment); assertTrue(procEnvironment.size() + applicationEnvironment.size() == result.size()); assertEquals("foo.bar.Main", result.get("appMainClass")); } /** * Test prefixing of map */ @Test public void testPrefixMap() throws Exception { final HashMap procEnvironment = new HashMap(); procEnvironment.put("JAVA_HOME", "/usr/opt/java"); final Map result = MapUtils.prefix(procEnvironment, "env"); assertTrue(procEnvironment.size() == result.size()); assertEquals("/usr/opt/java", result.get("env.JAVA_HOME")); } }commons-exec-1.3-src/src/test/java/org/apache/commons/exec/util/StringUtilTest.java100644 0 0 6327 12425540623 25563 0ustar 0 0 /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.commons.exec.util; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import java.util.HashMap; import java.util.Map; import org.junit.Test; /** * @version $Id: StringUtilTest.java 1557338 2014-01-11 10:34:22Z sebb $ */ public class StringUtilTest { /** * Test no string substitution */ @Test public void testNoStringSubstitution() throws Exception { final Map vars = new HashMap(); vars.put("foo", "FOO"); vars.put("bar", "BAR"); assertEquals("This is a FOO & BAR test", StringUtils.stringSubstitution("This is a FOO & BAR test", vars, true).toString()); } /** * Test a default string substitution, e.g. all placeholders * are expanded. */ @Test public void testDefaultStringSubstitution() throws Exception { final Map vars = new HashMap(); vars.put("foo", "FOO"); vars.put("bar", "BAR"); assertEquals("This is a FOO & BAR test", StringUtils.stringSubstitution("This is a ${foo} & ${bar} test", vars, true).toString()); assertEquals("This is a FOO & BAR test", StringUtils.stringSubstitution("This is a ${foo} & ${bar} test", vars, false).toString()); } /** * Test an incomplete string substitution where not all placeholders * are expanded. */ @Test public void testIncompleteSubstitution() throws Exception { final Map vars = new HashMap(); vars.put("foo", "FOO"); assertEquals("This is a FOO & ${bar} test", StringUtils.stringSubstitution("This is a ${foo} & ${bar} test", vars, true).toString()); try { StringUtils.stringSubstitution("This is a ${foo} & ${bar} test", vars, false).toString(); fail(); } catch (final RuntimeException e) { // nothing to do } } /** * Test a erroneous template. */ @Test public void testErroneousTemplate() throws Exception { final Map vars = new HashMap(); vars.put("foo", "FOO"); assertEquals("This is a FOO & ${}} test", StringUtils.stringSubstitution("This is a ${foo} & ${}} test", vars, true).toString()); } }commons-exec-1.3-src/src/test/scripts/acrord32.bat100644 0 0 1722 12425540623 17237 0ustar 0 0 @ECHO OFF REM Licensed to the Apache Software Foundation (ASF) under one or more REM contributor license agreements. See the NOTICE file distributed with REM this work for additional information regarding copyright ownership. REM The ASF licenses this file to You under the Apache License, Version 2.0 REM (the "License"); you may not use this file except in compliance with REM the License. You may obtain a copy of the License at REM REM http://www.apache.org/licenses/LICENSE-2.0 REM REM Unless required by applicable law or agreed to in writing, software REM distributed under the License is distributed on an "AS IS" BASIS, REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. REM See the License for the specific language governing permissions and REM limitations under the License. echo "[acrord32] Printing the following document : '%3'" ping -n 10 -w 1000 127.0.0.1 > nul echo "[acrord32] Finished printing" exit 1 commons-exec-1.3-src/src/test/scripts/environment.bat100644 0 0 1714 12425540623 20165 0ustar 0 0 @ECHO OFF REM Little batch file to run nearly foerver REM see http://malektips.com/dos0017.html REM REM Licensed to the Apache Software Foundation (ASF) under one or more REM contributor license agreements. See the NOTICE file distributed with REM this work for additional information regarding copyright ownership. REM The ASF licenses this file to You under the Apache License, Version 2.0 REM (the "License"); you may not use this file except in compliance with REM the License. You may obtain a copy of the License at REM REM http://www.apache.org/licenses/LICENSE-2.0 REM REM Unless required by applicable law or agreed to in writing, software REM distributed under the License is distributed on an "AS IS" BASIS, REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. REM See the License for the specific language governing permissions and REM limitations under the License. REM print the environment variables setcommons-exec-1.3-src/src/test/scripts/environment.dcl100644 0 0 1755 12425540623 20166 0ustar 0 0 $!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! $! $! Licensed to the Apache Software Foundation (ASF) under one or more $! contributor license agreements. See the NOTICE file distributed with $! this work for additional information regarding copyright ownership. $! The ASF licenses this file to You under the Apache License, Version 2.0 $! (the "License"); you may not use this file except in compliance with $! the License. You may obtain a copy of the License at $! $! http://www.apache.org/licenses/LICENSE-2.0 $! $! Unless required by applicable law or agreed to in writing, software $! distributed under the License is distributed on an "AS IS" BASIS, $! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. $! See the License for the specific language governing permissions and $! limitations under the License. $! $!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! $! $! print the "environment" variables $! $ show symbol *commons-exec-1.3-src/src/test/scripts/error.bat100644 0 0 1657 12425540623 16760 0ustar 0 0 @ECHO OFF REM Licensed to the Apache Software Foundation (ASF) under one or more REM contributor license agreements. See the NOTICE file distributed with REM this work for additional information regarding copyright ownership. REM The ASF licenses this file to You under the Apache License, Version 2.0 REM (the "License"); you may not use this file except in compliance with REM the License. You may obtain a copy of the License at REM REM http://www.apache.org/licenses/LICENSE-2.0 REM REM Unless required by applicable law or agreed to in writing, software REM distributed under the License is distributed on an "AS IS" BASIS, REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. REM See the License for the specific language governing permissions and REM limitations under the License. REM This test script will return an error exit code @echo FOO.%TEST_ENV_VAR%.%1 EXIT 1 commons-exec-1.3-src/src/test/scripts/error.dcl100644 0 0 2173 12425540623 16746 0ustar 0 0 $!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! $! $! Licensed to the Apache Software Foundation (ASF) under one or more $! contributor license agreements. See the NOTICE file distributed with $! this work for additional information regarding copyright ownership. $! The ASF licenses this file to You under the Apache License, Version 2.0 $! (the "License"); you may not use this file except in compliance with $! the License. You may obtain a copy of the License at $! $! http://www.apache.org/licenses/LICENSE-2.0 $! $! Unless required by applicable law or agreed to in writing, software $! distributed under the License is distributed on an "AS IS" BASIS, $! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. $! See the License for the specific language governing permissions and $! limitations under the License. $! $!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! $! $! do something and return an error result code $! $ ENV_VAR=f$trnlnm("TEST_ENV_VAR") $ write sys$output "FOO.''ENV_VAR'.''P1'" $! $ exit %x10000002 ! this is an Error, but does not print a messagecommons-exec-1.3-src/src/test/scripts/forever.bat100644 0 0 2166 12425540623 17273 0ustar 0 0 @ECHO OFF REM Little batch file to run nearly foerver REM see http://malektips.com/dos0017.html REM REM Licensed to the Apache Software Foundation (ASF) under one or more REM contributor license agreements. See the NOTICE file distributed with REM this work for additional information regarding copyright ownership. REM The ASF licenses this file to You under the Apache License, Version 2.0 REM (the "License"); you may not use this file except in compliance with REM the License. You may obtain a copy of the License at REM REM http://www.apache.org/licenses/LICENSE-2.0 REM REM Unless required by applicable law or agreed to in writing, software REM distributed under the License is distributed on an "AS IS" BASIS, REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. REM See the License for the specific language governing permissions and REM limitations under the License. REM run an infinite loop so the script will never ever terminate on its behalf REM and append a '.' after each second :LOOP ECHO . >> .\target\forever.txt @ping 127.0.0.1 -n 2 -w 1000 > nul GOTO LOOPcommons-exec-1.3-src/src/test/scripts/forever.dcl100644 0 0 2641 12425540623 17265 0ustar 0 0 $!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! $! $! Licensed to the Apache Software Foundation (ASF) under one or more $! contributor license agreements. See the NOTICE file distributed with $! this work for additional information regarding copyright ownership. $! The ASF licenses this file to You under the Apache License, Version 2.0 $! (the "License"); you may not use this file except in compliance with $! the License. You may obtain a copy of the License at $! $! http://www.apache.org/licenses/LICENSE-2.0 $! $! Unless required by applicable law or agreed to in writing, software $! distributed under the License is distributed on an "AS IS" BASIS, $! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. $! See the License for the specific language governing permissions and $! limitations under the License. $! $!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! $! $! run an infinite loop so the script will never ever terminate $! $! Suppress timeout warning $ l_msg=f$environment("MESSAGE") $ SET MESSAGE /NOFACILITY /NOIDENTIFICATION /NOSEVERITY /NOTEXT $! $ SET NOON $ ON CONTROL_Y THEN GOTO DONE $ close/nolog OUT $ open/write OUT [.target]forever.txt ! create the output file $LOOP: $ write OUT "." $ read /prompt="."/time_out=1 sys$command dummy $ GOTO LOOP $! $DONE: $ close/nolog OUT $! Restore message settings $ SET MESSAGE 'l_msg'commons-exec-1.3-src/src/test/scripts/ping.bat100644 0 0 2066 12425540623 16557 0ustar 0 0 @ECHO OFF REM Little batch file to run nearly foerver REM see http://malektips.com/dos0017.html REM REM Licensed to the Apache Software Foundation (ASF) under one or more REM contributor license agreements. See the NOTICE file distributed with REM this work for additional information regarding copyright ownership. REM The ASF licenses this file to You under the Apache License, Version 2.0 REM (the "License"); you may not use this file except in compliance with REM the License. You may obtain a copy of the License at REM REM http://www.apache.org/licenses/LICENSE-2.0 REM REM Unless required by applicable law or agreed to in writing, software REM distributed under the License is distributed on an "AS IS" BASIS, REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. REM See the License for the specific language governing permissions and REM limitations under the License. REM ping is started as subprocess which runs '%1' seconds echo "[ping.bat] Blocking for %1 seconds ..." ping.exe -n %1 -w 1000 127.0.0.1 > nulcommons-exec-1.3-src/src/test/scripts/ping.dcl100644 0 0 2150 12425540623 16545 0ustar 0 0 $!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! $! $! Licensed to the Apache Software Foundation (ASF) under one or more $! contributor license agreements. See the NOTICE file distributed with $! this work for additional information regarding copyright ownership. $! The ASF licenses this file to You under the Apache License, Version 2.0 $! (the "License"); you may not use this file except in compliance with $! the License. You may obtain a copy of the License at $! $! http://www.apache.org/licenses/LICENSE-2.0 $! $! Unless required by applicable law or agreed to in writing, software $! distributed under the License is distributed on an "AS IS" BASIS, $! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. $! See the License for the specific language governing permissions and $! limitations under the License. $! $!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! $! $! ping is started as subprocess which runs for 'P1' seconds $! $ write sys$output "[ping.dcl] Blocking for ''P1' seconds ..." $ tcpip ping 127.0.0.1 /number_packets='P1 /wait=1 commons-exec-1.3-src/src/test/scripts/printargs.bat100644 0 0 1760 12425540623 17633 0ustar 0 0 @ECHO OFF REM Licensed to the Apache Software Foundation (ASF) under one or more REM contributor license agreements. See the NOTICE file distributed with REM this work for additional information regarding copyright ownership. REM The ASF licenses this file to You under the Apache License, Version 2.0 REM (the "License"); you may not use this file except in compliance with REM the License. You may obtain a copy of the License at REM REM http://www.apache.org/licenses/LICENSE-2.0 REM REM Unless required by applicable law or agreed to in writing, software REM distributed under the License is distributed on an "AS IS" BASIS, REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. REM See the License for the specific language governing permissions and REM limitations under the License. REM checking for emptiness was tricky - see http://www.robvanderwoude.com/parameters.php :Loop IF [%1]==[] GOTO Continue @ECHO "%1" SHIFT GOTO Loop :Continuecommons-exec-1.3-src/src/test/scripts/printargs.dcl100644 0 0 2655 12425540623 17633 0ustar 0 0 $!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! $! $! Licensed to the Apache Software Foundation (ASF) under one or more $! contributor license agreements. See the NOTICE file distributed with $! this work for additional information regarding copyright ownership. $! The ASF licenses this file to You under the Apache License, Version 2.0 $! (the "License"); you may not use this file except in compliance with $! the License. You may obtain a copy of the License at $! $! http://www.apache.org/licenses/LICENSE-2.0 $! $! Unless required by applicable law or agreed to in writing, software $! distributed under the License is distributed on an "AS IS" BASIS, $! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. $! See the License for the specific language governing permissions and $! limitations under the License. $! $!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! $! $! Print arguments $! $! Crude, but effective. Works even if argument contains un-doubled double-quotes $ if f$length(P1) .gt. 0 then write sys$output P1 $ if f$length(P2) .gt. 0 then write sys$output P2 $ if f$length(P3) .gt. 0 then write sys$output P3 $ if f$length(P4) .gt. 0 then write sys$output P4 $ if f$length(P5) .gt. 0 then write sys$output P5 $ if f$length(P6) .gt. 0 then write sys$output P6 $ if f$length(P7) .gt. 0 then write sys$output P7 $ if f$length(P8) .gt. 0 then write sys$output P8commons-exec-1.3-src/src/test/scripts/stdin.bat100644 0 0 1577 12425540623 16751 0ustar 0 0 @ECHO OFF REM Licensed to the Apache Software Foundation (ASF) under one or more REM contributor license agreements. See the NOTICE file distributed with REM this work for additional information regarding copyright ownership. REM The ASF licenses this file to You under the Apache License, Version 2.0 REM (the "License"); you may not use this file except in compliance with REM the License. You may obtain a copy of the License at REM REM http://www.apache.org/licenses/LICENSE-2.0 REM REM Unless required by applicable law or agreed to in writing, software REM distributed under the License is distributed on an "AS IS" BASIS, REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. REM See the License for the specific language governing permissions and REM limitations under the License. set /p answer=What's your name? : echo Hello %answer%!commons-exec-1.3-src/src/test/scripts/stdin.dcl100644 0 0 2064 12425540623 16735 0ustar 0 0 $!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! $! $! Licensed to the Apache Software Foundation (ASF) under one or more $! contributor license agreements. See the NOTICE file distributed with $! this work for additional information regarding copyright ownership. $! The ASF licenses this file to You under the Apache License, Version 2.0 $! (the "License"); you may not use this file except in compliance with $! the License. You may obtain a copy of the License at $! $! http://www.apache.org/licenses/LICENSE-2.0 $! $! Unless required by applicable law or agreed to in writing, software $! distributed under the License is distributed on an "AS IS" BASIS, $! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. $! See the License for the specific language governing permissions and $! limitations under the License. $! $!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! $! $! Read input and display it $! $ read /prompt="What's your name? : " sys$command answer $ write sys$output "Hello ''answer'!"commons-exec-1.3-src/src/test/scripts/test.bat100644 0 0 1755 12425540623 16605 0ustar 0 0 @ECHO OFF REM REM Licensed to the Apache Software Foundation (ASF) under one or more REM contributor license agreements. See the NOTICE file distributed with REM this work for additional information regarding copyright ownership. REM The ASF licenses this file to You under the Apache License, Version 2.0 REM (the "License"); you may not use this file except in compliance with REM the License. You may obtain a copy of the License at REM REM http://www.apache.org/licenses/LICENSE-2.0 REM REM Unless required by applicable law or agreed to in writing, software REM distributed under the License is distributed on an "AS IS" BASIS, REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. REM See the License for the specific language governing permissions and REM limitations under the License. REM REM REM print the given environment variable and command line parameter REM since this is verified by the regression test @ECHO FOO.%TEST_ENV_VAR%.%1 commons-exec-1.3-src/src/test/scripts/test.dcl100644 0 0 2165 12425540623 16575 0ustar 0 0 $!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! $! $! Licensed to the Apache Software Foundation (ASF) under one or more $! contributor license agreements. See the NOTICE file distributed with $! this work for additional information regarding copyright ownership. $! The ASF licenses this file to You under the Apache License, Version 2.0 $! (the "License"); you may not use this file except in compliance with $! the License. You may obtain a copy of the License at $! $! http://www.apache.org/licenses/LICENSE-2.0 $! $! Unless required by applicable law or agreed to in writing, software $! distributed under the License is distributed on an "AS IS" BASIS, $! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. $! See the License for the specific language governing permissions and $! limitations under the License. $! $!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! $! $! print the given environment variable and command line parameter $! since this is verified by the regression test $! $ write sys$output "FOO.''TEST_ENV_VAR'.''P1'" $! $ exit 1 ! normal exitcommons-exec-1.3-src/src/test/scripts/acrord32.sh100775 0 0 1711 12425540623 17106 0ustar 0 0 #!/bin/sh # # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # Simulate printing a PDF document echo "[acrord32] Printing the following document : $3" for i in {1..10} do sleep 1 done echo "[acrord32] Finished printing" exit 1 commons-exec-1.3-src/src/test/scripts/environment.sh100775 0 0 1503 12425540623 20032 0ustar 0 0 #!/bin/sh # # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # print the environment variables envcommons-exec-1.3-src/src/test/scripts/error.sh100775 0 0 1562 12425540623 16624 0ustar 0 0 #!/bin/sh # # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # # do something and return en error result code echo FOO.$TEST_ENV_VAR.$1 exit 1 commons-exec-1.3-src/src/test/scripts/forever.sh100775 0 0 1735 12425540623 17145 0ustar 0 0 #!/bin/sh # # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # run an infinite loop so the script will never ever terminate on its behalf # and append a '.' after each second while test "notempty" do sleep 1 echo '.\c' >> ./target/forever.txt donecommons-exec-1.3-src/src/test/scripts/invoker.sh100775 0 0 1645 12425540623 17152 0ustar 0 0 #!/bin/sh # # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # echo "invoker.sh -- going to start daemon process" cd ../../../target nohup sleep 10 & echo "invoker.sh -- daemon process was started"commons-exec-1.3-src/src/test/scripts/ping.sh100775 0 0 2046 12425540623 16426 0ustar 0 0 #!/bin/sh # # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # ping is started as subprocess which runs for '$1' seconds echo "[ping.sh] Blocking for $1 seconds ..." # see EXEC-52 - option must appear after the hostname! if test "$(uname -s)" = "HP-UX" then ping 127.0.0.1 -n $1 else ping -c $1 127.0.0.1 fi commons-exec-1.3-src/src/test/scripts/printargs.sh100775 0 0 1613 12425540623 17501 0ustar 0 0 #!/bin/sh # # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # Helper script to print out the command line arguments while [ $# -gt 0 ] do echo "$1" shift done commons-exec-1.3-src/src/test/scripts/redirect.sh100775 0 0 1663 12425540623 17276 0ustar 0 0 #!/bin/sh # # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # read from stdin and output to stdout while read myline do echo "stdout: $myline" done echo 1>&2 "stderr: Finished reading from stdin" exit 0 commons-exec-1.3-src/src/test/scripts/standalone.sh100775 0 0 1525 12425540623 17622 0ustar 0 0 #!/bin/sh # # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # mkdir target/ cat pom.xml | gzip> ./target/mybackup.gz commons-exec-1.3-src/src/test/scripts/stdin.sh100775 0 0 1535 12425540623 16614 0ustar 0 0 #!/bin/sh # # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # echo "What's your name? : " read answer echo "Hello $answer!" commons-exec-1.3-src/src/test/scripts/test.sh100775 0 0 1653 12425540623 16453 0ustar 0 0 #!/bin/sh # # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # print the given environment variable and command line parameter # since this is verified by the regression test echo FOO.$TEST_ENV_VAR.$1