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