java/sql-dk/src/info/globalcode/sql/dk/Functions.java
author František Kučera <franta-hg@frantovo.cz>
Tue, 26 Feb 2019 18:19:49 +0100
branchv_0
changeset 236 a3ec71fa8e17
parent 220 0bc544b38cfa
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 info.globalcode.sql.dk.configuration.NameIdentified;
    21 import info.globalcode.sql.dk.configuration.PropertyDeclaration;
    22 import info.globalcode.sql.dk.configuration.PropertyDeclarations;
    23 import info.globalcode.sql.dk.formatting.Formatter;
    24 import java.io.BufferedReader;
    25 import java.io.File;
    26 import java.io.IOException;
    27 import java.io.InputStream;
    28 import java.io.InputStreamReader;
    29 import java.io.PrintWriter;
    30 import java.util.ArrayList;
    31 import java.util.Arrays;
    32 import java.util.Collection;
    33 import java.util.Collections;
    34 import java.util.List;
    35 import java.util.Map;
    36 import java.util.regex.Matcher;
    37 import java.util.regex.Pattern;
    38 
    39 /**
    40  *
    41  * @author Ing. František Kučera (frantovo.cz)
    42  */
    43 public class Functions {
    44 
    45 	private static final String NBSP = " ";
    46 	private static final Pattern WHITESPACE_TO_REPLACE = Pattern.compile("\\n|\\r|\\t|" + NBSP);
    47 
    48 	private Functions() {
    49 	}
    50 
    51 	public static boolean equalz(Object a, Object b) {
    52 		return a == null ? b == null : a.equals(b);
    53 	}
    54 
    55 	/**
    56 	 *
    57 	 * @param text String to be examinated
    58 	 * @param trim whether text should be trimmed before examination
    59 	 * @return whether text is not empty and one or more characters long (after prospective trim)
    60 	 */
    61 	public static boolean isEmpty(String text, boolean trim) {
    62 		if (text == null) {
    63 			return true;
    64 		} else {
    65 			if (trim) {
    66 				text = text.trim();
    67 			}
    68 			return text.isEmpty();
    69 		}
    70 	}
    71 
    72 	/**
    73 	 * @see #isEmpty(java.lang.String, boolean)
    74 	 */
    75 	public static boolean isNotEmpty(String text, boolean trim) {
    76 		return !isEmpty(text, trim);
    77 	}
    78 
    79 	public boolean isEmpty(Collection c) {
    80 		return c == null || c.isEmpty();
    81 	}
    82 
    83 	public boolean isNotEmpty(Collection c) {
    84 		return !isEmpty(c);
    85 	}
    86 
    87 	public boolean isEmpty(Map m) {
    88 		return m == null || m.isEmpty();
    89 	}
    90 
    91 	public boolean isNotEmpty(Map m) {
    92 		return !isEmpty(m);
    93 	}
    94 
    95 	/**
    96 	 * @return empty collection if given one is null | or the original one
    97 	 */
    98 	public static <T> Collection<T> notNull(Collection<T> c) {
    99 		if (c == null) {
   100 			return Collections.emptyList();
   101 		} else {
   102 			return c;
   103 		}
   104 	}
   105 
   106 	public static <T extends NameIdentified> T findByName(Collection<T> collection, String name) {
   107 		for (T element : notNull(collection)) {
   108 			if (element != null && equalz(element.getName(), name)) {
   109 				return element;
   110 			}
   111 		}
   112 
   113 		return null;
   114 	}
   115 
   116 	/**
   117 	 * Copy file from Java resources to file system.
   118 	 */
   119 	public static void installResource(String resourceName, File target) throws IOException {
   120 		try (BufferedReader reader = new BufferedReader(new InputStreamReader(Functions.class.getClassLoader().getResourceAsStream(resourceName)))) {
   121 			try (PrintWriter writer = new PrintWriter(target)) {
   122 				while (true) {
   123 					String line = reader.readLine();
   124 					if (line == null) {
   125 						break;
   126 					} else {
   127 						writer.println(line);
   128 					}
   129 				}
   130 			}
   131 		}
   132 	}
   133 
   134 	public static String rpad(String s, int n) {
   135 		if (n > 0) {
   136 			return String.format("%1$-" + n + "s", s);
   137 		} else {
   138 			return s;
   139 		}
   140 	}
   141 
   142 	public static String lpad(String s, int n) {
   143 		if (n > 0) {
   144 			return String.format("%1$" + n + "s", s);
   145 		} else {
   146 			return s;
   147 		}
   148 	}
   149 
   150 	public static String repeat(char ch, int count) {
   151 		char[] array = new char[count];
   152 		Arrays.fill(array, ch);
   153 		return new String(array);
   154 	}
   155 	private final static char[] HEX_ALPHABET = "0123456789abcdef".toCharArray();
   156 
   157 	public static String toHex(byte[] bytes) {
   158 		char[] hexChars = new char[bytes.length * 2];
   159 		for (int j = 0; j < bytes.length; j++) {
   160 			int v = bytes[j] & 0xFF;
   161 			hexChars[j * 2] = HEX_ALPHABET[v >>> 4];
   162 			hexChars[j * 2 + 1] = HEX_ALPHABET[v & 0x0F];
   163 		}
   164 		return new String(hexChars);
   165 	}
   166 
   167 	public static String readString(InputStream in) throws IOException {
   168 		try (BufferedReader br = new BufferedReader(new InputStreamReader(in))) {
   169 			StringBuilder result = new StringBuilder();
   170 			for (String line = br.readLine(); line != null; line = br.readLine()) {
   171 				result.append(line);
   172 				result.append('\n');
   173 			}
   174 			return result.toString();
   175 		}
   176 	}
   177 
   178 	/**
   179 	 * @param <P> type of the last parent
   180 	 * @param <T> type of the examined class
   181 	 * @param type examined class
   182 	 * @param lastParent the last parent type to stop at
   183 	 * @return list of types starting with <code>type</code> and ending with <code>lastParent</code>
   184 	 */
   185 	public static <P, T extends P> List<Class<? extends P>> getClassHierarchy(Class<T> type, Class<P> lastParent) {
   186 		List<Class<? extends P>> hierarchy = new ArrayList<>();
   187 
   188 		for (Class current = type; current != null && lastParent.isAssignableFrom(current); current = current.getSuperclass()) {
   189 			hierarchy.add(current);
   190 		}
   191 
   192 		return hierarchy;
   193 	}
   194 
   195 	public static PropertyDeclaration[] getPropertyDeclarations(Class<? extends Formatter> formatterClass) {
   196 		PropertyDeclarations properties = formatterClass.getAnnotation(PropertyDeclarations.class);
   197 
   198 		if (properties == null) {
   199 			PropertyDeclaration p = formatterClass.getAnnotation(PropertyDeclaration.class);
   200 			return p == null ? new PropertyDeclaration[]{} : new PropertyDeclaration[]{p};
   201 		} else {
   202 			return properties.value();
   203 		}
   204 	}
   205 
   206 	/**
   207 	 * TODO: support background or styles and move to ColorfulPrintWriter
   208 	 *
   209 	 * @param out
   210 	 * @param valueString
   211 	 * @param basicColor
   212 	 * @param escapeColor
   213 	 */
   214 	public static void printValueWithWhitespaceReplaced(ColorfulPrintWriter out, String valueString, ColorfulPrintWriter.TerminalColor basicColor, ColorfulPrintWriter.TerminalColor escapeColor) {
   215 
   216 		Matcher m = WHITESPACE_TO_REPLACE.matcher(valueString);
   217 
   218 		int start = 0;
   219 
   220 		while (m.find(start)) {
   221 
   222 			printColorOrNot(out, basicColor, valueString.substring(start, m.start()));
   223 
   224 			switch (m.group()) {
   225 				case "\n":
   226 					out.print(escapeColor, "↲");
   227 					break;
   228 				case "\r":
   229 					out.print(escapeColor, "⏎");
   230 					break;
   231 				case "\t":
   232 					out.print(escapeColor, "↹");
   233 					break;
   234 				case NBSP:
   235 					out.print(escapeColor, "⎵");
   236 					break;
   237 				default:
   238 					throw new IllegalStateException("Unexpected whitespace token: „" + m.group() + "“");
   239 			}
   240 
   241 			start = m.end();
   242 		}
   243 
   244 		printColorOrNot(out, basicColor, valueString.substring(start, valueString.length()));
   245 	}
   246 
   247 	private static void printColorOrNot(ColorfulPrintWriter out, ColorfulPrintWriter.TerminalColor color, String text) {
   248 		if (color == null) {
   249 			out.print(text);
   250 		} else {
   251 			out.print(color, text);
   252 		}
   253 	}
   254 }