/* * 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.json; import org.json.JSONException; import org.json.JSONObject; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import twitter4j.RateLimitStatus; import twitter4j.TwitterException; import twitter4j.conf.Configuration; import twitter4j.http.HttpResponse; import static twitter4j.internal.util.InternalParseUtil.getInt; /** * A data class representing Twitter REST API's rate limit status * * @author Yusuke Yamamoto - yusuke at mac.com * @see <a href="https://dev.twitter.com/docs/rate-limiting">Rate Limiting | * Twitter Developers</a> */ /* package */final class RateLimitStatusJSONImpl implements RateLimitStatus, java.io.Serializable { private static final long serialVersionUID = 1625565652687304084L; private int remaining; private int limit; private int resetTimeInSeconds; private int secondsUntilReset; private RateLimitStatusJSONImpl(final int limit, final int remaining, final int resetTimeInSeconds) { this.limit = limit; this.remaining = remaining; this.resetTimeInSeconds = resetTimeInSeconds; secondsUntilReset = (int) ((resetTimeInSeconds * 1000L - System.currentTimeMillis()) / 1000); } RateLimitStatusJSONImpl(final JSONObject json) throws TwitterException { init(json); } @Override public boolean equals(final Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; final RateLimitStatusJSONImpl that = (RateLimitStatusJSONImpl) o; if (limit != that.limit) return false; if (remaining != that.remaining) return false; if (resetTimeInSeconds != that.resetTimeInSeconds) return false; if (secondsUntilReset != that.secondsUntilReset) return false; return true; } /** * {@inheritDoc} */ @Override public int getLimit() { return limit; } /** * {@inheritDoc} */ @Override public int getRemaining() { return remaining; } /** * {@inheritDoc} */ @Override public int getRemainingHits() { return getRemaining(); } /** * {@inheritDoc} */ @Override public int getResetTimeInSeconds() { return resetTimeInSeconds; } /** * {@inheritDoc} */ @Override public int getSecondsUntilReset() { return secondsUntilReset; } @Override public int hashCode() { int result = remaining; result = 31 * result + limit; result = 31 * result + resetTimeInSeconds; result = 31 * result + secondsUntilReset; return result; } @Override public String toString() { return "RateLimitStatusJSONImpl{" + "remaining=" + remaining + ", limit=" + limit + ", resetTimeInSeconds=" + resetTimeInSeconds + ", secondsUntilReset=" + secondsUntilReset + '}'; } void init(final JSONObject json) throws TwitterException { limit = getInt("limit", json); remaining = getInt("remaining", json); resetTimeInSeconds = getInt("reset", json); secondsUntilReset = (int) ((resetTimeInSeconds * 1000L - System.currentTimeMillis()) / 1000); } static RateLimitStatus createFromResponseHeader(final HttpResponse res) { if (null == res) return null; int remainingHits;// "X-Rate-Limit-Remaining" int limit;// "X-Rate-Limit-Limit" int resetTimeInSeconds;// not included in the response header. Need to // be calculated. final String strLimit = res.getResponseHeader("X-Rate-Limit-Limit"); if (strLimit != null) { limit = Integer.parseInt(strLimit); } else return null; final String remaining = res.getResponseHeader("X-Rate-Limit-Remaining"); if (remaining != null) { remainingHits = Integer.parseInt(remaining); } else return null; final String reset = res.getResponseHeader("X-Rate-Limit-Reset"); if (reset != null) { final long longReset = Long.parseLong(reset); resetTimeInSeconds = (int) longReset; } else return null; return new RateLimitStatusJSONImpl(limit, remainingHits, resetTimeInSeconds); } static Map<String, RateLimitStatus> createRateLimitStatuses(final HttpResponse res, final Configuration conf) throws TwitterException { final JSONObject json = res.asJSONObject(); final Map<String, RateLimitStatus> map = createRateLimitStatuses(json); return map; } static Map<String, RateLimitStatus> createRateLimitStatuses(final JSONObject json) throws TwitterException { final Map<String, RateLimitStatus> map = new HashMap<String, RateLimitStatus>(); try { final JSONObject resources = json.getJSONObject("resources"); final Iterator<?> resourceKeys = resources.keys(); while (resourceKeys.hasNext()) { final JSONObject resource = resources.getJSONObject((String) resourceKeys.next()); final Iterator<?> endpointKeys = resource.keys(); while (endpointKeys.hasNext()) { final String endpoint = (String) endpointKeys.next(); final JSONObject rateLimitStatusJSON = resource.getJSONObject(endpoint); final RateLimitStatus rateLimitStatus = new RateLimitStatusJSONImpl(rateLimitStatusJSON); map.put(endpoint, rateLimitStatus); } } return Collections.unmodifiableMap(map); } catch (final JSONException jsone) { throw new TwitterException(jsone); } } }