1/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.example.codelab.rssexample;
18
19import android.content.ContentProvider;
20import android.content.ContentProviderDatabaseHelper;
21import android.content.UriMatcher;
22import android.content.Context;
23import android.database.Cursor;
24import android.database.SQLException;
25import android.database.sqlite.SQLiteDatabase;
26import android.database.sqlite.SQLiteQueryBuilder;
27import android.net.Uri;
28import android.content.ContentValues;
29import android.text.TextUtils;
30
31import java.util.logging.Logger;
32
33// Content Provider for RSS feed information. Each row describes a single
34// RSS feed. See the public static constants at the end of this class
35// to learn what each record contains.
36public class RssContentProvider extends ContentProvider {
37    private Logger mLogger = Logger.getLogger("com.example.codelab.rssexample");
38    private SQLiteDatabase mDb;
39    private DatabaseHelper mDbHelper = new DatabaseHelper();
40    private static final String DATABASE_NAME = "rssitems.db";
41    private static final String DATABASE_TABLE_NAME = "rssItems";
42    private static final int DB_VERSION = 1;
43    private static final int ALL_MESSAGES = 1;
44    private static final int SPECIFIC_MESSAGE = 2;
45
46    // Set up our URL matchers to help us determine what an
47    // incoming URI parameter is.
48    private static final UriMatcher URI_MATCHER;
49    static{
50        URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
51        URI_MATCHER.addURI("my_rss_item", "rssitem", ALL_MESSAGES);
52        URI_MATCHER.addURI("my_rss_item", "rssitem/#", SPECIFIC_MESSAGE);
53    }
54
55    // Here's the public URI used to query for RSS items.
56    public static final Uri CONTENT_URI = Uri.parse( "content://my_rss_item/rssitem");
57
58    // Here are our column name constants, used to query for field values.
59    public static final String ID = "_id";
60    public static final String URL = "url";
61    public static final String TITLE = "title";
62    public static final String HAS_BEEN_READ = "hasbeenread";
63    public static final String CONTENT = "rawcontent";
64    public static final String LAST_UPDATED = "lastupdated";
65    public static final String DEFAULT_SORT_ORDER = TITLE + " DESC";
66
67    // Database creation/version management helper.
68    // Create it statically because we don't need to have customized instances.
69    private static class DatabaseHelper extends ContentProviderDatabaseHelper{
70
71        @Override
72        public void onCreate(SQLiteDatabase db){
73            try{
74                String sql = "CREATE TABLE " + DATABASE_TABLE_NAME + "(" +
75                ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
76                URL + " TEXT," +
77                TITLE + " TEXT," +
78                HAS_BEEN_READ + " BOOLEAN DEFAULT 0," +
79                CONTENT + " TEXT," +
80                LAST_UPDATED + " INTEGER DEFAULT 0);";
81                Logger.getLogger("com.example.codelab.rssexample").info("DatabaseHelper.onCreate(): SQL statement: " + sql);
82                db.execSQL(sql);
83                Logger.getLogger("com.example.codelab.rssexample").info("DatabaseHelper.onCreate(): Created a database");
84            } catch (SQLException e) {
85                Logger.getLogger("com.example.codelab.rssexample").warning("DatabaseHelper.onCreate(): Couldn't create a database!");
86            }
87        }
88
89        @Override
90        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
91            // Don't have any upgrades yet, so if this gets called for some reason we'll
92            // just drop the existing table, and recreate the database with the
93            // standard method.
94            db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE_NAME + ";");
95
96        }
97    }
98
99    @Override
100    public boolean onCreate() {
101        // First we need to open the database. If this is our first time,
102        // the attempt to retrieve a database will throw
103        // FileNotFoundException, and we will then create the database.
104        final Context con = getContext();
105        try{
106            mDb = mDbHelper.openDatabase(getContext(), DATABASE_NAME, null, DB_VERSION);
107            mLogger.info("RssContentProvider.onCreate(): Opened a database");
108        } catch (Exception ex) {
109              return false;
110        }
111        if(mDb == null){
112            return false;
113        } else {
114            return true;
115        }
116    }
117
118    // Convert the URI into a custom MIME type.
119    // Our UriMatcher will parse the URI to decide whether the
120    // URI is for a single item or a list.
121    @Override
122    public String getType(Uri uri) {
123        switch (URI_MATCHER.match(uri)){
124            case ALL_MESSAGES:
125                return "vnd.android.cursor.dir/rssitem"; // List of items.
126            case SPECIFIC_MESSAGE:
127                return "vnd.android.cursor.item/rssitem";     // Specific item.
128            default:
129                return null;
130        }
131    }
132
133    @Override
134    public Cursor query(Uri uri, String[] projection, String selection,
135            String[] selectionArgs, String groupBy, String having, String sortOrder) {
136        // We won't bother checking the validity of params here, but you should!
137
138        // SQLiteQueryBuilder is the helper class that creates the
139        // proper SQL syntax for us.
140        SQLiteQueryBuilder qBuilder = new SQLiteQueryBuilder();
141
142        // Set the table we're querying.
143        qBuilder.setTables(DATABASE_TABLE_NAME);
144
145        // If the query ends in a specific record number, we're
146        // being asked for a specific record, so set the
147        // WHERE clause in our query.
148        if((URI_MATCHER.match(uri)) == SPECIFIC_MESSAGE){
149            qBuilder.appendWhere("_id=" + uri.getPathLeafId());
150        }
151
152        // Set sort order. If none specified, use default.
153        if(TextUtils.isEmpty(sortOrder)){
154            sortOrder = DEFAULT_SORT_ORDER;
155        }
156
157        // Make the query.
158        Cursor c = qBuilder.query(mDb,
159                projection,
160                selection,
161                selectionArgs,
162                groupBy,
163                having,
164                sortOrder);
165        c.setNotificationUri(getContext().getContentResolver(), uri);
166        return c;
167    }
168
169    @Override
170    public int update(Uri uri, ContentValues values, String whereClause) {
171        // NOTE Argument checking code omitted. Check your parameters!
172        int updateCount = mDb.update(DATABASE_TABLE_NAME, values, whereClause);
173
174        // Notify any listeners and return the updated row count.
175        getContext().getContentResolver().notifyUpdate(uri, null);
176        return updateCount;
177    }
178
179    @Override
180    public Uri insert(Uri requestUri, ContentValues initialValues) {
181        // NOTE Argument checking code omitted. Check your parameters! Check that
182        // your row addition request succeeded!
183
184       long rowId = -1;
185       rowId = mDb.insert(DATABASE_TABLE_NAME, "rawcontent", initialValues);
186       Uri newUri = CONTENT_URI.addId(rowId);
187
188       // Notify any listeners and return the URI of the new row.
189       getContext().getContentResolver().notifyInsert(CONTENT_URI, null);
190       return newUri;
191    }
192
193    @Override
194    public int delete(Uri uri, String where) {
195        // NOTE Argument checking code omitted. Check your parameters!
196        int rowCount = mDb.delete(DATABASE_TABLE_NAME, ID + " = " + uri.getPathLeafId());
197
198        // Notify any listeners and return the deleted row count.
199        getContext().getContentResolver().notifyDelete(uri, null);
200        return rowCount;
201    }
202}
203