diff --git a/.gitignore b/.gitignore index 4ad3c195d..ef0e7689d 100644 --- a/.gitignore +++ b/.gitignore @@ -28,4 +28,7 @@ Thumbs.db /private # Local files -/captures \ No newline at end of file +/captures + +# JRE error dumps +hs_err_*.log \ No newline at end of file diff --git a/build.gradle b/build.gradle index d986c252d..7c1edd996 100644 --- a/build.gradle +++ b/build.gradle @@ -37,7 +37,7 @@ subprojects { SupportLib : '25.2.0', MariotakuCommons: '0.9.11', RestFu : '0.9.35', - ObjectCursor : '0.9.13', + ObjectCursor : '0.9.16', PlayServices : '10.2.0', MapsUtils : '0.4.4', Crashlyrics : '2.6.6', diff --git a/twidere/src/androidTest/kotlin/org/mariotaku/twidere/extension/ViewExtensionsKtTest.kt b/twidere/src/androidTest/kotlin/org/mariotaku/twidere/extension/ViewExtensionsKtTest.kt index 6dc426088..24883f208 100644 --- a/twidere/src/androidTest/kotlin/org/mariotaku/twidere/extension/ViewExtensionsKtTest.kt +++ b/twidere/src/androidTest/kotlin/org/mariotaku/twidere/extension/ViewExtensionsKtTest.kt @@ -20,6 +20,7 @@ package org.mariotaku.twidere.extension import android.support.test.runner.AndroidJUnit4 +import org.junit.Test import org.junit.runner.RunWith /** @@ -28,4 +29,9 @@ import org.junit.runner.RunWith @RunWith(AndroidJUnit4::class) class ViewExtensionsKtTest { + @Test + fun testEmpty() { + + } + } \ No newline at end of file diff --git a/twidere/src/androidTest/kotlin/org/mariotaku/twidere/util/ObjectCursorTest.kt b/twidere/src/androidTest/kotlin/org/mariotaku/twidere/util/ObjectCursorTest.kt new file mode 100644 index 000000000..84cf97285 --- /dev/null +++ b/twidere/src/androidTest/kotlin/org/mariotaku/twidere/util/ObjectCursorTest.kt @@ -0,0 +1,47 @@ +/* + * Twidere - Twitter client for Android + * + * Copyright (C) 2012-2017 Mariotaku Lee + * + * This program 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. + * + * This program 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 this program. If not, see . + */ + +package org.mariotaku.twidere.util + +import android.database.MatrixCursor +import android.support.test.runner.AndroidJUnit4 +import org.junit.Test +import org.junit.runner.RunWith +import org.mariotaku.library.objectcursor.ObjectCursor +import org.mariotaku.twidere.model.FiltersData +import org.mariotaku.twidere.model.ParcelableStatus + +/** + * Created by mariotaku on 2017/3/5. + */ +@RunWith(AndroidJUnit4::class) +class ObjectCursorTest { + + @Test + fun testSimple() { + val cur = MatrixCursor(emptyArray(), 0) + ObjectCursor.indicesFrom(cur, ParcelableStatus::class.java) + } + + @Test + fun testMemberClass() { + val cur = MatrixCursor(emptyArray(), 0) + ObjectCursor.indicesFrom(cur, FiltersData.BaseItem::class.java) + } +} diff --git a/twidere/src/main/java/org/mariotaku/twidere/loader/ExtendedObjectCursorLoader.java b/twidere/src/main/java/org/mariotaku/twidere/loader/ExtendedObjectCursorLoader.java index dba0fd5ce..8334d9ee3 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/loader/ExtendedObjectCursorLoader.java +++ b/twidere/src/main/java/org/mariotaku/twidere/loader/ExtendedObjectCursorLoader.java @@ -22,7 +22,6 @@ package org.mariotaku.twidere.loader; import android.content.Context; import android.net.Uri; -import org.mariotaku.library.objectcursor.ObjectCursor; import org.mariotaku.twidere.loader.iface.IExtendedLoader; /** @@ -30,9 +29,8 @@ import org.mariotaku.twidere.loader.iface.IExtendedLoader; */ public class ExtendedObjectCursorLoader extends ObjectCursorLoader implements IExtendedLoader { - public ExtendedObjectCursorLoader(Context context, Class> indicesClass, - Uri uri, String[] projection, String selection, String[] selectionArgs, - String sortOrder, boolean fromUser) { + public ExtendedObjectCursorLoader(Context context, Class indicesClass, Uri uri, + String[] projection, String selection, String[] selectionArgs, String sortOrder, boolean fromUser) { super(context, indicesClass, uri, projection, selection, selectionArgs, sortOrder); setFromUser(fromUser); } diff --git a/twidere/src/main/java/org/mariotaku/twidere/loader/ObjectCursorLoader.java b/twidere/src/main/java/org/mariotaku/twidere/loader/ObjectCursorLoader.java index 650202e72..2238bbd77 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/loader/ObjectCursorLoader.java +++ b/twidere/src/main/java/org/mariotaku/twidere/loader/ObjectCursorLoader.java @@ -30,7 +30,6 @@ import org.mariotaku.library.objectcursor.ObjectCursor; import java.io.FileDescriptor; import java.io.PrintWriter; -import java.lang.reflect.InvocationTargetException; import java.util.Arrays; import java.util.List; @@ -40,7 +39,7 @@ import java.util.List; public class ObjectCursorLoader extends FixedAsyncTaskLoader> { final ForceLoadContentObserver mObserver; - final Class> mIndicesClass; + final Class mObjectClass; Uri mUri; String[] mProjection; @@ -71,17 +70,7 @@ public class ObjectCursorLoader extends FixedAsyncTaskLoader> { @SuppressWarnings("TryWithIdenticalCatches") @NonNull private ObjectCursor.CursorIndices createIndices(final Cursor cursor) { - try { - return mIndicesClass.getConstructor(Cursor.class).newInstance(cursor); - } catch (NoSuchMethodException e) { - throw new RuntimeException(e); - } catch (InvocationTargetException e) { - throw new RuntimeException(e); - } catch (InstantiationException e) { - throw new RuntimeException(e); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } + return ObjectCursor.indicesFrom(cursor, mObjectClass); } /* Runs on the UI thread */ @@ -112,9 +101,9 @@ public class ObjectCursorLoader extends FixedAsyncTaskLoader> { * calls to {@link #setUri(Uri)}, {@link #setSelection(String)}, etc * to specify the query to perform. */ - public ObjectCursorLoader(Context context, Class> indicesClass) { + public ObjectCursorLoader(Context context, Class objectClass) { super(context); - mIndicesClass = indicesClass; + mObjectClass = objectClass; mObserver = new ForceLoadContentObserver(); } @@ -124,11 +113,10 @@ public class ObjectCursorLoader extends FixedAsyncTaskLoader> { * ContentResolver.query()} for documentation on the meaning of the * parameters. These will be passed as-is to that call. */ - public ObjectCursorLoader(Context context, Class> indicesClass, - Uri uri, String[] projection, String selection, - String[] selectionArgs, String sortOrder) { + public ObjectCursorLoader(Context context, Class objectClass, Uri uri, String[] projection, + String selection, String[] selectionArgs, String sortOrder) { super(context); - mIndicesClass = indicesClass; + mObjectClass = objectClass; mObserver = new ForceLoadContentObserver(); mUri = uri; mProjection = projection; diff --git a/twidere/src/main/java/org/mariotaku/twidere/util/DataImportExportUtils.java b/twidere/src/main/java/org/mariotaku/twidere/util/DataImportExportUtils.java index 4e7738717..459c81af4 100644 --- a/twidere/src/main/java/org/mariotaku/twidere/util/DataImportExportUtils.java +++ b/twidere/src/main/java/org/mariotaku/twidere/util/DataImportExportUtils.java @@ -43,13 +43,7 @@ import org.mariotaku.twidere.annotation.Preference; import org.mariotaku.twidere.annotation.PreferenceType; import org.mariotaku.twidere.constant.SharedPreferenceConstants; import org.mariotaku.twidere.model.FiltersData; -import org.mariotaku.twidere.model.FiltersData$BaseItemCursorIndices; -import org.mariotaku.twidere.model.FiltersData$BaseItemValuesCreator; -import org.mariotaku.twidere.model.FiltersData$UserItemCursorIndices; -import org.mariotaku.twidere.model.FiltersData$UserItemValuesCreator; import org.mariotaku.twidere.model.Tab; -import org.mariotaku.twidere.model.TabCursorIndices; -import org.mariotaku.twidere.model.TabValuesCreator; import org.mariotaku.twidere.provider.TwidereDataStore.Filters; import org.mariotaku.twidere.provider.TwidereDataStore.Tabs; import org.mariotaku.twidere.util.content.ContentResolverUtils; @@ -115,13 +109,13 @@ public class DataImportExportUtils implements Constants { final ContentResolver cr = context.getContentResolver(); data.setUsers(queryAll(cr, Filters.Users.CONTENT_URI, Filters.Users.COLUMNS, - FiltersData$UserItemCursorIndices.class)); + FiltersData.UserItem.class)); data.setKeywords(queryAll(cr, Filters.Keywords.CONTENT_URI, Filters.Keywords.COLUMNS, - FiltersData$BaseItemCursorIndices.class)); + FiltersData.BaseItem.class)); data.setSources(queryAll(cr, Filters.Sources.CONTENT_URI, Filters.Sources.COLUMNS, - FiltersData$BaseItemCursorIndices.class)); + FiltersData.BaseItem.class)); data.setLinks(queryAll(cr, Filters.Links.CONTENT_URI, Filters.Links.COLUMNS, - FiltersData$BaseItemCursorIndices.class)); + FiltersData.BaseItem.class)); exportItem(zos, ENTRY_FILTERS, FiltersData.class, data); } if (hasFlag(flags, FLAG_TABS)) { @@ -131,7 +125,7 @@ public class DataImportExportUtils implements Constants { if (c != null) { final List tabs = new ArrayList<>(c.getCount()); try { - TabCursorIndices ci = new TabCursorIndices(c); + final ObjectCursor.CursorIndices ci = ObjectCursor.indicesFrom(c, Tab.class); c.moveToFirst(); while (!c.isAfterLast()) { tabs.add(ci.newObject(c)); @@ -152,16 +146,11 @@ public class DataImportExportUtils implements Constants { } private static List queryAll(ContentResolver cr, Uri uri, String[] projection, - Class> cls) throws IOException { + Class cls) throws IOException { Cursor c = cr.query(uri, projection, null, null, null); if (c == null) return null; try { - final ObjectCursor.CursorIndices ci; - try { - ci = cls.getConstructor(Cursor.class).newInstance(c); - } catch (Exception e) { - throw new RuntimeException(e); - } + final ObjectCursor.CursorIndices ci = ObjectCursor.indicesFrom(c, cls); List items = new ArrayList<>(c.getCount()); c.moveToFirst(); while (!c.isAfterLast()) { @@ -252,31 +241,36 @@ public class DataImportExportUtils implements Constants { void insertBase(ContentResolver cr, Uri uri, List items) throws IOException { if (items == null) return; + final ObjectCursor.ValuesCreator baseItemCreator = + ObjectCursor.valuesCreatorFrom(FiltersData.BaseItem.class); List values = new ArrayList<>(items.size()); for (FiltersData.BaseItem item : items) { - values.add(FiltersData$BaseItemValuesCreator.create(item)); + values.add(baseItemCreator.create(item)); } ContentResolverUtils.bulkInsert(cr, uri, values); } void insertUser(ContentResolver cr, Uri uri, List items) throws IOException { if (items == null) return; + final ObjectCursor.ValuesCreator userItemCreator = + ObjectCursor.valuesCreatorFrom(FiltersData.UserItem.class); List values = new ArrayList<>(items.size()); for (FiltersData.UserItem item : items) { - values.add(FiltersData$UserItemValuesCreator.create(item)); + values.add(userItemCreator.create(item)); } ContentResolverUtils.bulkInsert(cr, uri, values); } }); } if (hasFlag(flags, FLAG_TABS)) { + final ObjectCursor.ValuesCreator creator = ObjectCursor.valuesCreatorFrom(Tab.class); importItemsList(context, zipFile, ENTRY_TABS, Tab.class, new ContentResolverProcessStrategy>() { @Override public boolean importItem(ContentResolver cr, List items) throws IOException { if (items == null) return false; List values = new ArrayList<>(items.size()); for (Tab item : items) { - values.add(TabValuesCreator.create(item)); + values.add(creator.create(item)); } cr.delete(Tabs.CONTENT_URI, null, null); ContentResolverUtils.bulkInsert(cr, Tabs.CONTENT_URI, values); @@ -292,8 +286,8 @@ public class DataImportExportUtils implements Constants { } private static void importSharedPreferencesData(@NonNull final ZipFile zipFile, @NonNull final Context context, - @NonNull final String preferencesName, @NonNull final String entryName, - @NonNull final SharedPreferencesProcessStrategy strategy) throws IOException { + @NonNull final String preferencesName, @NonNull final String entryName, + @NonNull final SharedPreferencesProcessStrategy strategy) throws IOException { final ZipEntry entry = zipFile.getEntry(entryName); if (entry == null) return; final JsonParser jsonParser = LoganSquare.JSON_FACTORY.createParser(zipFile.getInputStream(entry)); @@ -314,8 +308,8 @@ public class DataImportExportUtils implements Constants { } private static void exportSharedPreferencesData(@NonNull final ZipOutputStream zos, final Context context, - @NonNull final String preferencesName, @NonNull final String entryName, - @NonNull final SharedPreferencesProcessStrategy strategy) throws IOException { + @NonNull final String preferencesName, @NonNull final String entryName, + @NonNull final SharedPreferencesProcessStrategy strategy) throws IOException { final SharedPreferences preferences = context.getSharedPreferences(preferencesName, Context.MODE_PRIVATE); final Map map = preferences.getAll(); zos.putNextEntry(new ZipEntry(entryName)); @@ -330,10 +324,10 @@ public class DataImportExportUtils implements Constants { } private static void importItemsList(@NonNull final Context context, - @NonNull final ZipFile zipFile, - @NonNull final String entryName, - @NonNull final Class itemCls, - @NonNull final ContentResolverProcessStrategy> strategy) + @NonNull final ZipFile zipFile, + @NonNull final String entryName, + @NonNull final Class itemCls, + @NonNull final ContentResolverProcessStrategy> strategy) throws IOException { final ZipEntry entry = zipFile.getEntry(entryName); if (entry == null) return; @@ -344,9 +338,9 @@ public class DataImportExportUtils implements Constants { private static void exportItemsList(@NonNull final ZipOutputStream zos, - @NonNull final String entryName, - @NonNull final Class itemCls, - @NonNull final List itemList) throws IOException { + @NonNull final String entryName, + @NonNull final Class itemCls, + @NonNull final List itemList) throws IOException { zos.putNextEntry(new ZipEntry(entryName)); final JsonGenerator jsonGenerator = LoganSquare.JSON_FACTORY.createGenerator(zos); LoganSquareMapperFinder.mapperFor(itemCls).serialize(itemList, jsonGenerator); @@ -355,10 +349,10 @@ public class DataImportExportUtils implements Constants { } private static void importItem(@NonNull final Context context, - @NonNull final ZipFile zipFile, - @NonNull final String entryName, - @NonNull final Class itemCls, - @NonNull final ContentResolverProcessStrategy strategy) + @NonNull final ZipFile zipFile, + @NonNull final String entryName, + @NonNull final Class itemCls, + @NonNull final ContentResolverProcessStrategy strategy) throws IOException { final ZipEntry entry = zipFile.getEntry(entryName); if (entry == null) return; @@ -369,9 +363,9 @@ public class DataImportExportUtils implements Constants { private static void exportItem(@NonNull final ZipOutputStream zos, - @NonNull final String entryName, - @NonNull final Class itemCls, - @NonNull final T item) throws IOException { + @NonNull final String entryName, + @NonNull final Class itemCls, + @NonNull final T item) throws IOException { zos.putNextEntry(new ZipEntry(entryName)); final JsonGenerator jsonGenerator = LoganSquare.JSON_FACTORY.createGenerator(zos); LoganSquareMapperFinder.mapperFor(itemCls).serialize(item, jsonGenerator, true); diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/activity/ComposeActivity.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/activity/ComposeActivity.kt index 64a5ca48a..1ca7a4153 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/activity/ComposeActivity.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/activity/ComposeActivity.kt @@ -64,6 +64,7 @@ import org.mariotaku.abstask.library.AbstractTask import org.mariotaku.abstask.library.TaskStarter import org.mariotaku.kpreferences.get import org.mariotaku.ktextension.* +import org.mariotaku.library.objectcursor.ObjectCursor import org.mariotaku.pickncrop.library.MediaPickerActivity import org.mariotaku.twidere.Constants.* import org.mariotaku.twidere.R @@ -452,7 +453,7 @@ class ComposeActivity : BaseActivity(), OnMenuItemClickListener, OnClickListener this.inReplyToStatus = this@ComposeActivity.inReplyToStatus this.isPossiblySensitive = this@ComposeActivity.possiblySensitive } - val values = DraftValuesCreator.create(draft) + val values = ObjectCursor.valuesCreatorFrom(Draft::class.java).create(draft) val draftUri = contentResolver.insert(Drafts.CONTENT_URI, values) displayNewDraftNotification(text, draftUri) return draftUri diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/activity/DataExportActivity.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/activity/DataExportActivity.kt index f6ea00713..878ae2df4 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/activity/DataExportActivity.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/activity/DataExportActivity.kt @@ -82,16 +82,20 @@ class DataExportActivity : BaseActivity(), DataExportImportTypeSelectorDialogFra } } - internal class ExportSettingsTask(private val activity: DataExportActivity, private val mPath: String?, private val mFlags: Int) : AsyncTask() { + internal class ExportSettingsTask( + private val activity: DataExportActivity, + private val path: String?, + private val flags: Int + ) : AsyncTask() { override fun doInBackground(vararg params: Any): Boolean? { - if (mPath == null) return false + if (path == null) return false val sdf = SimpleDateFormat("yyyy-MM-dd_HH-mm-ss", Locale.US) val fileName = String.format("Twidere_Settings_%s.zip", sdf.format(Date())) - val file = File(mPath, fileName) + val file = File(path, fileName) file.delete() try { - DataImportExportUtils.exportData(activity, file, mFlags) + DataImportExportUtils.exportData(activity, file, flags) return true } catch (e: IOException) { Log.w(LOGTAG, e) diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/adapter/DraftsAdapter.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/adapter/DraftsAdapter.kt index 1dcd984c1..7204c3994 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/adapter/DraftsAdapter.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/adapter/DraftsAdapter.kt @@ -26,14 +26,16 @@ import android.view.View import android.view.ViewGroup import com.bumptech.glide.RequestManager import org.mariotaku.kpreferences.get +import org.mariotaku.library.objectcursor.ObjectCursor import org.mariotaku.twidere.R import org.mariotaku.twidere.constant.mediaPreviewStyleKey import org.mariotaku.twidere.extension.model.getActionName import org.mariotaku.twidere.model.Draft -import org.mariotaku.twidere.model.DraftCursorIndices import org.mariotaku.twidere.model.draft.StatusObjectExtras import org.mariotaku.twidere.model.util.ParcelableMediaUtils -import org.mariotaku.twidere.util.* +import org.mariotaku.twidere.util.DataStoreUtils +import org.mariotaku.twidere.util.SharedPreferencesWrapper +import org.mariotaku.twidere.util.Utils import org.mariotaku.twidere.util.dagger.GeneralComponentHelper import org.mariotaku.twidere.view.holder.DraftViewHolder import javax.inject.Inject @@ -53,7 +55,7 @@ class DraftsAdapter( field = value notifyDataSetChanged() } - private var indices: DraftCursorIndices? = null + private var indices: ObjectCursor.CursorIndices? = null init { GeneralComponentHelper.build(context).inject(this) @@ -122,9 +124,7 @@ class DraftsAdapter( override fun swapCursor(c: Cursor?): Cursor? { val old = super.swapCursor(c) - if (c != null) { - indices = DraftCursorIndices(c) - } + indices = c?.let { ObjectCursor.indicesFrom(it, Draft::class.java) } return old } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/adapter/UserAutoCompleteAdapter.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/adapter/UserAutoCompleteAdapter.kt index 3b02d013d..785a1d7e7 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/adapter/UserAutoCompleteAdapter.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/adapter/UserAutoCompleteAdapter.kt @@ -29,6 +29,7 @@ import android.view.View import android.widget.TextView import com.bumptech.glide.RequestManager import org.mariotaku.kpreferences.get +import org.mariotaku.library.objectcursor.ObjectCursor import org.mariotaku.sqliteqb.library.Columns import org.mariotaku.sqliteqb.library.Expression import org.mariotaku.sqliteqb.library.OrderBy @@ -36,10 +37,9 @@ import org.mariotaku.twidere.R import org.mariotaku.twidere.constant.displayProfileImageKey import org.mariotaku.twidere.constant.profileImageStyleKey import org.mariotaku.twidere.extension.loadProfileImage -import org.mariotaku.twidere.model.ParcelableUserCursorIndices +import org.mariotaku.twidere.model.ParcelableUser import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.provider.TwidereDataStore.CachedUsers -import org.mariotaku.twidere.util.MediaLoaderWrapper import org.mariotaku.twidere.util.SharedPreferencesWrapper import org.mariotaku.twidere.util.UserColorNameManager import org.mariotaku.twidere.util.Utils @@ -61,7 +61,7 @@ class UserAutoCompleteAdapter( private val displayProfileImage: Boolean private var profileImageStyle: Int - private var indices: ParcelableUserCursorIndices? = null + private var indices: ObjectCursor.CursorIndices? = null var accountKey: UserKey? = null @@ -79,11 +79,11 @@ class UserAutoCompleteAdapter( icon.style = profileImageStyle - text1.text = userColorNameManager.getUserNickname(cursor.getString(indices.key), cursor.getString(indices.name)) + text1.text = userColorNameManager.getUserNickname(cursor.getString(indices[CachedUsers.USER_KEY]), cursor.getString(indices[CachedUsers.NAME])) @SuppressLint("SetTextI18n") - text2.text = "@${cursor.getString(indices.screen_name)}" + text2.text = "@${cursor.getString(indices[CachedUsers.SCREEN_NAME])}" if (displayProfileImage) { - val profileImageUrl = cursor.getString(indices.profile_image_url) + val profileImageUrl = cursor.getString(indices[CachedUsers.PROFILE_IMAGE_URL]) requestManager.loadProfileImage(context, profileImageUrl, profileImageStyle).into(icon) } else { //TODO cancel image load @@ -101,7 +101,7 @@ class UserAutoCompleteAdapter( } override fun convertToString(cursor: Cursor?): CharSequence { - return cursor!!.getString(indices!!.screen_name) + return cursor!!.getString(indices!![CachedUsers.SCREEN_NAME]) } override fun runQueryOnBackgroundThread(constraint: CharSequence): Cursor? { @@ -127,9 +127,7 @@ class UserAutoCompleteAdapter( } override fun swapCursor(cursor: Cursor?): Cursor? { - if (cursor != null) { - indices = ParcelableUserCursorIndices(cursor) - } + indices = cursor?.let { ObjectCursor.indicesFrom(it, ParcelableUser::class.java) } return super.swapCursor(cursor) } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/extension/model/FiltersDataExtensions.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/extension/model/FiltersDataExtensions.kt index 71dc082af..361293269 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/extension/model/FiltersDataExtensions.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/extension/model/FiltersDataExtensions.kt @@ -5,8 +5,10 @@ import android.net.Uri import org.mariotaku.ktextension.addAllEnhanced import org.mariotaku.ktextension.isNullOrEmpty import org.mariotaku.ktextension.map +import org.mariotaku.library.objectcursor.ObjectCursor import org.mariotaku.sqliteqb.library.Expression -import org.mariotaku.twidere.model.* +import org.mariotaku.twidere.model.FiltersData +import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.provider.TwidereDataStore.Filters import org.mariotaku.twidere.util.content.ContentResolverUtils import org.xmlpull.v1.XmlPullParser @@ -24,7 +26,8 @@ fun FiltersData.read(cr: ContentResolver, loadSubscription: Boolean = false) { val c = cr.query(uri, Filters.COLUMNS, where, null, null) ?: return null @Suppress("ConvertTryFinallyToUseCall") try { - return c.map(`FiltersData$BaseItemCursorIndices`(c)) + val indices = ObjectCursor.indicesFrom(c, FiltersData.BaseItem::class.java) + return c.map(indices) } finally { c.close() } @@ -34,7 +37,8 @@ fun FiltersData.read(cr: ContentResolver, loadSubscription: Boolean = false) { val c = cr.query(Filters.Users.CONTENT_URI, Filters.Users.COLUMNS, where, null, null) ?: return@run null @Suppress("ConvertTryFinallyToUseCall") try { - return@run c.map(`FiltersData$UserItemCursorIndices`(c)) + val indices = ObjectCursor.indicesFrom(c, FiltersData.UserItem::class.java) + return@run c.map(indices) } finally { c.close() } @@ -45,33 +49,31 @@ fun FiltersData.read(cr: ContentResolver, loadSubscription: Boolean = false) { } fun FiltersData.write(cr: ContentResolver, deleteOld: Boolean = true) { + val baseCreator = ObjectCursor.valuesCreatorFrom(FiltersData.BaseItem::class.java) + val userCreator = ObjectCursor.valuesCreatorFrom(FiltersData.UserItem::class.java) if (users != null) { if (deleteOld) { cr.delete(Filters.Users.CONTENT_URI, null, null) } - ContentResolverUtils.bulkInsert(cr, Filters.Users.CONTENT_URI, - users.map(`FiltersData$UserItemValuesCreator`::create)) + ContentResolverUtils.bulkInsert(cr, Filters.Users.CONTENT_URI, users.map(userCreator::create)) } if (keywords != null) { if (deleteOld) { cr.delete(Filters.Keywords.CONTENT_URI, null, null) } - ContentResolverUtils.bulkInsert(cr, Filters.Keywords.CONTENT_URI, - keywords.map(`FiltersData$BaseItemValuesCreator`::create)) + ContentResolverUtils.bulkInsert(cr, Filters.Keywords.CONTENT_URI, keywords.map(baseCreator::create)) } if (sources != null) { if (deleteOld) { cr.delete(Filters.Sources.CONTENT_URI, null, null) } - ContentResolverUtils.bulkInsert(cr, Filters.Sources.CONTENT_URI, - sources.map(`FiltersData$BaseItemValuesCreator`::create)) + ContentResolverUtils.bulkInsert(cr, Filters.Sources.CONTENT_URI, sources.map(baseCreator::create)) } if (links != null) { if (deleteOld) { cr.delete(Filters.Links.CONTENT_URI, null, null) } - ContentResolverUtils.bulkInsert(cr, Filters.Links.CONTENT_URI, - links.map(`FiltersData$BaseItemValuesCreator`::create)) + ContentResolverUtils.bulkInsert(cr, Filters.Links.CONTENT_URI, links.map(baseCreator::create)) } } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/CursorActivitiesFragment.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/CursorActivitiesFragment.kt index d511eea9a..81805c97a 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/CursorActivitiesFragment.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/CursorActivitiesFragment.kt @@ -339,7 +339,9 @@ abstract class CursorActivitiesFragment : AbsActivitiesFragment() { class CursorActivitiesLoader(context: Context, uri: Uri, projection: Array, selection: String, selectionArgs: Array, - sortOrder: String, fromUser: Boolean) : ExtendedObjectCursorLoader(context, ParcelableActivityCursorIndices::class.java, uri, projection, selection, selectionArgs, sortOrder, fromUser) { + sortOrder: String, fromUser: Boolean + ) : ExtendedObjectCursorLoader(context, ParcelableActivity::class.java, uri, + projection, selection, selectionArgs, sortOrder, fromUser) { override fun createObjectCursor(cursor: Cursor, indices: ObjectCursor.CursorIndices): ObjectCursor { val filteredUserIds = DataStoreUtils.getFilteredUserIds(context) diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/CursorStatusesFragment.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/CursorStatusesFragment.kt index bc04d1c3d..458bb841c 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/CursorStatusesFragment.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/CursorStatusesFragment.kt @@ -43,7 +43,10 @@ import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter.IndicatorPosition import org.mariotaku.twidere.constant.IntentConstants.EXTRA_FROM_USER import org.mariotaku.twidere.loader.ExtendedObjectCursorLoader -import org.mariotaku.twidere.model.* +import org.mariotaku.twidere.model.ParameterizedExpression +import org.mariotaku.twidere.model.ParcelableStatus +import org.mariotaku.twidere.model.SimpleRefreshTaskParam +import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.event.* import org.mariotaku.twidere.provider.TwidereDataStore.Filters import org.mariotaku.twidere.provider.TwidereDataStore.Statuses @@ -98,8 +101,8 @@ abstract class CursorStatusesFragment : AbsStatusesFragment() { accountKeys[it].toString() } val expression = processWhere(where, selectionArgs) - return ExtendedObjectCursorLoader(context, ParcelableStatusCursorIndices::class.java, uri, - projection, expression.sql, expression.parameters, sortOrder, fromUser) + return ExtendedObjectCursorLoader(context, ParcelableStatus::class.java, uri, projection, + expression.sql, expression.parameters, sortOrder, fromUser) } override fun createMessageBusCallback(): Any { diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/CustomTabsFragment.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/CustomTabsFragment.kt index 5f501188e..3c1a9105b 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/CustomTabsFragment.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/CustomTabsFragment.kt @@ -47,6 +47,7 @@ import org.mariotaku.chameleon.Chameleon import org.mariotaku.ktextension.Bundle import org.mariotaku.ktextension.contains import org.mariotaku.ktextension.set +import org.mariotaku.library.objectcursor.ObjectCursor import org.mariotaku.sqliteqb.library.Columns.Column import org.mariotaku.sqliteqb.library.Expression import org.mariotaku.sqliteqb.library.RawItemArray @@ -60,8 +61,6 @@ import org.mariotaku.twidere.extension.applyTheme import org.mariotaku.twidere.extension.model.isOfficial import org.mariotaku.twidere.model.AccountDetails import org.mariotaku.twidere.model.Tab -import org.mariotaku.twidere.model.TabCursorIndices -import org.mariotaku.twidere.model.TabValuesCreator import org.mariotaku.twidere.model.tab.DrawableHolder import org.mariotaku.twidere.model.tab.TabConfiguration import org.mariotaku.twidere.model.tab.iface.AccountCallback @@ -378,14 +377,15 @@ class CustomTabsFragment : BaseFragment(), LoaderCallbacks, MultiChoice return@setOnClickListener } } + val valuesCreator = ObjectCursor.valuesCreatorFrom(Tab::class.java) when (tag) { TAG_EDIT_TAB -> { val where = Expression.equalsArgs(Tabs._ID).sql val whereArgs = arrayOf(tab.id.toString()) - context.contentResolver.update(Tabs.CONTENT_URI, TabValuesCreator.create(tab), where, whereArgs) + context.contentResolver.update(Tabs.CONTENT_URI, valuesCreator.create(tab), where, whereArgs) } TAG_ADD_TAB -> { - context.contentResolver.insert(Tabs.CONTENT_URI, TabValuesCreator.create(tab)) + context.contentResolver.insert(Tabs.CONTENT_URI, valuesCreator.create(tab)) } } SettingsActivity.setShouldRestart(activity) @@ -473,7 +473,7 @@ class CustomTabsFragment : BaseFragment(), LoaderCallbacks, MultiChoice private val iconColor: Int = ThemeUtils.getThemeForegroundColor(context) private val tempTab: Tab = Tab() - private var indices: TabCursorIndices? = null + private var indices: ObjectCursor.CursorIndices? = null override fun bindView(view: View, context: Context?, cursor: Cursor) { super.bindView(view, context, cursor) @@ -504,9 +504,7 @@ class CustomTabsFragment : BaseFragment(), LoaderCallbacks, MultiChoice } override fun changeCursor(cursor: Cursor?) { - if (cursor != null) { - indices = TabCursorIndices(cursor) - } + indices = cursor?.let { ObjectCursor.indicesFrom(it, Tab::class.java) } super.changeCursor(cursor) } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/StatusFragment.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/StatusFragment.kt index cbe73a97e..a278c7c5b 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/StatusFragment.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/StatusFragment.kt @@ -72,6 +72,7 @@ import org.mariotaku.kpreferences.get import org.mariotaku.ktextension.applyFontFamily import org.mariotaku.ktextension.contains import org.mariotaku.ktextension.findPositionByItemId +import org.mariotaku.library.objectcursor.ObjectCursor import org.mariotaku.microblog.library.MicroBlogException import org.mariotaku.microblog.library.twitter.model.Paging import org.mariotaku.microblog.library.twitter.model.TranslationResult @@ -2134,13 +2135,14 @@ class StatusFragment : BaseFragment(), LoaderCallbacks? = null private val secondaryTextColor = ThemeUtils.getTextColorSecondary(context) override fun swapCursor(c: Cursor?): Cursor? { - val old = super.swapCursor(c) - if (c != null) { - indices = `FiltersData$BaseItemCursorIndices`(c) - } - return old + indices = c?.let { ObjectCursor.indicesFrom(it, FiltersData.BaseItem::class.java) } + return super.swapCursor(c) } override fun bindView(view: View, context: Context, cursor: Cursor) { @@ -347,8 +344,8 @@ abstract class BaseFiltersFragment : AbsContentListViewFragment= 0) { + val ssb = SpannableStringBuilder(cursor.getString(indices[Filters.VALUE])) + if (cursor.getLong(indices[Filters.SOURCE]) >= 0) { val start = ssb.length ssb.append("*") val end = start + 1 @@ -363,7 +360,7 @@ abstract class BaseFiltersFragment : AbsContentListViewFragment? = null private val secondaryTextColor = ThemeUtils.getTextColorSecondary(context) init { @@ -182,15 +183,15 @@ class FilteredUsersFragment : BaseFiltersFragment() { icon.visibility = View.GONE - val userId = UserKey.valueOf(cursor.getString(indices.userKey)) - val name = cursor.getString(indices.name) - val screenName = cursor.getString(indices.screenName) + val userId = UserKey.valueOf(cursor.getString(indices[Filters.Users.USER_KEY])) + val name = cursor.getString(indices[Filters.Users.NAME]) + val screenName = cursor.getString(indices[Filters.Users.SCREEN_NAME]) val displayName = userColorNameManager.getDisplayName(userId, name, screenName, nameFirst) text1.text = displayName val ssb = SpannableStringBuilder(displayName) - if (cursor.getLong(indices.source) >= 0) { + if (cursor.getLong(indices[Filters.Users.SOURCE]) >= 0) { val start = ssb.length ssb.append("*") val end = start + 1 @@ -203,17 +204,14 @@ class FilteredUsersFragment : BaseFiltersFragment() { } override fun swapCursor(c: Cursor?): Cursor? { - val old = super.swapCursor(c) - if (c != null) { - indices = `FiltersData$UserItemCursorIndices`(c) - } - return old + indices = c?.let { ObjectCursor.indicesFrom(it, FiltersData.UserItem::class.java) } + return super.swapCursor(c) } override fun isSelectable(position: Int): Boolean { val cursor = this.cursor ?: return false if (cursor.moveToPosition(position)) { - return cursor.getLong(indices!!.source) < 0 + return cursor.getLong(indices!![Filters.Users.SOURCE]) < 0 } return false } @@ -221,7 +219,7 @@ class FilteredUsersFragment : BaseFiltersFragment() { fun getUserKeyString(position: Int): String? { val cursor = this.cursor ?: return null if (cursor.moveToPosition(position)) { - return cursor.getString(indices!!.userKey) + return cursor.getString(indices!![Filters.Users.USER_KEY]) } return null } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/filter/FiltersSubscriptionsFragment.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/filter/FiltersSubscriptionsFragment.kt index 2286168c6..dc0eae9c9 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/filter/FiltersSubscriptionsFragment.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/filter/FiltersSubscriptionsFragment.kt @@ -23,6 +23,7 @@ import kotlinx.android.synthetic.main.layout_list_with_empty_view.* import okhttp3.HttpUrl import org.mariotaku.abstask.library.TaskStarter import org.mariotaku.ktextension.* +import org.mariotaku.library.objectcursor.ObjectCursor import org.mariotaku.sqliteqb.library.Expression import org.mariotaku.twidere.R import org.mariotaku.twidere.TwidereConstants.REQUEST_PURCHASE_EXTRA_FEATURES @@ -37,8 +38,6 @@ import org.mariotaku.twidere.fragment.BaseFragment import org.mariotaku.twidere.fragment.ExtraFeaturesIntroductionDialogFragment import org.mariotaku.twidere.fragment.ProgressDialogFragment import org.mariotaku.twidere.model.FiltersSubscription -import org.mariotaku.twidere.model.FiltersSubscriptionCursorIndices -import org.mariotaku.twidere.model.FiltersSubscriptionValuesCreator import org.mariotaku.twidere.model.analyzer.PurchaseFinished import org.mariotaku.twidere.provider.TwidereDataStore.Filters import org.mariotaku.twidere.task.filter.RefreshFiltersSubscriptionsTask @@ -229,7 +228,7 @@ class FiltersSubscriptionsFragment : BaseFragment(), LoaderManager.LoaderCallbac val whereArgs = ids.toStringArray() resolver.query(Filters.Subscriptions.CONTENT_URI, Filters.Subscriptions.COLUMNS, where, whereArgs, null)?.useCursor { cursor -> - val indices = FiltersSubscriptionCursorIndices(cursor) + val indices = ObjectCursor.indicesFrom(cursor, FiltersSubscription::class.java) cursor.moveToFirst() while (!cursor.isAfterLast) { val subscription = indices.newObject(cursor) @@ -261,11 +260,11 @@ class FiltersSubscriptionsFragment : BaseFragment(), LoaderManager.LoaderCallbac class FilterSubscriptionsAdapter(context: Context) : SimpleCursorAdapter(context, R.layout.list_item_two_line, null, arrayOf(Filters.Subscriptions.NAME), intArrayOf(android.R.id.text1), 0) { - private var indices: FiltersSubscriptionCursorIndices? = null + private var indices: ObjectCursor.CursorIndices? = null private var tempObject: FiltersSubscription = FiltersSubscription() override fun swapCursor(c: Cursor?): Cursor? { - indices = if (c != null) FiltersSubscriptionCursorIndices(c) else null + indices = c?.let { ObjectCursor.indicesFrom(it, FiltersSubscription::class.java) } return super.swapCursor(c) } @@ -295,7 +294,8 @@ class FiltersSubscriptionsFragment : BaseFragment(), LoaderManager.LoaderCallbac subscription.setupUrl(editUrl.text.toString()) val component = subscription.instantiateComponent(context) ?: return@setPositiveButton component.firstAdded() - context.contentResolver.insert(Filters.Subscriptions.CONTENT_URI, FiltersSubscriptionValuesCreator.create(subscription)) + val vc = ObjectCursor.valuesCreatorFrom(FiltersSubscription::class.java) + context.contentResolver.insert(Filters.Subscriptions.CONTENT_URI, vc.create(subscription)) } builder.setNegativeButton(android.R.string.cancel, null) val dialog = builder.create() diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/message/MessageConversationInfoFragment.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/message/MessageConversationInfoFragment.kt index 6680a5d71..614ace5fd 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/message/MessageConversationInfoFragment.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/message/MessageConversationInfoFragment.kt @@ -57,6 +57,7 @@ import org.mariotaku.chameleon.ChameleonUtils import org.mariotaku.kpreferences.get import org.mariotaku.ktextension.setItemAvailability import org.mariotaku.ktextension.useCursor +import org.mariotaku.library.objectcursor.ObjectCursor import org.mariotaku.microblog.library.MicroBlog import org.mariotaku.microblog.library.MicroBlogException import org.mariotaku.microblog.library.twitter.TwitterUpload @@ -455,7 +456,8 @@ class MessageConversationInfoFragment : BaseFragment(), IToolBarSupportFragment, context.contentResolver.query(Conversations.CONTENT_URI, Conversations.COLUMNS, where, whereArgs, null).useCursor { cur -> if (cur.moveToFirst()) { - return ParcelableMessageConversationCursorIndices.fromCursor(cur) + val indices = ObjectCursor.indicesFrom(cur, ParcelableMessageConversation::class.java) + return indices.newObject(cur) } } return null diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/message/MessageNewConversationFragment.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/message/MessageNewConversationFragment.kt index 10d1e52b1..8e94b7edb 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/message/MessageNewConversationFragment.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/message/MessageNewConversationFragment.kt @@ -40,6 +40,7 @@ import org.mariotaku.kpreferences.get import org.mariotaku.ktextension.Bundle import org.mariotaku.ktextension.set import org.mariotaku.ktextension.setItemAvailability +import org.mariotaku.library.objectcursor.ObjectCursor import org.mariotaku.sqliteqb.library.Expression import org.mariotaku.twidere.R import org.mariotaku.twidere.adapter.SelectableUsersAdapter @@ -48,8 +49,10 @@ import org.mariotaku.twidere.constant.nameFirstKey import org.mariotaku.twidere.extension.model.isOfficial import org.mariotaku.twidere.fragment.BaseFragment import org.mariotaku.twidere.loader.CacheUserSearchLoader -import org.mariotaku.twidere.model.* +import org.mariotaku.twidere.model.ParcelableMessageConversation import org.mariotaku.twidere.model.ParcelableMessageConversation.ConversationType +import org.mariotaku.twidere.model.ParcelableUser +import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.util.AccountUtils import org.mariotaku.twidere.provider.TwidereDataStore.Messages.Conversations import org.mariotaku.twidere.task.twitter.message.SendMessageTask @@ -247,7 +250,7 @@ class MessageNewConversationFragment : BaseFragment(), LoaderCallbacks(context, ParcelableMessageCursorIndices::class.java) { + ) : ObjectCursorLoader(context, ParcelableMessage::class.java) { private val atomicConversation = AtomicReference() val conversation: ParcelableMessageConversation? get() = atomicConversation.get() diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/message/MessagesEntriesFragment.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/message/MessagesEntriesFragment.kt index a92f2811b..66a1d42ef 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/message/MessagesEntriesFragment.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/fragment/message/MessagesEntriesFragment.kt @@ -44,7 +44,6 @@ import org.mariotaku.twidere.fragment.iface.IFloatingActionButtonFragment import org.mariotaku.twidere.fragment.iface.IFloatingActionButtonFragment.ActionInfo import org.mariotaku.twidere.loader.ObjectCursorLoader import org.mariotaku.twidere.model.ParcelableMessageConversation -import org.mariotaku.twidere.model.ParcelableMessageConversationCursorIndices import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.event.GetMessagesTaskEvent import org.mariotaku.twidere.provider.TwidereDataStore.Messages @@ -84,7 +83,7 @@ class MessagesEntriesFragment : AbsContentListRecyclerViewFragment?> { - val loader = ObjectCursorLoader(context, ParcelableMessageConversationCursorIndices::class.java) + val loader = ObjectCursorLoader(context, ParcelableMessageConversation::class.java) val projection = (Conversations.COLUMNS + Conversations.UNREAD_COUNT).map { TwidereQueryBuilder.mapConversationsProjection(it) }.toTypedArray() diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/loader/CacheUserSearchLoader.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/loader/CacheUserSearchLoader.kt index 86b77cf96..97bd301ec 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/loader/CacheUserSearchLoader.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/loader/CacheUserSearchLoader.kt @@ -1,13 +1,13 @@ package org.mariotaku.twidere.loader import android.content.Context +import org.mariotaku.library.objectcursor.ObjectCursor import org.mariotaku.microblog.library.MicroBlog import org.mariotaku.microblog.library.twitter.model.User import org.mariotaku.sqliteqb.library.Columns import org.mariotaku.sqliteqb.library.Expression import org.mariotaku.twidere.model.AccountDetails import org.mariotaku.twidere.model.ParcelableUser -import org.mariotaku.twidere.model.ParcelableUserCursorIndices import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.provider.TwidereDataStore.CachedUsers import org.mariotaku.twidere.util.UserColorNameManager @@ -47,10 +47,10 @@ class CacheUserSearchLoader( val selectionArgs = arrayOf(queryEscaped, queryEscaped, *nicknameKeys) val c = context.contentResolver.query(CachedUsers.CONTENT_URI, CachedUsers.BASIC_COLUMNS, selection.sql, selectionArgs, null)!! - val i = ParcelableUserCursorIndices(c) + val i = ObjectCursor.indicesFrom(c, ParcelableUser::class.java) c.moveToFirst() while (!c.isAfterLast) { - if (list.none { it.key.toString() == c.getString(i.key) }) { + if (list.none { it.key.toString() == c.getString(i[CachedUsers.USER_KEY]) }) { list.add(i.newObject(c)) } c.moveToNext() diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/loader/ParcelableUserLoader.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/loader/ParcelableUserLoader.kt index 543b60f62..46059f45f 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/loader/ParcelableUserLoader.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/loader/ParcelableUserLoader.kt @@ -27,6 +27,7 @@ import android.text.TextUtils import android.util.Log import org.mariotaku.abstask.library.TaskStarter import org.mariotaku.ktextension.set +import org.mariotaku.library.objectcursor.ObjectCursor import org.mariotaku.microblog.library.MicroBlog import org.mariotaku.microblog.library.MicroBlogException import org.mariotaku.microblog.library.twitter.model.User @@ -38,13 +39,16 @@ import org.mariotaku.twidere.TwidereConstants.* import org.mariotaku.twidere.annotation.AccountType import org.mariotaku.twidere.annotation.Referral import org.mariotaku.twidere.extension.model.newMicroBlogInstance -import org.mariotaku.twidere.model.* +import org.mariotaku.twidere.model.AccountDetails +import org.mariotaku.twidere.model.ParcelableUser +import org.mariotaku.twidere.model.SingleResponse +import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.util.AccountUtils import org.mariotaku.twidere.model.util.ParcelableUserUtils import org.mariotaku.twidere.model.util.UserKeyUtils import org.mariotaku.twidere.provider.TwidereDataStore.CachedUsers import org.mariotaku.twidere.task.UpdateAccountInfoTask -import org.mariotaku.twidere.util.ContentValuesCreator.createCachedUser +import org.mariotaku.twidere.util.ContentValuesCreator import org.mariotaku.twidere.util.TwitterWrapper import org.mariotaku.twidere.util.UserColorNameManager import org.mariotaku.twidere.util.dagger.GeneralComponentHelper @@ -85,7 +89,7 @@ class ParcelableUserLoader( if (!omitIntentExtra && extras != null) { val user = extras.getParcelable(EXTRA_USER) if (user != null) { - val values = ParcelableUserValuesCreator.create(user) + val values = ObjectCursor.valuesCreatorFrom(ParcelableUser::class.java).create(user) resolver.insert(CachedUsers.CONTENT_URI, values) ParcelableUserUtils.updateExtraInformation(user, details, userColorNameManager) return SingleResponse(user).apply { @@ -118,7 +122,7 @@ class ParcelableUserLoader( whereArgs, null)?.let { cur -> try { cur.moveToFirst() - val indices = ParcelableUserCursorIndices(cur) + val indices = ObjectCursor.indicesFrom(cur, ParcelableUser::class.java) while (!cur.isAfterLast) { val user = indices.newObject(cur) if (TextUtils.equals(UserKeyUtils.getUserHost(user), user.key.host)) { @@ -152,7 +156,7 @@ class ParcelableUserLoader( twitterUser = TwitterWrapper.tryShowUser(twitter, id, screenName, details.type) } } - val cachedUserValues = createCachedUser(twitterUser, profileImageSize) + val cachedUserValues = ContentValuesCreator.createCachedUser(twitterUser, profileImageSize) resolver.insert(CachedUsers.CONTENT_URI, cachedUserValues) val user = ParcelableUserUtils.fromUser(twitterUser, accountKey, profileImageSize = profileImageSize) diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/provider/TwidereDataProvider.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/provider/TwidereDataProvider.kt index 135be4e77..6b0228f22 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/provider/TwidereDataProvider.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/provider/TwidereDataProvider.kt @@ -41,6 +41,7 @@ import okhttp3.Dns import org.apache.commons.lang3.ArrayUtils import org.mariotaku.ktextension.isNullOrEmpty import org.mariotaku.ktextension.toNulls +import org.mariotaku.library.objectcursor.ObjectCursor import org.mariotaku.sqliteqb.library.Columns.Column import org.mariotaku.sqliteqb.library.Expression import org.mariotaku.sqliteqb.library.RawItemArray @@ -52,7 +53,6 @@ import org.mariotaku.twidere.annotation.ReadPositionTag import org.mariotaku.twidere.app.TwidereApplication import org.mariotaku.twidere.model.AccountPreferences import org.mariotaku.twidere.model.Draft -import org.mariotaku.twidere.model.DraftCursorIndices import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.event.UnreadCountUpdatedEvent import org.mariotaku.twidere.provider.TwidereDataStore.* @@ -360,7 +360,7 @@ class TwidereDataProvider : ContentProvider(), LazyLoadCallback { val draftId = values.getAsLong(BaseColumns._ID) ?: return -1 val where = Expression.equals(Drafts._ID, draftId) val c = context.contentResolver.query(Drafts.CONTENT_URI, Drafts.COLUMNS, where.sql, null, null) ?: return -1 - val i = DraftCursorIndices(c) + val i = ObjectCursor.indicesFrom(c, Draft::class.java) val item: Draft try { if (!c.moveToFirst()) return -1 diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/service/LengthyOperationsService.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/service/LengthyOperationsService.kt index 0808a74a4..db78b5ddf 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/service/LengthyOperationsService.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/service/LengthyOperationsService.kt @@ -47,6 +47,7 @@ import org.mariotaku.ktextension.configure import org.mariotaku.ktextension.toLong import org.mariotaku.ktextension.toTypedArray import org.mariotaku.ktextension.useCursor +import org.mariotaku.library.objectcursor.ObjectCursor import org.mariotaku.microblog.library.MicroBlogException import org.mariotaku.microblog.library.twitter.TwitterUpload import org.mariotaku.microblog.library.twitter.model.MediaUploadResponse @@ -121,7 +122,7 @@ class LengthyOperationsService : BaseIntentService("lengthy_operations") { val where = Expression.equals(Drafts._ID, draftId) @SuppressLint("Recycle") val draft: Draft = contentResolver.query(Drafts.CONTENT_URI, Drafts.COLUMNS, where.sql, null, null)?.useCursor { - val i = DraftCursorIndices(it) + val i = ObjectCursor.indicesFrom(it, Draft::class.java) if (!it.moveToFirst()) return@useCursor null return@useCursor i.newObject(it) } ?: return diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/task/UpdateAccountInfoTask.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/task/UpdateAccountInfoTask.kt index 8021453b0..cc309972f 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/task/UpdateAccountInfoTask.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/task/UpdateAccountInfoTask.kt @@ -8,11 +8,15 @@ import android.content.Context import android.support.v4.util.LongSparseArray import android.text.TextUtils import org.mariotaku.abstask.library.AbstractTask +import org.mariotaku.library.objectcursor.ObjectCursor import org.mariotaku.sqliteqb.library.Expression import org.mariotaku.twidere.TwidereConstants.ACCOUNT_TYPE import org.mariotaku.twidere.extension.model.setAccountKey import org.mariotaku.twidere.extension.model.setAccountUser -import org.mariotaku.twidere.model.* +import org.mariotaku.twidere.model.AccountDetails +import org.mariotaku.twidere.model.ParcelableUser +import org.mariotaku.twidere.model.Tab +import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.provider.TwidereDataStore.* import java.io.IOException @@ -57,7 +61,8 @@ class UpdateAccountInfoTask( private fun updateTabs(resolver: ContentResolver, accountKey: UserKey) { val tabsCursor = resolver.query(Tabs.CONTENT_URI, Tabs.COLUMNS, null, null, null) ?: return try { - val indices = TabCursorIndices(tabsCursor) + val indices = ObjectCursor.indicesFrom(tabsCursor, Tab::class.java) + val creator = ObjectCursor.valuesCreatorFrom(Tab::class.java) tabsCursor.moveToFirst() val values = LongSparseArray() while (!tabsCursor.isAfterLast) { @@ -68,7 +73,7 @@ class UpdateAccountInfoTask( val keys = arguments.accountKeys if (TextUtils.equals(accountKey.id, accountId) && keys == null) { arguments.accountKeys = arrayOf(accountKey) - values.put(tab.id, TabValuesCreator.create(tab)) + values.put(tab.id, creator.create(tab)) } } tabsCursor.moveToNext() diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/task/filter/RefreshFiltersSubscriptionsTask.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/task/filter/RefreshFiltersSubscriptionsTask.kt index e936cadfb..82080eeac 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/task/filter/RefreshFiltersSubscriptionsTask.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/task/filter/RefreshFiltersSubscriptionsTask.kt @@ -6,12 +6,11 @@ import android.content.Context import android.net.Uri import org.mariotaku.abstask.library.AbstractTask import org.mariotaku.ktextension.useCursor +import org.mariotaku.library.objectcursor.ObjectCursor import org.mariotaku.sqliteqb.library.Expression import org.mariotaku.twidere.extension.model.instantiateComponent import org.mariotaku.twidere.model.FiltersData -import org.mariotaku.twidere.model.FiltersSubscriptionCursorIndices -import org.mariotaku.twidere.model.`FiltersData$BaseItemValuesCreator` -import org.mariotaku.twidere.model.`FiltersData$UserItemValuesCreator` +import org.mariotaku.twidere.model.FiltersSubscription import org.mariotaku.twidere.provider.TwidereDataStore.Filters import org.mariotaku.twidere.util.DebugLog import org.mariotaku.twidere.util.content.ContentResolverUtils @@ -26,7 +25,7 @@ class RefreshFiltersSubscriptionsTask(val context: Context) : AbstractTask() resolver.query(Filters.Subscriptions.CONTENT_URI, Filters.Subscriptions.COLUMNS, null, null, null)?.useCursor { cursor -> - val indices = FiltersSubscriptionCursorIndices(cursor) + val indices = ObjectCursor.indicesFrom(cursor, FiltersSubscription::class.java) cursor.moveToFirst() while (!cursor.isAfterLast) { val subscription = indices.newObject(cursor) @@ -72,9 +71,10 @@ class RefreshFiltersSubscriptionsTask(val context: Context) : AbstractTask?, sourceId: Long) { resolver.delete(Filters.Users.CONTENT_URI, Expression.equalsArgs(Filters.Users.SOURCE).sql, arrayOf(sourceId.toString())) + val creator = ObjectCursor.valuesCreatorFrom(FiltersData.UserItem::class.java) items?.map { item -> item.source = sourceId - return@map `FiltersData$UserItemValuesCreator`.create(item) + return@map creator.create(item) }?.let { items -> ContentResolverUtils.bulkInsert(resolver, Filters.Users.CONTENT_URI, items) } @@ -83,9 +83,10 @@ class RefreshFiltersSubscriptionsTask(val context: Context) : AbstractTask?, uri: Uri, sourceId: Long) { resolver.delete(uri, Expression.equalsArgs(Filters.SOURCE).sql, arrayOf(sourceId.toString())) + val creator = ObjectCursor.valuesCreatorFrom(FiltersData.BaseItem::class.java) items?.map { item -> item.source = sourceId - return@map `FiltersData$BaseItemValuesCreator`.create(item) + return@map creator.create(item) }?.let { items -> ContentResolverUtils.bulkInsert(resolver, uri, items) } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/GetStatusesTask.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/GetStatusesTask.kt index 8a198ce38..cf47aff7a 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/GetStatusesTask.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/GetStatusesTask.kt @@ -10,6 +10,7 @@ import org.apache.commons.lang3.ArrayUtils import org.apache.commons.lang3.math.NumberUtils import org.mariotaku.abstask.library.TaskStarter import org.mariotaku.kpreferences.get +import org.mariotaku.library.objectcursor.ObjectCursor import org.mariotaku.microblog.library.MicroBlog import org.mariotaku.microblog.library.MicroBlogException import org.mariotaku.microblog.library.twitter.model.Paging @@ -23,7 +24,7 @@ import org.mariotaku.twidere.TwidereConstants.QUERY_PARAM_NOTIFY_CHANGE import org.mariotaku.twidere.constant.loadItemLimitKey import org.mariotaku.twidere.extension.model.newMicroBlogInstance import org.mariotaku.twidere.model.AccountDetails -import org.mariotaku.twidere.model.ParcelableStatusValuesCreator +import org.mariotaku.twidere.model.ParcelableStatus import org.mariotaku.twidere.model.RefreshTaskParam import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.event.GetStatusesTaskEvent @@ -165,6 +166,7 @@ abstract class GetStatusesTask( // Get id diff of first and last item val sortDiff = firstSortId - lastSortId + val creator = ObjectCursor.valuesCreatorFrom(ParcelableStatus::class.java) for (i in 0 until statuses.size) { val item = statuses[i] val status = ParcelableStatusUtils.fromStatus(item, accountKey, false, profileImageSize) @@ -173,7 +175,7 @@ abstract class GetStatusesTask( sortDiff, i, statuses.size) status.inserted_date = System.currentTimeMillis() mediaLoader.preloadStatus(status) - values[i] = ParcelableStatusValuesCreator.create(status) + values[i] = creator.create(status) if (minIdx == -1 || item < statuses[minIdx]) { minIdx = i minPositionKey = status.position_key diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/GetTrendsTask.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/GetTrendsTask.kt index a00701f6d..1012ceab6 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/GetTrendsTask.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/GetTrendsTask.kt @@ -25,64 +25,66 @@ import android.content.ContentValues import android.content.Context import android.net.Uri import android.support.v4.util.ArraySet +import org.mariotaku.library.objectcursor.ObjectCursor import org.mariotaku.microblog.library.MicroBlog import org.mariotaku.microblog.library.MicroBlogException import org.mariotaku.microblog.library.twitter.model.Trends -import org.mariotaku.sqliteqb.library.Expression +import org.mariotaku.sqliteqb.library.Expression.and +import org.mariotaku.sqliteqb.library.Expression.equalsArgs import org.mariotaku.twidere.TwidereConstants.LOGTAG -import org.mariotaku.twidere.annotation.AccountType +import org.mariotaku.twidere.annotation.AccountType.FANFOU import org.mariotaku.twidere.extension.model.newMicroBlogInstance import org.mariotaku.twidere.model.ParcelableTrend -import org.mariotaku.twidere.model.ParcelableTrendValuesCreator import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.event.TrendsRefreshedEvent -import org.mariotaku.twidere.model.util.AccountUtils +import org.mariotaku.twidere.model.util.AccountUtils.getAccountDetails import org.mariotaku.twidere.provider.TwidereDataStore.CachedHashtags import org.mariotaku.twidere.provider.TwidereDataStore.CachedTrends -import org.mariotaku.twidere.util.DebugLog +import org.mariotaku.twidere.task.BaseAbstractTask +import org.mariotaku.twidere.util.DebugLog.w import org.mariotaku.twidere.util.content.ContentResolverUtils +import org.mariotaku.twidere.util.content.ContentResolverUtils.bulkInsert import java.util.* /** * Created by mariotaku on 16/2/24. */ class GetTrendsTask( - context: android.content.Context, - private val accountKey: org.mariotaku.twidere.model.UserKey, + context: Context, + private val accountKey: UserKey, private val woeId: Int -) : org.mariotaku.twidere.task.BaseAbstractTask(context) { +) : BaseAbstractTask(context) { override fun doLongOperation(param: Any?) { - val details = org.mariotaku.twidere.model.util.AccountUtils.getAccountDetails(android.accounts.AccountManager.get(context), accountKey, true) ?: return - val twitter = details.newMicroBlogInstance(context, cls = org.mariotaku.microblog.library.MicroBlog::class.java) + val details = getAccountDetails(AccountManager.get(context), accountKey, true) ?: return + val twitter = details.newMicroBlogInstance(context, cls = MicroBlog::class.java) try { val trends = when { - details.type == org.mariotaku.twidere.annotation.AccountType.FANFOU -> twitter.fanfouTrends + details.type == FANFOU -> twitter.fanfouTrends else -> twitter.getLocationTrends(woeId).firstOrNull() } ?: return - storeTrends(context.contentResolver, org.mariotaku.twidere.provider.TwidereDataStore.CachedTrends.Local.CONTENT_URI, trends) - } catch (e: org.mariotaku.microblog.library.MicroBlogException) { - org.mariotaku.twidere.util.DebugLog.w(LOGTAG, tr = e) + storeTrends(context.contentResolver, CachedTrends.Local.CONTENT_URI, trends) + } catch (e: MicroBlogException) { + w(LOGTAG, tr = e) } } override fun afterExecute(handler: Any?, result: Unit) { - bus.post(org.mariotaku.twidere.model.event.TrendsRefreshedEvent()) + bus.post(TrendsRefreshedEvent()) } - private fun storeTrends(cr: android.content.ContentResolver, uri: android.net.Uri, trends: org.mariotaku.microblog.library.twitter.model.Trends) { - val hashtags = android.support.v4.util.ArraySet() - val deleteWhere = org.mariotaku.sqliteqb.library.Expression.and(org.mariotaku.sqliteqb.library.Expression.equalsArgs(org.mariotaku.twidere.provider.TwidereDataStore.CachedTrends.ACCOUNT_KEY), - org.mariotaku.sqliteqb.library.Expression.equalsArgs(org.mariotaku.twidere.provider.TwidereDataStore.CachedTrends.WOEID)).sql + private fun storeTrends(cr: ContentResolver, uri: Uri, trends: Trends) { + val hashtags = ArraySet() + val deleteWhere = and(equalsArgs(CachedTrends.ACCOUNT_KEY), equalsArgs(CachedTrends.WOEID)).sql val deleteWhereArgs = arrayOf(accountKey.toString(), woeId.toString()) - cr.delete(org.mariotaku.twidere.provider.TwidereDataStore.CachedTrends.Local.CONTENT_URI, deleteWhere, deleteWhereArgs) + cr.delete(CachedTrends.Local.CONTENT_URI, deleteWhere, deleteWhereArgs) - val allTrends = java.util.ArrayList() + val allTrends = ArrayList() trends.trends.forEachIndexed { idx, trend -> val hashtag = trend.name.replaceFirst("#", "") hashtags.add(hashtag) - allTrends.add(org.mariotaku.twidere.model.ParcelableTrend().apply { + allTrends.add(ParcelableTrend().apply { this.account_key = accountKey this.woe_id = woeId this.name = trend.name @@ -90,10 +92,11 @@ class GetTrendsTask( this.trend_order = idx }) } - org.mariotaku.twidere.util.content.ContentResolverUtils.bulkInsert(cr, uri, allTrends.map(org.mariotaku.twidere.model.ParcelableTrendValuesCreator::create)) + val creator = ObjectCursor.valuesCreatorFrom(ParcelableTrend::class.java) + bulkInsert(cr, uri, allTrends.map(creator::create)) ContentResolverUtils.bulkDelete(cr, CachedHashtags.CONTENT_URI, CachedHashtags.NAME, false, hashtags, null, null) - ContentResolverUtils.bulkInsert(cr, CachedHashtags.CONTENT_URI, hashtags.map { + bulkInsert(cr, CachedHashtags.CONTENT_URI, hashtags.map { val values = ContentValues() values.put(CachedHashtags.NAME, it) return@map values diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/UpdateStatusTask.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/UpdateStatusTask.kt index d3aa27796..fbcd315f3 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/UpdateStatusTask.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/UpdateStatusTask.kt @@ -21,6 +21,7 @@ import net.ypresto.androidtranscoder.format.MediaFormatStrategyPresets import org.apache.commons.lang3.ArrayUtils import org.apache.commons.lang3.math.NumberUtils import org.mariotaku.ktextension.* +import org.mariotaku.library.objectcursor.ObjectCursor import org.mariotaku.microblog.library.MicroBlog import org.mariotaku.microblog.library.MicroBlogException import org.mariotaku.microblog.library.fanfou.model.PhotoStatusUpdate @@ -646,8 +647,8 @@ class UpdateStatusTask( val sizeLimit = account.mediaSizeLimit body = getBodyFromMedia(context, media, sizeLimit, chucked, ContentLengthInputStream.ReadListener { length, position -> - callback?.onUploadingProgressChanged(index, position, length) - }) + callback?.onUploadingProgressChanged(index, position, length) + }) val mediaUploadEvent = MediaUploadEvent.create(context, media) mediaUploadEvent.setFileSize(body.body.length()) body.geometry?.let { geometry -> @@ -927,7 +928,8 @@ class UpdateStatusTask( draft.timestamp = System.currentTimeMillis() config(draft) val resolver = context.contentResolver - val draftUri = resolver.insert(Drafts.CONTENT_URI, DraftValuesCreator.create(draft)) ?: return -1 + val creator = ObjectCursor.valuesCreatorFrom(Draft::class.java) + val draftUri = resolver.insert(Drafts.CONTENT_URI, creator.create(draft)) ?: return -1 return NumberUtils.toLong(draftUri.lastPathSegment, -1) } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/message/GetMessagesTask.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/message/GetMessagesTask.kt index 469f4c31d..79ce48e37 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/message/GetMessagesTask.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/message/GetMessagesTask.kt @@ -25,6 +25,7 @@ import android.content.Context import org.mariotaku.ktextension.toInt import org.mariotaku.ktextension.toLong import org.mariotaku.ktextension.useCursor +import org.mariotaku.library.objectcursor.ObjectCursor import org.mariotaku.microblog.library.MicroBlog import org.mariotaku.microblog.library.MicroBlogException import org.mariotaku.microblog.library.twitter.model.DMResponse @@ -429,18 +430,20 @@ class GetMessagesTask( fun storeMessages(context: Context, data: DatabaseUpdateData, details: AccountDetails, showNotification: Boolean = false) { val resolver = context.contentResolver + val conversationCreator = ObjectCursor.valuesCreatorFrom(ParcelableMessageConversation::class.java) val conversationsValues = data.conversations.filterNot { it.id in data.deleteConversations }.map { - val values = ParcelableMessageConversationValuesCreator.create(it) + val values = conversationCreator.create(it) if (it._id > 0) { values.put(Conversations._ID, it._id) } return@map values } + val messageCreator = ObjectCursor.valuesCreatorFrom(ParcelableMessage::class.java) val messagesValues = data.messages.filterNot { data.deleteMessages[it.conversation_id]?.contains(it.id) ?: false - }.map(ParcelableMessageValuesCreator::create) + }.map(messageCreator::create) for ((conversationId, messageIds) in data.deleteMessages) { val where = Expression.and(Expression.equalsArgs(Messages.ACCOUNT_KEY), @@ -480,11 +483,11 @@ class GetMessagesTask( val whereArgs = newIds.toTypedArray() + accountKey.toString() return context.contentResolver.query(Conversations.CONTENT_URI, Conversations.COLUMNS, where, whereArgs, null).useCursor { cur -> - val indices = ParcelableMessageConversationCursorIndices(cur) + val indices = ObjectCursor.indicesFrom(cur, ParcelableMessageConversation::class.java) cur.moveToFirst() while (!cur.isAfterLast) { - val conversationId = cur.getString(indices.id) - val timestamp = cur.getLong(indices.local_timestamp) + val conversationId = cur.getString(indices[Conversations.CONVERSATION_ID]) + val timestamp = cur.getLong(indices[Conversations.LOCAL_TIMESTAMP]) val conversation = this[conversationId] ?: run { val obj = indices.newObject(cur) this[conversationId] = obj diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/message/MarkMessageReadTask.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/message/MarkMessageReadTask.kt index 52f1c7089..1e825cb14 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/message/MarkMessageReadTask.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/task/twitter/message/MarkMessageReadTask.kt @@ -23,6 +23,7 @@ import android.accounts.AccountManager import android.annotation.SuppressLint import android.content.ContentValues import android.content.Context +import org.mariotaku.library.objectcursor.ObjectCursor import org.mariotaku.microblog.library.MicroBlog import org.mariotaku.microblog.library.MicroBlogException import org.mariotaku.sqliteqb.library.Expression @@ -31,7 +32,10 @@ import org.mariotaku.twidere.annotation.AccountType import org.mariotaku.twidere.extension.model.isOfficial import org.mariotaku.twidere.extension.model.newMicroBlogInstance import org.mariotaku.twidere.extension.model.timestamp -import org.mariotaku.twidere.model.* +import org.mariotaku.twidere.model.AccountDetails +import org.mariotaku.twidere.model.ParcelableMessage +import org.mariotaku.twidere.model.ParcelableMessageConversation +import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.message.conversation.TwitterOfficialConversationExtras import org.mariotaku.twidere.model.util.AccountUtils import org.mariotaku.twidere.provider.TwidereDataStore.Messages @@ -103,7 +107,8 @@ class MarkMessageReadTask( where, whereArgs, OrderBy(Messages.LOCAL_TIMESTAMP, false).sql) ?: return null try { if (cur.moveToFirst()) { - return ParcelableMessageCursorIndices.fromCursor(cur) + val indices = ObjectCursor.indicesFrom(cur, ParcelableMessage::class.java) + return indices.newObject(cur) } } finally { cur.close() diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/util/AccountMigrator.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/util/AccountMigrator.kt index f4b2f95d6..319435152 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/util/AccountMigrator.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/util/AccountMigrator.kt @@ -6,10 +6,10 @@ import android.database.sqlite.SQLiteDatabase import com.bluelinelabs.logansquare.LoganSquare import org.mariotaku.ktextension.HexColorFormat import org.mariotaku.ktextension.toHexColor +import org.mariotaku.library.objectcursor.ObjectCursor import org.mariotaku.twidere.TwidereConstants.* import org.mariotaku.twidere.annotation.AuthTypeInt import org.mariotaku.twidere.model.ParcelableCredentials -import org.mariotaku.twidere.model.ParcelableCredentialsCursorIndices import org.mariotaku.twidere.model.ParcelableUser import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.model.account.cred.BasicCredentials @@ -27,7 +27,7 @@ import org.mariotaku.twidere.provider.TwidereDataStore.Accounts fun migrateAccounts(am: AccountManager, db: SQLiteDatabase) { val cur = db.query(Accounts.TABLE_NAME, Accounts.COLUMNS, null, null, null, null, null) ?: return try { - val indices = ParcelableCredentialsCursorIndices(cur) + val indices = ObjectCursor.indicesFrom(cur, ParcelableCredentials::class.java) cur.moveToFirst() while (!cur.isAfterLast) { val credentials = indices.newObject(cur) diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/util/ContentNotificationManager.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/util/ContentNotificationManager.kt index 46d3e5805..bc715cd9e 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/util/ContentNotificationManager.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/util/ContentNotificationManager.kt @@ -30,6 +30,7 @@ import android.net.Uri import android.support.v4.app.NotificationCompat import org.mariotaku.kpreferences.get import org.mariotaku.ktextension.isEmpty +import org.mariotaku.library.objectcursor.ObjectCursor import org.mariotaku.microblog.library.twitter.model.Activity import org.mariotaku.sqliteqb.library.* import org.mariotaku.sqliteqb.library.Columns.Column @@ -99,22 +100,22 @@ class ContentNotificationManager( val usersCount = userCursor.count val statusesCount = statusCursor.count if (statusesCount == 0 || usersCount == 0) return - val statusIndices = ParcelableStatusCursorIndices(statusCursor) - val userIndices = ParcelableStatusCursorIndices(userCursor) - val positionKey = if (statusCursor.moveToFirst()) statusCursor.getLong(statusIndices.position_key) else -1L + val statusIndices = ObjectCursor.indicesFrom(statusCursor, ParcelableStatus::class.java) + val userIndices = ObjectCursor.indicesFrom(userCursor, ParcelableStatus::class.java) + val positionKey = if (statusCursor.moveToFirst()) statusCursor.getLong(statusIndices[Statuses.POSITION_KEY]) else -1L val notificationTitle = resources.getQuantityString(R.plurals.N_new_statuses, statusesCount, statusesCount) val notificationContent: String userCursor.moveToFirst() - val displayName = userColorNameManager.getDisplayName(userCursor.getString(userIndices.user_key), - userCursor.getString(userIndices.user_name), userCursor.getString(userIndices.user_screen_name), + val displayName = userColorNameManager.getDisplayName(userCursor.getString(userIndices[Statuses.USER_KEY]), + userCursor.getString(userIndices[Statuses.USER_NAME]), userCursor.getString(userIndices[Statuses.USER_SCREEN_NAME]), nameFirst) if (usersCount == 1) { notificationContent = context.getString(R.string.from_name, displayName) } else if (usersCount == 2) { userCursor.moveToPosition(1) - val othersName = userColorNameManager.getDisplayName(userCursor.getString(userIndices.user_key), - userCursor.getString(userIndices.user_name), userCursor.getString(userIndices.user_screen_name), + val othersName = userColorNameManager.getDisplayName(userCursor.getString(userIndices[Statuses.USER_KEY]), + userCursor.getString(userIndices[Statuses.USER_NAME]), userCursor.getString(userIndices[Statuses.USER_SCREEN_NAME]), nameFirst) notificationContent = resources.getString(R.string.from_name_and_name, displayName, othersName) } else { @@ -178,7 +179,7 @@ class ContentNotificationManager( builder.setStyle(style) builder.setAutoCancel(true) style.setSummaryText(accountName) - val ci = ParcelableActivityCursorIndices(c) + val ci = ObjectCursor.indicesFrom(c, ParcelableActivity::class.java) var timestamp: Long = -1 val filteredUserIds = DataStoreUtils.getFilteredUserIds(context) @@ -276,11 +277,11 @@ class ContentNotificationManager( try { if (cur.isEmpty) return - val indices = ParcelableMessageConversationCursorIndices(cur) + val indices = ObjectCursor.indicesFrom(cur, ParcelableMessageConversation::class.java) var messageSum: Int = 0 cur.forEachRow { cur, pos -> - messageSum += cur.getInt(indices.unread_count) + messageSum += cur.getInt(indices[Conversations.UNREAD_COUNT]) return@forEachRow true } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/util/ContentValuesCreator.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/util/ContentValuesCreator.kt index d1f61d703..70642def6 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/util/ContentValuesCreator.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/util/ContentValuesCreator.kt @@ -20,6 +20,7 @@ package org.mariotaku.twidere.util import android.content.ContentValues +import org.mariotaku.library.objectcursor.ObjectCursor import org.mariotaku.microblog.library.twitter.model.SavedSearch import org.mariotaku.microblog.library.twitter.model.Status import org.mariotaku.microblog.library.twitter.model.User @@ -34,7 +35,7 @@ object ContentValuesCreator { fun createCachedUser(user: User, profileImageSize: String = "normal"): ContentValues { val values = ContentValues() - ParcelableUserValuesCreator.writeTo(ParcelableUserUtils.fromUser(user, null, + ObjectCursor.valuesCreatorFrom(ParcelableUser::class.java).writeTo(ParcelableUserUtils.fromUser(user, null, profileImageSize = profileImageSize), values) return values } @@ -78,8 +79,8 @@ object ContentValuesCreator { } fun createStatus(orig: Status, accountKey: UserKey, profileImageSize: String): ContentValues { - return ParcelableStatusValuesCreator.create(ParcelableStatusUtils.fromStatus(orig, - accountKey, false, profileImageSize)) + return ObjectCursor.valuesCreatorFrom(ParcelableStatus::class.java) + .create(ParcelableStatusUtils.fromStatus(orig, accountKey, false, profileImageSize)) } fun createActivity(activity: ParcelableActivity, details: AccountDetails): ContentValues { @@ -109,7 +110,7 @@ object ContentValuesCreator { activity.status_text_plain = status.text_plain activity.status_source = status.source } - ParcelableActivityValuesCreator.writeTo(activity, values) + ObjectCursor.valuesCreatorFrom(ParcelableActivity::class.java).writeTo(activity, values) return values } diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/util/DataStoreFunctions.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/util/DataStoreFunctions.kt index 41a3b631b..4d1440428 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/util/DataStoreFunctions.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/util/DataStoreFunctions.kt @@ -10,11 +10,15 @@ import android.support.annotation.WorkerThread import android.support.v4.util.LongSparseArray import org.mariotaku.kpreferences.get import org.mariotaku.ktextension.useCursor +import org.mariotaku.library.objectcursor.ObjectCursor import org.mariotaku.sqliteqb.library.* import org.mariotaku.twidere.constant.filterPossibilitySensitiveStatusesKey import org.mariotaku.twidere.constant.filterUnavailableQuoteStatusesKey -import org.mariotaku.twidere.model.* +import org.mariotaku.twidere.model.Draft +import org.mariotaku.twidere.model.ParcelableActivity +import org.mariotaku.twidere.model.ParcelableStatus import org.mariotaku.twidere.model.ParcelableStatus.FilterFlags +import org.mariotaku.twidere.model.UserKey import org.mariotaku.twidere.provider.TwidereDataStore.* import org.mariotaku.twidere.util.DataStoreUtils.ACTIVITIES_URIS import java.io.IOException @@ -94,7 +98,7 @@ fun deleteDrafts(context: Context, draftIds: LongArray): Int { context.contentResolver.query(Drafts.CONTENT_URI, Drafts.COLUMNS, where, whereArgs, null).useCursor { cursor -> - val indices = DraftCursorIndices(cursor) + val indices = ObjectCursor.indicesFrom(cursor, Draft::class.java) cursor.moveToFirst() while (!cursor.isAfterLast) { val draft = indices.newObject(cursor) @@ -194,12 +198,13 @@ fun updateActivity(cr: ContentResolver, uri: Uri, val c = cr.query(uri, Activities.COLUMNS, where, whereArgs, null) ?: return val values = LongSparseArray() try { - val ci = ParcelableActivityCursorIndices(c) + val ci = ObjectCursor.indicesFrom(c, ParcelableActivity::class.java) + val vc = ObjectCursor.valuesCreatorFrom(ParcelableActivity::class.java) c.moveToFirst() while (!c.isAfterLast) { val activity = ci.newObject(c) action(activity) - values.put(activity._id, ParcelableActivityValuesCreator.create(activity)) + values.put(activity._id, vc.create(activity)) c.moveToNext() } } catch (e: IOException) { diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/util/DataStoreUtils.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/util/DataStoreUtils.kt index 707ad5f98..addf17ca2 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/util/DataStoreUtils.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/util/DataStoreUtils.kt @@ -159,7 +159,8 @@ object DataStoreUtils { if (accountKeys.all { it == null }) return arrayOfNulls(accountKeys.size) return getObjectFieldArray(context, uri, accountKeys, Conversations.ACCOUNT_KEY, Conversations.COLUMNS, OrderBy(SQLFunctions.MIN(Messages.LOCAL_TIMESTAMP)), null, null, - ::ParcelableMessageConversationCursorIndices, { arrayOfNulls(it) }) + { ObjectCursor.indicesFrom(it, ParcelableMessageConversation::class.java) }, + { arrayOfNulls(it) }) } fun getNewestConversations(context: Context, uri: Uri, accountKeys: Array, @@ -167,7 +168,8 @@ object DataStoreUtils { if (accountKeys.all { it == null }) return arrayOfNulls(accountKeys.size) return getObjectFieldArray(context, uri, accountKeys, Conversations.ACCOUNT_KEY, Conversations.COLUMNS, OrderBy(SQLFunctions.MAX(Messages.LOCAL_TIMESTAMP)), extraWhere, extraWhereArgs, - ::ParcelableMessageConversationCursorIndices, { arrayOfNulls(it) }) + { ObjectCursor.indicesFrom(it, ParcelableMessageConversation::class.java) }, + { arrayOfNulls(it) }) } fun getNewestStatusSortIds(context: Context, uri: Uri, accountKeys: Array): LongArray { @@ -800,6 +802,8 @@ object DataStoreUtils { val cr = context.contentResolver try { + val baseCreator = ObjectCursor.valuesCreatorFrom(FiltersData.BaseItem::class.java) + val userCreator = ObjectCursor.valuesCreatorFrom(FiltersData.UserItem::class.java) val userValues = ArrayList() val keywordValues = ArrayList() val linkValues = ArrayList() @@ -808,12 +812,12 @@ object DataStoreUtils { userItem.userKey = user.key userItem.screenName = user.screen_name userItem.name = user.name - userValues.add(`FiltersData$UserItemValuesCreator`.create(userItem)) + userValues.add(userCreator.create(userItem)) val keywordItem = FiltersData.BaseItem() keywordItem.value = "@" + user.screen_name keywordItem.userKey = user.key - keywordValues.add(`FiltersData$BaseItemValuesCreator`.create(keywordItem)) + keywordValues.add(baseCreator.create(keywordItem)) // Insert user link (without scheme) to links val linkItem = FiltersData.BaseItem() @@ -821,7 +825,7 @@ object DataStoreUtils { val linkWithoutScheme = userLink.toString().substringAfter("://") linkItem.value = linkWithoutScheme linkItem.userKey = user.key - linkValues.add(`FiltersData$BaseItemValuesCreator`.create(linkItem)) + linkValues.add(baseCreator.create(linkItem)) } ContentResolverUtils.bulkInsert(cr, Filters.Users.CONTENT_URI, userValues) @@ -861,8 +865,9 @@ object DataStoreUtils { for (uri in DataStoreUtils.STATUSES_URIS) { val cur = resolver.query(uri, Statuses.COLUMNS, where, whereArgs, null) ?: continue try { - if (cur.count > 0 && cur.moveToFirst()) { - status = ParcelableStatusCursorIndices.fromCursor(cur) + if (cur.moveToFirst()) { + val indices = ObjectCursor.indicesFrom(cur, ParcelableStatus::class.java) + status = indices.newObject(cur) } } finally { cur.close() @@ -885,7 +890,7 @@ object DataStoreUtils { val resolver = context.contentResolver val status = ParcelableStatusUtils.fromStatus(result, accountKey, false) resolver.delete(CachedStatuses.CONTENT_URI, where, whereArgs) - resolver.insert(CachedStatuses.CONTENT_URI, ParcelableStatusValuesCreator.create(status)) + resolver.insert(CachedStatuses.CONTENT_URI, ObjectCursor.valuesCreatorFrom(ParcelableStatus::class.java).create(status)) return status } @@ -898,7 +903,8 @@ object DataStoreUtils { val cur = resolver.query(Conversations.CONTENT_URI, Conversations.COLUMNS, where, whereArgs, null) ?: return null try { if (cur.moveToFirst()) { - return ParcelableMessageConversationCursorIndices.fromCursor(cur) + val indices = ObjectCursor.indicesFrom(cur, ParcelableMessageConversation::class.java) + return indices.newObject(cur) } } finally { cur.close() diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/util/content/TwidereSQLiteOpenHelper.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/util/content/TwidereSQLiteOpenHelper.kt index fb1604e22..6745db95d 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/util/content/TwidereSQLiteOpenHelper.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/util/content/TwidereSQLiteOpenHelper.kt @@ -26,6 +26,7 @@ import android.database.sqlite.SQLiteDatabase import android.database.sqlite.SQLiteOpenHelper import android.os.Build import org.mariotaku.kpreferences.get +import org.mariotaku.library.objectcursor.ObjectCursor import org.mariotaku.sqliteqb.library.* import org.mariotaku.sqliteqb.library.Columns.Column import org.mariotaku.sqliteqb.library.query.SQLCreateTriggerQuery.Event @@ -34,7 +35,6 @@ import org.mariotaku.twidere.TwidereConstants.SHARED_PREFERENCES_NAME import org.mariotaku.twidere.annotation.CustomTabType import org.mariotaku.twidere.constant.defaultAPIConfigKey import org.mariotaku.twidere.model.Tab -import org.mariotaku.twidere.model.TabValuesCreator import org.mariotaku.twidere.model.tab.TabConfiguration import org.mariotaku.twidere.provider.TwidereDataStore.* import org.mariotaku.twidere.provider.TwidereDataStore.Messages.Conversations @@ -104,6 +104,7 @@ class TwidereSQLiteOpenHelper( private fun setupDefaultTabs(db: SQLiteDatabase) { + val creator = ObjectCursor.valuesCreatorFrom(Tab::class.java) db.beginTransaction() @CustomTabType val tabTypes = arrayOf(CustomTabType.HOME_TIMELINE, CustomTabType.NOTIFICATIONS_TIMELINE, @@ -117,7 +118,7 @@ class TwidereSQLiteOpenHelper( this.icon = conf!!.icon.persistentKey this.position = i } - db.insert(Tabs.TABLE_NAME, null, TabValuesCreator.create(tab)) + db.insert(Tabs.TABLE_NAME, null, creator.create(tab)) } db.setTransactionSuccessful() db.endTransaction() diff --git a/twidere/src/main/kotlin/org/mariotaku/twidere/util/sync/FileBasedDraftsSyncAction.kt b/twidere/src/main/kotlin/org/mariotaku/twidere/util/sync/FileBasedDraftsSyncAction.kt index 828b90d5e..64a96e524 100644 --- a/twidere/src/main/kotlin/org/mariotaku/twidere/util/sync/FileBasedDraftsSyncAction.kt +++ b/twidere/src/main/kotlin/org/mariotaku/twidere/util/sync/FileBasedDraftsSyncAction.kt @@ -4,12 +4,11 @@ import android.content.Context import android.support.v4.util.LongSparseArray import org.mariotaku.ktextension.map import org.mariotaku.ktextension.set +import org.mariotaku.library.objectcursor.ObjectCursor import org.mariotaku.sqliteqb.library.Expression import org.mariotaku.twidere.extension.model.filename import org.mariotaku.twidere.extension.model.unique_id_non_null import org.mariotaku.twidere.model.Draft -import org.mariotaku.twidere.model.DraftCursorIndices -import org.mariotaku.twidere.model.DraftValuesCreator import org.mariotaku.twidere.provider.TwidereDataStore.Drafts import org.mariotaku.twidere.util.DebugLog import org.mariotaku.twidere.util.content.ContentResolverUtils @@ -45,7 +44,8 @@ abstract class FileBasedDraftsSyncAction(val context: Context) : val localDrafts = run { val cur = context.contentResolver.query(Drafts.CONTENT_URI, Drafts.COLUMNS, null, null, null)!! try { - return@run cur.map(DraftCursorIndices(cur)) + val indices = ObjectCursor.indicesFrom(cur, Draft::class.java) + return@run cur.map(indices) } finally { cur.close() } @@ -121,19 +121,20 @@ abstract class FileBasedDraftsSyncAction(val context: Context) : val fileList = downloadRemoteInfoList.joinToString(",") { it.draftFileName } DebugLog.d(LOGTAG_SYNC, "Downloading remote drafts $fileList") ContentResolverUtils.bulkInsert(context.contentResolver, Drafts.CONTENT_URI, - downloadDrafts(downloadRemoteInfoList).map { DraftValuesCreator.create(it) }) + downloadDrafts(downloadRemoteInfoList).map { ObjectCursor.valuesCreatorFrom(Draft::class.java).create(it) }) } // Update local items if (updateLocalInfoList.size() > 0) { val fileList = (0 until updateLocalInfoList.size()).joinToString(",") { updateLocalInfoList.valueAt(it).draftFileName } DebugLog.d(LOGTAG_SYNC, "Updating local drafts $fileList") + val creator = ObjectCursor.valuesCreatorFrom(Draft::class.java) for (index in 0 until updateLocalInfoList.size()) { val draft = Draft() if (draft.loadFromRemote(updateLocalInfoList.valueAt(index))) { val where = Expression.equalsArgs(Drafts._ID).sql val whereArgs = arrayOf(updateLocalInfoList.keyAt(index).toString()) - context.contentResolver.update(Drafts.CONTENT_URI, DraftValuesCreator.create(draft), where, whereArgs) + context.contentResolver.update(Drafts.CONTENT_URI, creator.create(draft), where, whereArgs) } } } @@ -156,7 +157,8 @@ abstract class FileBasedDraftsSyncAction(val context: Context) : snapshotsListFile.writer().use { writer -> val cur = context.contentResolver.query(Drafts.CONTENT_URI, Drafts.COLUMNS, null, null, null)!! try { - cur.map(DraftCursorIndices(cur)).map { it.unique_id_non_null }.forEach { line -> + val indices = ObjectCursor.indicesFrom(cur, Draft::class.java) + cur.map(indices).map { it.unique_id_non_null }.forEach { line -> writer.write(line) writer.write("\n") }