fr.mixit.android.io.RemoteSessionsHandler.java Source code

Java tutorial

Introduction

Here is the source code for fr.mixit.android.io.RemoteSessionsHandler.java

Source

/*
 * Copyright 2010 Peter Kuterna
 *
 * 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 fr.mixit.android.io;

import android.content.ContentProviderOperation;
import android.content.ContentResolver;
import android.database.Cursor;
import android.graphics.Color;
import android.net.Uri;
import android.util.Log;
import fr.mixit.android.provider.MixItContract;
import fr.mixit.android.provider.MixItDatabase;
import fr.mixit.android.utils.Lists;
import fr.mixit.android.utils.Maps;
import fr.mixit.android.utils.Sets;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;

/**
 * Handle a remote {@link org.json.JSONArray} that defines a set of {@link fr.mixit.android.provider.MixItContract.Sessions}
 * entries.
 */
public class RemoteSessionsHandler extends JSONHandler {

    private static final String TAG = "SessionsHandler";

    public RemoteSessionsHandler() {
        super(MixItContract.CONTENT_AUTHORITY);
    }

    @Override
    public ArrayList<ContentProviderOperation> parse(ArrayList<JSONArray> entries, ContentResolver resolver)
            throws JSONException {
        final ArrayList<ContentProviderOperation> batch = Lists.newArrayList();
        final HashSet<String> sessionIds = Sets.newHashSet();
        final HashMap<String, HashSet<String>> sessionSpeakerIds = Maps.newHashMap();
        final HashMap<String, HashSet<String>> sessionTagIds = Maps.newHashMap();

        int nrEntries = 0;
        for (JSONArray sessions : entries) {
            Log.d(TAG, "Retrieved " + sessions.length() + " session entries.");
            nrEntries += sessions.length();

            for (int i = 0; i < sessions.length(); i++) {
                JSONObject session = sessions.getJSONObject(i);
                String sessionId = session.getString("id");

                //               final String sessionId = sanitizeId(sessionId);
                final Uri sessionUri = MixItContract.Sessions.buildSessionUri(sessionId);
                sessionIds.add(sessionId);
                //              int isStarred = isStarred(sessionUri, resolver);

                boolean sessionUpdated = false;
                boolean newSession = false;
                ContentProviderOperation.Builder builder;
                if (isRowExisting(sessionUri, SessionsQuery.PROJECTION, resolver)) {
                    builder = ContentProviderOperation.newUpdate(sessionUri);
                    sessionUpdated = isSessionUpdated(sessionUri, session, resolver);
                } else {
                    newSession = true;
                    builder = ContentProviderOperation.newInsert(MixItContract.Sessions.CONTENT_URI);
                    builder.withValue(MixItContract.Sessions.SESSION_ID, sessionId);
                }

                if (newSession || sessionUpdated) {
                    builder.withValue(MixItContract.Sessions.TITLE, session.getString("name"));
                    if (session.has("room")) {
                        String room = session.getString("room");
                        if (room == null || room.length() == 0) {
                            room = "";
                        }
                        builder.withValue(MixItContract.Sessions.ROOM, room);
                    }
                    builder.withValue(MixItContract.Sessions.SUMMARY, session.getString("description"));

                    if (session.has("track")) {
                        final String trackId = session.getString("track");
                        builder.withValue(MixItContract.Sessions.TRACK_ID, trackId);
                    }

                    if (session.has("slot")) {
                        final String trackId = session.getString("slot");
                        builder.withValue(MixItContract.Sessions.SLOT_ID, trackId);
                    }

                    batch.add(builder.build());
                }

                if (session.has("speakers")) {
                    final Uri speakerSessionsUri = MixItContract.Sessions.buildSpeakersDirUri(sessionId);
                    final JSONArray speakers = session.getJSONArray("speakers");
                    final HashSet<String> speakerIds = Sets.newHashSet();

                    if (!isLocalSync()) {
                        final boolean sessionSpeakersUpdated = isSessionSpeakersUpdated(speakerSessionsUri,
                                speakers, resolver);
                        if (sessionSpeakersUpdated) {
                            Log.d(TAG, "Speakers of session with sessionId " + sessionId + " was udpated.");

                            batch.add(ContentProviderOperation.newUpdate(sessionUri)
                                    .withValue(MixItContract.Sessions.UPDATED, true).build());
                        }
                    }

                    for (int j = 0; j < speakers.length(); j++) {
                        /*                   JSONObject speaker = speakers.getJSONObject(j);
                                               
                                             final String speakerId = speaker.getString("speakerId");
                                             speakerIds.add(speakerId);*/

                        final String speakerId = speakers.getString(j);
                        speakerIds.add(speakerId);

                        batch.add(ContentProviderOperation.newInsert(speakerSessionsUri)
                                .withValue(MixItDatabase.SessionsSpeakers.SPEAKER_ID, speakerId)
                                .withValue(MixItDatabase.SessionsSpeakers.SESSION_ID, sessionId).build());
                    }

                    sessionSpeakerIds.put(sessionId, speakerIds);
                }

                if (session.has("tags")) {
                    final Uri tagSessionsUri = MixItContract.Sessions.buildTagsDirUri(sessionId);
                    final JSONArray tags = session.getJSONArray("tags");
                    final HashSet<String> tagIds = Sets.newHashSet();

                    if (!isLocalSync()) {
                        final boolean sessionTagsUpdated = isSessionTagsUpdated(tagSessionsUri, tags, resolver);
                        if (sessionTagsUpdated) {
                            Log.d(TAG, "Tags of session with sessionId " + sessionId + " was udpated.");
                            batch.add(ContentProviderOperation.newUpdate(sessionUri)
                                    .withValue(MixItContract.Sessions.UPDATED, true).build());
                        }
                    }

                    for (int j = 0; j < tags.length(); j++) {
                        /*                   JSONObject tag = tags.getJSONObject(j);
                            
                                             final String tagId = tag.getString("tagId");
                                             tagIds.add(tagId);*/

                        final String tagId = tags.getString(j);
                        tagIds.add(tagId);

                        batch.add(ContentProviderOperation.newInsert(tagSessionsUri)
                                .withValue(MixItDatabase.SessionsTags.TAG_ID, tagId)
                                .withValue(MixItDatabase.SessionsTags.SESSION_ID, sessionId).build());
                    }

                    sessionTagIds.put(sessionId, tagIds);
                }
            }
        }

        if (isRemoteSync() && nrEntries > 0) {
            for (Map.Entry<String, HashSet<String>> entry : sessionSpeakerIds.entrySet()) {
                String sessionId = entry.getKey();
                HashSet<String> speakerIds = entry.getValue();
                final Uri speakerSessionsUri = MixItContract.Sessions.buildSpeakersDirUri(sessionId);
                HashSet<String> lostSpeakerIds = getLostIds(speakerIds, speakerSessionsUri,
                        SpeakersQuery.PROJECTION, SpeakersQuery.SPEAKER_ID, resolver);
                for (String lostSpeakerId : lostSpeakerIds) {
                    final Uri deleteUri = MixItContract.Sessions.buildSessionSpeakerUri(sessionId, lostSpeakerId);
                    batch.add(ContentProviderOperation.newDelete(deleteUri).build());
                }
            }

            HashSet<String> lostSessionIds = getLostIds(sessionIds, MixItContract.Sessions.CONTENT_URI,
                    SessionsQuery.PROJECTION, SessionsQuery.SESSION_ID, resolver);
            for (String lostSessionId : lostSessionIds) {
                Uri deleteUri = MixItContract.Sessions.buildSpeakersDirUri(lostSessionId);
                batch.add(ContentProviderOperation.newDelete(deleteUri).build());
                deleteUri = MixItContract.Sessions.buildSessionUri(lostSessionId);
                batch.add(ContentProviderOperation.newDelete(deleteUri).build());
            }
        }

        return batch;
    }

