package ir.xweb.util;
import java.io.*;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.GZIPOutputStream;
public class Tools {
/**
* Version of lastIndexOf that uses regular expressions for the search by
* Julian Cochran.
*/
public static int lastIndexOfRegex(String message, String regex) {
// Need to add an extra character to message because to ensure
// split works if toFind is right at the end of the message.
message = message + " ";
String separated[] = message.split(regex);
if (separated == null || separated.length == 0 || separated.length == 1) {
return -1;
}
return separated[separated.length - 1].length();
}
/**
* Version of indexOf that uses regular expressions for the search by Julian
* Cochran.
*/
public static int indexOf(String text, String regex) {
// Need to add an extra character to message because to ensure
// split works if toFind is right at the end of the message.
text = text + " ";
String separated[] = text.split(regex);
if (separated == null || separated.length == 0 || separated.length == 1) {
return -1;
}
return separated[0].length();
}
/**
* @deprecated please use {@link #gzip(java.io.File, java.io.File) zip(java.io.File, java.io.File)}
*/
@Deprecated
public static void zipFile(File src, File dist) throws IOException {
gzip(src, dist);
}
/**
* Compress one specific file with gzip
* @param src Source file
* @param dist Destination file. Parent directory of this file should exist
* @throws IOException
*/
public static void gzip(final File src, final File dist) throws IOException {
if(src == null) {
throw new IllegalArgumentException("null src");
}
if(!src.exists() || !src.isFile()) {
throw new IllegalArgumentException("Src file does not exist of it's not file");
}
if(dist == null) {
throw new IllegalArgumentException("dist src");
}
FileInputStream fis = null;
GZIPOutputStream gzos = null;
try {
fis = new FileInputStream(src);
gzos = new GZIPOutputStream(new FileOutputStream(dist));
int size;
byte[] buffer = new byte[20480];
while((size = fis.read(buffer)) > 0) {
gzos.write(buffer, 0, size);
}
} catch (Exception ex) {
throw new IOException(ex);
} finally {
if(fis != null) {
try {
fis.close();
} catch (Exception ex) {}
}
if(gzos != null) {
try {
gzos.flush();
gzos.finish();
gzos.close();
} catch (Exception ex){}
}
}
}
public static String getUrlParam(final String queryString, final String encoding, final String name) throws UnsupportedEncodingException {
final Map<String, String[]> params = parseQueryString(queryString, encoding);
final String[] values = params.get(name);
if(values != null && values.length > 0) {
return values[0];
}
return null;
}
@Deprecated
public static HashMap<String, List<String>> parseQueryString(String queryString) {
final Map<String, String[]> params = parseQueryString(queryString, "utf-8");
final HashMap<String, List<String>> map = new HashMap<String, List<String>>(params.size());
for(Map.Entry<String, String[]> e:params.entrySet()) {
map.put(e.getKey(), Arrays.asList(e.getValue()));
}
return map;
}
public static Map<String,String[]> parseQueryString(
final String data,
final String encoding) {
if ((data != null) && (data.length() > 0)) {
final Map<String, String[]> map = new HashMap<String, String[]>();
// use the specified encoding to extract bytes out of the
// given string so that the encoding is not lost. If an
// encoding is not specified, let it use platform default
byte[] bytes = null;
try {
if (encoding == null) {
bytes = data.getBytes();
} else {
bytes = data.getBytes(encoding);
}
parseParameters(map, bytes, encoding);
return map;
} catch (UnsupportedEncodingException ex) {
throw new IllegalArgumentException(ex);
}
}
return Collections.emptyMap();
}
private static void parseParameters(
final Map<String,String[]> map,
final byte[] data,
final String encoding) throws UnsupportedEncodingException {
if (data != null && data.length > 0) {
int ix = 0;
int ox = 0;
String key = null;
String value = null;
while (ix < data.length) {
byte c = data[ix++];
switch ((char) c) {
case '&':
value = new String(data, 0, ox, encoding);
if (key != null) {
putMapEntry(map, key, value);
key = null;
}
ox = 0;
break;
case '=':
if (key == null) {
key = new String(data, 0, ox, encoding);
ox = 0;
} else {
data[ox++] = c;
}
break;
case '+':
data[ox++] = (byte)' ';
break;
case '%':
data[ox++] = (byte)((convertHexDigit(data[ix++]) << 4)
+ convertHexDigit(data[ix++]));
break;
default:
data[ox++] = c;
}
}
//The last value does not end in '&'. So save it now.
if (key != null) {
value = new String(data, 0, ox, encoding);
putMapEntry(map, key, value);
}
}
}
private static byte convertHexDigit(final byte b) {
if ((b >= '0') && (b <= '9')) return (byte)(b - '0');
if ((b >= 'a') && (b <= 'f')) return (byte)(b - 'a' + 10);
if ((b >= 'A') && (b <= 'F')) return (byte)(b - 'A' + 10);
throw new IllegalArgumentException();
}
private static void putMapEntry(
final Map<String, String[]> map,
final String name,
final String value) {
String[] newValues = null;
final String[] oldValues = map.get(name);
if (oldValues == null) {
newValues = new String[1];
newValues[0] = value;
} else {
newValues = new String[oldValues.length + 1];
System.arraycopy(oldValues, 0, newValues, 0, oldValues.length);
newValues[oldValues.length] = value;
}
map.put(name, newValues);
}
/**
* Calculate file checksum
* @param file Source file
* @return Hex string for checksum
* @throws IOException
*/
public static String checkSum(final File file) throws IOException {
if(file == null) {
throw new IllegalArgumentException("null file");
}
if(!file.exists()) {
throw new IllegalArgumentException("File does not exist: " + file);
}
FileInputStream fis = null;
try {
final MessageDigest md = MessageDigest.getInstance("MD5");
fis = new FileInputStream(file);
byte[] array = new byte[10240];
int size;
while((size = fis.read(array)) > 0) {
md.update(array, 0, size);
}
byte[] mdbytes = md.digest();
//convert the byte to hex format
StringBuffer sb = new StringBuffer("");
for (int i = 0; i < mdbytes.length; i++) {
sb.append(Integer.toString((mdbytes[i] & 0xff) + 0x100, 16).substring(1));
}
return sb.toString();
} catch (NoSuchAlgorithmException ex) {
throw new IOException(ex);
} finally {
if(fis != null) {
try {
fis.close();
} catch (Exception ex) {}
}
}
}
public static String md5(String pass) {
if(pass != null) {
try {
MessageDigest algorithm = MessageDigest.getInstance("MD5");
byte[] defaultBytes = pass.getBytes("UTF-8");
algorithm.reset();
algorithm.update(defaultBytes);
byte messageDigest[] = algorithm.digest();
StringBuffer hexString = new StringBuffer();
for (int i = 0; i < messageDigest.length; i++) {
String hex = Integer.toHexString(0xFF & messageDigest[i]);
if (hex.length() == 1)
{
hexString.append('0');
}
hexString.append(hex);
}
return hexString.toString();
} catch (NoSuchAlgorithmException ex) {
// never happen
} catch (UnsupportedEncodingException e) {
// never happen
}
}
return null;
}
public static String readTextFile(File file) throws IOException {
if(file == null) {
throw new IllegalArgumentException("null file");
}
// Max 20KB
if(file.length() > 20 * 1000) {
throw new IllegalArgumentException("Illegal file size");
}
StringBuilder s = new StringBuilder();
FileInputStream fis = null;
try {
fis = new FileInputStream(file);
InputStreamReader r = new InputStreamReader(fis, "UTF-8");
char[] buffer = new char[1024];
int size = 0;
while((size = r.read(buffer)) > 0) {
s.append(buffer, 0, size);
}
} finally {
if(fis != null) {
try {
fis.close();
} catch (Exception ex) {}
}
}
return s.toString();
}
public static void writeTextFile(String s, File file) throws IOException {
if(file == null) {
throw new IllegalArgumentException("null file");
}
FileOutputStream fos = null;
try {
fos = new FileOutputStream(file);
OutputStreamWriter w = new OutputStreamWriter(fos, "UTF-8");
w.write(s);
w.flush();
} finally {
if(fos != null) {
try {
fos.close();
} catch (Exception ex) {}
}
}
}
public static boolean isValidFilename(String filename) {
if(System.getProperty("os.name").toLowerCase().contains("Windows")) {
Pattern pattern = Pattern.compile(
"# Match a valid Windows filename (unspecified file system). \n" +
"^ # Anchor to start of string. \n" +
"(?! # Assert filename is not: CON, PRN, \n" +
" (?: # AUX, NUL, COM1, COM2, COM3, COM4, \n" +
" CON|PRN|AUX|NUL| # COM5, COM6, COM7, COM8, COM9, \n" +
" COM[1-9]|LPT[1-9] # LPT1, LPT2, LPT3, LPT4, LPT5, \n" +
" ) # LPT6, LPT7, LPT8, and LPT9... \n" +
" (?:\\.[^.]*)? # followed by optional extension \n" +
" $ # and end of string \n" +
") # End negative lookahead assertion. \n" +
"[^<>:\"/\\\\|?*\\x00-\\x1F]* # Zero or more valid filename chars.\n" +
"[^<>:\"/\\\\|?*\\x00-\\x1F\\ .] # Last char is not a space or dot. \n" +
"$ # Anchor to end of string. ",
Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE | Pattern.COMMENTS);
Matcher matcher = pattern.matcher(filename);
boolean isMatch = matcher.matches();
return isMatch;
} else {
return filename.matches("^[^.\\\\/:*?\"<>|]?[^\\\\/:*?\"<>|]*");
}
}
public static String getFileExtension(final String f) {
int i = f.lastIndexOf('.');
if (i > 0) {
return f.substring(i + 1);
}
return f;
}
public static String implode(final String glue, final Collection<?> parts) {
final StringBuffer b = new StringBuffer();
for(Object s:parts) {
if(b.length() != 0) {
b.append(glue);
}
b.append(s);
}
return b.toString();
}
public static String implode(final String glue, final Object... parts) {
return implode(glue, Arrays.asList(parts));
}
@Deprecated
public static String implode(final Collection<?> c, final String glue) {
final StringBuffer b = new StringBuffer();
for(Object s:c) {
if(b.length() != 0) {
b.append(glue);
}
b.append(s);
}
return b.toString();
}
}