Android Open Source - scrumchatter Scrum Chatter Provider






From Project

Back to project page scrumchatter.

License

The source code is released under:

GNU General Public License

If you think the Android project scrumchatter listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/**
 * Copyright 2013 Carmen Alvarez//from  w w w .j  a va2 s  .  co m
 *
 * This file is part of Scrum Chatter.
 *
 * Scrum Chatter 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.
 *
 * Scrum Chatter 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 Scrum Chatter. If not, see <http://www.gnu.org/licenses/>.
 */
package ca.rmen.android.scrumchatter.provider;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

import android.content.ContentProvider;
import android.content.ContentProviderOperation;
import android.content.ContentProviderResult;
import android.content.ContentValues;
import android.content.OperationApplicationException;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteCursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQuery;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.provider.BaseColumns;
import android.util.Log;
import ca.rmen.android.scrumchatter.Constants;

/**
 * Provider for the Scrum Chatter app. This provider provides access to the
 * member, meeting, and meeting_member tables, and the member_stats view.
 * 
 * Part of this class was generated using the Android Content Provider
 * Generator: https://github.com/BoD/android-contentprovider-generator
 */
public class ScrumChatterProvider extends ContentProvider {
    private static final String TAG = Constants.TAG + ScrumChatterProvider.class.getSimpleName();

    private static final String TYPE_CURSOR_ITEM = "vnd.android.cursor.item/";
    private static final String TYPE_CURSOR_DIR = "vnd.android.cursor.dir/";

    public static final String AUTHORITY = "ca.rmen.android.scrumchatter.provider";
    static final String CONTENT_URI_BASE = "content://" + AUTHORITY;

    public static final String QUERY_NOTIFY = "QUERY_NOTIFY"; // NO_UCD (use private)
    public static final String QUERY_GROUP_BY = "QUERY_GROUP_BY"; // NO_UCD (use private)

    private static final int URI_TYPE_TEAM = 0;
    private static final int URI_TYPE_TEAM_ID = 1;

    private static final int URI_TYPE_MEETING_MEMBER = 2;
    private static final int URI_TYPE_MEETING_MEMBER_ID = 3;

    private static final int URI_TYPE_MEMBER = 4;
    private static final int URI_TYPE_MEMBER_ID = 5;

    private static final int URI_TYPE_MEETING = 6;
    private static final int URI_TYPE_MEETING_ID = 7;

    private static final int URI_TYPE_MEMBER_STATS = 8;

