001/******************************************************************************* 002The MIT License (MIT) 003 004Copyright (c) 2024 KILLCODING.COM 005 006Permission is hereby granted, free of charge, to any person obtaining a copy 007of this software and associated documentation files (the "Software"), to deal 008in the Software without restriction, including without limitation the rights 009to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 010copies of the Software, and to permit persons to whom the Software is 011furnished to do so, subject to the following conditions: 012 013The above copyright notice and this permission notice shall be included in 014all copies or substantial portions of the Software. 015 016THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 017IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 018FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 019AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 020LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 021OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 022THE SOFTWARE. 023*****************************************************************************/ 024package com.killcoding.tool; 025 026import java.util.List; 027import java.util.Collections; 028import java.util.ArrayList; 029import java.util.Random; 030import java.net.InetAddress; 031import com.killcoding.log.Logger; 032import java.net.URL; 033import java.net.URI; 034import java.net.URISyntaxException; 035import java.io.File; 036import com.killcoding.log.LoggerFactory; 037import java.net.URLClassLoader; 038import java.io.FileFilter; 039import java.net.MalformedURLException; 040import java.security.MessageDigest; 041import com.killcoding.file.BaseFile; 042import java.util.Arrays; 043import java.nio.file.Files; 044import java.util.stream.Collectors; 045import java.nio.file.Paths; 046import java.nio.file.Path; 047import java.io.IOException; 048import java.nio.file.LinkOption; 049 050public final class CommonTools { 051 052 private static String HOSTNAME = null; 053 054 055 public static URLClassLoader loadJars(String libDirs) throws Exception { 056 return loadJars(libDirs,ClassLoader.getSystemClassLoader()); 057 } 058 059 public static URLClassLoader loadJars(String[] libDirs) throws Exception { 060 return loadJars(libDirs,ClassLoader.getSystemClassLoader()); 061 } 062 063 public static URLClassLoader loadJars(String[] libDirs,ClassLoader classLoader) throws Exception { 064 return loadJars(String.join(";",libDirs),classLoader); 065 } 066 067 public static URLClassLoader loadJars(String libDirs,ClassLoader classLoader) throws Exception { 068 if (libDirs == null) 069 return null; 070 071 List<URL> urlList = new ArrayList<URL>(); 072 List<String> libDirArr = Arrays.asList(libDirs.split(";")); 073 for(String libDir : libDirArr){ 074 File jars = new File(libDir); 075 if(!jars.exists()) 076 continue; 077 078 if(jars.isDirectory()){ 079 List<String> list = findFiles(jars.getAbsolutePath(),".jar"); 080 for(String jarPath : list){ 081 urlList.add(new File(jarPath).toURL()); 082 } 083 } 084 if(jars.isFile()){ 085 boolean isJar = jars.getName().toLowerCase().endsWith(".jar"); 086 087 if(isJar) urlList.add(jars.toURL()); 088 } 089 } 090 091 URL[] urls = urlList.toArray(new URL[]{}); 092 093 URLClassLoader cl = new URLClassLoader(urls,classLoader); 094 return cl; 095 } 096 097 public static List<String> findFiles(String dir,String ext) throws IOException { 098 099 if(!new File(dir).exists()) return new ArrayList<String>(); 100 101 List<Path> paths = Files.walk(Paths.get(dir)) 102 .filter(Files::isRegularFile) 103 .filter(path -> path.toString().toLowerCase().endsWith(ext)) 104 .collect(Collectors.toList()); 105 106 return paths.stream() 107 .map(path -> path.toAbsolutePath().toString()) 108 .collect(Collectors.toList()); 109 } 110 111 public static List<String> findFiles(String dir) throws IOException { 112 113 if(!new File(dir).exists()) return new ArrayList<String>(); 114 115 List<Path> paths = Files.walk(Paths.get(dir)) 116 .filter(Files::isRegularFile) 117 .collect(Collectors.toList()); 118 119 return paths.stream() 120 .map(path -> path.toAbsolutePath().toString()) 121 .collect(Collectors.toList()); 122 } 123 124 public static List<String> findSubDirs(String dir) throws IOException { 125 126 if(!new File(dir).exists()) return new ArrayList<String>(); 127 128 List<Path> paths = Files.walk(Paths.get(dir)) 129 .filter(Files::isDirectory) 130 .collect(Collectors.toList()); 131 132 return paths.stream() 133 .map(path -> path.toAbsolutePath().toString()) 134 .collect(Collectors.toList()); 135 } 136 137 public static String getJarPath(Class clazz) { 138 try { 139 return new File(clazz.getProtectionDomain().getCodeSource().getLocation().toURI()) 140 .getParentFile().getPath().replaceAll("\\\\", "/"); 141 } catch (Exception e) { 142 Logger.systemError(CommonTools.class, e); 143 return null; 144 } 145 } 146 147 public static boolean isBlank(Object o) { 148 if (o == null) 149 return true; 150 151 if (o.toString().trim().equals("")) 152 return true; 153 154 return false; 155 } 156 157 public static File getSystemProperties(Class clazz, String envKey, String propFileName) { 158 try { 159 File envFile = null; 160 161 String envFilePath = System.getenv(envKey) == null ? System.getProperty(envKey) : System.getenv(envKey); 162 if (envFilePath != null) { 163 envFile = new File(envFilePath); 164 if(!envFile.exists()){ 165 Logger.systemDebug(CommonTools.class,"Missing %s",envFilePath); 166 } 167 } 168 169 if (envFile != null && envFile.exists()) { 170 Logger.systemDebug(CommonTools.class,"Found %s",envFile.getPath()); 171 return envFile; 172 } 173 174 String jarPath = new File(clazz.getProtectionDomain().getCodeSource().getLocation().toURI()).getParentFile().getPath(); 175 File jarConfigFile = new File(String.format("%s/%s", jarPath, propFileName)); 176 177 if(!jarConfigFile.exists()) { 178 jarConfigFile = new File(String.format("%s/config/%s", jarPath, propFileName)); 179 } 180 181 if (jarConfigFile.exists()) { 182 Logger.systemDebug(CommonTools.class,"Found %s",jarConfigFile.getPath()); 183 return jarConfigFile; 184 } 185 186 String jarParentPath = new File(jarPath).getParentFile() 187 .getPath(); 188 189 File jarParentConfigFile = new File(String.format("%s/%s", jarParentPath, propFileName)); 190 191 if(!jarParentConfigFile.exists()) { 192 jarParentConfigFile = new File(String.format("%s/config/%s", jarParentPath, propFileName)); 193 } 194 195 if (jarParentConfigFile.exists()) { 196 Logger.systemDebug(CommonTools.class,"Found %s",jarParentConfigFile.getPath()); 197 return jarParentConfigFile; 198 } 199 200 URL classPathFileUrl = clazz.getResource(String.format("/%s", propFileName)); 201 if (classPathFileUrl != null) { 202 Logger.systemDebug(CommonTools.class,"Found %s",classPathFileUrl.getPath()); 203 return new File(classPathFileUrl.toURI()); 204 } 205 206 classPathFileUrl = clazz.getResource(String.format("/config/%s", propFileName)); 207 if (classPathFileUrl != null) { 208 Logger.systemDebug(CommonTools.class,"Found %s",classPathFileUrl.getPath()); 209 return new File(classPathFileUrl.toURI()); 210 } 211 try{ 212 classPathFileUrl = clazz.getResource("/"); 213 if (classPathFileUrl != null) { 214 String classParentPath = new File(classPathFileUrl.toURI()).getParent(); 215 if(classParentPath != null){ 216 File classParentConfigFile = new File(String.format("%s/%s", classParentPath, propFileName)); 217 218 if(!classParentConfigFile.exists()) { 219 classParentConfigFile = new File(String.format("%s/config/%s", classParentPath, propFileName)); 220 } 221 222 if(!classParentConfigFile.exists()) { 223 Logger.systemDebug(CommonTools.class,"Found %s",classParentConfigFile.getPath()); 224 return classParentConfigFile; 225 } 226 } 227 } 228 }catch(Exception e){ 229 Logger.systemDebug(CommonTools.class,"Missing class path."); 230 Logger.systemDebug(CommonTools.class, e.getMessage(),e); 231 } 232 } catch (Exception e) { 233 Logger.systemError(CommonTools.class, e); 234 } 235 Logger.systemDebug(CommonTools.class,"Missing %s",propFileName); 236 return null; 237 } 238 239 public synchronized static String getHostname() { 240 241 if(HOSTNAME != null) return HOSTNAME; 242 243 HOSTNAME = System.getenv("HOSTNAME"); 244 if(HOSTNAME == null){ 245 try { 246 InetAddress addr = InetAddress.getLocalHost(); 247 HOSTNAME = addr.getHostName(); 248 System.setProperty("HOSTNAME",HOSTNAME); 249 System.setProperty("hostname",HOSTNAME); 250 } catch (Exception e) { 251 Logger.systemError(CommonTools.class, e); 252 } 253 } 254 return HOSTNAME; 255 } 256 257 public static String generateId(int len) { 258 final Character[] CHARS = new Character[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 259 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 260 'y', 'z' }; 261 StringBuffer id = new StringBuffer(); 262 for (int i = 0; i < len; i++) { 263 char c = CHARS[new Random().nextInt(CHARS.length)]; 264 id.append(c); 265 } 266 return id.toString(); 267 } 268 269 public static <T> List<List<T>> averageAssign(List<T> source, int limit) { 270 if (null == source || source.isEmpty()) { 271 return Collections.emptyList(); 272 } 273 List<List<T>> result = new ArrayList<>(); 274 int listCount = (source.size() - 1) / limit + 1; 275 int remaider = source.size() % listCount; 276 int number = source.size() / listCount; 277 int offset = 0; 278 for (int i = 0; i < listCount; i++) { 279 List<T> value; 280 if (remaider > 0) { 281 value = source.subList(i * number + offset, (i + 1) * number + offset + 1); 282 remaider--; 283 offset++; 284 } else { 285 value = source.subList(i * number + offset, (i + 1) * number + offset); 286 } 287 result.add(value); 288 } 289 return result; 290 } 291 292 public static String md5(String text) { 293 char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 294 'A', 'B', 'C', 'D', 'E', 'F' }; 295 296 try { 297 byte[] btInput = text.getBytes(BaseFile.CHARSET); 298 MessageDigest mdInst = MessageDigest.getInstance("MD5"); 299 mdInst.update(btInput); 300 byte[] md = mdInst.digest(); 301 int j = md.length; 302 char str[] = new char[j * 2]; 303 int k = 0; 304 for (int i = 0; i < j; i++) { 305 byte byte0 = md[i]; 306 str[k++] = hexDigits[byte0 >>> 4 & 0xf]; 307 str[k++] = hexDigits[byte0 & 0xf]; 308 } 309 return new String(str); 310 } catch (Exception e) { 311 LoggerFactory.getLogger(CommonTools.class).error(e.getMessage(),e); 312 return null; 313 } 314 315 } 316 317}