View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    *  contributor license agreements.  See the NOTICE file distributed with
4    *  this work for additional information regarding copyright ownership.
5    *  The ASF licenses this file to You under the Apache License, Version 2.0
6    *  (the "License"); you may not use this file except in compliance with
7    *  the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   *  Unless required by applicable law or agreed to in writing, software
12   *  distributed under the License is distributed on an "AS IS" BASIS,
13   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   *  See the License for the specific language governing permissions and
15   *  limitations under the License.
16   */
17  
18  package org.apache.commons.exec;
19  
20  import static org.junit.jupiter.api.Assertions.fail;
21  
22  import java.io.File;
23  import java.io.IOException;
24  import java.time.Duration;
25  import java.util.HashMap;
26  import java.util.Map;
27  
28  import org.junit.jupiter.api.Test;
29  
30  /**
31   * An example based on the tutorial where the user can safely play with
32   * <ul>
33   * <li>blocking or non-blocking print jobs
34   * <li>with print job timeouts to trigger the {@code ExecuteWatchdog}
35   * <li>with the {@code exitValue} returned from the print script
36   * </ul>
37   */
38  public class TutorialTest {
39  
40      private final class PrintResultHandler extends DefaultExecuteResultHandler {
41  
42          private ExecuteWatchdog watchdog;
43  
44          public PrintResultHandler(final ExecuteWatchdog watchdog) {
45              this.watchdog = watchdog;
46          }
47  
48          public PrintResultHandler(final int exitValue) {
49              super.onProcessComplete(exitValue);
50          }
51  
52          @Override
53          public void onProcessComplete(final int exitValue) {
54              super.onProcessComplete(exitValue);
55              System.out.println("[resultHandler] The document was successfully printed ...");
56          }
57  
58          @Override
59          public void onProcessFailed(final ExecuteException e) {
60              super.onProcessFailed(e);
61              if (watchdog != null && watchdog.killedProcess()) {
62                  System.err.println("[resultHandler] The print process timed out");
63              } else {
64                  System.err.println("[resultHandler] The print process failed to do : " + e.getMessage());
65              }
66          }
67      }
68  
69      /** The directory to pick up the test scripts */
70      private final File testDir = new File("src/test/scripts");
71  
72      /** Simulates a PDF print job */
73      private final File acroRd32Script = TestUtil.resolveScriptForOS(testDir + "/acrord32");
74  
75      /**
76       * Simulate printing a PDF document.
77       *
78       * @param file              the file to print
79       * @param printJobTimeout   the printJobTimeout (ms) before the watchdog terminates the print process
80       * @param printInBackground printing done in the background or blocking
81       * @return a print result handler (implementing a future)
82       * @throws IOException the test failed
83       */
84      public PrintResultHandler print(final File file, final Duration printJobTimeout, final boolean printInBackground) throws IOException {
85  
86          int exitValue;
87          ExecuteWatchdog watchdog = null;
88          PrintResultHandler resultHandler;
89  
90          // build up the command line to using a 'java.io.File'
91          final Map<String, File> map = new HashMap<>();
92          map.put("file", file);
93          final CommandLine commandLine = new CommandLine(acroRd32Script);
94          commandLine.addArgument("/p");
95          commandLine.addArgument("/h");
96          commandLine.addArgument("${file}");
97          commandLine.setSubstitutionMap(map);
98  
99          // create the executor and consider the exitValue '1' as success
100         final Executor executor = DefaultExecutor.builder().get();
101         executor.setExitValue(1);
102 
103         // create a watchdog if requested
104         if (printJobTimeout.toMillis() > 0) {
105             watchdog = ExecuteWatchdog.builder().setTimeout(printJobTimeout).get();
106             executor.setWatchdog(watchdog);
107         }
108 
109         // pass a "ExecuteResultHandler" when doing background printing
110         if (printInBackground) {
111             System.out.println("[print] Executing non-blocking print job  ...");
112             resultHandler = new PrintResultHandler(watchdog);
113             executor.execute(commandLine, resultHandler);
114         } else {
115             System.out.println("[print] Executing blocking print job  ...");
116             exitValue = executor.execute(commandLine);
117             resultHandler = new PrintResultHandler(exitValue);
118         }
119 
120         return resultHandler;
121     }
122 
123     @Test
124     public void testTutorialExample() throws Exception {
125 
126         final Duration printJobTimeout = Duration.ofSeconds(15);
127         final boolean printInBackground = false;
128         final File pdfFile = new File("/Documents and Settings/foo.pdf");
129 
130         PrintResultHandler printResult;
131 
132         try {
133             // printing takes around 10 seconds
134             System.out.println("[main] Preparing print job ...");
135             printResult = print(pdfFile, printJobTimeout, printInBackground);
136             System.out.println("[main] Successfully sent the print job ...");
137         } catch (final Exception e) {
138             e.printStackTrace();
139             fail("[main] Printing of the following document failed : " + pdfFile.getAbsolutePath());
140             throw e;
141         }
142 
143         // come back to check the print result
144         System.out.println("[main] Test is exiting but waiting for the print job to finish...");
145         printResult.waitFor();
146         System.out.println("[main] The print job has finished ...");
147     }
148 }