    private static final UriMatcher URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);

    static {
        URI_MATCHER.addURI(AUTHORITY, TeamColumns.TABLE_NAME, URI_TYPE_TEAM);
        URI_MATCHER.addURI(AUTHORITY, TeamColumns.TABLE_NAME + "/#", URI_TYPE_TEAM_ID);

        URI_MATCHER.addURI(AUTHORITY, MeetingMemberColumns.TABLE_NAME, URI_TYPE_MEETING_MEMBER);
        URI_MATCHER.addURI(AUTHORITY, MeetingMemberColumns.TABLE_NAME + "/#", URI_TYPE_MEETING_MEMBER_ID);

        URI_MATCHER.addURI(AUTHORITY, MemberColumns.TABLE_NAME, URI_TYPE_MEMBER);
        URI_MATCHER.addURI(AUTHORITY, MemberColumns.TABLE_NAME + "/#", URI_TYPE_MEMBER_ID);

        URI_MATCHER.addURI(AUTHORITY, MeetingColumns.TABLE_NAME, URI_TYPE_MEETING);
        URI_MATCHER.addURI(AUTHORITY, MeetingColumns.TABLE_NAME + "/#", URI_TYPE_MEETING_ID);

        URI_MATCHER.addURI(AUTHORITY, MemberStatsColumns.VIEW_NAME, URI_TYPE_MEMBER_STATS);

    }

    private ScrumChatterDatabase mScrumChatterDatabase;

    @Override
    public boolean onCreate() {
        mScrumChatterDatabase = new ScrumChatterDatabase(getContext());
        return true;
    }

    @Override
    public String getType(Uri uri) {
        final int match = URI_MATCHER.match(uri);
        switch (match) {
            case URI_TYPE_TEAM:
                return TYPE_CURSOR_DIR + TeamColumns.TABLE_NAME;
            case URI_TYPE_TEAM_ID:
                return TYPE_CURSOR_ITEM + TeamColumns.TABLE_NAME;

            case URI_TYPE_MEETING_MEMBER:
                return TYPE_CURSOR_DIR + MeetingMemberColumns.TABLE_NAME;
            case URI_TYPE_MEETING_MEMBER_ID:
                return TYPE_CURSOR_ITEM + MeetingMemberColumns.TABLE_NAME;

            case URI_TYPE_MEMBER:
                return TYPE_CURSOR_DIR + MemberColumns.TABLE_NAME;
            case URI_TYPE_MEMBER_ID:
                return TYPE_CURSOR_ITEM + MemberColumns.TABLE_NAME;

            case URI_TYPE_MEETING:
                return TYPE_CURSOR_DIR + MeetingColumns.TABLE_NAME;
            case URI_TYPE_MEETING_ID:
                return TYPE_CURSOR_ITEM + MeetingColumns.TABLE_NAME;

            case URI_TYPE_MEMBER_STATS:
                return TYPE_CURSOR_ITEM + MemberStatsColumns.VIEW_NAME;

        }
        return null;
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        Log.d(TAG, "insert uri=" + uri + " values=" + values);
        final String table = uri.getLastPathSegment();
        SQLiteDatabase db = mScrumChatterDatabase.getWritableDatabase();
        final long rowId = db.insert(table, null, values);
        // When we insert a row into the meeting table, we have to add
        // all existing members to this meeting. To do this, we create
        // one row for each member into the meeting_member table for this team.
        if (table.equals(MeetingColumns.TABLE_NAME)) {
            int teamId = values.getAsInteger(MeetingColumns.TEAM_ID);
            Cursor members = db.query(MemberColumns.TABLE_NAME, new String[] { MemberColumns._ID }, MemberColumns.TEAM_ID + "=? AND " + MemberColumns.DELETED
                    + "=0 ", new String[] { String.valueOf(teamId) }, null, null, null);
            if (members != null) {
                ContentValues[] newMeetingMembers = new ContentValues[members.getCount()];
                if (members.moveToFirst()) {
                    int i = 0;
                    do {
                        long memberId = members.getLong(0);
                        values = new ContentValues();
                        values.put(MeetingMemberColumns.MEMBER_ID, memberId);
                        values.put(MeetingMemberColumns.MEETING_ID, rowId);
                        values.put(MeetingMemberColumns.DURATION, 0L);
                        newMeetingMembers[i++] = values;
                    } while (members.moveToNext());
                }
                bulkInsert(MeetingMemberColumns.CONTENT_URI, newMeetingMembers);
                members.close();
            }
        }
        if (rowId != -1 && !db.inTransaction()) notifyChange(uri);

        Uri result = uri.buildUpon().appendEncodedPath(String.valueOf(rowId)).build();
        Log.v(TAG, "Created row with uri " + result);
        return result;
    }

    @Override
    public int bulkInsert(Uri uri, ContentValues[] values) {
        Log.d(TAG, "bulkInsert uri=" + uri + " values.length=" + values.length);
        final String table = uri.getLastPathSegment();
        final SQLiteDatabase db = mScrumChatterDatabase.getWritableDatabase();
        int res = 0;
        db.beginTransaction();
        try {
            for (final ContentValues v : values) {
                final long id = db.insert(table, null, v);
                if (id != -1) {
                    res++;
                }
            }
            db.setTransactionSuccessful();
        } finally {
            db.endTransaction();
        }
        if (res != 0 && !db.inTransaction()) notifyChange(uri);

        return res;
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
        StatementParams params = getStatementParams(uri, selection);
        Log.d(TAG, "update uri=" + uri + " values=" + values + " selection=" + selection + ", selectionArgs = " + Arrays.toString(selectionArgs));
        SQLiteDatabase db = mScrumChatterDatabase.getWritableDatabase();
        final int res = db.update(params.table, values, params.selection, selectionArgs);
        if (res != 0 && !db.inTransaction()) notifyChange(uri);
        return res;
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        Log.d(TAG, "delete uri=" + uri + " selection=" + selection);
        StatementParams params = getStatementParams(uri, selection);
        SQLiteDatabase db = mScrumChatterDatabase.getWritableDatabase();
        final int res = db.delete(params.table, params.selection, selectionArgs);
        if (res != 0 && !db.inTransaction()) notifyChange(uri);
        return res;
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
        final String groupBy = uri.getQueryParameter(QUERY_GROUP_BY);
        Log.d(TAG,
                "query uri=" + uri + ", projection = " + Arrays.toString(projection) + " selection=" + selection + " selectionArgs = "
                        + Arrays.toString(selectionArgs) + " sortOrder=" + sortOrder + " groupBy=" + groupBy);
        final QueryParams queryParams = getQueryParams(uri, selection, selectionArgs);
        SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
        qb.setTables(queryParams.table);

        // @formatter:off
    final Cursor res = qb.query(
        mScrumChatterDatabase.getReadableDatabase(), projection,
        queryParams.selection, selectionArgs, groupBy, null,
        sortOrder == null ? queryParams.orderBy : sortOrder);
    // @formatter:on
        logCursor(res, selectionArgs);
        res.setNotificationUri(getContext().getContentResolver(), uri);

        return res;
    }

    /**
     * Perform all operations in a single transaction and notify all relevant URIs at the end. The {@link MemberStatsColumns#CONTENT_URI} uri is always notified
     * for a successful transaction.
     * 
     * @see android.content.ContentProvider#applyBatch(java.util.ArrayList)
     */
    @Override
    public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations) throws OperationApplicationException {
        Log.v(TAG, "applyBatch: " + operations);
        Set<Uri> urisToNotify = new HashSet<Uri>();
        for (ContentProviderOperation operation : operations)
            urisToNotify.add(operation.getUri());
        urisToNotify.add(MemberStatsColumns.CONTENT_URI);
        Log.v(TAG, "applyBatch: will notify these uris after persisting: " + urisToNotify);
        SQLiteDatabase db = mScrumChatterDatabase.getWritableDatabase();
        db.beginTransaction();
        try {
            ContentProviderResult[] result = super.applyBatch(operations);
            db.setTransactionSuccessful();
            for (Uri uri : urisToNotify)
                notifyChange(uri);
            return result;
        } finally {
            db.endTransaction();
        }
    }

    /**
     * Log the query of the given cursor.
     * 
     * @param cursor
     * @param selectionArgs
     */
    private void logCursor(Cursor cursor, String[] selectionArgs) {
        try {
            Field queryField = SQLiteCursor.class.getDeclaredField("mQuery");
            queryField.setAccessible(true);
            SQLiteQuery sqliteQuery = (SQLiteQuery) queryField.get((SQLiteCursor) cursor);
            Log.v(TAG, sqliteQuery.toString() + ": " + Arrays.toString(selectionArgs));
        } catch (Exception e) {
            Log.v(TAG, e.getMessage(), e);
        }
    }

    private void notifyChange(Uri uri) {
        String notify = uri.getQueryParameter(QUERY_NOTIFY);
        Log.v(TAG, "notifyChange: uri = " + uri + ", notify = " + notify);
        if (notify == null || "true".equals(notify)) {
            // Notify the uri which changed.
            Set<Uri> urisToNotify = new HashSet<Uri>();
            urisToNotify.add(uri);

            // Whether a meeting, meeting_member, or meeting table was
            // modified, update the member_stats view.
            urisToNotify.add(MemberStatsColumns.CONTENT_URI);

            // Notify other uris if they depend on the given uri which just
            // changed.
            int matchedId = URI_MATCHER.match(uri);
            // If a member changed, notify the the meeting_member uri.
            if (matchedId == URI_TYPE_MEMBER_ID || matchedId == URI_TYPE_MEMBER) {
                urisToNotify.add(MeetingMemberColumns.CONTENT_URI);
            }
            // If a meeting changed, notify the meeting_member uri, including
            // the meeting id in the uri to notify,
            // if the given uri is for a specific meeting.
            else if (matchedId == URI_TYPE_MEETING_ID || matchedId == URI_TYPE_MEETING) {
                Uri meetingMemberUriToNotify = MeetingMemberColumns.CONTENT_URI;
                // A specific meeting changed, notify meeting_member for that
                // meeting.
                if (matchedId == URI_TYPE_MEETING_ID) {
                    String meetingId = uri.getLastPathSegment();
                    meetingMemberUriToNotify = meetingMemberUriToNotify.buildUpon().appendPath(meetingId).build();
                }
                urisToNotify.add(meetingMemberUriToNotify);
            }

            // Notify all the relevant uris.
            for (Uri uriToNotify : urisToNotify) {
                Log.v(TAG, "notifyChange: notify uri " + uriToNotify);
                getContext().getContentResolver().notifyChange(uriToNotify, null);
            }
        }
    }

    /**
     * To be used for updates and deletes
     */
    private static class StatementParams {
        public String table;
        public String selection;

    }

    /**
     * To be used for queries
     */
    private static class QueryParams extends StatementParams {
        public String orderBy;
    }

    /**
     * Used for write operations (insert, update, delete).
     * 
     * Returns a StatementParams containing the table name and possibly a
     * selection, depending on whether a selection was provided by the user, and
     * if an id was provided in the Uri.
     * 
     * @param uri
     *            provided by the user of the ContentProvider. If the uri
     *            contains a path with an id, we will add the id to the
     *            selection.
     * @param selection
     *            provided by the user of the ContentProvider
     * @return the table and selection to use based on the uri and selection
     *         provided by the user of the ContentProvider.
     */
    private StatementParams getStatementParams(Uri uri, String selection) {
        StatementParams res = new StatementParams();
        String id = null;
        int matchedId = URI_MATCHER.match(uri);
        switch (matchedId) {
            case URI_TYPE_TEAM_ID:
                id = uri.getLastPathSegment();
            case URI_TYPE_TEAM:
                res.table = TeamColumns.TABLE_NAME;
                break;
            case URI_TYPE_MEETING_MEMBER_ID:
            case URI_TYPE_MEETING_MEMBER:
                res.table = MeetingMemberColumns.TABLE_NAME;
                break;
            case URI_TYPE_MEMBER_ID:
                id = uri.getLastPathSegment();
            case URI_TYPE_MEMBER:
                res.table = MemberColumns.TABLE_NAME;
                break;
            case URI_TYPE_MEETING_ID:
                id = uri.getLastPathSegment();
            case URI_TYPE_MEETING:
                res.table = MeetingColumns.TABLE_NAME;
                break;

            default:
                throw new IllegalArgumentException("The uri '" + uri + "' is not supported by this ContentProvider");
        }

        if (id != null) {
            if (selection != null) res.selection = BaseColumns._ID + "=" + id + " and (" + selection + ")";
            else
                res.selection = BaseColumns._ID + "=" + id;
        } else {
            res.selection = selection;
        }

        return res;
    }

    /**
     * Used for read operations (select).
     * 
     * @param uri
     *            provided by the user of the ContentProvider. If the uri
     *            contains a path with an id, we will add the id to the
     *            selection.
     * @param selection
     *            provided by the user of the ContentProvider
     * @return the full QueryParams based on the Uri and selection provided by
     *         the user of the ContentProvider.
     */
    private QueryParams getQueryParams(Uri uri, String selection, String[] selectionArgs) {
        QueryParams res = new QueryParams();
        String id = null;
        int matchedId = URI_MATCHER.match(uri);
        res.selection = selection;
        switch (matchedId) {
        // The meeting_member table is a join table between the meeting and
        // member tables.
        // This table does not have an _id field. If the Uri contains an id,
        // this will be used as the meeting id.
            case URI_TYPE_MEETING_MEMBER:
            case URI_TYPE_MEETING_MEMBER_ID:
                // The join contains the member, meeting_member, and meeting tables.
                res.table = MemberColumns.TABLE_NAME + " LEFT OUTER JOIN " + MeetingMemberColumns.TABLE_NAME + " ON " + MemberColumns.TABLE_NAME + "."
                        + MemberColumns._ID + " = " + MeetingMemberColumns.TABLE_NAME + "." + MeetingMemberColumns.MEMBER_ID + " LEFT OUTER JOIN "
                        + MeetingColumns.TABLE_NAME + " ON " + MeetingColumns.TABLE_NAME + "." + MeetingColumns._ID + " = " + MeetingMemberColumns.TABLE_NAME
                        + "." + MeetingMemberColumns.MEETING_ID;

                // If a specific meeting is specified, append a selection
                // on the meeting id to the end of the existing selection
                if (matchedId == URI_TYPE_MEETING_MEMBER_ID) {
                    String meetingId = uri.getLastPathSegment();
                    res.selection = MeetingMemberColumns.MEETING_ID + "=" + meetingId;
                    if (selection != null) res.selection = selection + " AND (" + res.selection + ") ";
                }
                res.orderBy = MemberColumns.NAME;
                break;

            case URI_TYPE_TEAM_ID:
                id = uri.getLastPathSegment();
            case URI_TYPE_TEAM:
                res.table = TeamColumns.TABLE_NAME;
                res.orderBy = TeamColumns.DEFAULT_ORDER;
                break;

            case URI_TYPE_MEMBER_ID:
                id = uri.getLastPathSegment();
            case URI_TYPE_MEMBER:
                res.table = MemberColumns.TABLE_NAME;
                res.orderBy = MemberColumns.DEFAULT_ORDER;
                break;

            case URI_TYPE_MEETING_ID:
                id = uri.getLastPathSegment();
            case URI_TYPE_MEETING:
                res.table = MeetingColumns.TABLE_NAME;
                res.orderBy = MeetingColumns.DEFAULT_ORDER;
                break;

            case URI_TYPE_MEMBER_STATS:
                res.table = MemberStatsColumns.VIEW_NAME;
                res.orderBy = MemberStatsColumns.DEFAULT_ORDER;
                break;

            default:
                throw new IllegalArgumentException("The uri '" + uri + "' is not supported by this ContentProvider");
        }

        if (id != null) {
            if (selection != null) res.selection = BaseColumns._ID + "=" + id + " and (" + selection + ")";
            else
                res.selection = BaseColumns._ID + "=" + id;
        }

        return res;
    }
}




