java/sql-dk/src/info/globalcode/sql/dk/ColorfulPrintWriter.java
author František Kučera <franta-hg@frantovo.cz>
Tue, 26 Feb 2019 18:19:49 +0100
branchv_0
changeset 236 a3ec71fa8e17
parent 155 eb3676c6929b
permissions -rw-r--r--
Avoid reusing/rewriting the DB connection properties.
There was weird random errors while testing connection to multiple DB in parallel when one of them was meta connection to same DB connection.
Two kinds of exception: 1) missing password 2) „Passing DB password as CLI parameter is insecure!“
     1 /**
     2  * SQL-DK
     3  * Copyright © 2013 František Kučera (frantovo.cz)
     4  *
     5  * This program is free software: you can redistribute it and/or modify
     6  * it under the terms of the GNU General Public License as published by
     7  * the Free Software Foundation, either version 3 of the License, or
     8  * (at your option) any later version.
     9  *
    10  * This program is distributed in the hope that it will be useful,
    11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    13  * GNU General Public License for more details.
    14  *
    15  * You should have received a copy of the GNU General Public License
    16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
    17  */
    18 package info.globalcode.sql.dk;
    19 
    20 import java.io.File;
    21 import java.io.FileNotFoundException;
    22 import java.io.OutputStream;
    23 import java.io.PrintWriter;
    24 import java.io.UnsupportedEncodingException;
    25 import java.io.Writer;
    26 import java.util.EnumSet;
    27 
    28 /**
    29  * PrintWriter with convenience methods for printing color and formatted text.
    30  *
    31  * Uses ANSI Escape Sequences.
    32  * See: http://www.tldp.org/HOWTO/Bash-Prompt-HOWTO/x329.html
    33  *
    34  * @author Ing. František Kučera (frantovo.cz)
    35  */
    36 public class ColorfulPrintWriter extends PrintWriter {
    37 
    38 	public enum TerminalColor {
    39 
    40 		Black(30, 40),
    41 		Red(31, 41),
    42 		Green(32, 42),
    43 		Yellow(33, 43),
    44 		Blue(34, 44),
    45 		Magenta(35, 45),
    46 		Cyan(36, 46),
    47 		White(37, 47);
    48 		private final int foregroundCode;
    49 		private final int backgroundCode;
    50 
    51 		private TerminalColor(int foregroundCode, int backgroundCode) {
    52 			this.foregroundCode = foregroundCode;
    53 			this.backgroundCode = backgroundCode;
    54 		}
    55 
    56 		public int getForegroundCode() {
    57 			return foregroundCode;
    58 		}
    59 
    60 		public int getBackgroundCode() {
    61 			return backgroundCode;
    62 		}
    63 	}
    64 
    65 	public enum TerminalStyle {
    66 
    67 		Reset(0),
    68 		Bright(1),
    69 		Dim(2),
    70 		Underscore(4),
    71 		Blink(5),
    72 		Reverse(7),
    73 		Hidden(8);
    74 		private int code;
    75 
    76 		private TerminalStyle(int code) {
    77 			this.code = code;
    78 		}
    79 
    80 		public int getCode() {
    81 			return code;
    82 		}
    83 	}
    84 	private final boolean COLOR_ENABLED;
    85 	private boolean colorful = true;
    86 
    87 	public void setStyle(TerminalStyle style) {
    88 		setStyle(EnumSet.of(style));
    89 	}
    90 
    91 	public void setStyle(EnumSet<TerminalStyle> styles) {
    92 		printCodes(getStyleCodes(styles));
    93 	}
    94 
    95 	private static int[] getStyleCodes(EnumSet<TerminalStyle> styles) {
    96 		int[] array = new int[styles.size()];
    97 		int i = 0;
    98 		for (TerminalStyle s : styles) {
    99 			array[i++] = s.getCode();
   100 		}
   101 		return array;
   102 	}
   103 
   104 	/**
   105 	 * Print (usually audible) bell code (\007, \a, ^G)
   106 	 */
   107 	public void bell() {
   108 		print("\007");
   109 	}
   110 
   111 	/**
   112 	 * Eat the last character
   113 	 */
   114 	public void backspace() {
   115 		print("\b");
   116 	}
   117 
   118 	/**
   119 	 * Eat n last characters
   120 	 *
   121 	 * @param count n
   122 	 */
   123 	public void backspace(int count) {
   124 		for (int i = 0; i < count; i++) {
   125 			backspace();
   126 		}
   127 	}
   128 
   129 	/**
   130 	 * With 100 ms delay and all colors.
   131 	 *
   132 	 * @see #printRainbow(java.lang.String, int,
   133 	 * info.globalcode.sql.dk.ColorfulPrintWriter.TerminalColor[])
   134 	 */
   135 	public void printRainbow(String string) {
   136 		printRainbow(string, 100);
   137 	}
   138 
   139 	/**
   140 	 * With all colors.
   141 	 *
   142 	 * @see #printRainbow(java.lang.String, int,
   143 	 * info.globalcode.sql.dk.ColorfulPrintWriter.TerminalColor[])
   144 	 */
   145 	public void printRainbow(String string, int delay) {
   146 		printRainbow(string, delay, TerminalColor.values());
   147 	}
   148 
   149 	/**
   150 	 * Prints rainbow text – (re)writes same text subsequently in given colors and then in default
   151 	 * color.
   152 	 *
   153 	 * @param string text to be printed, should not contain \n new line (then rainbow does not work
   154 	 * – use println() after printRainbow() instead)
   155 	 * @param delay delay between rewrites
   156 	 * @param colors list of colors to be used
   157 	 */
   158 	public void printRainbow(String string, int delay, TerminalColor... colors) {
   159 		for (TerminalColor c : colors) {
   160 			print(c, string);
   161 			try {
   162 				Thread.sleep(delay);
   163 			} catch (InterruptedException e) {
   164 				// no time to sleep
   165 				break;
   166 			}
   167 			backspace(string.length());
   168 			flush();
   169 		}
   170 		print(string);
   171 	}
   172 
   173 	public void setForegroundColor(TerminalColor color) {
   174 		printCodes(color.getForegroundCode());
   175 	}
   176 
   177 	public void setBackgroundColor(TerminalColor color) {
   178 		printCodes(color.getBackgroundCode());
   179 	}
   180 
   181 	public void print(TerminalColor foregroundColor, String string) {
   182 		setForegroundColor(foregroundColor);
   183 		print(string);
   184 		resetAll();
   185 	}
   186 
   187 	public void println(TerminalColor foregroundColor, String string) {
   188 		print(foregroundColor, string);
   189 		println();
   190 	}
   191 
   192 	public void print(TerminalColor foregroundColor, TerminalColor backgroundColor, String string) {
   193 		setForegroundColor(foregroundColor);
   194 		setBackgroundColor(backgroundColor);
   195 		print(string);
   196 		resetAll();
   197 	}
   198 
   199 	public void println(TerminalColor foregroundColor, TerminalColor backgroundColor, String string) {
   200 		print(foregroundColor, backgroundColor, string);
   201 		println();
   202 	}
   203 
   204 	public void print(TerminalColor foregroundColor, TerminalColor backgroundColor, EnumSet<TerminalStyle> styles, String string) {
   205 		setForegroundColor(foregroundColor);
   206 		setBackgroundColor(backgroundColor);
   207 		setStyle(styles);
   208 		print(string);
   209 		resetAll();
   210 	}
   211 
   212 	public void println(TerminalColor foregroundColor, TerminalColor backgroundColor, EnumSet<TerminalStyle> styles, String string) {
   213 		print(foregroundColor, backgroundColor, styles, string);
   214 		println();
   215 	}
   216 
   217 	public void print(TerminalColor foregroundColor, TerminalColor backgroundColor, TerminalStyle style, String string) {
   218 		print(foregroundColor, backgroundColor, EnumSet.of(style), string);
   219 	}
   220 
   221 	public void println(TerminalColor foregroundColor, TerminalColor backgroundColor, TerminalStyle style, String string) {
   222 		print(foregroundColor, backgroundColor, style, string);
   223 		println();
   224 	}
   225 
   226 	public void print(TerminalColor foregroundColor, EnumSet<TerminalStyle> styles, String string) {
   227 		setForegroundColor(foregroundColor);
   228 		setStyle(styles);
   229 		print(string);
   230 		resetAll();
   231 	}
   232 
   233 	public void println(TerminalColor foregroundColor, EnumSet<TerminalStyle> styles, String string) {
   234 		print(foregroundColor, styles, string);
   235 		println();
   236 	}
   237 
   238 	public void print(TerminalColor foregroundColor, TerminalStyle style, String string) {
   239 		print(foregroundColor, EnumSet.of(style), string);
   240 	}
   241 
   242 	public void println(TerminalColor foregroundColor, TerminalStyle style, String string) {
   243 		print(foregroundColor, style, string);
   244 		println();
   245 	}
   246 
   247 	public void print(EnumSet<TerminalStyle> styles, String string) {
   248 		setStyle(styles);
   249 		print(string);
   250 		resetAll();
   251 	}
   252 
   253 	public void println(EnumSet<TerminalStyle> styles, String string) {
   254 		print(styles, string);
   255 		println();
   256 	}
   257 
   258 	public void print(TerminalStyle style, String string) {
   259 		print(EnumSet.of(style), string);
   260 	}
   261 
   262 	public void println(TerminalStyle style, String string) {
   263 		print(style, string);
   264 		println();
   265 	}
   266 
   267 	public void resetAll() {
   268 		printCodes(TerminalStyle.Reset.code);
   269 	}
   270 
   271 	private void printCodes(int... codes) {
   272 		if (COLOR_ENABLED && colorful) {
   273 			print("\033[");
   274 			for (int i = 0; i < codes.length; i++) {
   275 				print(codes[i]);
   276 				if (i < codes.length - 1 && codes.length > 1) {
   277 					print(";");
   278 				}
   279 			}
   280 			print("m");
   281 		}
   282 	}
   283 
   284 	/**
   285 	 * Colors can be switched on/off during usage of this writer.
   286 	 *
   287 	 * @return whether colors are currently turned on
   288 	 * @see #isColorEnabled()
   289 	 */
   290 	public boolean isColorful() {
   291 		return colorful;
   292 	}
   293 
   294 	/**
   295 	 * Collors might be definitively disabled in constructor. If not, they can be turned on/off
   296 	 * during usage of this writer by {@linkplain #setColorful(boolean)}
   297 	 *
   298 	 * @return whether colors are allowed for this instance of this class
   299 	 * @see #isColorful()
   300 	 */
   301 	public boolean isColorEnabled() {
   302 		return COLOR_ENABLED;
   303 	}
   304 
   305 	/**
   306 	 * @see #isColorful()
   307 	 * @see #isColorEnabled()
   308 	 */
   309 	public void setColorful(boolean colorful) {
   310 		this.colorful = colorful;
   311 	}
   312 
   313 	public ColorfulPrintWriter(File file) throws FileNotFoundException {
   314 		super(file);
   315 		COLOR_ENABLED = true;
   316 	}
   317 
   318 	public ColorfulPrintWriter(OutputStream out) {
   319 		super(out);
   320 		COLOR_ENABLED = true;
   321 	}
   322 
   323 	public ColorfulPrintWriter(String fileName) throws FileNotFoundException {
   324 		super(fileName);
   325 		COLOR_ENABLED = true;
   326 	}
   327 
   328 	public ColorfulPrintWriter(Writer out) {
   329 		super(out);
   330 		COLOR_ENABLED = true;
   331 	}
   332 
   333 	public ColorfulPrintWriter(File file, String csn) throws FileNotFoundException, UnsupportedEncodingException {
   334 		super(file, csn);
   335 		COLOR_ENABLED = true;
   336 	}
   337 
   338 	/**
   339 	 * @param colorEnabled colors might be definitively disabled by this option – this might be more
   340 	 * optimalizable than dynamic turning off colors by {@linkplain #setColorful(boolean)} which is
   341 	 * not definitive (colors can be turned on during live of this instance). This might be useful
   342 	 * if you need an instance of this class but don't need colors at all.
   343 	 */
   344 	public ColorfulPrintWriter(OutputStream out, boolean autoFlush, boolean colorEnabled) {
   345 		super(out, autoFlush);
   346 		COLOR_ENABLED = colorEnabled;
   347 	}
   348 
   349 	public ColorfulPrintWriter(String fileName, String csn) throws FileNotFoundException, UnsupportedEncodingException {
   350 		super(fileName, csn);
   351 		COLOR_ENABLED = true;
   352 	}
   353 
   354 	public ColorfulPrintWriter(Writer out, boolean autoFlush) {
   355 		super(out, autoFlush);
   356 		COLOR_ENABLED = true;
   357 	}
   358 }