/* * Copyright 2014 sonaive.com. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.sonaive.v2ex.io; import android.content.ContentProviderOperation; import android.content.Context; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import com.google.gson.Gson; import com.google.gson.JsonElement; import com.sonaive.v2ex.io.model.Member; import com.sonaive.v2ex.provider.V2exContract; import com.sonaive.v2ex.sync.api.Api; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import static com.sonaive.v2ex.util.LogUtils.LOGD; import static com.sonaive.v2ex.util.LogUtils.LOGE; import static com.sonaive.v2ex.util.LogUtils.makeLogTag; /** * Created by liutao on 12/10/14. */ public class MembersHandler extends JSONHandler { private static final String TAG = makeLogTag(MembersHandler.class); private HashMap<String, Member> mMembers = new HashMap<>(); public MembersHandler(Context context) { super(context); } @Override public void makeContentProviderOperations(ArrayList<ContentProviderOperation> list) { Uri uri = V2exContract.Members.CONTENT_URI; HashMap<String, String> memberHashcodes = loadMemberHashcodes(); HashSet<String> membersToKeep = new HashSet<>(); boolean isIncrementalUpdate = memberHashcodes != null && memberHashcodes.size() > 0; if (isIncrementalUpdate) { LOGD(TAG, "Doing incremental update for members."); } else { LOGD(TAG, "Doing FULL (non incremental) update for members."); list.add(ContentProviderOperation.newDelete(uri).build()); } int updatedMembers = 0; for (Member member : mMembers.values()) { String hashCode = member.getImportHashcode(); membersToKeep.add(String.valueOf(member.id)); // add member, if necessary if (!isIncrementalUpdate || !memberHashcodes.containsKey(String.valueOf(member.id)) || !memberHashcodes.get(String.valueOf(member.id)).equals(hashCode)) { ++updatedMembers; boolean isNew = !isIncrementalUpdate || !memberHashcodes.containsKey(String.valueOf(member.id)); buildMember(isNew, member, list); } } LOGD(TAG, "Members: " + (isIncrementalUpdate ? "INCREMENTAL" : "FULL") + " update. " + updatedMembers + " to update, New total: " + mMembers.size()); } private void buildMember(boolean isInsert, Member member, ArrayList<ContentProviderOperation> list) { Uri uri = V2exContract.Members.buildMemberUsernameUri(member.username); ContentProviderOperation.Builder builder; if (isInsert) { builder = ContentProviderOperation.newInsert(uri); } else { builder = ContentProviderOperation.newUpdate(uri); } list.add(builder.withValue(V2exContract.Members.MEMBER_ID, member.id) .withValue(V2exContract.Members.MEMBER_URL, member.url) .withValue(V2exContract.Members.MEMBER_USERNAME, member.username) .withValue(V2exContract.Members.MEMBER_WEBSITE, member.website) .withValue(V2exContract.Members.MEMBER_TWITTER, member.twitter) .withValue(V2exContract.Members.MEMBER_PSN, member.psn) .withValue(V2exContract.Members.MEMBER_GITHUB, member.github) .withValue(V2exContract.Members.MEMBER_BTC, member.btc) .withValue(V2exContract.Members.MEMBER_LOCATION, member.location) .withValue(V2exContract.Members.MEMBER_TAGLINE, member.tagline) .withValue(V2exContract.Members.MEMBER_BIO, member.bio) .withValue(V2exContract.Members.MEMBER_AVATAR_MINI, member.avatar_mini) .withValue(V2exContract.Members.MEMBER_AVATAR_NORMAL, member.avatar_normal) .withValue(V2exContract.Members.MEMBER_AVATAR_LARGE, member.avatar_large) .withValue(V2exContract.Members.MEMBER_CREATED, member.created) .withValue(V2exContract.Members.MEMBER_IMPORT_HASHCODE, member.getImportHashcode()) .build()); } private void buildDeleteOperation(String memberId, ArrayList<ContentProviderOperation> list) { Uri thisMemberUri = V2exContract.Members.buildMemberUsernameUri(memberId); list.add(ContentProviderOperation.newDelete(thisMemberUri).build()); } @Override public void process(JsonElement element) { Member member = new Gson().fromJson(element, Member.class); mMembers.put(String.valueOf(member.id), member); } @Override public String getBody(Bundle data) { if (data != null) { return data.getString(Api.ARG_RESULT); } return ""; } private HashMap<String, String> loadMemberHashcodes() { Uri uri = V2exContract.Members.CONTENT_URI; Cursor cursor = mContext.getContentResolver().query(uri, MemberHashcodeQuery.PROJECTION, null, null, null); if (cursor == null) { LOGE(TAG, "Error querying member hashcodes (got null cursor)"); return null; } if (cursor.getCount() < 1) { LOGE(TAG, "Error querying member hashcodes (no records returned)"); cursor.close(); return null; } HashMap<String, String> result = new HashMap<String, String>(); while (cursor.moveToNext()) { String videoId = cursor.getString(MemberHashcodeQuery.MEMBER_ID); String hashcode = cursor.getString(MemberHashcodeQuery.MEMBER_IMPORT_HASHCODE); result.put(videoId, hashcode == null ? "" : hashcode); } cursor.close(); return result; } private interface MemberHashcodeQuery { String[] PROJECTION = { V2exContract.Members._ID, V2exContract.Members.MEMBER_ID, V2exContract.Members.MEMBER_IMPORT_HASHCODE }; final int _ID = 0; final int MEMBER_ID = 1; final int MEMBER_IMPORT_HASHCODE = 2; } }