diff --git a/app/src/main/java/io/legado/app/api/ReaderProvider.java b/app/src/main/java/io/legado/app/api/ReaderProvider.java deleted file mode 100644 index 81d918219..000000000 --- a/app/src/main/java/io/legado/app/api/ReaderProvider.java +++ /dev/null @@ -1,358 +0,0 @@ -/* - * Copyright (C) 2020 w568w - */ - -package io.legado.app.api; - -import android.content.ContentProvider; -import android.content.ContentResolver; -import android.content.ContentValues; -import android.content.UriMatcher; -import android.database.CharArrayBuffer; -import android.database.ContentObserver; -import android.database.Cursor; -import android.database.DataSetObserver; -import android.net.Uri; -import android.os.Bundle; - -import com.google.gson.Gson; - -import org.jetbrains.annotations.NotNull; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; - -import io.legado.app.web.controller.BookshelfController; -import io.legado.app.web.controller.SourceController; -import io.legado.app.web.utils.ReturnData; - -/** - * Export book data to other app. - */ -public class ReaderProvider extends ContentProvider { - private enum RequestCode { - saveSource, saveSources, saveBook, deleteSources, getSource, getSources, getBookshelf, getChapterList, getBookContent - } - - public static final String POST_BODY_KEY = "json"; - public static final String AUTHORITY = "io.legado.app.api.ReaderProvider"; - private static UriMatcher sMatcher = new UriMatcher(UriMatcher.NO_MATCH); - private SourceController mSourceController; - private BookshelfController mBookshelfController; - - static { - sMatcher.addURI(AUTHORITY, "source/insert", RequestCode.saveSource.ordinal()); - sMatcher.addURI(AUTHORITY, "sources/insert", RequestCode.saveSources.ordinal()); - sMatcher.addURI(AUTHORITY, "book/insert", RequestCode.saveBook.ordinal()); - sMatcher.addURI(AUTHORITY, "sources/delete", RequestCode.deleteSources.ordinal()); - sMatcher.addURI(AUTHORITY, "source/query", RequestCode.getSource.ordinal()); - sMatcher.addURI(AUTHORITY, "sources/query", RequestCode.getSources.ordinal()); - sMatcher.addURI(AUTHORITY, "books/query", RequestCode.getBookshelf.ordinal()); - sMatcher.addURI(AUTHORITY, "book/chapter/query", RequestCode.getChapterList.ordinal()); - sMatcher.addURI(AUTHORITY, "book/content/query", RequestCode.getBookContent.ordinal()); - } - - public ReaderProvider() { - } - - @Override - public int delete(@NotNull Uri uri, String selection, String[] selectionArgs) { - if (sMatcher.match(uri) < 0) - return -1; - switch (RequestCode.values()[sMatcher.match(uri)]) { - case deleteSources: - mSourceController.deleteSources(selection); - break; - default: - throw new IllegalStateException("Unexpected value: " + RequestCode.values()[sMatcher.match(uri)].name()); - } - return 0; - } - - @Override - public String getType(@NotNull Uri uri) { - throw new UnsupportedOperationException("Not yet implemented"); - } - - @Override - public Uri insert(@NotNull Uri uri, ContentValues values) { - if (sMatcher.match(uri) < 0) - return null; - switch (RequestCode.values()[sMatcher.match(uri)]) { - case saveSource: - mSourceController.saveSource(values.getAsString(POST_BODY_KEY)); - break; - case saveBook: - mBookshelfController.saveBook(values.getAsString(POST_BODY_KEY)); - case saveSources: - mSourceController.saveSources(values.getAsString(POST_BODY_KEY)); - default: - throw new IllegalStateException("Unexpected value: " + RequestCode.values()[sMatcher.match(uri)].name()); - } - return null; - } - - @Override - public boolean onCreate() { - mSourceController = new SourceController(); - mBookshelfController = new BookshelfController(); - return false; - } - - @Override - public Cursor query(Uri uri, String[] projection, String selection, - String[] selectionArgs, String sortOrder) { - - Map> map = new HashMap<>(); - - ArrayList list = new ArrayList<>(); - list.add(uri.getQueryParameter("url")); - map.put("url", list); - - list = new ArrayList<>(); - list.add(uri.getQueryParameter("index")); - map.put("index", list); - - if (sMatcher.match(uri) < 0) - return null; - switch (RequestCode.values()[sMatcher.match(uri)]) { - case getSource: - return new SimpleCursor(mSourceController.getSource(map)); - case getSources: - return new SimpleCursor(mSourceController.getSources()); - case getBookshelf: - return new SimpleCursor(mBookshelfController.getBookshelf()); - case getBookContent: - return new SimpleCursor(mBookshelfController.getBookContent(map)); - case getChapterList: - return new SimpleCursor(mBookshelfController.getChapterList(map)); - default: - throw new IllegalStateException("Unexpected value: " + RequestCode.values()[sMatcher.match(uri)].name()); - } - } - - @Override - public int update(@NotNull Uri uri, ContentValues values, String selection, - String[] selectionArgs) { - throw new UnsupportedOperationException("Not yet implemented"); - } - - /** - * Simple inner class to deliver json callback data. - * - * Only getString() makes sense. - */ - private static class SimpleCursor implements Cursor { - private String mData; - - public SimpleCursor(ReturnData data) { - this.mData = new Gson().toJson(data); - } - - @Override - public int getCount() { - return 1; - } - - @Override - public int getPosition() { - return 0; - } - - @Override - public boolean move(int i) { - return true; - } - - @Override - public boolean moveToPosition(int i) { - return true; - } - - @Override - public boolean moveToFirst() { - return true; - } - - @Override - public boolean moveToLast() { - return true; - } - - @Override - public boolean moveToNext() { - return true; - } - - @Override - public boolean moveToPrevious() { - return true; - } - - @Override - public boolean isFirst() { - return true; - } - - @Override - public boolean isLast() { - return true; - } - - @Override - public boolean isBeforeFirst() { - return false; - } - - @Override - public boolean isAfterLast() { - return false; - } - - @Override - public int getColumnIndex(String s) { - return 0; - } - - @Override - public int getColumnIndexOrThrow(String s) throws IllegalArgumentException { - throw new UnsupportedOperationException("Not yet implemented"); - } - - @Override - public String getColumnName(int i) { - return null; - } - - @Override - public String[] getColumnNames() { - return new String[0]; - } - - @Override - public int getColumnCount() { - return 0; - } - - @Override - public byte[] getBlob(int i) { - return new byte[0]; - } - - @Override - public String getString(int i) { - return mData; - } - - @Override - public void copyStringToBuffer(int i, CharArrayBuffer charArrayBuffer) { - - } - - @Override - public short getShort(int i) { - return 0; - } - - @Override - public int getInt(int i) { - return 0; - } - - @Override - public long getLong(int i) { - return 0; - } - - @Override - public float getFloat(int i) { - return 0; - } - - @Override - public double getDouble(int i) { - return 0; - } - - @Override - public int getType(int i) { - return 0; - } - - @Override - public boolean isNull(int i) { - return false; - } - - @Override - public void deactivate() { - - } - - @Override - public boolean requery() { - return false; - } - - @Override - public void close() { - - } - - @Override - public boolean isClosed() { - return false; - } - - @Override - public void registerContentObserver(ContentObserver contentObserver) { - - } - - @Override - public void unregisterContentObserver(ContentObserver contentObserver) { - - } - - @Override - public void registerDataSetObserver(DataSetObserver dataSetObserver) { - - } - - @Override - public void unregisterDataSetObserver(DataSetObserver dataSetObserver) { - - } - - @Override - public void setNotificationUri(ContentResolver contentResolver, Uri uri) { - - } - - @Override - public Uri getNotificationUri() { - return null; - } - - @Override - public boolean getWantsAllOnMoveCalls() { - return false; - } - - @Override - public void setExtras(Bundle bundle) { - - } - - @Override - public Bundle getExtras() { - return null; - } - - @Override - public Bundle respond(Bundle bundle) { - return null; - } - } -} diff --git a/app/src/main/java/io/legado/app/api/ReaderProvider.kt b/app/src/main/java/io/legado/app/api/ReaderProvider.kt new file mode 100644 index 000000000..efac5256d --- /dev/null +++ b/app/src/main/java/io/legado/app/api/ReaderProvider.kt @@ -0,0 +1,311 @@ +/* + * Copyright (C) 2020 w568w + */ +package io.legado.app.api + +import android.content.ContentProvider +import android.content.ContentResolver +import android.content.ContentValues +import android.content.UriMatcher +import android.database.CharArrayBuffer +import android.database.ContentObserver +import android.database.Cursor +import android.database.DataSetObserver +import android.net.Uri +import android.os.Bundle +import com.google.gson.Gson +import io.legado.app.App +import io.legado.app.web.controller.BookshelfController +import io.legado.app.web.controller.SourceController +import io.legado.app.web.utils.ReturnData +import java.util.* + +/** + * Export book data to other app. + */ +class ReaderProvider : ContentProvider() { + private enum class RequestCode { + saveSource, saveSources, saveBook, deleteSources, getSource, getSources, getBookshelf, getChapterList, getBookContent + } + + companion object { + const val POST_BODY_KEY = "json" + private val authority = "${App.INSTANCE.packageName}.ReaderProvider" + private val sMatcher = UriMatcher(UriMatcher.NO_MATCH) + + init { + sMatcher.addURI( + authority, + "source/insert", + RequestCode.saveSource.ordinal + ) + sMatcher.addURI( + authority, + "sources/insert", + RequestCode.saveSources.ordinal + ) + sMatcher.addURI( + authority, + "book/insert", + RequestCode.saveBook.ordinal + ) + sMatcher.addURI( + authority, + "sources/delete", + RequestCode.deleteSources.ordinal + ) + sMatcher.addURI( + authority, + "source/query", + RequestCode.getSource.ordinal + ) + sMatcher.addURI( + authority, + "sources/query", + RequestCode.getSources.ordinal + ) + sMatcher.addURI( + authority, + "books/query", + RequestCode.getBookshelf.ordinal + ) + sMatcher.addURI( + authority, + "book/chapter/query", + RequestCode.getChapterList.ordinal + ) + sMatcher.addURI( + authority, + "book/content/query", + RequestCode.getBookContent.ordinal + ) + } + } + + override fun delete( + uri: Uri, + selection: String?, + selectionArgs: Array? + ): Int { + if (sMatcher.match(uri) < 0) return -1 + when (RequestCode.values()[sMatcher.match(uri)]) { + RequestCode.deleteSources -> SourceController.deleteSources(selection) + else -> throw IllegalStateException( + "Unexpected value: " + RequestCode.values()[sMatcher.match(uri)].name + ) + } + return 0 + } + + override fun getType(uri: Uri): String? { + throw UnsupportedOperationException("Not yet implemented") + } + + override fun insert(uri: Uri, values: ContentValues?): Uri? { + if (sMatcher.match(uri) < 0) return null + when (RequestCode.values()[sMatcher.match(uri)]) { + RequestCode.saveSource -> values?.let { + SourceController.saveSource(values.getAsString(POST_BODY_KEY)) + } + RequestCode.saveBook -> values?.let { + BookshelfController.saveBook(values.getAsString(POST_BODY_KEY)) + } + RequestCode.saveSources -> values?.let { + SourceController.saveSources(values.getAsString(POST_BODY_KEY)) + } + else -> throw IllegalStateException( + "Unexpected value: " + RequestCode.values()[sMatcher.match(uri)].name + ) + } + return null + } + + override fun onCreate(): Boolean { + return false + } + + override fun query( + uri: Uri, projection: Array?, selection: String?, + selectionArgs: Array?, sortOrder: String? + ): Cursor? { + val map: MutableMap> = HashMap() + uri.getQueryParameter("url")?.let { + map["url"] = arrayListOf(it) + } + uri.getQueryParameter("index")?.let { + map["index"] = arrayListOf(it) + } + return if (sMatcher.match(uri) < 0) null else when (RequestCode.values()[sMatcher.match(uri)]) { + RequestCode.getSource -> SimpleCursor(SourceController.getSource(map)) + RequestCode.getSources -> SimpleCursor(SourceController.sources) + RequestCode.getBookshelf -> SimpleCursor(BookshelfController.bookshelf) + RequestCode.getBookContent -> SimpleCursor(BookshelfController.getBookContent(map)) + RequestCode.getChapterList -> SimpleCursor(BookshelfController.getChapterList(map)) + else -> throw IllegalStateException( + "Unexpected value: " + RequestCode.values()[sMatcher.match(uri)].name + ) + } + } + + override fun update( + uri: Uri, values: ContentValues?, selection: String?, + selectionArgs: Array? + ): Int { + throw UnsupportedOperationException("Not yet implemented") + } + + /** + * Simple inner class to deliver json callback data. + * + * Only getString() makes sense. + */ + private class SimpleCursor(data: ReturnData?) : Cursor { + + private val mData: String = Gson().toJson(data) + + override fun getCount(): Int { + return 1 + } + + override fun getPosition(): Int { + return 0 + } + + override fun move(i: Int): Boolean { + return true + } + + override fun moveToPosition(i: Int): Boolean { + return true + } + + override fun moveToFirst(): Boolean { + return true + } + + override fun moveToLast(): Boolean { + return true + } + + override fun moveToNext(): Boolean { + return true + } + + override fun moveToPrevious(): Boolean { + return true + } + + override fun isFirst(): Boolean { + return true + } + + override fun isLast(): Boolean { + return true + } + + override fun isBeforeFirst(): Boolean { + return false + } + + override fun isAfterLast(): Boolean { + return false + } + + override fun getColumnIndex(s: String): Int { + return 0 + } + + @Throws(IllegalArgumentException::class) + override fun getColumnIndexOrThrow(s: String): Int { + throw UnsupportedOperationException("Not yet implemented") + } + + override fun getColumnName(i: Int): String? { + return null + } + + override fun getColumnNames(): Array { + return arrayOf() + } + + override fun getColumnCount(): Int { + return 0 + } + + override fun getBlob(i: Int): ByteArray { + return ByteArray(0) + } + + override fun getString(i: Int): String { + return mData + } + + override fun copyStringToBuffer( + i: Int, + charArrayBuffer: CharArrayBuffer + ) { + } + + override fun getShort(i: Int): Short { + return 0 + } + + override fun getInt(i: Int): Int { + return 0 + } + + override fun getLong(i: Int): Long { + return 0 + } + + override fun getFloat(i: Int): Float { + return 0f + } + + override fun getDouble(i: Int): Double { + return 0.0 + } + + override fun getType(i: Int): Int { + return 0 + } + + override fun isNull(i: Int): Boolean { + return false + } + + override fun deactivate() {} + override fun requery(): Boolean { + return false + } + + override fun close() {} + override fun isClosed(): Boolean { + return false + } + + override fun registerContentObserver(contentObserver: ContentObserver) {} + override fun unregisterContentObserver(contentObserver: ContentObserver) {} + override fun registerDataSetObserver(dataSetObserver: DataSetObserver) {} + override fun unregisterDataSetObserver(dataSetObserver: DataSetObserver) {} + override fun setNotificationUri(contentResolver: ContentResolver, uri: Uri) {} + + override fun getNotificationUri(): Uri? { + return null + } + + override fun getWantsAllOnMoveCalls(): Boolean { + return false + } + + override fun setExtras(bundle: Bundle) {} + override fun getExtras(): Bundle? { + return null + } + + override fun respond(bundle: Bundle): Bundle? { + return null + } + + } +} \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/web/HttpServer.kt b/app/src/main/java/io/legado/app/web/HttpServer.kt index 7afcd6c25..066a921c3 100644 --- a/app/src/main/java/io/legado/app/web/HttpServer.kt +++ b/app/src/main/java/io/legado/app/web/HttpServer.kt @@ -33,10 +33,10 @@ class HttpServer(port: Int) : NanoHTTPD(port) { val postData = files["postData"] when (uri) { - "/saveSource" -> returnData = SourceController().saveSource(postData) - "/saveSources" -> returnData = SourceController().saveSources(postData) - "/saveBook" -> returnData = BookshelfController().saveBook(postData) - "/deleteSources" -> returnData = SourceController().deleteSources(postData) + "/saveSource" -> returnData = SourceController.saveSource(postData) + "/saveSources" -> returnData = SourceController.saveSources(postData) + "/saveBook" -> returnData = BookshelfController.saveBook(postData) + "/deleteSources" -> returnData = SourceController.deleteSources(postData) } } @@ -44,13 +44,13 @@ class HttpServer(port: Int) : NanoHTTPD(port) { val parameters = session.parameters when (uri) { - "/getSource" -> returnData = SourceController().getSource(parameters) - "/getSources" -> returnData = SourceController().sources - "/getBookshelf" -> returnData = BookshelfController().bookshelf + "/getSource" -> returnData = SourceController.getSource(parameters) + "/getSources" -> returnData = SourceController.sources + "/getBookshelf" -> returnData = BookshelfController.bookshelf "/getChapterList" -> - returnData = BookshelfController().getChapterList(parameters) + returnData = BookshelfController.getChapterList(parameters) "/getBookContent" -> - returnData = BookshelfController().getBookContent(parameters) + returnData = BookshelfController.getBookContent(parameters) } } } diff --git a/app/src/main/java/io/legado/app/web/controller/BookshelfController.kt b/app/src/main/java/io/legado/app/web/controller/BookshelfController.kt index 9347ee1bb..300acedce 100644 --- a/app/src/main/java/io/legado/app/web/controller/BookshelfController.kt +++ b/app/src/main/java/io/legado/app/web/controller/BookshelfController.kt @@ -11,7 +11,7 @@ import io.legado.app.utils.getPrefInt import io.legado.app.web.utils.ReturnData import kotlinx.coroutines.runBlocking -class BookshelfController { +object BookshelfController { val bookshelf: ReturnData get() { diff --git a/app/src/main/java/io/legado/app/web/controller/SourceController.kt b/app/src/main/java/io/legado/app/web/controller/SourceController.kt index cb066ddc8..a76fe31e9 100644 --- a/app/src/main/java/io/legado/app/web/controller/SourceController.kt +++ b/app/src/main/java/io/legado/app/web/controller/SourceController.kt @@ -9,7 +9,7 @@ import io.legado.app.utils.fromJsonArray import io.legado.app.utils.fromJsonObject import io.legado.app.web.utils.ReturnData -class SourceController { +object SourceController { val sources: ReturnData get() {