OpenConcerto

Dépôt officiel du code source de l'ERP OpenConcerto
sonarqube

svn://code.openconcerto.org/openconcerto

Rev

Rev 80 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
17 ilm 1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
5
 *
6
 * The contents of this file are subject to the terms of the GNU General Public License Version 3
7
 * only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
8
 * copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
9
 * language governing permissions and limitations under the License.
10
 *
11
 * When distributing the software, include this License Header Notice in each file.
12
 */
13
 
14
 package org.openconcerto.utils;
15
 
16
import java.io.BufferedReader;
17
import java.io.IOException;
18
import java.io.InputStream;
19
import java.io.InputStreamReader;
20
import java.io.PrintStream;
21
import java.util.concurrent.Callable;
22
import java.util.concurrent.CountDownLatch;
23
import java.util.concurrent.ExecutorService;
24
import java.util.concurrent.Executors;
25
import java.util.concurrent.Future;
26
 
27
/**
28
 * Redirect streams of a process to System.out and System.err.
29
 *
30
 * @author Sylvain
31
 */
32
public class ProcessStreams {
33
 
34
    private final ExecutorService exec = Executors.newFixedThreadPool(2);
35
    private final CountDownLatch latch;
36
    private final Future<?> out;
37
    private final Future<?> err;
38
 
39
    public ProcessStreams(final Process p) {
40
        this.latch = new CountDownLatch(2);
41
        this.out = writeToAsync(p.getInputStream(), System.out);
42
        this.err = writeToAsync(p.getErrorStream(), System.err);
43
        new Thread(new Runnable() {
44
            public void run() {
45
                try {
46
                    ProcessStreams.this.latch.await();
47
                } catch (InterruptedException e) {
48
                    // ne rien faire
49
                    e.printStackTrace();
50
                } finally {
51
                    ProcessStreams.this.exec.shutdown();
52
                }
53
            }
54
        }).start();
55
    }
56
 
57
    protected final void stopOut() {
58
        this.stop(this.out);
59
    }
60
 
61
    protected final void stopErr() {
62
        this.stop(this.err);
63
    }
64
 
65
    private final void stop(Future<?> f) {
66
        // TODO
67
        // ATTN don't interrupt, hangs in readLine()
68
        f.cancel(false);
69
    }
70
 
71
    private final Future<?> writeToAsync(final InputStream ins, final PrintStream outs) {
72
        return this.exec.submit(new Callable<Object>() {
73
            public Object call() throws InterruptedException, IOException {
74
                try {
75
                    writeTo(ins, outs);
76
                    return null;
77
                } finally {
78
                    ProcessStreams.this.latch.countDown();
79
                }
80
            }
81
        });
82
    }
83
 
84
    /**
85
     * Copy ins to outs, line by line.
86
     *
87
     * @param ins the source.
88
     * @param outs the destination.
89
     * @throws InterruptedException if current thread is interrupted.
90
     * @throws IOException if io error.
91
     */
92
    public static final void writeTo(InputStream ins, PrintStream outs) throws InterruptedException, IOException {
93
        final BufferedReader r = new BufferedReader(new InputStreamReader(ins));
94
        String encodedName;
95
        while ((encodedName = r.readLine()) != null) {
96
            if (Thread.currentThread().isInterrupted()) {
97
                throw new InterruptedException();
98
            }
99
            outs.println(encodedName);
100
        }
101
    }
102
 
103
}