OpenConcerto

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

svn://code.openconcerto.org/openconcerto

Rev

Rev 17 | Rev 93 | Go to most recent revision | Details | Compare with Previous | 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
 
80 ilm 34
    static public enum Action {
35
        /**
36
         * Redirect process streams to ours.
37
         */
38
        REDIRECT,
39
        /**
40
         * Close process streams.
41
         */
42
        CLOSE,
43
        /**
44
         * Do nothing, which is dangerous as the process will hang until its output is read.
45
         */
46
        DO_NOTHING
47
    }
48
 
49
    static public final Process handle(final Process p, final Action action) throws IOException {
50
        if (action == Action.CLOSE) {
51
            p.getInputStream().close();
52
            p.getErrorStream().close();
53
        } else if (action == Action.REDIRECT) {
54
            new ProcessStreams(p);
55
        }
56
        return p;
57
    }
58
 
17 ilm 59
    private final ExecutorService exec = Executors.newFixedThreadPool(2);
60
    private final CountDownLatch latch;
61
    private final Future<?> out;
62
    private final Future<?> err;
63
 
64
    public ProcessStreams(final Process p) {
65
        this.latch = new CountDownLatch(2);
66
        this.out = writeToAsync(p.getInputStream(), System.out);
67
        this.err = writeToAsync(p.getErrorStream(), System.err);
80 ilm 68
        this.exec.submit(new Runnable() {
17 ilm 69
            public void run() {
70
                try {
71
                    ProcessStreams.this.latch.await();
72
                } catch (InterruptedException e) {
73
                    // ne rien faire
74
                    e.printStackTrace();
75
                } finally {
76
                    ProcessStreams.this.exec.shutdown();
77
                }
78
            }
80 ilm 79
        });
17 ilm 80
    }
81
 
82
    protected final void stopOut() {
83
        this.stop(this.out);
84
    }
85
 
86
    protected final void stopErr() {
87
        this.stop(this.err);
88
    }
89
 
90
    private final void stop(Future<?> f) {
91
        // TODO
92
        // ATTN don't interrupt, hangs in readLine()
93
        f.cancel(false);
94
    }
95
 
96
    private final Future<?> writeToAsync(final InputStream ins, final PrintStream outs) {
97
        return this.exec.submit(new Callable<Object>() {
98
            public Object call() throws InterruptedException, IOException {
99
                try {
100
                    writeTo(ins, outs);
101
                    return null;
102
                } finally {
103
                    ProcessStreams.this.latch.countDown();
104
                }
105
            }
106
        });
107
    }
108
 
109
    /**
110
     * Copy ins to outs, line by line.
111
     *
112
     * @param ins the source.
113
     * @param outs the destination.
114
     * @throws InterruptedException if current thread is interrupted.
115
     * @throws IOException if io error.
116
     */
117
    public static final void writeTo(InputStream ins, PrintStream outs) throws InterruptedException, IOException {
118
        final BufferedReader r = new BufferedReader(new InputStreamReader(ins));
119
        String encodedName;
120
        while ((encodedName = r.readLine()) != null) {
121
            if (Thread.currentThread().isInterrupted()) {
122
                throw new InterruptedException();
123
            }
124
            outs.println(encodedName);
125
        }
126
    }
127
 
128
}