Java Source Code List

ca.rmen.android.scrumchatter.Constants.java
ca.rmen.android.scrumchatter.about.AboutActivity.java
ca.rmen.android.scrumchatter.dialog.ChoiceDialogFragment.java
ca.rmen.android.scrumchatter.dialog.ConfirmDialogFragment.java
ca.rmen.android.scrumchatter.dialog.DialogFragmentFactory.java
ca.rmen.android.scrumchatter.dialog.DialogStyleHacks.java
ca.rmen.android.scrumchatter.dialog.InfoDialogFragment.java
ca.rmen.android.scrumchatter.dialog.InputDialogFragment.java
ca.rmen.android.scrumchatter.dialog.ProgressDialogFragment.java
ca.rmen.android.scrumchatter.export.DBExport.java
ca.rmen.android.scrumchatter.export.FileExport.java
ca.rmen.android.scrumchatter.export.MeetingExport.java
ca.rmen.android.scrumchatter.export.MeetingsExport.java
ca.rmen.android.scrumchatter.main.MainActivity.java
ca.rmen.android.scrumchatter.meeting.Meetings.java
ca.rmen.android.scrumchatter.meeting.detail.MeetingActivity.java
ca.rmen.android.scrumchatter.meeting.detail.MeetingCursorAdapter.java
ca.rmen.android.scrumchatter.meeting.detail.MeetingFragment.java
ca.rmen.android.scrumchatter.meeting.detail.MeetingPagerAdapter.java
ca.rmen.android.scrumchatter.meeting.detail.Meeting.java
ca.rmen.android.scrumchatter.meeting.list.MeetingsCursorAdapter.java
ca.rmen.android.scrumchatter.meeting.list.MeetingsListFragment.java
ca.rmen.android.scrumchatter.member.list.MembersCursorAdapter.java
ca.rmen.android.scrumchatter.member.list.MembersListFragment.java
ca.rmen.android.scrumchatter.member.list.Members.java
ca.rmen.android.scrumchatter.provider.DBImport.java
ca.rmen.android.scrumchatter.provider.MeetingColumns.java
ca.rmen.android.scrumchatter.provider.MeetingCursorWrapper.java
ca.rmen.android.scrumchatter.provider.MeetingMemberColumns.java
ca.rmen.android.scrumchatter.provider.MeetingMemberCursorWrapper.java
ca.rmen.android.scrumchatter.provider.MemberColumns.java
ca.rmen.android.scrumchatter.provider.MemberCursorWrapper.java
ca.rmen.android.scrumchatter.provider.MemberStatsColumns.java
ca.rmen.android.scrumchatter.provider.ScrumChatterDatabase.java
ca.rmen.android.scrumchatter.provider.ScrumChatterProvider.java
ca.rmen.android.scrumchatter.provider.TeamColumns.java
ca.rmen.android.scrumchatter.team.TeamArrayAdapter.java
ca.rmen.android.scrumchatter.team.Teams.java
ca.rmen.android.scrumchatter.util.IOUtils.java
ca.rmen.android.scrumchatter.util.TextUtils.java
ca.rmen.android.scrumchatter.util.ViewHolder.java