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