1c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com/*
2c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com * [The "BSD licence"]
3c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com * Copyright (c) 2010 Ben Gruver
4c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com * All rights reserved.
5c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com *
6c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com * Redistribution and use in source and binary forms, with or without
7c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com * modification, are permitted provided that the following conditions
8c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com * are met:
9c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com * 1. Redistributions of source code must retain the above copyright
10c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com *    notice, this list of conditions and the following disclaimer.
11c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com * 2. Redistributions in binary form must reproduce the above copyright
12c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com *    notice, this list of conditions and the following disclaimer in the
13c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com *    documentation and/or other materials provided with the distribution.
14c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com * 3. The name of the author may not be used to endorse or promote products
15c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com *    derived from this software without specific prior written permission.
16c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com *
17c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com */
28c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.compackage org.jf.util;
29c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com
30c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.comimport java.io.BufferedReader;
31c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.comimport java.io.InputStreamReader;
32c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.comimport java.util.regex.Matcher;
33c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.comimport java.util.regex.Pattern;
34c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com
35c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.compublic class ConsoleUtil {
36c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com    /**
37c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com     * Attempt to find the width of the console. If it can't get the width, return a default of 80
38aae58716e7f8f145c8bf26e95578fbbaae586309Ben Gruver     * @return The current console width
39c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com     */
40c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com    public static int getConsoleWidth() {
41c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com        if (System.getProperty("os.name").toLowerCase().contains("windows")) {
42c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com            try {
43c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com                return attemptMode();
44c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com            } catch (Exception ex) {
45c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com            }
46c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com        } else {
47c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com            try {
48c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com                return attemptStty();
49c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com            } catch (Exception ex) {
50c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com            }
51c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com        }
52c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com
53c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com        return 80;
54c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com    }
55c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com
56c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com    private static int attemptStty() {
57c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com        String output = attemptCommand(new String[]{"sh", "-c", "stty size < /dev/tty"});
58c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com        if (output == null) {
59c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com            return 80;
60c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com        }
61c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com
62c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com        String[] vals = output.split(" ");
63c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com        if (vals.length < 2) {
64c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com            return 80;
65c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com        }
66c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com        return Integer.parseInt(vals[1]);
67c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com    }
68c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com
69c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com    private static int attemptMode() {
70c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com        String output = attemptCommand(new String[]{"mode", "con"});
71c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com        if (output == null) {
72c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com            return 80;
73c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com        }
74c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com
75c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com        Pattern pattern = Pattern.compile("Columns:[ \t]*(\\d+)");
76c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com        Matcher m = pattern.matcher(output);
77c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com        if (!m.find()) {
78c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com            return 80;
79c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com        }
80c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com
81c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com        return Integer.parseInt(m.group(1));
82c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com    }
83c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com
84c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com    private static String attemptCommand(String[] command) {
85c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com        StringBuffer buffer = null;
86c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com
87c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com        try {
88c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com
89c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com            Process p = Runtime.getRuntime().exec(command);
90c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com            BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
91c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com
92c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com            String line;
93c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com
94c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com            while ((line = reader.readLine()) != null) {
95c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com                if (buffer == null) {
96c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com                    buffer = new StringBuffer();
97c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com                }
98c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com
99c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com                buffer.append(line);
100c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com            }
101c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com
102c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com            if (buffer != null) {
103c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com                return buffer.toString();
104c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com            }
105c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com            return null;
106c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com        } catch (Exception ex) {
107c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com            return null;
108c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com        }
109c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com    }
110c616a0dadca9cbffdf4827eeb6c2da064ad9f7b7JesusFreke@JesusFreke.com}
111