/* * Firetweet - Twitter client for Android * * Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package twitter4j.internal.util; import org.json.JSONException; import org.json.JSONObject; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.text.NumberFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.Locale; import java.util.Map; import java.util.TimeZone; import twitter4j.TwitterException; import twitter4j.TwitterResponse; import twitter4j.http.HTMLEntity; import twitter4j.http.HttpResponse; /** * A tiny parse utility class. * * @author Yusuke Yamamoto - yusuke at mac.com */ public final class InternalParseUtil { private static ThreadLocal<Map<String, SimpleDateFormat>> formatMap = new ThreadLocal<Map<String, SimpleDateFormat>>() { @Override protected Map<String, SimpleDateFormat> initialValue() { return new HashMap<String, SimpleDateFormat>(); } }; private InternalParseUtil() { // should never be instantiated throw new AssertionError(); } public static boolean getBoolean(final String name, final JSONObject json) { final String str = getRawString(name, json); if (null == str || "null".equals(str)) return false; return Boolean.valueOf(str); } public static Date getDate(final String name, final JSONObject json) throws TwitterException { return getDate(name, json, "EEE MMM d HH:mm:ss z yyyy"); } public static Date getDate(final String name, final JSONObject json, final String format) throws TwitterException { final String dateStr = getUnescapedString(name, json); if ("null".equals(dateStr) || null == dateStr) return null; else return getDate(dateStr, format); } public static Date getDate(final String date, final String format) throws TwitterException { SimpleDateFormat sdf = formatMap.get().get(format); if (null == sdf) { sdf = new SimpleDateFormat(format, Locale.ENGLISH); sdf.setTimeZone(TimeZone.getTimeZone("GMT")); formatMap.get().put(format, sdf); } try { return sdf.parse(date); } catch (final ParseException pe) { throw new TwitterException("Unexpected date format(" + date + ") returned from twitter.com", pe); } } public static double getDouble(final String name, final JSONObject json) { final String str2 = getRawString(name, json); if (null == str2 || "".equals(str2) || "null".equals(str2)) return -1; else return Double.valueOf(str2); } public static String getHTMLUnescapedString(final String name, final JSONObject json) { return HTMLEntity.unescape(getRawString(name, json)); } public static int getInt(final String str) { if (null == str || "".equals(str) || "null".equals(str)) return -1; else { try { return Integer.valueOf(str); } catch (final NumberFormatException nfe) { // workaround for the API side issue // http://twitter4j.org/jira/browse/TFJ-484 return -1; } } } public static int getInt(final String name, final JSONObject json) { return getInt(getRawString(name, json)); } public static long getLong(String str) { if (null == str || "".equals(str) || "null".equals(str)) return -1; else { try { final Number number = NumberFormat.getInstance().parse(str); return number.longValue(); } catch (final ParseException e) { } // some count over 100 will be expressed as "100+" if (str.endsWith("+")) { str = str.substring(0, str.length() - 1); try { return Integer.valueOf(str) + 1; } catch (final NumberFormatException nfe) { // workaround for the API side issue // http://twitter4j.org/jira/browse/TFJ-484 return -1; } } try { return Long.valueOf(str); } catch (final NumberFormatException nfe) { // workaround for the API side issue // http://twitter4j.org/jira/browse/TFJ-484 return -1; } } } public static long getLong(final String name, final JSONObject json) { return getLong(getRawString(name, json)); } public static String getRawString(final String name, final JSONObject json) { try { if (json.isNull(name)) return null; return json.getString(name); } catch (final JSONException e) { return null; } } public static String getUnescapedString(final String name, final JSONObject json) { final String str = getRawString(name, json); if (str == null) return null; return str.replace("&", "&").replace("<", "<").replace(">", ">"); } public static String getURLDecodedString(final String name, final JSONObject json) { String returnValue = getRawString(name, json); if (returnValue != null) { try { returnValue = URLDecoder.decode(returnValue, "UTF-8"); } catch (final UnsupportedEncodingException ignore) { } } return returnValue; } public static Date parseTrendsDate(final String asOfStr) throws TwitterException { Date parsed; switch (asOfStr.length()) { case 10: parsed = new Date(Long.parseLong(asOfStr) * 1000); break; case 20: parsed = getDate(asOfStr, "yyyy-MM-dd'T'HH:mm:ss'Z'"); break; default: parsed = getDate(asOfStr, "EEE, d MMM yyyy HH:mm:ss z"); } return parsed; } public static int toAccessLevel(final HttpResponse res) { if (null == res) return -1; final String xAccessLevel = res.getResponseHeader("X-Access-Level"); int accessLevel; if (null == xAccessLevel) { accessLevel = TwitterResponse.NONE; } else { // https://dev.twitter.com/pages/application-permission-model-faq#how-do-we-know-what-the-access-level-of-a-user-token-is switch (xAccessLevel.length()) { // “read” (Read-only) case 4: accessLevel = TwitterResponse.READ; break; case 10: // “read-write” (Read & Write) accessLevel = TwitterResponse.READ_WRITE; break; case 25: // “read-write-directmessages” (Read, Write, & Direct // Message) accessLevel = TwitterResponse.READ_WRITE_DIRECTMESSAGES; break; case 26: // “read-write-privatemessages” (Read, Write, & Direct // Message) accessLevel = TwitterResponse.READ_WRITE_DIRECTMESSAGES; break; default: accessLevel = TwitterResponse.NONE; // unknown access level; } } return accessLevel; } }