PageRenderTime 47ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/atsys-web/src/main/java/com/sixlabs/atsys/domain/utils/ObjectUtils.java

https://gitlab.com/mfalzetta/poc-ttsec
Java | 338 lines | 223 code | 47 blank | 68 comment | 31 complexity | 593a3bb6b7d8493eed3cea3625ab7cf8 MD5 | raw file
  1. package com.sixlabs.atsys.domain.utils;
  2. import com.sixlabs.atsys.domain.ApplicationException;
  3. import com.rits.cloning.Cloner;
  4. import org.jetbrains.annotations.NotNull;
  5. import org.slf4j.Logger;
  6. import org.slf4j.LoggerFactory;
  7. import javax.json.Json;
  8. import javax.json.JsonObject;
  9. import javax.json.JsonObjectBuilder;
  10. import java.io.*;
  11. import java.security.MessageDigest;
  12. import java.security.NoSuchAlgorithmException;
  13. import java.util.Base64;
  14. import java.util.List;
  15. import java.util.Optional;
  16. import java.util.Properties;
  17. import java.util.concurrent.Callable;
  18. import java.util.concurrent.CompletableFuture;
  19. import java.util.concurrent.atomic.AtomicBoolean;
  20. import java.util.function.Function;
  21. import java.util.stream.Collectors;
  22. import java.util.stream.Stream;
  23. public class ObjectUtils {
  24. private static final Logger LOG = LoggerFactory.getLogger(ObjectUtils.class);
  25. private static final Cloner CLONER = new Cloner();
  26. static {
  27. // TODO: Incluir as classes do hibernate/eclipseLink.
  28. //CLONER.dontClone(UnitOfWorkQueryValueHolder.class);
  29. }
  30. private ObjectUtils() {
  31. }
  32. /**
  33. * Retorna uma cópia completa do objeto.
  34. *
  35. * @param objeto O objeto a ser copiado.
  36. * @param <E> O tipo do objeto.
  37. * @return A cópia do objeto.
  38. */
  39. public static <E> E copy(E objeto) {
  40. return objeto != null ? CLONER.deepClone(objeto) : null;
  41. }
  42. public static <T> boolean equals(T first, T second) {
  43. return first != null && first.equals(second);
  44. }
  45. public static <T> boolean changed(T from, T to) {
  46. return !equals(from, to);
  47. }
  48. public static <T> String toString(T object) {
  49. if (object != null) return object.toString();
  50. return null;
  51. }
  52. public static <T> String toString(Callable<T> callable) {
  53. return call(() -> {
  54. T value = callable.call();
  55. if (value != null) return value.toString();
  56. return null;
  57. });
  58. }
  59. public static <T> Optional<T> optionalOf(Object obj, Class<T> clazz) {
  60. return obj != null && obj.getClass().isAssignableFrom(clazz) ? Optional.of((T) obj) : Optional.empty();
  61. }
  62. public static Function<String, Integer> stringToInteger() {
  63. return codeStr -> {
  64. if (codeStr != null) return Integer.valueOf(codeStr);
  65. else return null;
  66. };
  67. }
  68. public static Function<String, Long> stringToLong() {
  69. return codeStr -> {
  70. if (codeStr != null) return Long.valueOf(codeStr);
  71. else return null;
  72. };
  73. }
  74. public static String toBase64(Object object) {
  75. String encoded = null;
  76. try {
  77. ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
  78. ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
  79. objectOutputStream.writeObject(object);
  80. objectOutputStream.close();
  81. encoded = new String(Base64.getEncoder().encode(byteArrayOutputStream.toByteArray()));
  82. } catch (Exception e) {
  83. processException(e, LOG);
  84. }
  85. return encoded;
  86. }
  87. public static <T> T fromBase64(String string, Class<T> clazz) {
  88. byte[] bytes = Base64.getDecoder().decode(string.getBytes());
  89. T object = null;
  90. try {
  91. ObjectInputStream objectInputStream = new ObjectInputStream(new ByteArrayInputStream(bytes));
  92. object = (T) objectInputStream.readObject();
  93. } catch (Exception e) {
  94. processException(e, LOG);
  95. }
  96. return object;
  97. }
  98. public static <T> CompletableFuture<List<T>> allOf(List<CompletableFuture<T>> futures) {
  99. CompletableFuture<Void> allDoneFuture =
  100. CompletableFuture.allOf(futures.toArray(new CompletableFuture[futures.size()]));
  101. return allDoneFuture.thenApply(v ->
  102. futures.stream().
  103. map(CompletableFuture::join).
  104. collect(Collectors.<T>toList())
  105. );
  106. }
  107. public static <T> CompletableFuture<List<T>> allOf(Stream<CompletableFuture<T>> futures) {
  108. return allOf(futures.collect(Collectors.toList()));
  109. }
  110. public static void run(Logger log, Executable block) {
  111. try {
  112. block.execute();
  113. } catch (Throwable e) {
  114. processException(e, log);
  115. }
  116. }
  117. /**
  118. * Executa um bloco de código. As seguintes regras de tratamento de exceções são aplicadas:
  119. * <ul>
  120. * <li>Exceções derivadas de {@link RuntimeException} são relançadas na sua forma original.</li>
  121. * <li>Exceções derivadas de {@link Exception} são relançadas como {@link RuntimeException}.</li>
  122. * </ul>
  123. *
  124. * @param block O bloco de código a ser executado.
  125. */
  126. public static void run(Executable block) {
  127. try {
  128. block.execute();
  129. } catch (RuntimeException e) {
  130. throw e;
  131. } catch (Exception e) {
  132. throw new RuntimeException(e);
  133. }
  134. }
  135. public static <T> T call(Logger log, Callable<T> block) {
  136. try {
  137. return block.call();
  138. } catch (Throwable e) {
  139. processException(e, log);
  140. }
  141. return null;
  142. }
  143. /**
  144. * Executa um bloco de código e retorna o resultado. As seguintes regras de tratamento de exceções são aplicadas:
  145. * <ul>
  146. * <li>Exceções derivadas de {@link RuntimeException} são relançadas na sua forma original.</li>
  147. * <li>Exceções derivadas de {@link Exception} são relançadas como {@link RuntimeException}.</li>
  148. * </ul>
  149. *
  150. * @param block O bloco de código a ser executado.
  151. * @param <T> O tipo do objeto de retorno do bloco de código.
  152. * @return O valor de retorno do bloco de código.
  153. */
  154. public static <T> T call(Callable<T> block) {
  155. try {
  156. return block.call();
  157. } catch (RuntimeException e) {
  158. throw e;
  159. } catch (Exception e) {
  160. throw new RuntimeException(e);
  161. }
  162. }
  163. public static boolean tryCatch(Logger log, Executable block, Executable always) {
  164. try {
  165. block.execute();
  166. return true;
  167. } catch (Throwable e) {
  168. processException(e, log);
  169. return false;
  170. } finally {
  171. run(log, always);
  172. }
  173. }
  174. /**
  175. * Executa o bloco de código, dependendo do estado de 'canRun'. Este método não levanta exceção.
  176. *
  177. * @param log O log a ser registrado.
  178. * @param canRun Indica se pode executar o bloco de código ou não.
  179. * @param block O bloco de código.
  180. */
  181. public static void run(Logger log, AtomicBoolean canRun, Executable block) {
  182. try {
  183. if (canRun.compareAndSet(true, false)) {
  184. block.execute();
  185. }
  186. } catch (Throwable e) {
  187. processException(e, log);
  188. } finally {
  189. canRun.compareAndSet(false, true);
  190. }
  191. }
  192. public static void processException(Throwable e, Logger log) {
  193. Optional<String> msg = ObjectUtils.unwrap(e);
  194. if (msg.isPresent()) log.warn(msg.get());
  195. else logError("Erro inesperado.", e, log);
  196. }
  197. public static void logError(String message, Throwable e, Logger log) {
  198. final String exMsg = e.getMessage();
  199. if (exMsg != null) log.error(message + " " + exMsg);
  200. else log.error(message, e);
  201. }
  202. public static Optional<String> unwrap(Throwable t) {
  203. if (t == null) return Optional.empty();
  204. if (t instanceof ApplicationException) return Optional.ofNullable(t.getMessage());
  205. return unwrap(t.getCause());
  206. }
  207. public static String toString(Properties properties) {
  208. StringWriter sw = new StringWriter();
  209. try {
  210. if (properties != null)
  211. properties.store(sw, "Propriedades no formato 'chave=valor'");
  212. } catch (Exception e) {
  213. processException(e, LOG);
  214. }
  215. return sw.toString();
  216. }
  217. public static Properties toProperties(String value) throws IOException {
  218. Properties props = new Properties();
  219. if (value != null) {
  220. props.load(new StringReader(value));
  221. return props;
  222. }
  223. return props;
  224. }
  225. /**
  226. * Converte uma string em um objeto Json.
  227. *
  228. * @param value A string.
  229. * @return O objeto Json.
  230. */
  231. public static JsonObject toJson(String value) {
  232. return Json.createReader(new StringReader(value)).readObject();
  233. }
  234. /**
  235. * Converte uma string em um contrutor de objetos Json. É útil para converter de string para Json, e
  236. * adicionar campos extras ao objeto Json antes da contrução.
  237. *
  238. * @param value A string.
  239. * @return O contrutor de objetos Json.
  240. */
  241. public static JsonObjectBuilder toBuilder(String value) {
  242. final JsonObjectBuilder jsonBuilder = Json.createObjectBuilder();
  243. toJson(value).forEach(jsonBuilder::add);
  244. return jsonBuilder;
  245. }
  246. /**
  247. * Retorna a representação em string hexadecimal do array de bytes.
  248. *
  249. * @param bytes O array de bytes.
  250. * @return A string em hexadecimal, que representa o array de bytes.
  251. */
  252. public static String toHex(byte[] bytes) {
  253. final StringBuilder s = new StringBuilder();
  254. for (byte aByte : bytes) {
  255. int parteAlta = ((aByte >> 4) & 0xf) << 4;
  256. int parteBaixa = aByte & 0xf;
  257. if (parteAlta == 0) {
  258. s.append('0');
  259. }
  260. s.append(Integer.toHexString(parteAlta | parteBaixa));
  261. }
  262. return s.toString();
  263. }
  264. /**
  265. * Aplica o hash SHA1 à string fornecida.
  266. *
  267. * @param value A string de entrada.
  268. * @return O hash SHA1 da string de entrada.
  269. */
  270. @NotNull
  271. public static String toSHA1(@NotNull final String value) {
  272. return hash(value, "SHA1");
  273. }
  274. /**
  275. * Obtém o hash da string.
  276. *
  277. * @param value A string de entrada.
  278. * @param algo O nome do algoritmo de hash.
  279. * @return O hash da string de entrada.
  280. */
  281. @NotNull
  282. public static String hash(@NotNull final String value, @NotNull final String algo) {
  283. try {
  284. MessageDigest md = MessageDigest.getInstance(algo);
  285. md.update(value.getBytes());
  286. return toHex(md.digest());
  287. } catch (NoSuchAlgorithmException e) {
  288. throw new RuntimeException(e);
  289. }
  290. }
  291. }