    private static boolean isSessionUpdated(Uri uri, JSONObject session, ContentResolver resolver)
            throws JSONException {
        final Cursor cursor = resolver.query(uri, SessionsQuery.PROJECTION, null, null, null);
        try {
            if (!cursor.moveToFirst())
                return false;

            final String curTitle = cursor.getString(SessionsQuery.TITLE).toLowerCase().trim();
            final String curSummary = cursor.getString(SessionsQuery.SUMMARY).toLowerCase().trim();
            final String curTrackId = cursor.getString(SessionsQuery.TRACK_ID) != null
                    ? cursor.getString(SessionsQuery.TRACK_ID).toLowerCase().trim()
                    : "";
            final String newTitle = session.getString("name").toLowerCase().trim();
            final String newSummary = session.getString("description").toLowerCase().trim();
            final String newTrackId = session.has("track") ? session.getString("track").toLowerCase().trim() : "";

            return (!curTitle.equals(newTitle) || !curSummary.equals(newSummary) || !curTrackId.equals(newTrackId));
        } finally {
            cursor.close();
        }
    }

    private static boolean isSessionSpeakersUpdated(Uri uri, JSONArray speakers, ContentResolver resolver)
            throws JSONException {
        final Cursor cursor = resolver.query(uri, SpeakersQuery.PROJECTION, null, null, null);
        try {
            if (!cursor.moveToFirst())
                return false;
            return cursor.getCount() != speakers.length();
        } finally {
            cursor.close();
        }
    }

    private static boolean isSessionTagsUpdated(Uri uri, JSONArray tags, ContentResolver resolver)
            throws JSONException {
        final Cursor cursor = resolver.query(uri, TagsQuery.PROJECTION, null, null, null);
        try {
            if (!cursor.moveToFirst())
                return false;
            return cursor.getCount() != tags.length();
        } finally {
            cursor.close();
        }
    }

    private interface SessionsQuery {
        String[] PROJECTION = { MixItContract.Sessions.SESSION_ID, MixItContract.Sessions.TITLE,
                MixItContract.Sessions.SUMMARY, MixItContract.Sessions.TRACK_ID, MixItContract.Sessions.ROOM,
                MixItContract.Sessions.STARRED, };

        int SESSION_ID = 0;
        int TITLE = 1;
        int SUMMARY = 2;
        int TRACK_ID = 3;
        int ROOM = 4;
        int STARRED = 5;
    }

    interface SpeakersQuery {
        String[] PROJECTION = { MixItContract.Speakers.SPEAKER_ID, };

        int SPEAKER_ID = 0;
    }

    interface TagsQuery {
        String[] PROJECTION = { MixItContract.Tags.TAG_ID, };

        int TAG_ID = 0;
    }

}