net.peterkuterna.android.apps.devoxxsched.io.RemoteScheduleHandler.java Source code

Java tutorial

Introduction

Here is the source code for net.peterkuterna.android.apps.devoxxsched.io.RemoteScheduleHandler.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 net.peterkuterna.android.apps.devoxxsched.io;

import java.util.ArrayList;
import java.util.HashMap;

import net.peterkuterna.android.apps.devoxxsched.provider.ScheduleContract;
import net.peterkuterna.android.apps.devoxxsched.provider.ScheduleContract.Blocks;
import net.peterkuterna.android.apps.devoxxsched.provider.ScheduleContract.Rooms;
import net.peterkuterna.android.apps.devoxxsched.provider.ScheduleContract.Sessions;
import net.peterkuterna.android.apps.devoxxsched.util.Lists;
import net.peterkuterna.android.apps.devoxxsched.util.Maps;
import net.peterkuterna.android.apps.devoxxsched.util.ParserUtils;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.content.ContentProviderOperation;
import android.content.ContentResolver;
import android.database.Cursor;
import android.net.Uri;
import android.provider.BaseColumns;
import android.util.Log;

/**
 * Handle a remote {@link JSONArray} that defines a set of {@link Blocks}
 * entries. Also updates the related {@link Sessions} with {@link Rooms} and
 * {@link Blocks} info.
 */
public class RemoteScheduleHandler extends JSONHandler {

    private static final String TAG = "ScheduleHandler";

    public RemoteScheduleHandler() {
        super(ScheduleContract.CONTENT_AUTHORITY);
    }

    @Override
    public ArrayList<ContentProviderOperation> parse(ArrayList<JSONArray> entries, ContentResolver resolver)
            throws JSONException {
        final ArrayList<ContentProviderOperation> batch = Lists.newArrayList();
        final HashMap<String, ContentProviderOperation> blockBatchMap = Maps.newHashMap();
        final HashMap<String, ContentProviderOperation> sessionUpdateBatchMap = Maps.newHashMap();

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

            for (int i = 0; i < schedules.length(); i++) {
                JSONObject schedule = schedules.getJSONObject(i);

                final long startTime = ParserUtils.parseDevoxxTime(schedule.getString("fromTime"));
                final long endTime = ParserUtils.parseDevoxxTime(schedule.getString("toTime"));
                final String kind = schedule.getString("kind");

                final String blockId = Blocks.generateBlockId(kind, startTime, endTime);

                if (!blockBatchMap.containsKey(blockId)) {
                    final Uri blockUri = Blocks.buildBlockUri(blockId);

                    ContentProviderOperation.Builder builder;
                    if (isRowExisting(Blocks.buildBlockUri(blockId), BlocksQuery.PROJECTION, resolver)) {
                        builder = ContentProviderOperation.newUpdate(blockUri);
                    } else {
                        builder = ContentProviderOperation.newInsert(Blocks.CONTENT_URI);
                        builder.withValue(Blocks.BLOCK_ID, blockId);
                    }
                    builder.withValue(Blocks.BLOCK_START, startTime);
                    builder.withValue(Blocks.BLOCK_END, endTime);

                    final String type = schedule.getString("type");
                    final String code = schedule.getString("code");

                    if (code.startsWith("D10")) {
                        builder.withValue(Blocks.BLOCK_TITLE, type.replaceAll("\\ \\(.*\\)", ""));
                    } else {
                        builder.withValue(Blocks.BLOCK_TITLE, schedule.getString("code"));
                    }

                    builder.withValue(Blocks.BLOCK_TYPE, kind);
                    blockBatchMap.put(blockId, builder.build());
                }

                if (schedule.has("presentationUri")) {
                    final Uri presentationUri = Uri.parse(schedule.getString("presentationUri"));
                    final String sessionId = presentationUri.getLastPathSegment();
                    final Uri sessionUri = Sessions.buildSessionUri(sessionId);

                    if (isRowExisting(sessionUri, SessionsQuery.PROJECTION, resolver)) {
                        String roomId = null;
                        if (schedule.has("room")) {
                            final String roomName = schedule.getString("room");
                            Cursor cursor = resolver.query(Rooms.buildRoomsWithNameUri(roomName),
                                    RoomsQuery.PROJECTION, null, null, null);
                            if (cursor.moveToNext()) {
                                roomId = cursor.getString(RoomsQuery.ROOM_ID);
                            }
                            cursor.close();
                        }
                        final ContentProviderOperation.Builder builder = ContentProviderOperation
                                .newUpdate(sessionUri);
                        builder.withValue(Sessions.BLOCK_ID, blockId);
                        builder.withValue(Sessions.ROOM_ID, roomId);
                        if (schedule.has("note")) {
                            final String note = schedule.getString("note");
                            if (note != null && note.trim().length() > 0) {
                                builder.withValue(Sessions.NOTE, note.trim());
                            }
                        }

                        sessionUpdateBatchMap.put(sessionId, builder.build());
                    }
                }
            }
        }

        batch.addAll(blockBatchMap.values());
        batch.addAll(sessionUpdateBatchMap.values());

        if (isRemoteSync() && nrEntries > 0) {
            for (String lostId : getLostIds(blockBatchMap.keySet(), Blocks.CONTENT_URI, BlocksQuery.PROJECTION,
                    BlocksQuery.BLOCK_ID, resolver)) {
                if (!lostId.startsWith("lab")) {
                    final Uri lostBlockUri = Blocks.buildBlockUri(lostId);
                    batch.add(ContentProviderOperation.newDelete(lostBlockUri).build());
                }
            }
            for (String lostId : getLostIds(sessionUpdateBatchMap.keySet(), Sessions.CONTENT_URI,
                    SessionsQuery.PROJECTION, SessionsQuery.SESSION_ID, resolver)) {
                Uri deleteUri = Sessions.buildSpeakersDirUri(lostId);
                batch.add(ContentProviderOperation.newDelete(deleteUri).build());
                deleteUri = Sessions.buildTagsDirUri(lostId);
                batch.add(ContentProviderOperation.newDelete(deleteUri).build());
                deleteUri = Sessions.buildSessionUri(lostId);
                batch.add(ContentProviderOperation.newDelete(deleteUri).build());
            }
        }

        return batch;
    }

    private interface SessionsQuery {
        String[] PROJECTION = { Sessions.SESSION_ID, };

        int SESSION_ID = 0;
    }

    private interface BlocksQuery {
        String[] PROJECTION = { Blocks.BLOCK_ID, };

        int BLOCK_ID = 0;
    }

    private interface RoomsQuery {
        String[] PROJECTION = { BaseColumns._ID, Rooms.ROOM_ID, };

        int _ID = 0;
        int ROOM_ID = 1;
    }

}