001package systems.dmx.core.util; 002 003import javax.servlet.http.Cookie; 004import javax.servlet.http.HttpServletRequest; 005import javax.ws.rs.core.Response; 006 007import java.io.File; 008import java.io.FileInputStream; 009import java.io.InputStream; 010import java.io.UnsupportedEncodingException; 011 012import java.math.BigInteger; 013 014import java.net.FileNameMap; 015import java.net.InetAddress; 016import java.net.Inet4Address; 017import java.net.Inet6Address; 018import java.net.URL; 019import java.net.URLConnection; 020import java.net.URLDecoder; 021import java.net.URLEncoder; 022 023import java.security.MessageDigest; 024import java.security.NoSuchAlgorithmException; 025 026import java.util.Map; 027import java.util.Scanner; 028 029 030 031/** 032 * Generic Java utilities. 033 */ 034public class JavaUtils { 035 036 037 038 // === Text === 039 040 public static String stripHTML(String html) { 041 return html.replaceAll("<.*?>", ""); // *? is the reluctant version of the * quantifier (which is greedy) 042 } 043 044 public static String times(String str, int times) { 045 StringBuilder sb = new StringBuilder(times * str.length()); 046 for (int i = 0; i < times; i++) { 047 sb.append(str); 048 } 049 return sb.toString(); 050 } 051 052 053 054 // === Files === 055 056 private static FileNameMap fileTypeMap = URLConnection.getFileNameMap(); 057 058 public static String getFileType(String fileName) { 059 String extension = getExtension(fileName); 060 if (!extension.equals("avi")) { 061 // Note: for .avi Java's file type map returns strange media type "application/x-troff-msvideo". 062 // See lib/content-types.properties under java home. 063 String fileType = fileTypeMap.getContentTypeFor(fileName); 064 if (fileType != null) { 065 return fileType; 066 } 067 } 068 // fallback 069 if (extension.equals("json")) { 070 return "application/json"; 071 } else if (extension.equals("mp3")) { 072 return "audio/mpeg"; 073 } else if (extension.equals("mp4")) { 074 return "video/mp4"; 075 } else if (extension.equals("avi")) { 076 return "video/avi"; 077 } else if (extension.equals("wmv")) { 078 return "video/x-ms-wmv"; 079 } else if (extension.equals("flv")) { 080 return "video/x-flv"; 081 } else if (extension.equals("svg")) { 082 return "image/svg+xml"; 083 } 084 // TODO: use a system property instead a hardcoded list 085 // 086 return null; 087 } 088 089 public static String getFilename(String path) { 090 return path.substring(path.lastIndexOf('/') + 1); 091 } 092 093 public static String getBasename(String fileName) { 094 int i = fileName.lastIndexOf("."); 095 if (i == -1) { 096 return fileName; 097 } 098 return fileName.substring(0, i); 099 } 100 101 public static String getExtension(String fileName) { 102 return fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase(); 103 } 104 105 public static String stripDriveLetter(String path) { 106 return path.replaceFirst("^[A-Z]:", ""); 107 } 108 109 // --- 110 111 public static File findUnusedFile(File file) { 112 String parent = file.getParent(); 113 String fileName = file.getName(); 114 String basename = getBasename(fileName); 115 String extension = getExtension(fileName); 116 int nr = 1; 117 while (file.exists()) { 118 nr++; 119 file = new File(parent, basename + "-" + nr + "." + extension); 120 } 121 return file; 122 } 123 124 // --- 125 126 public static String readTextFile(File file) { 127 try { 128 return readText(new FileInputStream(file)); 129 } catch (Exception e) { 130 throw new RuntimeException("Reading text file \"" + file + "\" failed", e); 131 } 132 } 133 134 public static String readText(InputStream in) { 135 StringBuilder text = new StringBuilder(); 136 Scanner scanner = new Scanner(in); 137 while (scanner.hasNextLine()) { 138 text.append(scanner.nextLine() + "\n"); 139 } 140 return text.toString(); 141 } 142 143 // --- 144 145 public static File createTempDirectory(String prefix) { 146 try { 147 File f = File.createTempFile(prefix, ".dir"); 148 String n = f.getAbsolutePath(); 149 f.delete(); 150 f = new File(n); 151 f.mkdir(); 152 return f; 153 } catch (Exception e) { 154 throw new RuntimeException("Creating temporary directory failed", e); 155 } 156 } 157 158 159 160 // === URLs === 161 162 public static String readTextURL(URL url) { 163 try { 164 return readText(url.openStream()); 165 } catch (Exception e) { 166 throw new RuntimeException("Reading from URL \"" + url + "\" failed", e); 167 } 168 } 169 170 // --- 171 172 public static String encodeURIComponent(String uriComp) { 173 try { 174 return URLEncoder.encode(uriComp, "UTF-8").replaceAll("\\+", "%20"); 175 } catch (UnsupportedEncodingException e) { 176 throw new RuntimeException("Encoding URI component \"" + uriComp + "\" failed", e); 177 } 178 } 179 180 public static String decodeURIComponent(String uriComp) { 181 try { 182 return URLDecoder.decode(uriComp, "UTF-8"); 183 } catch (UnsupportedEncodingException e) { 184 throw new RuntimeException("Decoding URI component \"" + uriComp + "\" failed", e); 185 } 186 } 187 188 189 190 // === Networking === 191 192 /** 193 * @param inetAddress IPv4 or IPv6 address or a machine name, e.g. "172.68.8.12" 194 * @param range IPv4 or IPv6 address range in CIDR notation, e.g. "172.68.8.0/24" 195 */ 196 public static boolean isInRange(String inetAddress, String range) { 197 try { 198 String[] r = range.split("/"); 199 BigInteger networkAddr = inetAddress(r[0]); 200 int maskNumber = Integer.parseInt(r[1]); 201 InetAddress addr = InetAddress.getByName(inetAddress); 202 BigInteger networkMask = networkMask(addr, maskNumber); 203 // 204 return inetAddress(addr).xor(networkAddr).and(networkMask).equals(BigInteger.ZERO); 205 } catch (Exception e) { 206 throw new RuntimeException("Checking IP range failed (inetAddress=\"" + inetAddress + 207 "\", range=\"" + range + "\"", e); 208 } 209 } 210 211 // --- 212 213 public static BigInteger inetAddress(String inetAddress) { 214 try { 215 return inetAddress(InetAddress.getByName(inetAddress)); 216 } catch (Exception e) { 217 throw new RuntimeException("Parsing inet address \"" + inetAddress + "\" failed", e); 218 } 219 } 220 221 public static BigInteger inetAddress(InetAddress inetAddress) { 222 return new BigInteger(1, inetAddress.getAddress()); // signum=1 (positive) 223 } 224 225 // --- 226 227 public static BigInteger networkMask(InetAddress addr, int maskNumber) { 228 if (addr instanceof Inet4Address) { 229 return networkMask(maskNumber, 32); 230 } else if (addr instanceof Inet6Address) { 231 return networkMask(maskNumber, 128); 232 } else { 233 throw new RuntimeException("Unexpected InetAddress object: " + addr.getClass().getName()); 234 } 235 } 236 237 public static BigInteger networkMask(int maskNumber, int size) { 238 String networkMask = times("1", maskNumber) + times("0", size - maskNumber); 239 return new BigInteger(networkMask, 2); // radix=2 (binary) 240 } 241 242 // --- 243 244 public static String cookieValue(HttpServletRequest request, String cookieName) { 245 for (Cookie cookie : request.getCookies()) { 246 if (cookie.getName().equals(cookieName)) { 247 return cookie.getValue(); 248 } 249 } 250 return null; 251 } 252 253 // --- 254 255 public static String requestInfo(HttpServletRequest request) { 256 String queryString = request.getQueryString(); 257 return request.getMethod() + " " + request.getRequestURI() + (queryString != null ? "?" + queryString : ""); 258 } 259 260 public static String responseInfo(Response.StatusType status) { 261 return status.getStatusCode() + " (" + status.getReasonPhrase() + ")"; 262 } 263 264 // --- 265 266 public static String requestDump(HttpServletRequest request) { 267 StringBuilder dump = new StringBuilder(request + ", session=" + request.getSession(false) + ", cookies="); 268 for (Cookie cookie : request.getCookies()) { 269 dump.append("\n " + cookie.getName() + "=" + cookie.getValue()); 270 } 271 return dump.toString(); 272 } 273 274 275 276 // === Encoding === 277 278 /* static { 279 for (Provider p : Security.getProviders()) { 280 System.out.println("### Security Provider " + p); 281 for (Provider.Service s : p.getServices()) { 282 System.out.println(" " + s); 283 } 284 } 285 } */ 286 287 public static String encodeSHA256(String data) { 288 try { 289 MessageDigest sha256 = MessageDigest.getInstance("SHA-256"); 290 return new String(encodeHex(sha256.digest(data.getBytes()))); 291 } catch (NoSuchAlgorithmException e) { 292 throw new RuntimeException("SHA256 encoding failed", e); 293 } 294 } 295 296 private static char[] encodeHex(byte[] data) { 297 final String DIGITS = "0123456789abcdef"; 298 int l = data.length; 299 char[] out = new char[l << 1]; 300 // two characters form the hex value 301 for (int i = 0, j = 0; i < l; i++) { 302 out[j++] = DIGITS.charAt((0xF0 & data[i]) >>> 4); 303 out[j++] = DIGITS.charAt(0x0F & data[i]); 304 } 305 return out; 306 } 307}