diff --git a/Wolf/.classpath b/Wolf/.classpath
new file mode 100644
index 0000000..ccfdb0d
--- /dev/null
+++ b/Wolf/.classpath
@@ -0,0 +1,13 @@
+
+
sun.misc.Encoder()/Decoder()
.String
this
+ * version is about three times as fast due to the fact that the Commons Codec result has to be recoded
+ * to a String
from byte[]
, which is very expensive.sun.misc.Encoder()/Decoder()
produce temporary arrays but since performance
+ * is quite low it probably does.char[]
representation i accordance with RFC 2045.
+ * @param sArr The bytes to convert. If null
or length 0 an empty array will be returned.
+ * @param lineSep Optional "\r\n" after 76 characters, unless end of file.null
.
+ */
+ public final static char[] encodeToChar(byte[] sArr, boolean lineSep)
+ {
+ // Check special case
+ int sLen = sArr != null ? sArr.length : 0;
+ if (sLen == 0)
+ return new char[0];
+
+ int eLen = (sLen / 3) * 3; // Length of even 24-bits.
+ int cCnt = ((sLen - 1) / 3 + 1) << 2; // Returned character count
+ int dLen = cCnt + (lineSep ? (cCnt - 1) / 76 << 1 : 0); // Length of returned array
+ char[] dArr = new char[dLen];
+
+ // Encode even 24-bits
+ for (int s = 0, d = 0, cc = 0; s < eLen;) {
+ // Copy next three bytes into lower 24 bits of int, paying attension to sign.
+ int i = (sArr[s++] & 0xff) << 16 | (sArr[s++] & 0xff) << 8 | (sArr[s++] & 0xff);
+
+ // Encode the int into four chars
+ dArr[d++] = CA[(i >>> 18) & 0x3f];
+ dArr[d++] = CA[(i >>> 12) & 0x3f];
+ dArr[d++] = CA[(i >>> 6) & 0x3f];
+ dArr[d++] = CA[i & 0x3f];
+
+ // Add optional line separator
+ if (lineSep && ++cc == 19 && d < dLen - 2) {
+ dArr[d++] = '\r';
+ dArr[d++] = '\n';
+ cc = 0;
+ }
+ }
+
+ // Pad and encode last bits if source isn't even 24 bits.
+ int left = sLen - eLen; // 0 - 2.
+ if (left > 0) {
+ // Prepare the int
+ int i = ((sArr[eLen] & 0xff) << 10) | (left == 2 ? ((sArr[sLen - 1] & 0xff) << 2) : 0);
+
+ // Set last four chars
+ dArr[dLen - 4] = CA[i >> 12];
+ dArr[dLen - 3] = CA[(i >>> 6) & 0x3f];
+ dArr[dLen - 2] = left == 2 ? CA[i & 0x3f] : '=';
+ dArr[dLen - 1] = '=';
+ }
+ return dArr;
+ }
+
+ /** Decodes a BASE64 encoded char array. All illegal characters will be ignored and can handle both arrays with
+ * and without line separators.
+ * @param sArr The source array. null
or length 0 will return an empty array.
+ * @return The decoded array of bytes. May be of length 0. Will be null
if the legal characters
+ * (including '=') isn't divideable by 4. (I.e. definitely corrupted).
+ */
+ public final static byte[] decode(char[] sArr)
+ {
+ // Check special case
+ int sLen = sArr != null ? sArr.length : 0;
+ if (sLen == 0)
+ return new byte[0];
+
+ // Count illegal characters (including '\r', '\n') to know what size the returned array will be,
+ // so we don't have to reallocate & copy it later.
+ int sepCnt = 0; // Number of separator characters. (Actually illegal characters, but that's a bonus...)
+ for (int i = 0; i < sLen; i++) // If input is "pure" (I.e. no line separators or illegal chars) base64 this loop can be commented out.
+ if (IA[sArr[i]] < 0)
+ sepCnt++;
+
+ // Check so that legal chars (including '=') are evenly divideable by 4 as specified in RFC 2045.
+ if ((sLen - sepCnt) % 4 != 0)
+ return null;
+
+ int pad = 0;
+ for (int i = sLen; i > 1 && IA[sArr[--i]] <= 0;)
+ if (sArr[i] == '=')
+ pad++;
+
+ int len = ((sLen - sepCnt) * 6 >> 3) - pad;
+
+ byte[] dArr = new byte[len]; // Preallocate byte[] of exact length
+
+ for (int s = 0, d = 0; d < len;) {
+ // Assemble three bytes into an int from four "valid" characters.
+ int i = 0;
+ for (int j = 0; j < 4; j++) { // j only increased if a valid char was found.
+ int c = IA[sArr[s++]];
+ if (c >= 0)
+ i |= c << (18 - j * 6);
+ else
+ j--;
+ }
+ // Add the bytes
+ dArr[d++] = (byte) (i >> 16);
+ if (d < len) {
+ dArr[d++]= (byte) (i >> 8);
+ if (d < len)
+ dArr[d++] = (byte) i;
+ }
+ }
+ return dArr;
+ }
+
+ /** Decodes a BASE64 encoded char array that is known to be resonably well formatted. The method is about twice as
+ * fast as {@link #decode(char[])}. The preconditions are:null
will throw an exception.
+ * @return The decoded array of bytes. May be of length 0.
+ */
+ public final static byte[] decodeFast(char[] sArr)
+ {
+ // Check special case
+ int sLen = sArr.length;
+ if (sLen == 0)
+ return new byte[0];
+
+ int sIx = 0, eIx = sLen - 1; // Start and end index after trimming.
+
+ // Trim illegal chars from start
+ while (sIx < eIx && IA[sArr[sIx]] < 0)
+ sIx++;
+
+ // Trim illegal chars from end
+ while (eIx > 0 && IA[sArr[eIx]] < 0)
+ eIx--;
+
+ // get the padding count (=) (0, 1 or 2)
+ int pad = sArr[eIx] == '=' ? (sArr[eIx - 1] == '=' ? 2 : 1) : 0; // Count '=' at end.
+ int cCnt = eIx - sIx + 1; // Content count including possible separators
+ int sepCnt = sLen > 76 ? (sArr[76] == '\r' ? cCnt / 78 : 0) << 1 : 0;
+
+ int len = ((cCnt - sepCnt) * 6 >> 3) - pad; // The number of decoded bytes
+ byte[] dArr = new byte[len]; // Preallocate byte[] of exact length
+
+ // Decode all but the last 0 - 2 bytes.
+ int d = 0;
+ for (int cc = 0, eLen = (len / 3) * 3; d < eLen;) {
+ // Assemble three bytes into an int from four "valid" characters.
+ int i = IA[sArr[sIx++]] << 18 | IA[sArr[sIx++]] << 12 | IA[sArr[sIx++]] << 6 | IA[sArr[sIx++]];
+
+ // Add the bytes
+ dArr[d++] = (byte) (i >> 16);
+ dArr[d++] = (byte) (i >> 8);
+ dArr[d++] = (byte) i;
+
+ // If line separator, jump over it.
+ if (sepCnt > 0 && ++cc == 19) {
+ sIx += 2;
+ cc = 0;
+ }
+ }
+
+ if (d < len) {
+ // Decode last 1-3 bytes (incl '=') into 1-3 bytes
+ int i = 0;
+ for (int j = 0; sIx <= eIx - pad; j++)
+ i |= IA[sArr[sIx++]] << (18 - j * 6);
+
+ for (int r = 16; d < len; r -= 8)
+ dArr[d++] = (byte) (i >> r);
+ }
+
+ return dArr;
+ }
+
+ // ****************************************************************************************
+ // * byte[] version
+ // ****************************************************************************************
+
+ /** Encodes a raw byte array into a BASE64 byte[]
representation i accordance with RFC 2045.
+ * @param sArr The bytes to convert. If null
or length 0 an empty array will be returned.
+ * @param lineSep Optional "\r\n" after 76 characters, unless end of file.null
.
+ */
+ public final static byte[] encodeToByte(byte[] sArr, boolean lineSep)
+ {
+ // Check special case
+ int sLen = sArr != null ? sArr.length : 0;
+ if (sLen == 0)
+ return new byte[0];
+
+ int eLen = (sLen / 3) * 3; // Length of even 24-bits.
+ int cCnt = ((sLen - 1) / 3 + 1) << 2; // Returned character count
+ int dLen = cCnt + (lineSep ? (cCnt - 1) / 76 << 1 : 0); // Length of returned array
+ byte[] dArr = new byte[dLen];
+
+ // Encode even 24-bits
+ for (int s = 0, d = 0, cc = 0; s < eLen;) {
+ // Copy next three bytes into lower 24 bits of int, paying attension to sign.
+ int i = (sArr[s++] & 0xff) << 16 | (sArr[s++] & 0xff) << 8 | (sArr[s++] & 0xff);
+
+ // Encode the int into four chars
+ dArr[d++] = (byte) CA[(i >>> 18) & 0x3f];
+ dArr[d++] = (byte) CA[(i >>> 12) & 0x3f];
+ dArr[d++] = (byte) CA[(i >>> 6) & 0x3f];
+ dArr[d++] = (byte) CA[i & 0x3f];
+
+ // Add optional line separator
+ if (lineSep && ++cc == 19 && d < dLen - 2) {
+ dArr[d++] = '\r';
+ dArr[d++] = '\n';
+ cc = 0;
+ }
+ }
+
+ // Pad and encode last bits if source isn't an even 24 bits.
+ int left = sLen - eLen; // 0 - 2.
+ if (left > 0) {
+ // Prepare the int
+ int i = ((sArr[eLen] & 0xff) << 10) | (left == 2 ? ((sArr[sLen - 1] & 0xff) << 2) : 0);
+
+ // Set last four chars
+ dArr[dLen - 4] = (byte) CA[i >> 12];
+ dArr[dLen - 3] = (byte) CA[(i >>> 6) & 0x3f];
+ dArr[dLen - 2] = left == 2 ? (byte) CA[i & 0x3f] : (byte) '=';
+ dArr[dLen - 1] = '=';
+ }
+ return dArr;
+ }
+
+ /** Decodes a BASE64 encoded byte array. All illegal characters will be ignored and can handle both arrays with
+ * and without line separators.
+ * @param sArr The source array. Length 0 will return an empty array. null
will throw an exception.
+ * @return The decoded array of bytes. May be of length 0. Will be null
if the legal characters
+ * (including '=') isn't divideable by 4. (I.e. definitely corrupted).
+ */
+ public final static byte[] decode(byte[] sArr)
+ {
+ // Check special case
+ int sLen = sArr.length;
+
+ // Count illegal characters (including '\r', '\n') to know what size the returned array will be,
+ // so we don't have to reallocate & copy it later.
+ int sepCnt = 0; // Number of separator characters. (Actually illegal characters, but that's a bonus...)
+ for (int i = 0; i < sLen; i++) // If input is "pure" (I.e. no line separators or illegal chars) base64 this loop can be commented out.
+ if (IA[sArr[i] & 0xff] < 0)
+ sepCnt++;
+
+ // Check so that legal chars (including '=') are evenly divideable by 4 as specified in RFC 2045.
+ if ((sLen - sepCnt) % 4 != 0)
+ return null;
+
+ int pad = 0;
+ for (int i = sLen; i > 1 && IA[sArr[--i] & 0xff] <= 0;)
+ if (sArr[i] == '=')
+ pad++;
+
+ int len = ((sLen - sepCnt) * 6 >> 3) - pad;
+
+ byte[] dArr = new byte[len]; // Preallocate byte[] of exact length
+
+ for (int s = 0, d = 0; d < len;) {
+ // Assemble three bytes into an int from four "valid" characters.
+ int i = 0;
+ for (int j = 0; j < 4; j++) { // j only increased if a valid char was found.
+ int c = IA[sArr[s++] & 0xff];
+ if (c >= 0)
+ i |= c << (18 - j * 6);
+ else
+ j--;
+ }
+
+ // Add the bytes
+ dArr[d++] = (byte) (i >> 16);
+ if (d < len) {
+ dArr[d++]= (byte) (i >> 8);
+ if (d < len)
+ dArr[d++] = (byte) i;
+ }
+ }
+
+ return dArr;
+ }
+
+
+ /** Decodes a BASE64 encoded byte array that is known to be resonably well formatted. The method is about twice as
+ * fast as {@link #decode(byte[])}. The preconditions are:null
will throw an exception.
+ * @return The decoded array of bytes. May be of length 0.
+ */
+ public final static byte[] decodeFast(byte[] sArr)
+ {
+ // Check special case
+ int sLen = sArr.length;
+ if (sLen == 0)
+ return new byte[0];
+
+ int sIx = 0, eIx = sLen - 1; // Start and end index after trimming.
+
+ // Trim illegal chars from start
+ while (sIx < eIx && IA[sArr[sIx] & 0xff] < 0)
+ sIx++;
+
+ // Trim illegal chars from end
+ while (eIx > 0 && IA[sArr[eIx] & 0xff] < 0)
+ eIx--;
+
+ // get the padding count (=) (0, 1 or 2)
+ int pad = sArr[eIx] == '=' ? (sArr[eIx - 1] == '=' ? 2 : 1) : 0; // Count '=' at end.
+ int cCnt = eIx - sIx + 1; // Content count including possible separators
+ int sepCnt = sLen > 76 ? (sArr[76] == '\r' ? cCnt / 78 : 0) << 1 : 0;
+
+ int len = ((cCnt - sepCnt) * 6 >> 3) - pad; // The number of decoded bytes
+ byte[] dArr = new byte[len]; // Preallocate byte[] of exact length
+
+ // Decode all but the last 0 - 2 bytes.
+ int d = 0;
+ for (int cc = 0, eLen = (len / 3) * 3; d < eLen;) {
+ // Assemble three bytes into an int from four "valid" characters.
+ int i = IA[sArr[sIx++]] << 18 | IA[sArr[sIx++]] << 12 | IA[sArr[sIx++]] << 6 | IA[sArr[sIx++]];
+
+ // Add the bytes
+ dArr[d++] = (byte) (i >> 16);
+ dArr[d++] = (byte) (i >> 8);
+ dArr[d++] = (byte) i;
+
+ // If line separator, jump over it.
+ if (sepCnt > 0 && ++cc == 19) {
+ sIx += 2;
+ cc = 0;
+ }
+ }
+
+ if (d < len) {
+ // Decode last 1-3 bytes (incl '=') into 1-3 bytes
+ int i = 0;
+ for (int j = 0; sIx <= eIx - pad; j++)
+ i |= IA[sArr[sIx++]] << (18 - j * 6);
+
+ for (int r = 16; d < len; r -= 8)
+ dArr[d++] = (byte) (i >> r);
+ }
+
+ return dArr;
+ }
+
+ // ****************************************************************************************
+ // * String version
+ // ****************************************************************************************
+
+ /** Encodes a raw byte array into a BASE64 String
representation i accordance with RFC 2045.
+ * @param sArr The bytes to convert. If null
or length 0 an empty array will be returned.
+ * @param lineSep Optional "\r\n" after 76 characters, unless end of file.null
.
+ */
+ public final static String encodeToString(byte[] sArr, boolean lineSep)
+ {
+ // Reuse char[] since we can't create a String incrementally anyway and StringBuffer/Builder would be slower.
+ return new String(encodeToChar(sArr, lineSep));
+ }
+
+ /** Decodes a BASE64 encoded String
. All illegal characters will be ignored and can handle both strings with
+ * and without line separators.decode(str.toCharArray())
instead. That
+ * will create a temporary array though. This version will use str.charAt(i)
to iterate the string.
+ * @param str The source string. null
or length 0 will return an empty array.
+ * @return The decoded array of bytes. May be of length 0. Will be null
if the legal characters
+ * (including '=') isn't divideable by 4. (I.e. definitely corrupted).
+ */
+ public final static byte[] decode(String str)
+ {
+ // Check special case
+ int sLen = str != null ? str.length() : 0;
+ if (sLen == 0)
+ return new byte[0];
+
+ // Count illegal characters (including '\r', '\n') to know what size the returned array will be,
+ // so we don't have to reallocate & copy it later.
+ int sepCnt = 0; // Number of separator characters. (Actually illegal characters, but that's a bonus...)
+ for (int i = 0; i < sLen; i++) // If input is "pure" (I.e. no line separators or illegal chars) base64 this loop can be commented out.
+ if (IA[str.charAt(i)] < 0)
+ sepCnt++;
+
+ // Check so that legal chars (including '=') are evenly divideable by 4 as specified in RFC 2045.
+ if ((sLen - sepCnt) % 4 != 0)
+ return null;
+
+ // Count '=' at end
+ int pad = 0;
+ for (int i = sLen; i > 1 && IA[str.charAt(--i)] <= 0;)
+ if (str.charAt(i) == '=')
+ pad++;
+
+ int len = ((sLen - sepCnt) * 6 >> 3) - pad;
+
+ byte[] dArr = new byte[len]; // Preallocate byte[] of exact length
+
+ for (int s = 0, d = 0; d < len;) {
+ // Assemble three bytes into an int from four "valid" characters.
+ int i = 0;
+ for (int j = 0; j < 4; j++) { // j only increased if a valid char was found.
+ int c = IA[str.charAt(s++)];
+ if (c >= 0)
+ i |= c << (18 - j * 6);
+ else
+ j--;
+ }
+ // Add the bytes
+ dArr[d++] = (byte) (i >> 16);
+ if (d < len) {
+ dArr[d++]= (byte) (i >> 8);
+ if (d < len)
+ dArr[d++] = (byte) i;
+ }
+ }
+ return dArr;
+ }
+
+ /** Decodes a BASE64 encoded string that is known to be resonably well formatted. The method is about twice as
+ * fast as {@link #decode(String)}. The preconditions are:null
will throw an exception.
+ * @return The decoded array of bytes. May be of length 0.
+ */
+ public final static byte[] decodeFast(String s)
+ {
+ // Check special case
+ int sLen = s.length();
+ if (sLen == 0)
+ return new byte[0];
+
+ int sIx = 0, eIx = sLen - 1; // Start and end index after trimming.
+
+ // Trim illegal chars from start
+ while (sIx < eIx && IA[s.charAt(sIx) & 0xff] < 0)
+ sIx++;
+
+ // Trim illegal chars from end
+ while (eIx > 0 && IA[s.charAt(eIx) & 0xff] < 0)
+ eIx--;
+
+ // get the padding count (=) (0, 1 or 2)
+ int pad = s.charAt(eIx) == '=' ? (s.charAt(eIx - 1) == '=' ? 2 : 1) : 0; // Count '=' at end.
+ int cCnt = eIx - sIx + 1; // Content count including possible separators
+ int sepCnt = sLen > 76 ? (s.charAt(76) == '\r' ? cCnt / 78 : 0) << 1 : 0;
+
+ int len = ((cCnt - sepCnt) * 6 >> 3) - pad; // The number of decoded bytes
+ byte[] dArr = new byte[len]; // Preallocate byte[] of exact length
+
+ // Decode all but the last 0 - 2 bytes.
+ int d = 0;
+ for (int cc = 0, eLen = (len / 3) * 3; d < eLen;) {
+ // Assemble three bytes into an int from four "valid" characters.
+ int i = IA[s.charAt(sIx++)] << 18 | IA[s.charAt(sIx++)] << 12 | IA[s.charAt(sIx++)] << 6 | IA[s.charAt(sIx++)];
+
+ // Add the bytes
+ dArr[d++] = (byte) (i >> 16);
+ dArr[d++] = (byte) (i >> 8);
+ dArr[d++] = (byte) i;
+
+ // If line separator, jump over it.
+ if (sepCnt > 0 && ++cc == 19) {
+ sIx += 2;
+ cc = 0;
+ }
+ }
+
+ if (d < len) {
+ // Decode last 1-3 bytes (incl '=') into 1-3 bytes
+ int i = 0;
+ for (int j = 0; sIx <= eIx - pad; j++)
+ i |= IA[s.charAt(sIx++)] << (18 - j * 6);
+
+ for (int r = 16; d < len; r -= 8)
+ dArr[d++] = (byte) (i >> r);
+ }
+
+ return dArr;
+ }
+}
\ No newline at end of file
diff --git a/Wolf/src/com/roy/wolf/util/CompressManager.java b/Wolf/src/com/roy/wolf/util/CompressManager.java
new file mode 100644
index 0000000..3469e2d
--- /dev/null
+++ b/Wolf/src/com/roy/wolf/util/CompressManager.java
@@ -0,0 +1,141 @@
+package com.roy.wolf.util;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.zip.Deflater;
+import java.util.zip.DeflaterOutputStream;
+import java.util.zip.Inflater;
+import java.util.zip.InflaterInputStream;
+
+public class CompressManager {
+ /**
+ * 压缩
+ *
+ * @param data
+ * 待压缩的数据
+ * @return byte[] 压缩后的数据
+ */
+ public static byte[] compress(byte[] data) {
+ byte[] output = new byte[0];
+
+ Deflater compresser = new Deflater();
+
+ compresser.reset();
+ compresser.setInput(data);
+ compresser.finish();
+ ByteArrayOutputStream bos = new ByteArrayOutputStream(data.length);
+ try {
+ byte[] buf = new byte[1024];
+ while (!compresser.finished()) {
+ int i = compresser.deflate(buf);
+ bos.write(buf, 0, i);
+ }
+ output = bos.toByteArray();
+ } catch (Exception e) {
+ output = data;
+ e.printStackTrace();
+ } finally {
+ try {
+ bos.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ compresser.end();
+ return output;
+ }
+
+ public byte[] compressData(OutputStream os) throws IOException {
+ byte[] output = new byte[0];
+
+ Deflater d = new Deflater();
+ DeflaterOutputStream dout = null;
+
+ try {
+ dout = new DeflaterOutputStream(os, d);
+ dout.write(output);
+ } catch (Exception e) {
+ output = null;
+ e.printStackTrace();
+ } finally {
+ try {
+ os.close();
+ dout.close();
+ } catch (Throwable e) {
+ e.printStackTrace();
+ }
+ }
+
+ return output;
+ }
+
+ /**
+ * 解压缩
+ *
+ * @param data
+ * 待解压的数据
+ * @return byte[] 解压缩后的数据
+ */
+ public static byte[] decompress(byte[] data) {
+ byte[] output = new byte[0];
+
+ Inflater decompresser = new Inflater();
+ decompresser.reset();
+ decompresser.setInput(data);
+
+ ByteArrayOutputStream o = new ByteArrayOutputStream(data.length);
+ try {
+ byte[] buf = new byte[1024];
+ while (!decompresser.finished()) {
+ int i = decompresser.inflate(buf);
+ o.write(buf, 0, i);
+ }
+ output = o.toByteArray();
+ } catch (Exception e) {
+ output = data;
+ e.printStackTrace();
+ } finally {
+ try {
+ o.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ decompresser.end();
+ return output;
+ }
+
+ public byte[] decompressData(InputStream is) throws IOException {
+ byte[] output = new byte[0];
+
+ InflaterInputStream in = null;
+ ByteArrayOutputStream bout = null;
+ int b;
+
+ try {
+ in = new InflaterInputStream(is);
+ bout = new ByteArrayOutputStream(512);
+
+ while ((b = in.read()) != -1) {
+ bout.write(b);
+ }
+
+ output = bout.toByteArray();
+ } catch (Exception e) {
+ output = null;
+ e.printStackTrace();
+ } finally {
+ try {
+ in.close();
+ bout.close();
+ } catch (Throwable e) {
+ e.printStackTrace();
+ }
+ }
+
+ return output;
+ }
+}
diff --git a/Wolf/src/com/roy/wolf/util/DeviceUtil.java b/Wolf/src/com/roy/wolf/util/DeviceUtil.java
new file mode 100644
index 0000000..4641f6e
--- /dev/null
+++ b/Wolf/src/com/roy/wolf/util/DeviceUtil.java
@@ -0,0 +1,199 @@
+package com.roy.wolf.util;
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.net.wifi.WifiInfo;
+import android.net.wifi.WifiManager;
+import android.os.Build;
+import android.provider.Settings.Secure;
+import android.telephony.TelephonyManager;
+import android.util.DisplayMetrics;
+import android.view.Display;
+import android.view.WindowManager;
+
+import java.lang.reflect.Method;
+
+/**
+ *
+ * 包含设备处理方法的工具类
+ *
+ */
+public class DeviceUtil {
+
+ public static final int SDK_VERSION_1_5 = 3;
+ public static final int SDK_VERSION_1_6 = 4;
+ public static final int SDK_VERSION_2_0 = 5;
+ public static final int SDK_VERSION_2_0_1 = 6;
+ public static final int SDK_VERSION_2_1 = 7;
+ public static final int SDK_VERSION_2_2 = 8;
+ public static final int SDK_VERSION_2_3 = 9;
+ public static final int SDK_VERSION_2_3_3 = 10;
+ public static final int SDK_VERSION_3_0 = 11;
+
+ public static final float DENSITY_LOW = 0.75f;
+ public static final float DENSITY_MEDIUM = 1.0f;
+ public static final float DENSITY_HIGH = 1.5f;
+ public static final float DENSITY_EXTRA_HIGH = 2.0f;
+
+ public static final int DPI_LOW = 120;
+ public static final int DPI_MEDIUM = 160;
+ public static final int DPI_HIGH = 240;
+ public static final int DPI_EXTRA_HIGH = 320;
+
+ public static final int SCREEN_HEIGHT_SMALL = 320; //related default screens are at least 240*320(px)
+ public static final int SCREEN_HEIGHT_NORMAL = 480; //related default screens are at least 320*480(px)
+ public static final int SCREEN_HEIGHT_LARGE = 800; //related default screens are at least 480*800(px)
+ public static final int SCREEN_HEIGHT_XLARGE = 1024; //related default screens are at least 1024*600(px)
+ public static final int SCREEN_HEIGHT_XXLARGE = 1280; //related default screens are at least 1280*768(px)
+
+ /**
+ * 获得设备型号
+ * @return
+ */
+ public static String getDeviceModel() {
+ return StringUtil.makeSafe(Build.MODEL);
+ }
+
+ /**
+ * 获得设备的固件版本号
+ */
+ public static String getReleaseVersion() {
+ return StringUtil.makeSafe(Build.VERSION.RELEASE);
+ }
+
+ /**
+ * 获得国际移动设备身份码即DeviceId
+ * @param context
+ * @return
+ */
+ public static String getIMEI(Context context) {
+ return ((TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE)).getDeviceId();
+ }
+
+ /**
+ * 获得MSISDN
+ * @param context
+ * @return
+ */
+ public static String getMSISDN(Context context) {
+ if(context == null)
+ return null;
+ String msisdn = ((TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE)).getLine1Number();
+ if(msisdn == null)
+ return "No phone number";
+ return (msisdn.equals("") ? "No phone number" : msisdn);
+ }
+
+ /**
+ * 获得国际移动用户识别码
+ * @param context
+ * @return
+ */
+ public static String getIMSI(Context context) {
+ return ((TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE)).getSubscriberId();
+ }
+
+ /**
+ * 获得设备屏幕矩形区域范围
+ * @param context
+ * @return
+ */
+ public static Rect getScreenRect(Context context) {
+ Display display = ((WindowManager)context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
+ int w = display.getWidth();
+ int h = display.getHeight();
+ return new Rect(0, 0, w, h);
+ }
+
+ /**
+ * 获得设备屏幕密度
+ */
+ public static float getScreenDensity(Context context) {
+ DisplayMetrics metrics = context.getApplicationContext().getResources().getDisplayMetrics();
+ return metrics.density;
+ }
+
+ public static int getScreenDensityDpi(Context context) {
+ DisplayMetrics metrics = context.getApplicationContext().getResources().getDisplayMetrics();
+ return (int)(metrics.density * 160);
+ }
+
+ /**
+ * 获得系统版本
+ */
+ public static String getSDKVersion(){
+ return android.os.Build.VERSION.SDK;
+ }
+
+ public static int getSDKVersionInt(){
+ try {
+ return Integer.valueOf(android.os.Build.VERSION.SDK);
+ } catch (Exception e) {
+ return 0;
+ }
+ //return android.os.Build.VERSION.SDK_INT;
+ }
+
+ /**
+ * 获得android_id
+ * @param context
+ * @return
+ */
+ public static String getAndroidId(Context context) {
+ return Secure.getString(context.getContentResolver(), Secure.ANDROID_ID);
+ }
+
+ /**
+ * 获得屏幕尺寸
+ * @param context
+ * @return
+ */
+ public static String getResolution(Context context) {
+ Rect rect = getScreenRect(context);
+ return rect.right + "x" + rect.bottom;
+ }
+
+ public static String getSerialNumber() {
+ String serialNumber = "";
+
+ try {
+ Class> c = Class.forName("android.os.SystemProperties");
+ Method get = c.getMethod("get", String.class);
+ serialNumber = (String) get.invoke(c, "ro.serialno");
+
+ if(serialNumber.equals("")) {
+ serialNumber = "?";
+ }
+ } catch (Exception e) {
+ if(serialNumber.equals("")) {
+ serialNumber = "?";
+ }
+ }
+
+ return serialNumber;
+ }
+
+ /**
+ * 获取系统cpu的abi(application binary interface)信息
+ * @return
+ */
+ public static String getCpuAbi() {
+ try {
+ return StringUtil.makeSafe(Build.CPU_ABI);
+ } catch(Error e) {
+ return "";
+ }
+ }
+
+ /**
+ * 获取wifi mac地址
+ * @return wifi mac地址(xx:xx:xx:xx:xx)
+ */
+ public static String getLocalMacAddress(Context context) {
+ WifiManager wifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
+ WifiInfo info = wifi.getConnectionInfo();
+
+ return info.getMacAddress();
+ }
+
+}
diff --git a/Wolf/src/com/roy/wolf/util/NetworkUtil.java b/Wolf/src/com/roy/wolf/util/NetworkUtil.java
new file mode 100644
index 0000000..c437003
--- /dev/null
+++ b/Wolf/src/com/roy/wolf/util/NetworkUtil.java
@@ -0,0 +1,200 @@
+package com.roy.wolf.util;
+
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.util.Enumeration;
+
+import org.apache.http.HttpHost;
+import org.apache.http.client.HttpClient;
+import org.apache.http.conn.params.ConnRoutePNames;
+import org.apache.http.params.HttpParams;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.telephony.TelephonyManager;
+import android.util.Log;
+
+/**
+ *
+ * 包含网络处理方法的工具类
+ *
+ */
+public class NetworkUtil {
+
+ private static final String TAG = NetworkInfo.class.getSimpleName();
+
+ public static boolean hasInternet(Context context) {
+ ConnectivityManager manager = (ConnectivityManager) context
+ .getSystemService(Context.CONNECTIVITY_SERVICE);
+ NetworkInfo info = manager.getActiveNetworkInfo();
+ if (info == null || !info.isConnected()) {
+ return false;
+ }
+// if (info.isRoaming()) {
+// //漫游
+// return true;
+// }
+ return true;
+ }
+
+ public static boolean isWiFiActive(Context inContext) {
+ Context context = inContext.getApplicationContext();
+ ConnectivityManager connectivity = (ConnectivityManager) context
+ .getSystemService(Context.CONNECTIVITY_SERVICE);
+ if (connectivity != null) {
+ NetworkInfo[] info = connectivity.getAllNetworkInfo();
+ if (info != null) {
+ for (int i = 0; i < info.length; i++) {
+ if (info[i].getTypeName().equals("WIFI") && info[i].isConnected()) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+ public static boolean hasMoreThanOneConnection(Context context){
+ ConnectivityManager manager = (ConnectivityManager)context
+ .getSystemService(Context.CONNECTIVITY_SERVICE);
+ if(manager==null){
+ return false;
+ }else{
+ NetworkInfo [] info = manager.getAllNetworkInfo();
+ int counter = 0;
+ for(int i = 0 ;iProvides extra functionality for Java Number classes.
+ * + * @author Rand McNeely + * @author Stephen Colebourne + * @author Steve Downey + * @author Eric Pugh + * @author Phil Steitz + * @author Matthew Hawthorne + * @author Gary Gregory + * @author Fredrik Westermarck + * @since 2.0 + * @version $Id: NumberUtils.java 609475 2008-01-06 23:58:59Z bayard $ + */ +public class NumberUtil { + + /** Reusable Long constant for zero. */ + public static final Long LONG_ZERO = Long.valueOf(0L); + /** Reusable Long constant for one. */ + public static final Long LONG_ONE = Long.valueOf(1L); + /** Reusable Long constant for minus one. */ + public static final Long LONG_MINUS_ONE = Long.valueOf(-1L); + /** Reusable Integer constant for zero. */ + public static final Integer INTEGER_ZERO = Integer.valueOf(0); + /** Reusable Integer constant for one. */ + public static final Integer INTEGER_ONE = Integer.valueOf(1); + /** Reusable Integer constant for minus one. */ + public static final Integer INTEGER_MINUS_ONE = Integer.valueOf(-1); + /** Reusable Short constant for zero. */ + public static final Short SHORT_ZERO = Short.valueOf((short) 0); + /** Reusable Short constant for one. */ + public static final Short SHORT_ONE = Short.valueOf((short) 1); + /** Reusable Short constant for minus one. */ + public static final Short SHORT_MINUS_ONE = Short.valueOf((short) -1); + /** Reusable Byte constant for zero. */ + public static final Byte BYTE_ZERO = Byte.valueOf((byte) 0); + /** Reusable Byte constant for one. */ + public static final Byte BYTE_ONE = Byte.valueOf((byte) 1); + /** Reusable Byte constant for minus one. */ + public static final Byte BYTE_MINUS_ONE = Byte.valueOf((byte) -1); + /** Reusable Double constant for zero. */ + public static final Double DOUBLE_ZERO = Double.valueOf(0.0d); + /** Reusable Double constant for one. */ + public static final Double DOUBLE_ONE = Double.valueOf(1.0d); + /** Reusable Double constant for minus one. */ + public static final Double DOUBLE_MINUS_ONE = Double.valueOf(-1.0d); + /** Reusable Float constant for zero. */ + public static final Float FLOAT_ZERO = Float.valueOf(0.0f); + /** Reusable Float constant for one. */ + public static final Float FLOAT_ONE = Float.valueOf(1.0f); + /** Reusable Float constant for minus one. */ + public static final Float FLOAT_MINUS_ONE = Float.valueOf(-1.0f); + + /** + *NumberUtils
instances should NOT be constructed in standard programming.
+ * Instead, the class should be used as NumberUtils.stringToInt("6");
.
This constructor is public to permit tools that require a JavaBean instance + * to operate.
+ */ + public NumberUtil() { + super(); + } + + /** + *Convert a String
to an int
, returning
+ * zero
if the conversion fails.
If the string is null
, zero
is returned.
+ * NumberUtils.toInt(null) = 0 + * NumberUtils.toInt("") = 0 + * NumberUtils.toInt("1") = 1 + *+ * + * @param str the string to convert, may be null + * @return the int represented by the string, or
zero
if
+ * conversion fails
+ * @since 2.1
+ */
+ public static int toInt(String str) {
+ return toInt(str, 0);
+ }
+
+
+ /**
+ * Convert a String
to an int
, returning a
+ * default value if the conversion fails.
If the string is null
, the default value is returned.
+ * NumberUtils.toInt(null, 1) = 1 + * NumberUtils.toInt("", 1) = 1 + * NumberUtils.toInt("1", 0) = 1 + *+ * + * @param str the string to convert, may be null + * @param defaultValue the default value + * @return the int represented by the string, or the default if conversion fails + * @since 2.1 + */ + public static int toInt(String str, int defaultValue) { + if(str == null || str.length() == 0) { + return defaultValue; + } + try { + return Integer.parseInt(str); + } catch (NumberFormatException nfe) { + return defaultValue; + } + } + + /** + *
Convert a String
to a long
, returning
+ * zero
if the conversion fails.
If the string is null
, zero
is returned.
+ * NumberUtils.toLong(null) = 0L + * NumberUtils.toLong("") = 0L + * NumberUtils.toLong("1") = 1L + *+ * + * @param str the string to convert, may be null + * @return the long represented by the string, or
0
if
+ * conversion fails
+ * @since 2.1
+ */
+ public static long toLong(String str) {
+ return toLong(str, 0L);
+ }
+
+ /**
+ * Convert a String
to a long
, returning a
+ * default value if the conversion fails.
If the string is null
, the default value is returned.
+ * NumberUtils.toLong(null, 1L) = 1L + * NumberUtils.toLong("", 1L) = 1L + * NumberUtils.toLong("1", 0L) = 1L + *+ * + * @param str the string to convert, may be null + * @param defaultValue the default value + * @return the long represented by the string, or the default if conversion fails + * @since 2.1 + */ + public static long toLong(String str, long defaultValue) { + if (str == null) { + return defaultValue; + } + try { + return Long.parseLong(str); + } catch (NumberFormatException nfe) { + return defaultValue; + } + } + + /** + *
Convert a String
to a float
, returning
+ * 0.0f
if the conversion fails.
If the string str
is null
,
+ * 0.0f
is returned.
+ * NumberUtils.toFloat(null) = 0.0f + * NumberUtils.toFloat("") = 0.0f + * NumberUtils.toFloat("1.5") = 1.5f + *+ * + * @param str the string to convert, may be
null
+ * @return the float represented by the string, or 0.0f
+ * if conversion fails
+ * @since 2.1
+ */
+ public static float toFloat(String str) {
+ return toFloat(str, 0.0f);
+ }
+
+ /**
+ * Convert a String
to a float
, returning a
+ * default value if the conversion fails.
If the string str
is null
, the default
+ * value is returned.
+ * NumberUtils.toFloat(null, 1.1f) = 1.0f + * NumberUtils.toFloat("", 1.1f) = 1.1f + * NumberUtils.toFloat("1.5", 0.0f) = 1.5f + *+ * + * @param str the string to convert, may be
null
+ * @param defaultValue the default value
+ * @return the float represented by the string, or defaultValue
+ * if conversion fails
+ * @since 2.1
+ */
+ public static float toFloat(String str, float defaultValue) {
+ if (str == null) {
+ return defaultValue;
+ }
+ try {
+ return Float.parseFloat(str);
+ } catch (NumberFormatException nfe) {
+ return defaultValue;
+ }
+ }
+
+ /**
+ * Convert a String
to a double
, returning
+ * 0.0d
if the conversion fails.
If the string str
is null
,
+ * 0.0d
is returned.
+ * NumberUtils.toDouble(null) = 0.0d + * NumberUtils.toDouble("") = 0.0d + * NumberUtils.toDouble("1.5") = 1.5d + *+ * + * @param str the string to convert, may be
null
+ * @return the double represented by the string, or 0.0d
+ * if conversion fails
+ * @since 2.1
+ */
+ public static double toDouble(String str) {
+ return toDouble(str, 0.0d);
+ }
+
+ /**
+ * Convert a String
to a double
, returning a
+ * default value if the conversion fails.
If the string str
is null
, the default
+ * value is returned.
+ * NumberUtils.toDouble(null, 1.1d) = 1.1d + * NumberUtils.toDouble("", 1.1d) = 1.1d + * NumberUtils.toDouble("1.5", 0.0d) = 1.5d + *+ * + * @param str the string to convert, may be
null
+ * @param defaultValue the default value
+ * @return the double represented by the string, or defaultValue
+ * if conversion fails
+ * @since 2.1
+ */
+ public static double toDouble(String str, double defaultValue) {
+ if (str == null) {
+ return defaultValue;
+ }
+ try {
+ return Double.parseDouble(str);
+ } catch (NumberFormatException nfe) {
+ return defaultValue;
+ }
+ }
+
+ //-----------------------------------------------------------------------
+ // must handle Long, Float, Integer, Float, Short,
+ // BigDecimal, BigInteger and Byte
+ // useful methods:
+ // Byte.decode(String)
+ // Byte.valueOf(String,int radix)
+ // Byte.valueOf(String)
+ // Double.valueOf(String)
+ // Float.valueOf(String)
+ // new Float(String)
+ // Integer.valueOf(String,int radix)
+ // Integer.valueOf(String)
+ // Integer.decode(String)
+ // Integer.getInteger(String)
+ // Integer.getInteger(String,int val)
+ // Integer.getInteger(String,Integer val)
+ // new Integer(String)
+ // new Double(String)
+ // new Byte(String)
+ // new Long(String)
+ // Long.getLong(String)
+ // Long.getLong(String,int)
+ // Long.getLong(String,Integer)
+ // Long.valueOf(String,int)
+ // Long.valueOf(String)
+ // new Short(String)
+ // Short.decode(String)
+ // Short.valueOf(String,int)
+ // Short.valueOf(String)
+ // new BigDecimal(String)
+ // new BigInteger(String)
+ // new BigInteger(String,int radix)
+ // Possible inputs:
+ // 45 45.5 45E7 4.5E7 Hex Oct Binary xxxF xxxD xxxf xxxd
+ // plus minus everything. Prolly more. A lot are not separable.
+
+ /**
+ * Turns a string value into a java.lang.Number.
+ * + *First, the value is examined for a type qualifier on the end
+ * ('f','F','d','D','l','L'
). If it is found, it starts
+ * trying to create successively larger types from the type specified
+ * until one is found that can represent the value.
If a type specifier is not found, it will check for a decimal point
+ * and then try successively larger types from Integer
to
+ * BigInteger
and from Float
to
+ * BigDecimal
.
If the string starts with 0x
or -0x
, it
+ * will be interpreted as a hexadecimal integer. Values with leading
+ * 0
's will not be interpreted as octal.
Returns null
if the string is null
.
This method does not trim the input string, i.e., strings with leading + * or trailing spaces will generate NumberFormatExceptions.
+ * + * @param str String containing a number, may be null + * @return Number created from the string + * @throws NumberFormatException if the value cannot be converted + */ + public static Number createNumber(String str) throws NumberFormatException { + if (str == null) { + return null; + } + if (StringUtil.isEmptyOrWhitespace(str)) { + throw new NumberFormatException("A blank string is not a valid number"); + } + if (str.startsWith("--")) { + // this is protection for poorness in java.lang.BigDecimal. + // it accepts this as a legal value, but it does not appear + // to be in specification of class. OS X Java parses it to + // a wrong value. + return null; + } + if (str.startsWith("0x") || str.startsWith("-0x")) { + return createInteger(str); + } + char lastChar = str.charAt(str.length() - 1); + String mant; + String dec; + String exp; + int decPos = str.indexOf('.'); + int expPos = str.indexOf('e') + str.indexOf('E') + 1; + + if (decPos > -1) { + + if (expPos > -1) { + if (expPos < decPos) { + throw new NumberFormatException(str + " is not a valid number."); + } + dec = str.substring(decPos + 1, expPos); + } else { + dec = str.substring(decPos + 1); + } + mant = str.substring(0, decPos); + } else { + if (expPos > -1) { + mant = str.substring(0, expPos); + } else { + mant = str; + } + dec = null; + } + if (!Character.isDigit(lastChar)) { + if (expPos > -1 && expPos < str.length() - 1) { + exp = str.substring(expPos + 1, str.length() - 1); + } else { + exp = null; + } + //Requesting a specific type.. + String numeric = str.substring(0, str.length() - 1); + boolean allZeros = isAllZeros(mant) && isAllZeros(exp); + switch (lastChar) { + case 'l' : + case 'L' : + if (dec == null + && exp == null + && (numeric.charAt(0) == '-' && isDigits(numeric.substring(1)) || isDigits(numeric))) { + try { + return createLong(numeric); + } catch (NumberFormatException nfe) { + //Too big for a long + } + return createBigInteger(numeric); + + } + throw new NumberFormatException(str + " is not a valid number."); + case 'f' : + case 'F' : + try { + Float f = NumberUtil.createFloat(numeric); + if (!(f.isInfinite() || (f.floatValue() == 0.0F && !allZeros))) { + //If it's too big for a float or the float value = 0 and the string + //has non-zeros in it, then float does not have the precision we want + return f; + } + + } catch (NumberFormatException nfe) { + // ignore the bad number + } + //Fall through + case 'd' : + case 'D' : + try { + Double d = NumberUtil.createDouble(numeric); + if (!(d.isInfinite() || (d.floatValue() == 0.0D && !allZeros))) { + return d; + } + } catch (NumberFormatException nfe) { + // ignore the bad number + } + try { + return createBigDecimal(numeric); + } catch (NumberFormatException e) { + // ignore the bad number + } + //Fall through + default : + throw new NumberFormatException(str + " is not a valid number."); + + } + } else { + //User doesn't have a preference on the return type, so let's start + //small and go from there... + if (expPos > -1 && expPos < str.length() - 1) { + exp = str.substring(expPos + 1, str.length()); + } else { + exp = null; + } + if (dec == null && exp == null) { + //Must be an int,long,bigint + try { + return createInteger(str); + } catch (NumberFormatException nfe) { + // ignore the bad number + } + try { + return createLong(str); + } catch (NumberFormatException nfe) { + // ignore the bad number + } + return createBigInteger(str); + + } else { + //Must be a float,double,BigDec + boolean allZeros = isAllZeros(mant) && isAllZeros(exp); + try { + Float f = createFloat(str); + if (!(f.isInfinite() || (f.floatValue() == 0.0F && !allZeros))) { + return f; + } + } catch (NumberFormatException nfe) { + // ignore the bad number + } + try { + Double d = createDouble(str); + if (!(d.isInfinite() || (d.doubleValue() == 0.0D && !allZeros))) { + return d; + } + } catch (NumberFormatException nfe) { + // ignore the bad number + } + + return createBigDecimal(str); + + } + } + } + + /** + *Utility method for {@link #createNumber(java.lang.String)}.
+ * + *Returns true
if s is null
.
null
+ */
+ private static boolean isAllZeros(String str) {
+ if (str == null) {
+ return true;
+ }
+ for (int i = str.length() - 1; i >= 0; i--) {
+ if (str.charAt(i) != '0') {
+ return false;
+ }
+ }
+ return str.length() > 0;
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Convert a String
to a Float
.
Returns null
if the string is null
.
String
to convert, may be null
+ * @return converted Float
+ * @throws NumberFormatException if the value cannot be converted
+ */
+ public static Float createFloat(String str) {
+ if (str == null) {
+ return null;
+ }
+ return Float.valueOf(str);
+ }
+
+ /**
+ * Convert a String
to a Double
.
Returns null
if the string is null
.
String
to convert, may be null
+ * @return converted Double
+ * @throws NumberFormatException if the value cannot be converted
+ */
+ public static Double createDouble(String str) {
+ if (str == null) {
+ return null;
+ }
+ return Double.valueOf(str);
+ }
+
+ /**
+ * Convert a String
to a Integer
, handling
+ * hex and octal notations.
Returns null
if the string is null
.
String
to convert, may be null
+ * @return converted Integer
+ * @throws NumberFormatException if the value cannot be converted
+ */
+ public static Integer createInteger(String str) {
+ if (str == null) {
+ return null;
+ }
+ // decode() handles 0xAABD and 0777 (hex and octal) as well.
+ return Integer.decode(str);
+ }
+
+ /**
+ * Convert a String
to a Long
.
Returns null
if the string is null
.
String
to convert, may be null
+ * @return converted Long
+ * @throws NumberFormatException if the value cannot be converted
+ */
+ public static Long createLong(String str) {
+ if (str == null) {
+ return null;
+ }
+ return Long.valueOf(str);
+ }
+
+ /**
+ * Convert a String
to a BigInteger
.
Returns null
if the string is null
.
String
to convert, may be null
+ * @return converted BigInteger
+ * @throws NumberFormatException if the value cannot be converted
+ */
+ public static BigInteger createBigInteger(String str) {
+ if (str == null) {
+ return null;
+ }
+ return new BigInteger(str);
+ }
+
+ /**
+ * Convert a String
to a BigDecimal
.
Returns null
if the string is null
.
String
to convert, may be null
+ * @return converted BigDecimal
+ * @throws NumberFormatException if the value cannot be converted
+ */
+ public static BigDecimal createBigDecimal(String str) {
+ if (str == null) {
+ return null;
+ }
+ // handle JDK1.3.1 bug where "" throws IndexOutOfBoundsException
+ if (StringUtil.isEmptyOrWhitespace(str)) {
+ throw new NumberFormatException("A blank string is not a valid number");
+ }
+ return new BigDecimal(str);
+ }
+
+ // Min in array
+ //--------------------------------------------------------------------
+ /**
+ * Returns the minimum value in an array.
+ * + * @param array an array, must not be null or empty + * @return the minimum value in the array + * @throws IllegalArgumentException ifarray
is null
+ * @throws IllegalArgumentException if array
is empty
+ */
+ public static long min(long[] array) {
+ // Validates input
+ if (array == null) {
+ throw new IllegalArgumentException("The Array must not be null");
+ } else if (array.length == 0) {
+ throw new IllegalArgumentException("Array cannot be empty.");
+ }
+
+ // Finds and returns min
+ long min = array[0];
+ for (int i = 1; i < array.length; i++) {
+ if (array[i] < min) {
+ min = array[i];
+ }
+ }
+
+ return min;
+ }
+
+ /**
+ * Returns the minimum value in an array.
+ * + * @param array an array, must not be null or empty + * @return the minimum value in the array + * @throws IllegalArgumentException ifarray
is null
+ * @throws IllegalArgumentException if array
is empty
+ */
+ public static int min(int[] array) {
+ // Validates input
+ if (array == null) {
+ throw new IllegalArgumentException("The Array must not be null");
+ } else if (array.length == 0) {
+ throw new IllegalArgumentException("Array cannot be empty.");
+ }
+
+ // Finds and returns min
+ int min = array[0];
+ for (int j = 1; j < array.length; j++) {
+ if (array[j] < min) {
+ min = array[j];
+ }
+ }
+
+ return min;
+ }
+
+ /**
+ * Returns the minimum value in an array.
+ * + * @param array an array, must not be null or empty + * @return the minimum value in the array + * @throws IllegalArgumentException ifarray
is null
+ * @throws IllegalArgumentException if array
is empty
+ */
+ public static short min(short[] array) {
+ // Validates input
+ if (array == null) {
+ throw new IllegalArgumentException("The Array must not be null");
+ } else if (array.length == 0) {
+ throw new IllegalArgumentException("Array cannot be empty.");
+ }
+
+ // Finds and returns min
+ short min = array[0];
+ for (int i = 1; i < array.length; i++) {
+ if (array[i] < min) {
+ min = array[i];
+ }
+ }
+
+ return min;
+ }
+
+ /**
+ * Returns the minimum value in an array.
+ * + * @param array an array, must not be null or empty + * @return the minimum value in the array + * @throws IllegalArgumentException ifarray
is null
+ * @throws IllegalArgumentException if array
is empty
+ */
+ public static byte min(byte[] array) {
+ // Validates input
+ if (array == null) {
+ throw new IllegalArgumentException("The Array must not be null");
+ } else if (array.length == 0) {
+ throw new IllegalArgumentException("Array cannot be empty.");
+ }
+
+ // Finds and returns min
+ byte min = array[0];
+ for (int i = 1; i < array.length; i++) {
+ if (array[i] < min) {
+ min = array[i];
+ }
+ }
+
+ return min;
+ }
+
+ /**
+ * Returns the minimum value in an array.
+ * + * @param array an array, must not be null or empty + * @return the minimum value in the array + * @throws IllegalArgumentException ifarray
is null
+ * @throws IllegalArgumentException if array
is empty
+ * @see IEEE754rUtils#min(double[]) IEEE754rUtils for a version of this method that handles NaN differently
+ */
+ public static double min(double[] array) {
+ // Validates input
+ if (array == null) {
+ throw new IllegalArgumentException("The Array must not be null");
+ } else if (array.length == 0) {
+ throw new IllegalArgumentException("Array cannot be empty.");
+ }
+
+ // Finds and returns min
+ double min = array[0];
+ for (int i = 1; i < array.length; i++) {
+ if (Double.isNaN(array[i])) {
+ return Double.NaN;
+ }
+ if (array[i] < min) {
+ min = array[i];
+ }
+ }
+
+ return min;
+ }
+
+ /**
+ * Returns the minimum value in an array.
+ * + * @param array an array, must not be null or empty + * @return the minimum value in the array + * @throws IllegalArgumentException ifarray
is null
+ * @throws IllegalArgumentException if array
is empty
+ * @see IEEE754rUtils#min(float[]) IEEE754rUtils for a version of this method that handles NaN differently
+ */
+ public static float min(float[] array) {
+ // Validates input
+ if (array == null) {
+ throw new IllegalArgumentException("The Array must not be null");
+ } else if (array.length == 0) {
+ throw new IllegalArgumentException("Array cannot be empty.");
+ }
+
+ // Finds and returns min
+ float min = array[0];
+ for (int i = 1; i < array.length; i++) {
+ if (Float.isNaN(array[i])) {
+ return Float.NaN;
+ }
+ if (array[i] < min) {
+ min = array[i];
+ }
+ }
+
+ return min;
+ }
+
+ // Max in array
+ //--------------------------------------------------------------------
+ /**
+ * Returns the maximum value in an array.
+ * + * @param array an array, must not be null or empty + * @return the minimum value in the array + * @throws IllegalArgumentException ifarray
is null
+ * @throws IllegalArgumentException if array
is empty
+ */
+ public static long max(long[] array) {
+ // Validates input
+ if (array == null) {
+ throw new IllegalArgumentException("The Array must not be null");
+ } else if (array.length == 0) {
+ throw new IllegalArgumentException("Array cannot be empty.");
+ }
+
+ // Finds and returns max
+ long max = array[0];
+ for (int j = 1; j < array.length; j++) {
+ if (array[j] > max) {
+ max = array[j];
+ }
+ }
+
+ return max;
+ }
+
+ /**
+ * Returns the maximum value in an array.
+ * + * @param array an array, must not be null or empty + * @return the minimum value in the array + * @throws IllegalArgumentException ifarray
is null
+ * @throws IllegalArgumentException if array
is empty
+ */
+ public static int max(int[] array) {
+ // Validates input
+ if (array == null) {
+ throw new IllegalArgumentException("The Array must not be null");
+ } else if (array.length == 0) {
+ throw new IllegalArgumentException("Array cannot be empty.");
+ }
+
+ // Finds and returns max
+ int max = array[0];
+ for (int j = 1; j < array.length; j++) {
+ if (array[j] > max) {
+ max = array[j];
+ }
+ }
+
+ return max;
+ }
+
+ /**
+ * Returns the maximum value in an array.
+ * + * @param array an array, must not be null or empty + * @return the minimum value in the array + * @throws IllegalArgumentException ifarray
is null
+ * @throws IllegalArgumentException if array
is empty
+ */
+ public static short max(short[] array) {
+ // Validates input
+ if (array == null) {
+ throw new IllegalArgumentException("The Array must not be null");
+ } else if (array.length == 0) {
+ throw new IllegalArgumentException("Array cannot be empty.");
+ }
+
+ // Finds and returns max
+ short max = array[0];
+ for (int i = 1; i < array.length; i++) {
+ if (array[i] > max) {
+ max = array[i];
+ }
+ }
+
+ return max;
+ }
+
+ /**
+ * Returns the maximum value in an array.
+ * + * @param array an array, must not be null or empty + * @return the minimum value in the array + * @throws IllegalArgumentException ifarray
is null
+ * @throws IllegalArgumentException if array
is empty
+ */
+ public static byte max(byte[] array) {
+ // Validates input
+ if (array == null) {
+ throw new IllegalArgumentException("The Array must not be null");
+ } else if (array.length == 0) {
+ throw new IllegalArgumentException("Array cannot be empty.");
+ }
+
+ // Finds and returns max
+ byte max = array[0];
+ for (int i = 1; i < array.length; i++) {
+ if (array[i] > max) {
+ max = array[i];
+ }
+ }
+
+ return max;
+ }
+
+ /**
+ * Returns the maximum value in an array.
+ * + * @param array an array, must not be null or empty + * @return the minimum value in the array + * @throws IllegalArgumentException ifarray
is null
+ * @throws IllegalArgumentException if array
is empty
+ * @see IEEE754rUtils#max(double[]) IEEE754rUtils for a version of this method that handles NaN differently
+ */
+ public static double max(double[] array) {
+ // Validates input
+ if (array== null) {
+ throw new IllegalArgumentException("The Array must not be null");
+ } else if (array.length == 0) {
+ throw new IllegalArgumentException("Array cannot be empty.");
+ }
+
+ // Finds and returns max
+ double max = array[0];
+ for (int j = 1; j < array.length; j++) {
+ if (Double.isNaN(array[j])) {
+ return Double.NaN;
+ }
+ if (array[j] > max) {
+ max = array[j];
+ }
+ }
+
+ return max;
+ }
+
+ /**
+ * Returns the maximum value in an array.
+ * + * @param array an array, must not be null or empty + * @return the minimum value in the array + * @throws IllegalArgumentException ifarray
is null
+ * @throws IllegalArgumentException if array
is empty
+ * @see IEEE754rUtils#max(float[]) IEEE754rUtils for a version of this method that handles NaN differently
+ */
+ public static float max(float[] array) {
+ // Validates input
+ if (array == null) {
+ throw new IllegalArgumentException("The Array must not be null");
+ } else if (array.length == 0) {
+ throw new IllegalArgumentException("Array cannot be empty.");
+ }
+
+ // Finds and returns max
+ float max = array[0];
+ for (int j = 1; j < array.length; j++) {
+ if (Float.isNaN(array[j])) {
+ return Float.NaN;
+ }
+ if (array[j] > max) {
+ max = array[j];
+ }
+ }
+
+ return max;
+ }
+
+ // 3 param min
+ //-----------------------------------------------------------------------
+ /**
+ * Gets the minimum of three long
values.
Gets the minimum of three int
values.
Gets the minimum of three short
values.
Gets the minimum of three byte
values.
Gets the minimum of three double
values.
If any value is NaN
, NaN
is
+ * returned. Infinity is handled.
Gets the minimum of three float
values.
If any value is NaN
, NaN
is
+ * returned. Infinity is handled.
Gets the maximum of three long
values.
Gets the maximum of three int
values.
Gets the maximum of three short
values.
Gets the maximum of three byte
values.
Gets the maximum of three double
values.
If any value is NaN
, NaN
is
+ * returned. Infinity is handled.
Gets the maximum of three float
values.
If any value is NaN
, NaN
is
+ * returned. Infinity is handled.
Compares two doubles
for order.
This method is more comprehensive than the standard Java greater + * than, less than and equals operators.
+ *-1
if the first value is less than the second.+1
if the first value is greater than the second.0
if the values are equal.+ * The ordering is as follows, largest to smallest: + *
-Double.MAX_VALUE
)
+ * Comparing NaN
with NaN
will
+ * return 0
.
double
+ * @param rhs the second double
+ * @return -1
if lhs is less, +1
if greater,
+ * 0
if equal to rhs
+ */
+ public static int compare(double lhs, double rhs) {
+ if (lhs < rhs) {
+ return -1;
+ }
+ if (lhs > rhs) {
+ return +1;
+ }
+ // Need to compare bits to handle 0.0 == -0.0 being true
+ // compare should put -0.0 < +0.0
+ // Two NaNs are also == for compare purposes
+ // where NaN == NaN is false
+ long lhsBits = Double.doubleToLongBits(lhs);
+ long rhsBits = Double.doubleToLongBits(rhs);
+ if (lhsBits == rhsBits) {
+ return 0;
+ }
+ // Something exotic! A comparison to NaN or 0.0 vs -0.0
+ // Fortunately NaN's long is > than everything else
+ // Also negzeros bits < poszero
+ // NAN: 9221120237041090560
+ // MAX: 9218868437227405311
+ // NEGZERO: -9223372036854775808
+ if (lhsBits < rhsBits) {
+ return -1;
+ } else {
+ return +1;
+ }
+ }
+
+ /**
+ * Compares two floats for order.
+ * + *This method is more comprehensive than the standard Java greater than, + * less than and equals operators.
+ *-1
if the first value is less than the second.
+ * +1
if the first value is greater than the second.
+ * 0
if the values are equal.
+ * The ordering is as follows, largest to smallest: + *
-Float.MAX_VALUE
)
+ * Comparing NaN
with NaN
will return
+ * 0
.
float
+ * @param rhs the second float
+ * @return -1
if lhs is less, +1
if greater,
+ * 0
if equal to rhs
+ */
+ public static int compare(float lhs, float rhs) {
+ if (lhs < rhs) {
+ return -1;
+ }
+ if (lhs > rhs) {
+ return +1;
+ }
+ //Need to compare bits to handle 0.0 == -0.0 being true
+ // compare should put -0.0 < +0.0
+ // Two NaNs are also == for compare purposes
+ // where NaN == NaN is false
+ int lhsBits = Float.floatToIntBits(lhs);
+ int rhsBits = Float.floatToIntBits(rhs);
+ if (lhsBits == rhsBits) {
+ return 0;
+ }
+ //Something exotic! A comparison to NaN or 0.0 vs -0.0
+ //Fortunately NaN's int is > than everything else
+ //Also negzeros bits < poszero
+ //NAN: 2143289344
+ //MAX: 2139095039
+ //NEGZERO: -2147483648
+ if (lhsBits < rhsBits) {
+ return -1;
+ } else {
+ return +1;
+ }
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Checks whether the String
contains only
+ * digit characters.
Null
and empty String will return
+ * false
.
String
to check
+ * @return true
if str contains only unicode numeric
+ */
+ public static boolean isDigits(String str) {
+ if (StringUtil.isEmpty(str)) {
+ return false;
+ }
+ for (int i = 0; i < str.length(); i++) {
+ if (!Character.isDigit(str.charAt(i))) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Checks whether the String a valid Java number.
+ * + *Valid numbers include hexadecimal marked with the 0x
+ * qualifier, scientific notation and numbers marked with a type
+ * qualifier (e.g. 123L).
Null
and empty String will return
+ * false
.
String
to check
+ * @return true
if the string is a correctly formatted number
+ */
+ public static boolean isNumber(String str) {
+ if (StringUtil.isEmpty(str)) {
+ return false;
+ }
+ char[] chars = str.toCharArray();
+ int sz = chars.length;
+ boolean hasExp = false;
+ boolean hasDecPoint = false;
+ boolean allowSigns = false;
+ boolean foundDigit = false;
+ // deal with any possible sign up front
+ int start = (chars[0] == '-') ? 1 : 0;
+ if (sz > start + 1) {
+ if (chars[start] == '0' && chars[start + 1] == 'x') {
+ int i = start + 2;
+ if (i == sz) {
+ return false; // str == "0x"
+ }
+ // checking hex (it can't be anything else)
+ for (; i < chars.length; i++) {
+ if ((chars[i] < '0' || chars[i] > '9')
+ && (chars[i] < 'a' || chars[i] > 'f')
+ && (chars[i] < 'A' || chars[i] > 'F')) {
+ return false;
+ }
+ }
+ return true;
+ }
+ }
+ sz--; // don't want to loop to the last char, check it afterwords
+ // for type qualifiers
+ int i = start;
+ // loop to the next to last char or to the last char if we need another digit to
+ // make a valid number (e.g. chars[0..5] = "1234E")
+ while (i < sz || (i < sz + 1 && allowSigns && !foundDigit)) {
+ if (chars[i] >= '0' && chars[i] <= '9') {
+ foundDigit = true;
+ allowSigns = false;
+
+ } else if (chars[i] == '.') {
+ if (hasDecPoint || hasExp) {
+ // two decimal points or dec in exponent
+ return false;
+ }
+ hasDecPoint = true;
+ } else if (chars[i] == 'e' || chars[i] == 'E') {
+ // we've already taken care of hex.
+ if (hasExp) {
+ // two E's
+ return false;
+ }
+ if (!foundDigit) {
+ return false;
+ }
+ hasExp = true;
+ allowSigns = true;
+ } else if (chars[i] == '+' || chars[i] == '-') {
+ if (!allowSigns) {
+ return false;
+ }
+ allowSigns = false;
+ foundDigit = false; // we need a digit after the E
+ } else {
+ return false;
+ }
+ i++;
+ }
+ if (i < chars.length) {
+ if (chars[i] >= '0' && chars[i] <= '9') {
+ // no type qualifier, OK
+ return true;
+ }
+ if (chars[i] == 'e' || chars[i] == 'E') {
+ // can't have an E at the last byte
+ return false;
+ }
+ if (!allowSigns
+ && (chars[i] == 'd'
+ || chars[i] == 'D'
+ || chars[i] == 'f'
+ || chars[i] == 'F')) {
+ return foundDigit;
+ }
+ if (chars[i] == 'l'
+ || chars[i] == 'L') {
+ // not allowing L with an exponent
+ return foundDigit && !hasExp;
+ }
+ // last character is illegal
+ return false;
+ }
+ // allowSigns is true iff the val ends in 'E'
+ // found digit it to make sure weird stuff like '.' and '1E-' doesn't pass
+ return !allowSigns && foundDigit;
+ }
+
+}
diff --git a/Wolf/src/com/roy/wolf/util/PreferenceUtil.java b/Wolf/src/com/roy/wolf/util/PreferenceUtil.java
new file mode 100644
index 0000000..ca7d338
--- /dev/null
+++ b/Wolf/src/com/roy/wolf/util/PreferenceUtil.java
@@ -0,0 +1,128 @@
+package com.roy.wolf.util;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.preference.PreferenceManager;
+import android.text.TextUtils;
+
+public class PreferenceUtil {
+
+ public static String getSharedString(Context context, String key, String defValue) {
+ return PreferenceManager.getDefaultSharedPreferences(context)
+ .getString(key, defValue);
+ }
+
+ public static void putSharedString(Context context, String key, String value) {
+ PreferenceManager.getDefaultSharedPreferences(context).edit()
+ .putString(key, value).commit();
+ }
+
+ public static int getSharedInt(Context context, String key, int defValue) {
+ return PreferenceManager.getDefaultSharedPreferences(context)
+ .getInt(key, defValue);
+ }
+
+ public static void putSharedInt(Context context, String key, int value) {
+ PreferenceManager.getDefaultSharedPreferences(context).edit()
+ .putInt(key, value).commit();
+ }
+
+ public static long getSharedLong(Context context, String key, long defValue) {
+ return PreferenceManager.getDefaultSharedPreferences(context)
+ .getLong(key, defValue);
+ }
+
+ public static void putSharedLong(Context context, String key, long value) {
+ PreferenceManager.getDefaultSharedPreferences(context).edit()
+ .putLong(key, value).commit();
+ }
+
+ public static boolean getSharedBoolean(Context context, String key, boolean defValue){
+ return PreferenceManager.getDefaultSharedPreferences(context)
+ .getBoolean(key, defValue);
+ }
+
+ public static void putSharedBoolean(Context context, String key, boolean value) {
+ PreferenceManager.getDefaultSharedPreferences(context).edit()
+ .putBoolean(key, value).commit();
+ }
+
+ public static void removeShare(Context context, String key){
+ PreferenceManager.getDefaultSharedPreferences(context).edit()
+ .remove(key).commit();
+ }
+
+ public static boolean getBoolean(Activity ac, String key, boolean defValue) {
+ return ac.getPreferences(Context.MODE_PRIVATE)
+ .getBoolean(key, defValue);
+ }
+
+ public static void putBoolean(Activity ac, String key, boolean value) {
+ ac.getPreferences(Context.MODE_PRIVATE)
+ .edit()
+ .putBoolean(key, value)
+ .commit();
+ }
+
+ public static int getInt(Activity ac, String key, int defValue) {
+ return ac.getPreferences(Context.MODE_PRIVATE)
+ .getInt(key, defValue);
+ }
+
+ public static void putInt(Activity ac, String key, int value) {
+ ac.getPreferences(Context.MODE_PRIVATE)
+ .edit()
+ .putInt(key, value)
+ .commit();
+ }
+
+ public static boolean updateShareInt(Intent data, Activity ac, String key,
+ int defValue) {
+ if (data != null) {
+ int t = data.getIntExtra(key, defValue);
+ if (t != getSharedInt(ac, key, defValue)) {
+ putSharedInt(ac, key, t);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static boolean updateShareBoolean(Intent data, Activity ac, String key) {
+ return updateShareBoolean(data, ac, key, true);
+ }
+
+ public static boolean updateShareBoolean(Intent data, Activity ac, String key,
+ boolean defValue) {
+ if (data != null) {
+ boolean b = data.getBooleanExtra(key, defValue);
+ if (b != getSharedBoolean(ac, key, defValue)) {
+ putSharedBoolean(ac, key, b);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static boolean updateShareString(Intent data, Activity ac, String key) {
+ if (data != null) {
+ String s = data.getStringExtra(key);
+
+ if (s != null) {
+ s = s.trim();
+
+ if (s.length() == 0) {
+ s = null;
+ }
+ }
+
+ if (!TextUtils.equals(s, getSharedString(ac, key, null))) {
+ putSharedString(ac, key, s);
+ return true;
+ }
+ }
+ return false;
+ }
+
+}
diff --git a/Wolf/src/com/roy/wolf/util/ProxyManager.java b/Wolf/src/com/roy/wolf/util/ProxyManager.java
new file mode 100644
index 0000000..51064c5
--- /dev/null
+++ b/Wolf/src/com/roy/wolf/util/ProxyManager.java
@@ -0,0 +1,143 @@
+package com.roy.wolf.util;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+import org.apache.http.HttpHost;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.util.Log;
+
+public class ProxyManager {
+ private static final String TAG = ProxyManager.class.getSimpleName();
+
+ private static ProxyManager mProxyManager;
+ private static Context mContext;
+
+ public static synchronized ProxyManager getnstance(Context context) {
+ if(mProxyManager == null) {
+ mContext = context;
+ mProxyManager = new ProxyManager();
+ }
+
+ return mProxyManager;
+ }
+
+ //set proxy for not WIFI network
+ public void setProxy() {
+ HttpHost proxyServer = getProxyServer();
+ if(proxyServer == null) {
+ return;
+ }
+
+ boolean isSuccess = setProxyHostField(proxyServer);
+ }
+
+ private HttpHost getProxyServer() {
+ HttpHost proxyServer = null;
+
+ ConnectivityManager manager = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
+ NetworkInfo info = manager.getActiveNetworkInfo();
+ String extraInfo = null;
+ if (info != null) {
+ extraInfo = StringUtil.strip(info.getExtraInfo());
+ }
+ if (!StringUtil.isEmptyOrWhitespace(extraInfo)) {
+ extraInfo = extraInfo.toLowerCase();
+
+ if (extraInfo.equals("cmwap") || extraInfo.equals("uniwap") || extraInfo.equals("3gwap")) {
+ proxyServer = new HttpHost("10.0.0.172", 80, "http");
+ } else if (extraInfo.equals("ctwap:cdma")) {
+ proxyServer = new HttpHost("10.0.0.200", 80, "http");
+ }
+ }
+
+ return proxyServer;
+ }
+
+ private boolean setProxyHostField(HttpHost proxyServer) {
+ // Getting network
+ Class> networkClass = null;
+ Object network = null;
+ try {
+ networkClass = Class.forName("android.webkit.Network");
+ if(networkClass != null) {
+ network = invokeMethod(networkClass, "getInstance", new Object[]{mContext}, Context.class);
+ }
+// Field networkField = networkClass.getDeclaredField("sNetwork");
+// network = getFieldValueSafely(networkField, null);
+ } catch (Exception ex) {
+ Log.e(TAG, "error getting network");
+ return false;
+ }
+ if (network == null) {
+ Log.e(TAG, "error getting network : null");
+ return false;
+ }
+ Object requestQueue = null;
+ try {
+ Field requestQueueField = networkClass.getDeclaredField("mRequestQueue");
+ requestQueue = getFieldValueSafely(requestQueueField, network);
+ } catch (Exception ex) {
+ Log.e(TAG, "error getting field value");
+ return false;
+ }
+ if (requestQueue == null) {
+ Log.e(TAG, "Request queue is null");
+ return false;
+ }
+ Field proxyHostField = null;
+ try {
+ Class> requestQueueClass = Class.forName("android.net.http.RequestQueue");
+ proxyHostField = requestQueueClass
+ .getDeclaredField("mProxyHost");
+ } catch (Exception ex) {
+ Log.e(TAG, "error getting proxy host field");
+ return false;
+ }
+ synchronized (mProxyManager) {
+ boolean temp = proxyHostField.isAccessible();
+ try {
+ proxyHostField.setAccessible(true);
+ proxyHostField.set(requestQueue, proxyServer);
+ } catch (Exception ex) {
+ Log.e(TAG, "error setting proxy host");
+ } finally {
+ proxyHostField.setAccessible(temp);
+ }
+ }
+ return true;
+ }
+
+ private Object getFieldValueSafely(Field field, Object classInstance) {
+ boolean oldAccessibleValue = field.isAccessible();
+ field.setAccessible(true);
+ Object result = null;
+ try {
+ result = field.get(classInstance);
+ } catch (IllegalArgumentException e) {
+// e.printStackTrace();
+ Log.e(TAG, e.getMessage());
+ } catch (IllegalAccessException e) {
+// e.printStackTrace();
+ Log.e(TAG, e.getMessage());
+ }
+ field.setAccessible(oldAccessibleValue);
+ return result;
+ }
+
+ private Object invokeMethod(Object object, String methodName, Object[] params, Class>... types) throws Exception {
+ Object out = null;
+ Class> c = object instanceof Class ? (Class>) object : object.getClass();
+ if (types != null) {
+ Method method = c.getMethod(methodName, types);
+ out = method.invoke(object, params);
+ } else {
+ Method method = c.getMethod(methodName);
+ out = method.invoke(object);
+ }
+ return out;
+ }
+}
diff --git a/Wolf/src/com/roy/wolf/util/SQLUtil.java b/Wolf/src/com/roy/wolf/util/SQLUtil.java
new file mode 100644
index 0000000..30b6e8d
--- /dev/null
+++ b/Wolf/src/com/roy/wolf/util/SQLUtil.java
@@ -0,0 +1,99 @@
+package com.roy.wolf.util;
+
+import android.database.sqlite.SQLiteDatabase;
+
+/**
+ *
+ * 包含生成SQL语句的常用方法。
+ *
+ */
+public class SQLUtil {
+ private static final String AND = " AND ";;
+ private static final String CMD_AND = "(%s) AND (%s)";
+ private static final String CMD_CREATE_TABLE = "CREATE TABLE %s (%s);";
+ private static final String CMD_OR = "(%s) OR (%s)";
+ private static final String CMD_SELECT = "%s=?";
+ private static final String OR = " OR ";
+
+ public static String and(String param1, String param2) {
+ return fun(CMD_AND, param1, param2);
+ }
+
+ public static String or(String param1, String param2) {
+ return fun(CMD_OR, param1, param2);
+ }
+
+ /**
+ * 创建表
+ * @param sQLiteDatabase
+ * @param tableName
+ * @param fields
+ */
+ public static void createTable(SQLiteDatabase sQLiteDatabase,
+ String tableName, String fields) {
+ String format = CMD_CREATE_TABLE;
+ Object[] params = new Object[2];
+ params[0] = tableName;
+ params[1] = fields;
+ String formatted = String.format(format, params);
+ sQLiteDatabase.execSQL(formatted);
+ }
+
+ private static String fun(String format, String param1, String param2) {
+ String formatted;
+ if ((param1 != null) && (param2 != null)) {
+ Object[] localObject = new Object[2];
+ localObject[0] = param1;
+ localObject[1] = param2;
+ formatted = String.format(format, localObject);
+ } else if (param1 != null) {
+ formatted = param1;
+ } else {
+ formatted = param2;
+ }
+
+ return formatted;
+ }
+
+ public static String getSelection(String field) {
+ Object[] params = new Object[1];
+ params[0] = field;
+ return String.format(CMD_SELECT, params);
+ }
+
+ public static String getSelectionAnd(String[] fields) {
+ return getSelection(AND, fields);
+ }
+
+ public static String getSelectionOr(String[] fields) {
+ return getSelection(OR, fields);
+ }
+
+ private static String getSelection(String operation,
+ String[] fields) {
+
+ int length;
+ if (fields != null) {
+ length = fields.length;
+ } else {
+ return StringUtil.EMPTY_STRING;
+ }
+
+ StringBuilder stringBuilder = new StringBuilder();
+
+ Object[] args = new Object[1];
+ args[0] = fields[0];
+ String str1 = String.format(CMD_SELECT, args);
+ stringBuilder.append(str1);
+
+ for (int n = 1; n < length; n++) {
+ stringBuilder.append(operation);
+ Object[] tmpargs = new Object[1];
+ tmpargs[0] = fields[n];
+ str1 = String.format(CMD_SELECT, tmpargs);
+ stringBuilder.append(str1);
+ }
+
+ return stringBuilder.toString();
+ }
+}
diff --git a/Wolf/src/com/roy/wolf/util/StringUtil.java b/Wolf/src/com/roy/wolf/util/StringUtil.java
new file mode 100644
index 0000000..c3517c5
--- /dev/null
+++ b/Wolf/src/com/roy/wolf/util/StringUtil.java
@@ -0,0 +1,3204 @@
+package com.roy.wolf.util;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.StringWriter;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.StringTokenizer;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Some common string manipulation utilities.
+ *
+ */
+public final class StringUtil {
+
+ public static final String EMPTY_STRING = "";
+
+ // \u3000 is the double-byte space character in UTF-8
+ // \u00A0 is the non-breaking space character ( )
+ // \u2007 is the figure space character ( )
+ // \u202F is the narrow non-breaking space character ( )
+ public static final String WHITE_SPACES = " \r\n\t\u3000\u00A0\u2007\u202F";
+
+ public static final String LINE_BREAKS = "\r\n";
+
+ private static final Pattern htmlTagPattern =
+ Pattern.compile("?[a-zA-Z][^>]*>");
+
+ private static final Pattern characterReferencePattern =
+ Pattern.compile("?[a-zA-Z0-9]{1,8};");
+
+ private static final Pattern dbSpecPattern =
+ Pattern.compile("(.*)\\{(\\d+),(\\d+)\\}(.*)");
+
+ private static final Pattern emailPattern = Pattern.compile("^[\\w]+[\\w\\.\\-\\+\\_]+@[\\w\\.\\-\\_]+\\.[\\w]+$");
+
+ private static final Pattern qqNumberPattern = Pattern.compile("^[1-9][0-9]{4,10}$");
+
+ private static final Pattern teleNumberPattern = Pattern.compile("^\\d{3}\\-\\d{8}|\\d{4}\\-\\d{7}$");
+
+ private static final Pattern cellNumberPattern = Pattern.compile("^1[358]\\d{9}$");
+
+ // This class should not be instantiated, hence the private constructor
+ private StringUtil() {}
+
+ public static boolean isEmail(String str) {
+ return emailPattern.matcher(str).matches();
+ }
+
+ public static boolean isQQNumber(String str) {
+ return qqNumberPattern.matcher(str).matches();
+ }
+
+ public static boolean isTeleNumber(String str) {
+ return teleNumberPattern.matcher(str).matches();
+ }
+
+ public static boolean isCellNumber(String str) {
+ return cellNumberPattern.matcher(str).matches();
+ }
+
+ /** Split "str" by run of delimiters and return. */
+ public static String[] split(String str, String delims) {
+ return split(str, delims, false);
+ }
+
+ /**
+ * Split "str" into tokens by delimiters and optionally remove white spaces
+ * from the splitted tokens.
+ *
+ * @param trimTokens if true, then trim the tokens
+ */
+ public static String[] split(String str, String delims, boolean trimTokens) {
+ StringTokenizer tokenizer = new StringTokenizer(str, delims);
+ int n = tokenizer.countTokens();
+ String[] list = new String[n];
+ for (int i = 0; i < n; i++) {
+ if (trimTokens) {
+ list[i] = tokenizer.nextToken().trim();
+ } else {
+ list[i] = tokenizer.nextToken();
+ }
+ }
+ return list;
+ }
+
+ /**
+ * Short hand for split(str, delims, true)
+ */
+ public static String[] splitAndTrim(String str, String delims) {
+ return split(str, delims, true);
+ }
+
+ /** Parse comma-separated list of ints and return as array. */
+ public static int[] splitInts(String str) throws IllegalArgumentException {
+ StringTokenizer tokenizer = new StringTokenizer(str, ",");
+ int n = tokenizer.countTokens();
+ int[] list = new int[n];
+ for (int i = 0; i < n; i++) {
+ String token = tokenizer.nextToken();
+ list[i] = Integer.parseInt(token);
+ }
+ return list;
+ }
+
+ /** Parse comma-separated list of longs and return as array. */
+ public static long[] splitLongs(String str) throws IllegalArgumentException {
+ StringTokenizer tokenizer = new StringTokenizer(str, ",");
+ int n = tokenizer.countTokens();
+ long[] list = new long[n];
+ for (int i = 0; i < n; i++) {
+ String token = tokenizer.nextToken();
+ list[i] = Long.parseLong(token);
+ }
+ return list;
+ }
+
+ /**
+ * Concatenates the given int[] array into one String, inserting a delimiter
+ * between each pair of elements.
+ */
+ public static String joinInts(int[] tokens, String delimiter) {
+ if (tokens == null) return "";
+ StringBuilder result = new StringBuilder();
+
+ for (int i = 0; i < tokens.length; i++) {
+ if (i > 0 && delimiter != null) {
+ result.append(delimiter);
+ }
+ result.append(String.valueOf(tokens[i]));
+ }
+ return result.toString();
+ }
+
+ /**
+ * Concatenates the given long[] array into one String, inserting a delimiter
+ * between each pair of elements.
+ */
+ public static String joinLongs(long[] tokens, String delimiter) {
+ if (tokens == null) return "";
+ StringBuilder result = new StringBuilder();
+
+ for (int i = 0; i < tokens.length; i++) {
+ if (i > 0 && delimiter != null) {
+ result.append(delimiter);
+ }
+ result.append(String.valueOf(tokens[i]));
+ }
+ return result.toString();
+ }
+
+ /**
+ * Concatenates the String representations of the elements of a
+ * String[] array into one String, and inserts a delimiter between
+ * each pair of elements.
+ *
+ * This includes the String[] case, because if s is a String, then
+ * s.toString() returns s.
+ *
+ * @deprecated Please use
+ * But note that {@code Join} does not consider null elements to be
+ * equivalent to the empty string, as this method does.
+ */
+ @Deprecated public static String join(Object[] tokens, String delimiter) {
+ if (tokens == null || tokens.length == 0) return "";
+ StringBuilder result = new StringBuilder();
+
+ for (int i = 0; i < tokens.length; i++) {
+ if (i > 0 && delimiter != null)
+ result.append(delimiter);
+
+ if (tokens[i] != null)
+ result.append(tokens[i].toString());
+ }
+ return result.toString();
+ }
+
+ /**
+ * Same as {@link #join(Object[],String)}, but takes a {@link Collection}
+ * instead.
+ *
+ * @deprecated Please use
+ * But note that {@code Join} does not consider null elements to be
+ * equivalent to the empty string, as this method does.
+ */
+ @Deprecated public static String join(Collection tokens, String delimiter) {
+ return join(tokens.toArray(), delimiter);
+ }
+
+ /** This replaces the occurances of 'what' in 'str' with 'with'
+ * @param str - the string o process
+ * @param what - to replace
+ * @param with - replace with this
+ * @return String str whete 'what' was repalced with 'with'
+ *
+ * @deprecated Please use {@link String#replace(CharSequence, CharSequence)}.
+ */
+ @Deprecated
+ public static String replace(String str, String what, String with) {
+ // Have to check this argument, for compatibility with the old impl.
+ // For the record, String.replace() is capable of handling an empty target
+ // string... but it does something kind of weird in that case.
+ assert(what.length() > 0);
+ return str.replace(what, with);
+ }
+
+ /**
+ * Reformats the given string to a fixed width by inserting
+ * carriage returns and trimming unnecessary whitespace.
+ *
+ * @param str the string to format
+ * @param width the fixed width (in characters)
+ */
+ public static String fixedWidth(String str, int width) {
+ String[] lines = split(str, "\n");
+ return fixedWidth(lines, width);
+ }
+
+ /**
+ * Reformats the given array of lines to a fixed width by inserting
+ * carriage returns and trimming unnecessary whitespace.
+ *
+ * @param lines - array of lines to format
+ * @param width - the fixed width (in characters)
+ */
+ public static String fixedWidth(String[] lines, int width) {
+ StringBuilder formatStr = new StringBuilder();
+
+ for (int i = 0; i < lines.length; i++) {
+ int curWidth = 0;
+ if (i != 0) {
+ formatStr.append("\n");
+ }
+ // a small optimization
+ if (lines[i].length() <= width) {
+ formatStr.append(lines[i]);
+ continue;
+ }
+ String[] words = splitAndTrim(lines[i], WHITE_SPACES);
+ for (int j = 0; j < words.length; j++) {
+ if (curWidth == 0 || (curWidth + words[j].length()) < width) {
+ // add a space if we're not at the beginning of a line
+ if (curWidth != 0) {
+ formatStr.append(" ");
+ curWidth += 1;
+ }
+ curWidth += words[j].length();
+ formatStr.append(words[j]);
+ } else {
+ formatStr.append("\n");
+ curWidth = words[j].length();
+ formatStr.append(words[j]);
+ }
+ }
+ }
+
+ return formatStr.toString();
+ }
+
+ /**
+ * Inserts spaces every splitLen characters so that the string will wrap.
+ *
+ * @param lineLen the length of the substrings to separate with spaces.
+ * @param original the original String
+ *
+ * @return original String with spaces inserted every lineLen characters.
+ *
+ */
+ public static String insertBreakingWhitespace(int lineLen, String original) {
+ if (original == null || lineLen <= 0) throw new IllegalArgumentException();
+
+ int length = original.length();
+ if (length <= lineLen)
+ // we can avoid the overhead of instantiating a StringBuilder
+ return original;
+ int currPos = 0;
+ StringBuilder retval = new StringBuilder();
+ while (length - currPos > lineLen) {
+ retval.append(original.substring(currPos, currPos + lineLen));
+ currPos += lineLen;
+ retval.append(" ");
+ }
+ retval.append(original.substring(currPos, length));
+ return retval.toString();
+ }
+
+ /**
+ * Indents the given String per line.
+ * @param iString The string to indent.
+ * @param iIndentDepth The depth of the indentation.
+ * @return The indented string.
+ */
+ public static String indent(String iString, int iIndentDepth) {
+ StringBuilder spacer = new StringBuilder();
+ spacer.append("\n");
+ for (int i = 0; i < iIndentDepth; i ++) {
+ spacer.append(" ");
+ }
+ return replace(iString, "\n", spacer.toString());
+ }
+
+ /**
+ * This is a both way strip
+ *
+ * @param str the string to strip
+ * @param left strip from left
+ * @param right strip from right
+ * @param what character(s) to strip
+ * @return the stripped string
+ */
+ public static String megastrip(String str,
+ boolean left, boolean right,
+ String what) {
+ if (str == null) {
+ return null;
+ }
+
+ int limitLeft = 0;
+ int limitRight = str.length() - 1;
+
+ while (left && limitLeft <= limitRight &&
+ what.indexOf(str.charAt(limitLeft)) >= 0) {
+ limitLeft ++;
+ }
+ while (right && limitRight>=limitLeft &&
+ what.indexOf(str.charAt(limitRight)) >= 0) {
+ limitRight --;
+ }
+
+ return str.substring(limitLeft, limitRight + 1);
+ }
+
+ /** lstrip - strips spaces from left
+ * @param str what to strip
+ * @return String the striped string
+ */
+ public static String lstrip(String str) {
+ return megastrip(str, true, false, WHITE_SPACES);
+ }
+
+ /** rstrip - strips spaces from right
+ * @param str what to strip
+ * @return String the striped string
+ */
+ public static String rstrip(String str) {
+ return megastrip(str, false, true, WHITE_SPACES);
+ }
+
+ /** strip - strips both ways
+ * @param str what to strip
+ * @return String the striped string
+ */
+ public static String strip(String str) {
+ return megastrip(str, true, true, WHITE_SPACES);
+ }
+
+ /** Strip white spaces from both end, and collapse white spaces
+ * in the middle.
+ * @param str what to strip
+ * @return String the striped and collapsed string
+ */
+ public static String stripAndCollapse(String str) {
+ return collapseWhitespace(strip(str));
+ }
+
+ /**
+ * Give me a string and a potential prefix, and I return the string
+ * following the prefix if the prefix matches, else null.
+ * Analogous to the c++ functions strprefix and var_strprefix.
+ */
+ public static String stripPrefix(String str, String prefix) {
+ return str.startsWith(prefix) ? str.substring(prefix.length()) : null;
+ }
+
+ /**
+ * Case insensitive version of stripPrefix.
+ * Analogous to the c++ functions strcaseprefix and var_strcaseprefix.
+ */
+ public static String stripPrefixIgnoreCase(String str, String prefix) {
+ if (str.length() >= prefix.length()
+ && str.substring(0, prefix.length()).equalsIgnoreCase(prefix)) {
+ return str.substring(prefix.length());
+ }
+
+ return null;
+ }
+
+ /**
+ * Strips all non-digit characters from a string.
+ *
+ * The resulting string will only contain characters for which isDigit()
+ * returns true.
+ *
+ * @param str the string to strip
+ * @return a string consisting of digits only, or an empty string
+ */
+ public static String stripNonDigits(String str) {
+ StringBuffer result = new StringBuffer(str.length());
+ for (char candidate : str.toCharArray()) {
+ if (Character.isDigit(candidate)) {
+ result.append(candidate);
+ }
+ }
+ return result.toString();
+ }
+
+ /**
+ * Counts the number of (not necessarily distinct) characters in the
+ * string that also happen to be in 'chars'
+ */
+ public static int numSharedChars(final String str, final String chars) {
+
+ if (str == null || chars == null) {
+ return 0;
+ }
+
+ int total = 0, pos = -1;
+ while ((pos = indexOfChars(str, chars, pos + 1)) != -1) {
+ total++;
+ }
+
+ return total;
+ }
+
+ /**
+ * Like String.indexOf() except that it will look for any of the
+ * characters in 'chars' (similar to C's strpbrk)
+ */
+ public static int indexOfChars(String str, String chars, int fromIndex) {
+ final int len = str.length();
+
+ for (int pos = fromIndex; pos < len; pos++) {
+ if (chars.indexOf(str.charAt(pos)) >= 0) {
+ return pos;
+ }
+ }
+
+ return -1;
+ }
+
+ /**
+ * Like String.indexOf() except that it will look for any of the
+ * characters in 'chars' (similar to C's strpbrk)
+ */
+ public static int indexOfChars(String str, String chars) {
+ return indexOfChars(str, chars, 0);
+ }
+
+ /**
+ * 2008-10-29 add 1.0
+ *//*
+ public static int[] indexArrayOfChars(String str, String chars, int fromIndex) {
+ StringBuffer indexes = new StringBuffer();
+
+ for(int index = fromIndex;;){
+ index = str.indexOf(chars,index);
+ if(index == -1){
+ break;
+ }
+
+ indexes.append(index + ",");
+ index++;
+ }
+
+ return splitInts(indexes.toString()) ;
+ }*/
+
+ /**
+ * Finds the last index in str of a character not in the characters
+ * in 'chars' (similar to ANSI string.find_last_not_of).
+ *
+ * Returns -1 if no such character can be found.
+ */
+ public static int lastIndexNotOf(String str, String chars, int fromIndex) {
+ fromIndex = Math.min(fromIndex, str.length() - 1);
+
+ for (int pos = fromIndex; pos >= 0; pos--) {
+ if (chars.indexOf(str.charAt(pos)) < 0) {
+ return pos;
+ }
+ }
+
+ return -1;
+ }
+
+ /**
+ * Like String.replace() except that it accepts any number of old chars.
+ * Replaces any occurrances of 'oldchars' in 'str' with 'newchar'.
+ * Example: replaceChars("Hello, world!", "H,!", ' ') returns " ello world "
+ */
+ public static String replaceChars(String str, String oldchars, char newchar) {
+ int pos = indexOfChars(str, oldchars);
+ if (pos == -1) {
+ return str;
+ }
+
+ StringBuilder buf = new StringBuilder(str);
+ do {
+ buf.setCharAt(pos, newchar);
+ pos = indexOfChars(str, oldchars, pos + 1);
+ } while (pos != -1);
+
+ return buf.toString();
+ }
+
+ /**
+ * Remove any occurrances of 'oldchars' in 'str'.
+ * Example: removeChars("Hello, world!", ",!") returns "Hello world"
+ */
+ public static String removeChars(String str, String oldchars) {
+ int pos = indexOfChars(str, oldchars);
+ if (pos == -1) {
+ return str;
+ }
+
+ StringBuilder buf = new StringBuilder();
+ int start = 0;
+ do {
+ buf.append(str.substring(start, pos));
+ start = pos + 1;
+ pos = indexOfChars(str, oldchars, start);
+ } while (pos != -1);
+
+ if (start < str.length()) {
+ buf.append(str.substring(start));
+ }
+ return buf.toString();
+ }
+
+ /**
+ * Removes all characters from 'str' that are not in 'retainChars'.
+ * Example: retainAllChars("Hello, world!", "lo") returns "llool"
+ */
+ public static String retainAllChars(String str, String retainChars) {
+ int pos = indexOfChars(str, retainChars);
+ if (pos == -1) {
+ return "";
+ }
+ StringBuilder buf = new StringBuilder();
+ do {
+ buf.append(str.charAt(pos));
+ pos = indexOfChars(str, retainChars, pos + 1);
+ } while (pos != -1);
+ return buf.toString();
+ }
+
+ /**
+ * Replaces microsoft "smart quotes" (curly " and ') with their
+ * ascii counterparts.
+ */
+ public static String replaceSmartQuotes(String str) {
+ // See http://www.microsoft.com/typography/unicode/1252.htm
+ str = replaceChars(str, "\u0091\u0092\u2018\u2019", '\'');
+ str = replaceChars(str, "\u0093\u0094\u201c\u201d", '"');
+ return str;
+ }
+
+ /**
+ * Convert a string of hex digits to a byte array, with the first
+ * byte in the array being the MSB. The string passed in should be
+ * just the raw digits (upper or lower case), with no leading
+ * or trailing characters (like '0x' or 'h').
+ * An odd number of characters is supported.
+ * If the string is empty, an empty array will be returned.
+ *
+ * This is significantly faster than using
+ * new BigInteger(str, 16).toByteArray();
+ * especially with larger strings. Here are the results of some
+ * microbenchmarks done on a P4 2.8GHz 2GB RAM running
+ * linux 2.4.22-gg11 and JDK 1.5 with an optimized build:
+ *
+ * String length hexToBytes (usec) BigInteger
+ * -----------------------------------------------------
+ * 16 0.570 1.43
+ * 256 8.21 44.4
+ * 1024 32.8 526
+ * 16384 546 121000
+ */
+ public static byte[] hexToBytes(String str) {
+ byte[] bytes = new byte[(str.length() + 1) / 2];
+ if (str.length() == 0) {
+ return bytes;
+ }
+ bytes[0] = 0;
+ int nibbleIdx = (str.length() % 2);
+ for (int i = 0; i < str.length(); i++) {
+ char c = str.charAt(i);
+ if (!isHex(c)) {
+ throw new IllegalArgumentException("string contains non-hex chars");
+ }
+ if ((nibbleIdx % 2) == 0) {
+ bytes[nibbleIdx >> 1] = (byte) (hexValue(c) << 4);
+ } else {
+ bytes[nibbleIdx >> 1] += (byte) hexValue(c);
+ }
+ nibbleIdx++;
+ }
+ return bytes;
+ }
+
+ /**
+ * Converts any instances of "\r" or "\r\n" style EOLs into "\n" (Line Feed).
+ */
+ public static String convertEOLToLF(String input) {
+ StringBuilder res = new StringBuilder(input.length());
+ char[] s = input.toCharArray();
+ int from = 0;
+ final int end = s.length;
+ for (int i = 0; i < end; i++) {
+ if (s[i] == '\r') {
+ res.append(s, from, i - from);
+ res.append('\n');
+ if (i + 1 < end && s[i + 1] == '\n') {
+ i++;
+ }
+
+ from = i + 1;
+ }
+ }
+
+ if (from == 0) { // no \r!
+ return input;
+ }
+
+ res.append(s, from, end - from);
+ return res.toString();
+ }
+
+ /** @deprecated Please inline this method. */
+ @Deprecated public static String convertEOLToCRLF(String input) {
+ return input.replaceAll("(\r\n|\r|\n)", "\r\n");
+ }
+
+ /**
+ * Returns a string consisting of "s", plus enough copies of "pad_ch" on the
+ * left hand side to make the length of "s" equal to or greater than len (if
+ * "s" is already longer than "len", then "s" is returned).
+ */
+ public static String padLeft(String s, int len, char pad_ch) {
+ if (s.length() >= len) {
+ return s;
+ } else {
+ StringBuilder sb = new StringBuilder();
+ int n = len - s.length();
+ for (int i = 0; i < n; i++) {
+ sb.append(pad_ch);
+ }
+ sb.append(s);
+ return sb.toString();
+ }
+ }
+
+ /**
+ * Returns a string consisting of "s", plus enough copies of "pad_ch" on the
+ * right hand side to make the length of "s" equal to or greater than len (if
+ * "s" is already longer than "len", then "s" is returned).
+ */
+ public static String padRight(String s, int len, char pad_ch) {
+ if (s.length() >= len) {
+ return s;
+ } else {
+ StringBuilder sb = new StringBuilder();
+ int n = len - s.length();
+ sb.append(s);
+ for (int i = 0; i < n; i++) {
+ sb.append(pad_ch);
+ }
+ return sb.toString();
+ }
+ }
+
+ /**
+ * Returns a string consisting of "s", with each of the first "len" characters
+ * replaced by "mask_ch" character.
+ */
+ public static String maskLeft(String s, int len, char mask_ch) {
+ if (len <= 0) {
+ return s;
+ }
+ len = Math.min(len, s.length());
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < len; i++) {
+ sb.append(mask_ch);
+ }
+ sb.append(s.substring(len));
+ return sb.toString();
+ }
+
+ /**
+ * Returns a string consisting of "s", with each of the last "len" characters
+ * replaces by "mask_ch" character.
+ */
+ public static String maskRight(String s, int len, char mask_ch) {
+ if (len <= 0) {
+ return s;
+ }
+ len = Math.min(len, s.length());
+ StringBuilder sb = new StringBuilder();
+ sb.append(s.substring(0, s.length() - len));
+ for (int i = 0; i < len; i++) {
+ sb.append(mask_ch);
+ }
+ return sb.toString();
+ }
+
+ private static boolean isOctal(char c) {
+ return (c >= '0') && (c <= '7');
+ }
+
+ private static boolean isHex(char c) {
+ return ((c >= '0') && (c <= '9')) ||
+ ((c >= 'a') && (c <= 'f')) ||
+ ((c >= 'A') && (c <= 'F'));
+ }
+
+ private static int hexValue(char c) {
+ if ((c >= '0') && (c <= '9')) {
+ return (c - '0');
+ } else if ((c >= 'a') && (c <= 'f')) {
+ return (c - 'a') + 10;
+ } else {
+ return (c - 'A') + 10;
+ }
+ }
+
+ /**
+ * Unescape any C escape sequences (\n, \r, \\, \ooo, etc) and return the
+ * resulting string.
+ */
+ public static String unescapeCString(String s) {
+ if (s.indexOf('\\') < 0) {
+ // Fast path: nothing to unescape
+ return s;
+ }
+
+ StringBuilder sb = new StringBuilder();
+ int len = s.length();
+ for (int i = 0; i < len;) {
+ char c = s.charAt(i++);
+ if (c == '\\' && (i < len)) {
+ c = s.charAt(i++);
+ switch (c) {
+ case 'a': c = '\007'; break;
+ case 'b': c = '\b'; break;
+ case 'f': c = '\f'; break;
+ case 'n': c = '\n'; break;
+ case 'r': c = '\r'; break;
+ case 't': c = '\t'; break;
+ case 'v': c = '\013'; break;
+ case '\\': c = '\\'; break;
+ case '?': c = '?'; break;
+ case '\'': c = '\''; break;
+ case '"': c = '\"'; break;
+
+ default: {
+ if ((c == 'x') && (i < len) && isHex(s.charAt(i))) {
+ // "\xXX"
+ int v = hexValue(s.charAt(i++));
+ if ((i < len) && isHex(s.charAt(i))) {
+ v = v*16 + hexValue(s.charAt(i++));
+ }
+ c = (char)v;
+ } else if (isOctal(c)) {
+ // "\OOO"
+ int v = (c - '0');
+ if ((i < len) && isOctal(s.charAt(i))) {
+ v = v*8 + (s.charAt(i++) - '0');
+ }
+ if ((i < len) && isOctal(s.charAt(i))) {
+ v = v*8 + (s.charAt(i++) - '0');
+ }
+ c = (char)v;
+ } else {
+ // Propagate unknown escape sequences.
+ sb.append('\\');
+ }
+ break;
+ }
+ }
+ }
+ sb.append(c);
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Unescape any MySQL escape sequences.
+ * See MySQL language reference Chapter 6 at
+ * http://www.mysql.com/doc/.
+ * This function will not work for other SQL-like
+ * dialects.
+ * @param s string to unescape, with the surrounding quotes.
+ * @return unescaped string, without the surrounding quotes.
+ * @exception IllegalArgumentException if s is not a valid MySQL string.
+ */
+ public static String unescapeMySQLString(String s)
+ throws IllegalArgumentException {
+ // note: the same buffer is used for both reading and writing
+ // it works because the writer can never outrun the reader
+ char chars[] = s.toCharArray();
+
+ // the string must be quoted 'like this' or "like this"
+ if (chars.length < 2 || chars[0] != chars[chars.length-1] ||
+ (chars[0] != '\'' && chars[0] != '"')) {
+ throw new IllegalArgumentException("not a valid MySQL string: " + s);
+ }
+
+ // parse the string and decode the backslash sequences; in addition,
+ // quotes can be escaped 'like this: ''', "like this: """, or 'like this: "'
+ int j = 1; // write position in the string (never exceeds read position)
+ int f = 0; // state: 0 (normal), 1 (backslash), 2 (quote)
+ for (int i = 1; i < chars.length - 1; i++) {
+ if (f == 0) { // previous character was normal
+ if (chars[i] == '\\') {
+ f = 1; // backslash
+ } else if (chars[i] == chars[0]) {
+ f = 2; // quoting character
+ } else {
+ chars[j++] = chars[i];
+ }
+ } else if (f == 1) { // previous character was a backslash
+ switch (chars[i]) {
+ case '0': chars[j++] = '\0'; break;
+ case '\'': chars[j++] = '\''; break;
+ case '"': chars[j++] = '"'; break;
+ case 'b': chars[j++] = '\b'; break;
+ case 'n': chars[j++] = '\n'; break;
+ case 'r': chars[j++] = '\r'; break;
+ case 't': chars[j++] = '\t'; break;
+ case 'z': chars[j++] = '\032'; break;
+ case '\\': chars[j++] = '\\'; break;
+ default:
+ // if the character is not special, backslash disappears
+ chars[j++] = chars[i];
+ break;
+ }
+ f = 0;
+ } else { // previous character was a quote
+ // quoting characters must be doubled inside a string
+ if (chars[i] != chars[0]) {
+ throw new IllegalArgumentException("not a valid MySQL string: " + s);
+ }
+ chars[j++] = chars[0];
+ f = 0;
+ }
+ }
+ // string contents cannot end with a special character
+ if (f != 0) {
+ throw new IllegalArgumentException("not a valid MySQL string: " + s);
+ }
+
+ // done
+ return new String(chars, 1, j - 1);
+ }
+
+ static Map Escapes the characters in a For example,
+ * String
value
+ * @return a String
value
+ */
+ public static final String unescapeHTML(String s) {
+ char[] chars = s.toCharArray();
+ char[] escaped = new char[chars.length];
+
+ // Note: escaped[pos] = end of the escaped char array.
+ int pos = 0;
+
+ for (int i = 0; i < chars.length;) {
+ if (chars[i] != '&') {
+ escaped[pos++] = chars[i++];
+ continue;
+ }
+
+ // Allow e.g. {
+ int j = i + 1;
+ if (j < chars.length && chars[j] == '#')
+ j++;
+
+ // Scan until we find a char that is not letter or digit.
+ for (; j < chars.length; j++) {
+ if (!Character.isLetterOrDigit(chars[j]))
+ break;
+ }
+
+ boolean replaced = false;
+ if (j < chars.length && chars[j] == ';') {
+ if (s.charAt(i + 1) == '#') { // Check for D; and
pattern
+ try {
+ long charcode = 0;
+ char ch = s.charAt(i + 2);
+ if (ch == 'x' || ch == 'X') {
+ charcode = Long.parseLong(new String(chars, i + 3, j - i - 3),
+ 16);
+ } else if (Character.isDigit(ch)) {
+ charcode = Long.parseLong(new String(chars, i + 2, j - i - 2));
+ }
+ if (charcode > 0 && charcode < 65536) {
+ escaped[pos++] = (char) charcode;
+ replaced = true;
+ }
+ } catch (NumberFormatException ex) {
+ // Failed, not replaced.
+ }
+
+ } else {
+ String key = new String(chars, i, j - i + 1);
+ Character repl = escapeStrings.get(key);
+ if (repl != null) {
+ escaped[pos++] = repl.charValue();
+ replaced = true;
+ }
+ }
+ j++; // Skip over ';'
+ }
+
+ if (!replaced) {
+ // Not a recognized escape sequence, leave as-is
+ System.arraycopy(chars, i, escaped, pos, j - i);
+ pos += j - i;
+ }
+ i = j;
+ }
+ return new String(escaped, 0, pos);
+ }
+
+ /**
+ * Given a String
, returns an equivalent String
with
+ * all HTML tags stripped. Note that HTML entities, such as "&" will
+ * still be preserved.
+ */
+ public static String stripHtmlTags(String string) {
+ if ((string == null) || "".equals(string)) {
+ return string;
+ }
+ return htmlTagPattern.matcher(string).replaceAll("");
+ }
+
+ /**
+ * We escape some characters in s to be able to make the string executable
+ * from a python string
+ */
+ public static String pythonEscape(String s) {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < s.length(); i++) {
+ char c = s.charAt(i);
+ switch (c) {
+ case '\n': sb.append("\\n"); break;
+ case '\r': sb.append("\\r"); break;
+ case '\t': sb.append("\\t"); break;
+ case '\\': sb.append("\\\\"); break;
+ case '\"': sb.append("\\\""); break;
+ case '\'': sb.append("\\\'"); break;
+ default: sb.append(c);
+ }
+ }
+ return sb.toString();
+ }
+
+ /**
+ * We escape some characters in s to be able to insert strings into JavaScript
+ * code. Also, make sure that we don't write out --> or or </scrip, which may
+ * close a script tag. Turns all non-ascii characters into ASCII javascript
+ * escape sequences (eg \udddd)
+ */
+ public static String escapeJavaScriptToAscii(String s) {
+ return javaScriptEscapeHelper(s, true);
+ }
+
+ private static final String[] UNSAFE_TAGS = { "script", "style",
+ "object", "applet", "!--" };
+
+ /**
+ * Helper for javaScriptEscape and javaScriptEscapeToAscii
+ */
+ private static String javaScriptEscapeHelper(String s,
+ boolean escapeToAscii) {
+
+ /*
+ * IMPORTANT: If you change the semantics of this method (by escaping
+ * extra characters, for example), please make similar changes to
+ * com.google.javascript.util.Escape.toJsString
+ */
+ StringBuilder sb = new StringBuilder(s.length() * 9 / 8);
+ for (int i = 0; i < s.length(); i++) {
+ char c = s.charAt(i);
+ switch (c) {
+ case '\n': sb.append("\\n"); break;
+ case '\r': sb.append("\\r"); break;
+ case '\t': sb.append("\\t"); break;
+ case '\\': sb.append("\\\\"); break;
+ case '\"': sb.append("\\\""); break;
+ case '\'': sb.append("\\\'"); break;
+
+ // escape '=' so that javascript won't be executed within tags
+ case '=': appendHexJavaScriptRepresentation(sb, c); break;
+
+ case '<': // for text that could potentially be interpreted as an
+ case '/': // unsafe opening or closing tag, escape the char to hex
+ boolean isUnsafe = false;
+ for (String tag : UNSAFE_TAGS) {
+ if (s.regionMatches(true, i + 1, tag, 0, tag.length())) {
+ isUnsafe = true;
+ break;
+ }
+ }
+ if (isUnsafe) {
+ appendHexJavaScriptRepresentation(sb, c);
+ } else {
+ sb.append(c);
+ }
+ break;
+ case '>' :
+ if (sb.length() > 0 && sb.charAt(sb.length() - 1) == '-') {
+ sb.append('\\');
+ }
+ sb.append(c);
+ break;
+ // Note: Mozilla browser treats the line/paragraph separator
+ // as string terminators, so we need to escape them.
+ case '\u2028': sb.append("\\u2028"); break;
+ case '\u2029': sb.append("\\u2029"); break;
+ default:
+ if (c >= 128 && escapeToAscii) {
+ appendHexJavaScriptRepresentation(sb, c);
+ } else {
+ sb.append(c);
+ }
+ }
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Returns a javascript representation of the character in a hex escaped
+ * format. Although this is a rather specific method, it is made public
+ * because it is also used by the JSCompiler.
+ *
+ *
+ * @param sb The buffer to which the hex representation should be appended.
+ * @param c The character to be appended.
+ */
+ public static void appendHexJavaScriptRepresentation(StringBuilder sb,
+ char c) {
+ sb.append("\\u");
+ String val = Integer.toHexString(c);
+ for (int j = val.length(); j < 4; j++) {
+ sb.append('0');
+ }
+ sb.append(val);
+ }
+
+
+ /**
+ * Undo escaping as performed in javaScriptEscape(.)
+ * Throws an IllegalArgumentException if the string contains
+ * bad escaping.
+ */
+ public static String unescapeJavaScript(String s) {
+ StringBuilder sb = new StringBuilder(s.length());
+ for (int i = 0; i < s.length(); ) {
+ char c = s.charAt(i);
+ if (c == '\\') {
+ i = javaScriptUnescapeHelper(s, i + 1, sb);
+ } else {
+ sb.append(c);
+ i++;
+ }
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Looks for an escape code starting at index i of s,
+ * and appends it to sb.
+ * @return the index of the first character in s
+ * after the escape code.
+ * @throws IllegalArgumentException if the escape code
+ * is invalid
+ */
+ private static int javaScriptUnescapeHelper(String s, int i,
+ StringBuilder sb) {
+ if (i >= s.length()) {
+ throw new IllegalArgumentException(
+ "End-of-string after escape character in [" + s + "]");
+ }
+
+ char c = s.charAt(i++);
+ switch (c) {
+ case 'n': sb.append('\n'); break;
+ case 'r': sb.append('\r'); break;
+ case 't': sb.append('\t'); break;
+ case '\\':
+ case '\"':
+ case '\'':
+ case '>':
+ sb.append(c);
+ break;
+ case 'u':
+ String hexCode;
+ try {
+ hexCode = s.substring(i, i + 4);
+ } catch (IndexOutOfBoundsException ioobe) {
+ throw new IllegalArgumentException(
+ "Invalid unicode sequence [" + s.substring(i) + "] at index " + i +
+ " in [" + s + "]");
+ }
+ int unicodeValue;
+ try {
+ unicodeValue = Integer.parseInt(hexCode, 16);
+ } catch (NumberFormatException nfe) {
+ throw new IllegalArgumentException(
+ "Invalid unicode sequence [" + hexCode + "] at index " + i +
+ " in [" + s + "]");
+ }
+ sb.append((char)unicodeValue);
+ i += 4;
+ break;
+ default:
+ throw new IllegalArgumentException(
+ "Unknown escape code [" + c + "] at index " + i + " in [" + s + "]");
+ }
+
+ return i;
+ }
+
+ /**
+ * Escape a string for use inside as XML element content. This escapes
+ * less-than and ampersand, only.
+ */
+ public static String escapeXmlContent(String s) {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < s.length(); i++) {
+ char c = s.charAt(i);
+ switch (c) {
+ case '&': sb.append("&"); break;
+ case '<': sb.append("<"); break;
+
+ case '\000': case '\001': case '\002': case '\003': case '\004':
+ case '\005': case '\006': case '\007': case '\010': case '\013':
+ case '\014': case '\016': case '\017': case '\020': case '\021':
+ case '\022': case '\023': case '\024': case '\025': case '\026':
+ case '\027': case '\030': case '\031': case '\032': case '\033':
+ case '\034': case '\035': case '\036': case '\037':
+ // do nothing, these are disallowed characters
+ break;
+ default: sb.append(c);
+ }
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Escape a string for use inside as XML single-quoted attributes. This
+ * escapes less-than, single-quote, ampersand, and (not strictly necessary)
+ * newlines.
+ */
+ public static String escapeXmlSingleQuoted(String s) {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < s.length(); i++) {
+ char c = s.charAt(i);
+ switch (c) {
+ case '\'': sb.append("""); break;
+ case '&': sb.append("&"); break;
+ case '<': sb.append("<"); break;
+ case '\n': sb.append("
"); break;
+
+ case '\000': case '\001': case '\002': case '\003': case '\004':
+ case '\005': case '\006': case '\007': case '\010': case '\013':
+ case '\014': case '\016': case '\017': case '\020': case '\021':
+ case '\022': case '\023': case '\024': case '\025': case '\026':
+ case '\027': case '\030': case '\031': case '\032': case '\033':
+ case '\034': case '\035': case '\036': case '\037':
+ // do nothing, these are disallowed characters
+ break;
+ default: sb.append(c);
+ }
+ }
+ return sb.toString();
+ }
+
+ /**
+ * We escape some characters in s to be able to insert strings into Java code
+ */
+ public static String escapeJava(String s) {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < s.length(); i++) {
+ char c = s.charAt(i);
+ switch (c) {
+ case '\n': sb.append("\\n"); break;
+ case '\r': sb.append("\\r"); break;
+ case '\t': sb.append("\\t"); break;
+ case '\\': sb.append("\\\\"); break;
+ case '\"': sb.append("\\\""); break;
+ case '&': sb.append("&"); break;
+ case '<': sb.append("<"); break;
+ case '>': sb.append(">"); break;
+ case '\'': sb.append("\\\'"); break;
+ default: sb.append(c);
+ }
+ }
+ return sb.toString();
+ }
+
+ /**
+ * String
to be suitable to pass to
+ * an SQL query.statement.executeQuery("SELECT * FROM MOVIES WHERE TITLE='" +
+ * StringEscapeUtils.escapeSql("McHale's Navy") +
+ * "'");
+ *
At present, this method only turns single-quotes into doubled single-quotes
+ * ("McHale's Navy"
=> "McHale''s Navy"
). It does not
+ * handle the cases of percent (%) or underscore (_) for use in LIKE clauses.
null
if null string input
+ */
+ public static String escapeSql(String str) {
+ if (str == null) {
+ return null;
+ }
+ return replace(str, "'", "''");
+ }
+
+ /**
+ * Escape a string so that it can be safely placed as value of an
+ * attribute. This is essentially similar to the {@link
+ * javaEscape(java.lang.String)} except that it escapes double quote
+ * to the HTML literal ". This is to prevent the double
+ * quote from being interpreted as the character closing the
+ * attribute.
+ */
+ public static String escapeJavaWithinAttribute(String s) {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < s.length(); i++) {
+ char c = s.charAt(i);
+ switch (c) {
+ case '\n': sb.append("\\n"); break;
+ case '\r': sb.append("\\r"); break;
+ case '\t': sb.append("\\t"); break;
+ case '\\': sb.append("\\\\"); break;
+ case '\"': sb.append("""); break;
+ case '&': sb.append("&"); break;
+ case '<': sb.append("<"); break;
+ case '>': sb.append(">"); break;
+ case '\'': sb.append("\\\'"); break;
+ default: sb.append(c);
+ }
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Returns a form of "s" appropriate for including in an XML document, after
+ * escaping certain special characters (e.g. '&' => '&', etc.)
+ */
+ public static String escapeXML(String s) {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < s.length(); i++) {
+ char ch = s.charAt(i);
+ switch (ch) {
+ case '"':
+ sb.append(""");
+ break;
+ case '&':
+ sb.append("&");
+ break;
+ case '\'':
+ sb.append("'");
+ break;
+ case '<':
+ sb.append("<");
+ break;
+ case '>':
+ sb.append(">");
+ break;
+ case '\0':
+ // \0 is not a valid XML char - skip it
+ break;
+ default:
+ sb.append(ch);
+ break;
+ }
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Escapes special characters (& < > ") from a string so it can safely be
+ * included in an HTML document. (same as xmlEscape
except that
+ * htmlEscape
does not escape the apostrophe character).
+ */
+ public static String escapeHTML(String s) {
+ // This method gets called A LOT so it has to be excruciatingly efficient.
+ // Older versions were responsible for several percent of all objects
+ // created on the heap, and 10% of total execution time.
+ // In particular, if the String has no characters that need escaping, this
+ // method should return its argument.
+
+ StringBuilder sb = null;
+ String replacement;
+ int start = 0; // the earliest input position we haven't copied yet.
+ for (int i = 0; i < s.length(); i++) {
+ switch (s.charAt(i)) {
+ case '"':
+ replacement = """;
+ break;
+ case '&':
+ replacement = "&";
+ break;
+ case '<':
+ replacement = "<";
+ break;
+ case '>':
+ replacement = ">";
+ break;
+ default:
+ replacement = null;
+ }
+
+ if (replacement != null) {
+ if (sb == null) {
+ // This is the first time we have found a replacement. Allocate the
+ // StringBuilder now.
+ // This initial size for the StringBuilder below will be exact if
+ // this initial replacement is the only one. If not, sb will expand.
+ sb = new StringBuilder(s.length() + replacement.length() - 1);
+ }
+ if (i > start) {
+ // we have to copy some of the earlier string.
+ sb.append(s.substring(start, i));
+ }
+ sb.append(replacement);
+ start = i+1;
+ }
+ }
+ // now possibly also copy what's leftover in the input string.
+ if (start > 0) {
+ sb.append(s.substring(start));
+ }
+
+ if (sb != null) {
+ return sb.toString();
+ }
+ return s;
+ }
+
+ /**
+ * Escapes the special characters from a string so it can be used as part of
+ * a regex pattern. This method is for use on gnu.regexp style regular
+ * expressions.
+ */
+ public static String escapeRegex(String s) {
+ StringBuilder sb = new StringBuilder();
+
+ for(int i = 0; i < s.length(); i++) {
+ char c = s.charAt(i);
+ // Test if c is an escapable character
+ if ("()|*+?.{}[]$^\\".indexOf(c) != -1) {
+ sb.append('\\');
+ sb.append(c);
+ }
+ else {
+ sb.append(c);
+ }
+ }
+
+ return sb.toString();
+ }
+
+ /**
+ * Escapes the special characters from a string so it can be used as part of
+ * a regex pattern. This method is for use on regexes in the flavor of the
+ * java.util.regex package. This method should be removed when we move to
+ * the java version 1.5 (Tiger) release, since that release gives us
+ * a literal regex flag as well as a quote method to produce literal regexes.
+ */
+ public static String escapeJavaUtilRegex(String s) {
+ // Use the quoting mechanism in Pattern unless it is interfered with
+ // by the contents of the string.
+ if (s.indexOf("\\E") == -1) {
+ return "\\Q" + s + "\\E";
+ }
+
+ // Very rare case: must escape each character.
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < s.length(); i++) {
+ sb.append('\\');
+ sb.append(s.charAt(i));
+ }
+
+ return sb.toString();
+ }
+
+ /**
+ * Escapes the '\' and '$' characters, which comprise the subset of regex
+ * characters that has special meaning in methods such as:
+ *
+ * java.util.regex.Matcher.appendReplacement(sb, replacement);+ *
java.lang.String.replaceAll(str, replacement);+ * + * Note that this method is offered in java version 1.5 as the method + * + *
java.util.regex.Matcher.quoteReplacement(String);+ */ + public static String escapeRegexReplacement(String s) { + StringBuilder sb = null; + + for (int i = 0, n = s.length(); i < n; i++) { + char c = s.charAt(i); + + switch (c) { + case '\\': + case '$': + if (sb == null) { + // This is the first replacement necessary. Initialize the + // string buffer to contain the all of the previously checked + // characters in 's' + sb = new StringBuilder(s.substring(0, i)); + } + sb.append('\\'); + default: + if (sb != null) { + sb.append(c); + } + break; + } + } + + return (sb == null) ? s : sb.toString(); + } + + + + /** + * The old interface to cropBetween - using a single char limit + */ + public static String cropBetween(String in, char limit) { + return cropBetween(in, String.valueOf(new char[]{limit})); + } + + /** + * This removes characters between maching charLimit chars. For example + * cropBetween("ab^cd^ef^gh^hi", '^') will return "abefhi" It will consider + * squences of 2 charLimit as one charLimit in the output + * + * @param in - the string to process + * @param limit - the limit of the string(s) to remove + * + * @return String - the cropped string + */ + public static String cropBetween(String in, String limit) { + StringBuilder out = new StringBuilder(); + int lastPos = 0; + int lenLimit = limit.length(); + boolean modeAdd = true; + int pos = -1; + while ((pos = in.indexOf(limit, lastPos)) >= 0) { + if (modeAdd) { + out.append(in.substring(lastPos, pos)); + } + modeAdd = !modeAdd; + lastPos = pos + lenLimit; + } + + // add the remainings + if (modeAdd) { + out.append(in.substring(lastPos)); + } + + return out.toString(); + } + + /** + * This converts a String to a list of strings by extracting the substrings + * between delimiter + * + * @param in - what to process + * @param delimiter - the delimiting string + * @param doStrip - to strip the substrings before adding to the list + * + * @return LinkedList + */ + public static LinkedList
null
, a new List
will be created.
+ *
+ * @return The collection to which the substrings were added. This is
+ * syntactic sugar to allow call chaining.
+ */
+ public static Collection+ * + * This is a more general version of collapseWhitespace. + * + *
+ * E.g. collapse("hello world", " ", "::") + * will return the following string: "hello::world" + *+ * + * @param str the string you want to munge + * @param chars all of the characters to be considered for munge + * @param replacement the replacement string + * @return String munged and replaced string. + */ + public static String collapse(String str, String chars, String replacement) { + if (str == null) { + return null; + } + + StringBuilder newStr = new StringBuilder(); + + boolean prevCharMatched = false; + char c; + for (int i = 0; i < str.length(); i++) { + c = str.charAt(i); + if (chars.indexOf(c) != -1) { + // this character is matched + if (prevCharMatched) { + // apparently a string of matched chars, so don't append anything + // to the string + continue; + } + prevCharMatched = true; + newStr.append(replacement); + } + else { + prevCharMatched = false; + newStr.append(c); + } + } + + return newStr.toString(); + } + + /** + * Read a String of up to maxLength bytes from an InputStream + * + * @param is input stream + * @param maxLength max number of bytes to read from "is". If this is -1, we + * read everything. + * + * @return String up to maxLength bytes, read from "is" + */ + public static String stream2String(InputStream is, int maxLength) + throws IOException { + byte[] buffer = new byte[4096]; + StringWriter sw = new StringWriter(); + int totalRead = 0; + int read = 0; + + do { + sw.write(new String(buffer, 0, read)); + totalRead += read; + read = is.read(buffer, 0, buffer.length); + } while (((-1 == maxLength) || (totalRead < maxLength)) && (read != -1)); + + return sw.toString(); + } + + /** + * Parse a list of substrings separated by a given delimiter. The delimiter + * can also appear in substrings (just double them): + * + * parseDelimitedString("this|is", '|') returns ["this","is"] + * parseDelimitedString("this||is", '|') returns ["this|is"] + * + * @param list String containing delimited substrings + * @param delimiter Delimiter (anything except ' ' is allowed) + * + * @return String[] A String array of parsed substrings + */ + public static String[] parseDelimitedList(String list, + char delimiter) { + String delim = "" + delimiter; + // Append a sentinel of delimiter + space + // (see comments below for more info) + StringTokenizer st = new StringTokenizer(list + delim + " ", + delim, + true); + ArrayList
Checks if a String is not empty ("") and not null.
+ * + *+ * StringUtils.isNotEmpty(null) = false + * StringUtils.isNotEmpty("") = false + * StringUtils.isNotEmpty(" ") = true + * StringUtils.isNotEmpty("bob") = true + * StringUtils.isNotEmpty(" bob ") = true + *+ * + * @param str the String to check, may be null + * @return
true
if the String is not empty and not null
+ */
+ public static boolean isNotEmpty(String s) {
+ return !isEmpty(s);
+ }
+
+ /**
+ * Helper function for null and empty string testing.
+ *
+ * @return true iff s == null or s.equals("");
+ */
+ public static boolean isEmpty(String s) {
+ return makeSafe(s).length() == 0;
+ }
+
+ /**
+ * Helper function for null, empty, and whitespace string testing.
+ *
+ * @return true if s == null or s.equals("") or s contains only whitespace
+ * characters.
+ */
+ public static boolean isEmptyOrWhitespace(String s) {
+ s = makeSafe(s);
+ for (int i = 0, n = s.length(); i < n; i++) {
+ if (!Character.isWhitespace(s.charAt(i))) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Helper function for making null strings safe for comparisons, etc.
+ *
+ * @return (s == null) ? "" : s;
+ */
+ public static String makeSafe(String s) {
+ return (s == null) ? "" : s;
+ }
+
+ /**
+ * Helper function for making empty strings into a null.
+ *
+ * @return null if s is zero length. otherwise, returns s.
+ */
+ public static String toNullIfEmpty(String s) {
+ return (StringUtil.isEmpty(s)) ? null : s;
+ }
+
+ /**
+ * Helper function for turning empty or whitespace strings into a null.
+ *
+ * @return null if s is zero length or if s contains only whitespace
+ * characters. otherwise, returns s.
+ */
+ public static String toNullIfEmptyOrWhitespace(String s) {
+ return (StringUtil.isEmptyOrWhitespace(s)) ? null : s;
+ }
+
+ /**
+ * Serializes a map
+ *
+ * @param map A map of String keys to arrays of String values
+ * @param keyValueDelim Delimiter between keys and values
+ * @param entryDelim Delimiter between entries
+ *
+ * @return String A string containing a serialized representation of the
+ * contents of the map.
+ *
+ * e.g. arrayMap2String({"foo":["bar","bar2"],"foo1":["bar1"]}, "=", "&")
+ * returns "foo=bar&foo=bar2&foo1=bar1"
+ */
+ public static String arrayMap2String(MapFor example: + *
+ * capitalize("foo bar").equals("Foo bar"); + * capitalize("2b or not 2b").equals("2b or not 2b") + * capitalize("Foo bar").equals("Foo bar"); + * capitalize("").equals(""); + *+ * + * @param s the string whose first character is to be uppercased + * @return a string equivalent to s with its first character + * converted to uppercase + * @throws NullPointerException if s is null + */ + public static String capitalize(String s) { + if (s.length() == 0) + return s; + char first = s.charAt(0); + char capitalized = Character.toUpperCase(first); + return (first == capitalized) + ? s + : capitalized + s.substring(1); + } + + //Contains + //----------------------------------------------------------------------- + /** + *
Checks if String contains a search character, handling null
.
+ * This method uses {@link String#indexOf(int)}.
A null
or empty ("") String will return false
.
+ * StringUtil.contains(null, *) = false + * StringUtil.contains("", *) = false + * StringUtil.contains("abc", 'a') = true + * StringUtil.contains("abc", 'z') = false + *+ * + * @param str the String to check, may be null + * @param searchChar the character to find + * @return true if the String contains the search character, + * false if not or
null
string input
+ * @since 2.0
+ */
+ public static boolean contains(String str, char searchChar) {
+ if (isEmpty(str)) {
+ return false;
+ }
+ return str.indexOf(searchChar) >= 0;
+ }
+
+ /**
+ * Checks if String contains a search String, handling null
.
+ * This method uses {@link String#indexOf(String)}.
A null
String will return false
.
+ * StringUtil.contains(null, *) = false + * StringUtil.contains(*, null) = false + * StringUtil.contains("", "") = true + * StringUtil.contains("abc", "") = true + * StringUtil.contains("abc", "a") = true + * StringUtil.contains("abc", "z") = false + *+ * + * @param str the String to check, may be null + * @param searchStr the String to find, may be null + * @return true if the String contains the search String, + * false if not or
null
string input
+ * @since 2.0
+ */
+ public static boolean contains(String str, String searchStr) {
+ if (str == null || searchStr == null) {
+ return false;
+ }
+ return str.indexOf(searchStr) >= 0;
+ }
+
+ /**
+ * Checks if String contains a search String irrespective of case,
+ * handling null
. This method uses
+ * {@link #contains(String, String)}.
A null
String will return false
.
+ * StringUtil.contains(null, *) = false + * StringUtil.contains(*, null) = false + * StringUtil.contains("", "") = true + * StringUtil.contains("abc", "") = true + * StringUtil.contains("abc", "a") = true + * StringUtil.contains("abc", "z") = false + * StringUtil.contains("abc", "A") = true + * StringUtil.contains("abc", "Z") = false + *+ * + * @param str the String to check, may be null + * @param searchStr the String to find, may be null + * @return true if the String contains the search String irrespective of + * case or false if not or
null
string input
+ */
+ public static boolean containsIgnoreCase(String str, String searchStr) {
+ if (str == null || searchStr == null) {
+ return false;
+ }
+ return contains(str.toUpperCase(), searchStr.toUpperCase());
+ }
+
+ //Reversing
+ //-----------------------------------------------------------------------
+ /**
+ * Reverses a String as per {@link StringBuffer#reverse()}.
+ * + *A null
String returns null
.
+ * StringUtil.reverse(null) = null + * StringUtil.reverse("") = "" + * StringUtil.reverse("bat") = "tab" + *+ * + * @param str the String to reverse, may be null + * @return the reversed String,
null
if null String input
+ */
+ public static String reverse(String str) {
+ if (str == null) {
+ return null;
+ }
+ return new StringBuffer(str).reverse().toString();
+ }
+
+ //Abbreviating
+ //-----------------------------------------------------------------------
+ /**
+ * Abbreviates a String using ellipses. This will turn + * "Now is the time for all good men" into "Now is the time for..."
+ * + *Specifically: + *
str
is less than maxWidth
characters
+ * long, return it.(substring(str, 0, max-3) + "...")
.maxWidth
is less than 4
, throw an
+ * IllegalArgumentException
.maxWidth
.+ * StringUtil.abbreviate(null, *) = null + * StringUtil.abbreviate("", 4) = "" + * StringUtil.abbreviate("abcdefg", 6) = "abc..." + * StringUtil.abbreviate("abcdefg", 7) = "abcdefg" + * StringUtil.abbreviate("abcdefg", 8) = "abcdefg" + * StringUtil.abbreviate("abcdefg", 4) = "a..." + * StringUtil.abbreviate("abcdefg", 3) = IllegalArgumentException + *+ * + * @param str the String to check, may be null + * @param maxWidth maximum length of result String, must be at least 4 + * @return abbreviated String,
null
if null String input
+ * @throws IllegalArgumentException if the width is too small
+ * @since 2.0
+ */
+ public static String abbreviate(String str, int maxWidth) {
+ return abbreviate(str, 0, maxWidth);
+ }
+
+ /**
+ * Abbreviates a String using ellipses. This will turn + * "Now is the time for all good men" into "...is the time for..."
+ * + *Works like abbreviate(String, int)
, but allows you to specify
+ * a "left edge" offset. Note that this left edge is not necessarily going to
+ * be the leftmost character in the result, or the first character following the
+ * ellipses, but it will appear somewhere in the result.
+ *
+ *
In no case will it return a String of length greater than
+ * maxWidth
.
+ * StringUtil.abbreviate(null, *, *) = null + * StringUtil.abbreviate("", 0, 4) = "" + * StringUtil.abbreviate("abcdefghijklmno", -1, 10) = "abcdefg..." + * StringUtil.abbreviate("abcdefghijklmno", 0, 10) = "abcdefg..." + * StringUtil.abbreviate("abcdefghijklmno", 1, 10) = "abcdefg..." + * StringUtil.abbreviate("abcdefghijklmno", 4, 10) = "abcdefg..." + * StringUtil.abbreviate("abcdefghijklmno", 5, 10) = "...fghi..." + * StringUtil.abbreviate("abcdefghijklmno", 6, 10) = "...ghij..." + * StringUtil.abbreviate("abcdefghijklmno", 8, 10) = "...ijklmno" + * StringUtil.abbreviate("abcdefghijklmno", 10, 10) = "...ijklmno" + * StringUtil.abbreviate("abcdefghijklmno", 12, 10) = "...ijklmno" + * StringUtil.abbreviate("abcdefghij", 0, 3) = IllegalArgumentException + * StringUtil.abbreviate("abcdefghij", 5, 6) = IllegalArgumentException + *+ * + * @param str the String to check, may be null + * @param offset left edge of source String + * @param maxWidth maximum length of result String, must be at least 4 + * @return abbreviated String,
null
if null String input
+ * @throws IllegalArgumentException if the width is too small
+ * @since 2.0
+ */
+ public static String abbreviate(String str, int offset, int maxWidth) {
+ if (str == null) {
+ return null;
+ }
+ if (maxWidth < 4) {
+ throw new IllegalArgumentException("Minimum abbreviation width is 4");
+ }
+ if (str.length() <= maxWidth) {
+ return str;
+ }
+ if (offset > str.length()) {
+ offset = str.length();
+ }
+ if ((str.length() - offset) < (maxWidth - 3)) {
+ offset = str.length() - (maxWidth - 3);
+ }
+ if (offset <= 4) {
+ return str.substring(0, maxWidth - 3) + "...";
+ }
+ if (maxWidth < 7) {
+ throw new IllegalArgumentException("Minimum abbreviation width with offset is 7");
+ }
+ if ((offset + (maxWidth - 3)) < str.length()) {
+ return "..." + abbreviate(str.substring(offset), maxWidth - 3);
+ }
+ return "..." + str.substring(str.length() - (maxWidth - 3));
+ }
+
+ public static List removeEmpty(List list){
+ List replace = new ArrayList();
+ Object obj;
+ for (Iterator iter = list.iterator(); iter.hasNext();) {
+ obj = iter.next();
+ if(obj != null){
+ replace.add(obj);
+ }
+ }
+
+ return replace;
+ }
+
+}