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