├── .gitignore ├── Android_debugdata_webtool ├── app │ ├── .gitignore │ ├── src │ │ └── main │ │ │ ├── res │ │ │ ├── values │ │ │ │ ├── strings.xml │ │ │ │ ├── colors.xml │ │ │ │ └── styles.xml │ │ │ ├── mipmap-hdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-mdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ └── ic_launcher_round.png │ │ │ └── layout │ │ │ │ └── activity_main.xml │ │ │ ├── AndroidManifest.xml │ │ │ └── java │ │ │ └── com │ │ │ └── itgowo │ │ │ └── tool │ │ │ └── android_debugdata_webtool │ │ │ ├── MainActivity.java │ │ │ └── DBManager.java │ ├── proguard-rules.pro │ └── build.gradle ├── webtoollibrary │ ├── .gitignore │ ├── src │ │ └── main │ │ │ ├── assets │ │ │ ├── images │ │ │ │ ├── bg.jpg │ │ │ │ ├── file.png │ │ │ │ ├── favicon.ico │ │ │ │ ├── folder.png │ │ │ │ ├── sort_asc.png │ │ │ │ ├── sort_both.png │ │ │ │ ├── sort_desc.png │ │ │ │ ├── sort_asc_disabled.png │ │ │ │ └── sort_desc_disabled.png │ │ │ ├── language │ │ │ │ └── Chinese.json │ │ │ ├── custom.css │ │ │ ├── css │ │ │ │ ├── select.dataTables.min.css │ │ │ │ ├── responsive.dataTables.min.css │ │ │ │ └── buttons.dataTables.min.css │ │ │ ├── index.html │ │ │ └── js │ │ │ │ ├── dataTables.responsive.min.js │ │ │ │ └── dataTables.select.min.js │ │ │ ├── java │ │ │ └── android_debugdata_webtool │ │ │ │ └── tool │ │ │ │ └── itgowo │ │ │ │ └── com │ │ │ │ └── webtoollibrary │ │ │ │ ├── utils │ │ │ │ ├── Constants.java │ │ │ │ ├── DebugDataAutoInitProvider.java │ │ │ │ ├── NetworkUtils.java │ │ │ │ ├── Utils.java │ │ │ │ ├── PrefHelper.java │ │ │ │ └── TableNameParser.java │ │ │ │ ├── action │ │ │ │ ├── Action.java │ │ │ │ ├── ActionAddDataToSp.java │ │ │ │ ├── ActionUpdateDataToSp.java │ │ │ │ ├── ActionDeleteDataFromSp.java │ │ │ │ ├── ActionGetSpList.java │ │ │ │ ├── ActionGetDataFromSpFile.java │ │ │ │ ├── ActionAddDataToDb.java │ │ │ │ ├── ActionUpdateDataToDb.java │ │ │ │ ├── ActionDeleteDataFromDb.java │ │ │ │ ├── ActionGetTableList.java │ │ │ │ ├── ActionDeleteFile.java │ │ │ │ ├── ActionGetDbList.java │ │ │ │ ├── ActionGetDataFromDbTable.java │ │ │ │ ├── ActionQuery.java │ │ │ │ └── ActionGetFileList.java │ │ │ │ ├── onDebugToolListener.java │ │ │ │ ├── DatabaseManager.java │ │ │ │ ├── ClientServer.java │ │ │ │ ├── Request.java │ │ │ │ ├── ResponseHandler.java │ │ │ │ ├── HttpRequest.java │ │ │ │ ├── DebugDataTool.java │ │ │ │ ├── RequestHandler.java │ │ │ │ └── Response.java │ │ │ └── AndroidManifest.xml │ ├── proguard-rules.pro │ └── build.gradle ├── settings.gradle ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── .gitignore ├── gradle.properties ├── build.gradle ├── gradlew.bat └── gradlew ├── img1.png ├── img2.png ├── img3.png ├── img4.png ├── img5.png ├── img6.png ├── img7.png ├── WebTool-Demo1.0.7.apk ├── android-WebDebugTool-1.0.10.aar ├── android-WebDebugTool-1.0.10-sources.jar ├── API ├── deleteFile.md ├── getDbList.md ├── getTableList.md ├── deleteDataFromSp.md ├── deleteDataFromDb.md ├── downloadFile.md ├── updateDataToSp.md ├── getSpList.md ├── addDataToSp.md ├── addDataToDb.md ├── updateDataToDb.md ├── getFileList.md ├── query.md ├── getDataFromSpFile.md └── getDataFromDbTable.md └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | Android_debugdata_webtool/.idea/ 2 | -------------------------------------------------------------------------------- /Android_debugdata_webtool/app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /Android_debugdata_webtool/webtoollibrary/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /Android_debugdata_webtool/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app', ':webtoollibrary' 2 | -------------------------------------------------------------------------------- /img1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itgowo/android-debugdata-webtool/HEAD/img1.png -------------------------------------------------------------------------------- /img2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itgowo/android-debugdata-webtool/HEAD/img2.png -------------------------------------------------------------------------------- /img3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itgowo/android-debugdata-webtool/HEAD/img3.png -------------------------------------------------------------------------------- /img4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itgowo/android-debugdata-webtool/HEAD/img4.png -------------------------------------------------------------------------------- /img5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itgowo/android-debugdata-webtool/HEAD/img5.png -------------------------------------------------------------------------------- /img6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itgowo/android-debugdata-webtool/HEAD/img6.png -------------------------------------------------------------------------------- /img7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itgowo/android-debugdata-webtool/HEAD/img7.png -------------------------------------------------------------------------------- /WebTool-Demo1.0.7.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itgowo/android-debugdata-webtool/HEAD/WebTool-Demo1.0.7.apk -------------------------------------------------------------------------------- /android-WebDebugTool-1.0.10.aar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itgowo/android-debugdata-webtool/HEAD/android-WebDebugTool-1.0.10.aar -------------------------------------------------------------------------------- /android-WebDebugTool-1.0.10-sources.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itgowo/android-debugdata-webtool/HEAD/android-WebDebugTool-1.0.10-sources.jar -------------------------------------------------------------------------------- /Android_debugdata_webtool/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Android_debugdata_webtool 3 | 4 | -------------------------------------------------------------------------------- /Android_debugdata_webtool/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itgowo/android-debugdata-webtool/HEAD/Android_debugdata_webtool/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /Android_debugdata_webtool/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | .externalNativeBuild 10 | -------------------------------------------------------------------------------- /Android_debugdata_webtool/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itgowo/android-debugdata-webtool/HEAD/Android_debugdata_webtool/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /Android_debugdata_webtool/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itgowo/android-debugdata-webtool/HEAD/Android_debugdata_webtool/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /Android_debugdata_webtool/webtoollibrary/src/main/assets/images/bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itgowo/android-debugdata-webtool/HEAD/Android_debugdata_webtool/webtoollibrary/src/main/assets/images/bg.jpg -------------------------------------------------------------------------------- /Android_debugdata_webtool/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itgowo/android-debugdata-webtool/HEAD/Android_debugdata_webtool/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /Android_debugdata_webtool/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itgowo/android-debugdata-webtool/HEAD/Android_debugdata_webtool/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /Android_debugdata_webtool/webtoollibrary/src/main/assets/images/file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itgowo/android-debugdata-webtool/HEAD/Android_debugdata_webtool/webtoollibrary/src/main/assets/images/file.png -------------------------------------------------------------------------------- /Android_debugdata_webtool/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itgowo/android-debugdata-webtool/HEAD/Android_debugdata_webtool/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /Android_debugdata_webtool/webtoollibrary/src/main/assets/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itgowo/android-debugdata-webtool/HEAD/Android_debugdata_webtool/webtoollibrary/src/main/assets/images/favicon.ico -------------------------------------------------------------------------------- /Android_debugdata_webtool/webtoollibrary/src/main/assets/images/folder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itgowo/android-debugdata-webtool/HEAD/Android_debugdata_webtool/webtoollibrary/src/main/assets/images/folder.png -------------------------------------------------------------------------------- /Android_debugdata_webtool/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itgowo/android-debugdata-webtool/HEAD/Android_debugdata_webtool/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /Android_debugdata_webtool/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itgowo/android-debugdata-webtool/HEAD/Android_debugdata_webtool/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /Android_debugdata_webtool/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itgowo/android-debugdata-webtool/HEAD/Android_debugdata_webtool/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /Android_debugdata_webtool/webtoollibrary/src/main/assets/images/sort_asc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itgowo/android-debugdata-webtool/HEAD/Android_debugdata_webtool/webtoollibrary/src/main/assets/images/sort_asc.png -------------------------------------------------------------------------------- /Android_debugdata_webtool/webtoollibrary/src/main/assets/images/sort_both.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itgowo/android-debugdata-webtool/HEAD/Android_debugdata_webtool/webtoollibrary/src/main/assets/images/sort_both.png -------------------------------------------------------------------------------- /Android_debugdata_webtool/webtoollibrary/src/main/assets/images/sort_desc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itgowo/android-debugdata-webtool/HEAD/Android_debugdata_webtool/webtoollibrary/src/main/assets/images/sort_desc.png -------------------------------------------------------------------------------- /Android_debugdata_webtool/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itgowo/android-debugdata-webtool/HEAD/Android_debugdata_webtool/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /Android_debugdata_webtool/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itgowo/android-debugdata-webtool/HEAD/Android_debugdata_webtool/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /Android_debugdata_webtool/webtoollibrary/src/main/assets/images/sort_asc_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itgowo/android-debugdata-webtool/HEAD/Android_debugdata_webtool/webtoollibrary/src/main/assets/images/sort_asc_disabled.png -------------------------------------------------------------------------------- /Android_debugdata_webtool/webtoollibrary/src/main/assets/images/sort_desc_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itgowo/android-debugdata-webtool/HEAD/Android_debugdata_webtool/webtoollibrary/src/main/assets/images/sort_desc_disabled.png -------------------------------------------------------------------------------- /Android_debugdata_webtool/app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #3F51B5 4 | #303F9F 5 | #FF4081 6 | 7 | -------------------------------------------------------------------------------- /Android_debugdata_webtool/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Wed Sep 12 14:24:40 CST 2018 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip 7 | -------------------------------------------------------------------------------- /Android_debugdata_webtool/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Android_debugdata_webtool/webtoollibrary/src/main/assets/language/Chinese.json: -------------------------------------------------------------------------------- 1 | { 2 | "sProcessing": "处理中...", 3 | "sLengthMenu": "显示 _MENU_ 项结果", 4 | "sZeroRecords": "没有匹配结果", 5 | "sInfo": "显示第 _START_ 至 _END_ 项结果,共 _TOTAL_ 项", 6 | "sInfoEmpty": "显示第 0 至 0 项结果,共 0 项", 7 | "sInfoFiltered": "(由 _MAX_ 项结果过滤)", 8 | "sInfoPostFix": "", 9 | "sSearch": "搜索:", 10 | "sUrl": "", 11 | "sEmptyTable": "表中数据为空", 12 | "sLoadingRecords": "载入中...", 13 | "sInfoThousands": ",", 14 | "oPaginate": { 15 | "sFirst": "首页", 16 | "sPrevious": "上页", 17 | "sNext": "下页", 18 | "sLast": "末页" 19 | }, 20 | "oAria": { 21 | "sSortAscending": ": 以升序排列此列", 22 | "sSortDescending": ": 以降序排列此列" 23 | } 24 | } -------------------------------------------------------------------------------- /Android_debugdata_webtool/webtoollibrary/src/main/java/android_debugdata_webtool/tool/itgowo/com/webtoollibrary/utils/Constants.java: -------------------------------------------------------------------------------- 1 | 2 | 3 | package android_debugdata_webtool.tool.itgowo.com.webtoollibrary.utils; 4 | 5 | 6 | public final class Constants { 7 | 8 | private Constants() { 9 | // This class in not publicly instantiable 10 | } 11 | /** 12 | * 数据库表结构常量, PRAGMA table_info(***) 13 | */ 14 | public static final String PrimaryKey = "pk"; 15 | public static final String NAME = "name"; 16 | public static final String TYPE = "type"; 17 | public static final String NotNull = "notnull"; 18 | public static final String DefaultValue = "dflt_value"; 19 | public static final String NULL = "null"; 20 | 21 | } 22 | -------------------------------------------------------------------------------- /Android_debugdata_webtool/webtoollibrary/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 9 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /API/deleteFile.md: -------------------------------------------------------------------------------- 1 | **简要描述:** 2 | 3 | - 删除文件 4 | 5 | **请求URL:** 6 | - ` / ` 7 | 8 | **请求方式:** 9 | - POST 10 | 11 | **参数:** 12 | 13 | ``` 14 | { 15 | "action": "deleteFile", 16 | "data": "/data/user/0/com.itgowo.tool.android_debugdata_webtool/databases" 17 | } 18 | 19 | ``` 20 | 21 | |参数名|必选|类型|说明| 22 | |:---- |:---|:----- |----- | 23 | |action |是 |string |执行动作| 24 | |data |否 |string | 要获取列表的根目录,不传则返回app根目录, | 25 | 26 | **返回示例** 27 | 28 | ``` 29 | { 30 | "code": 200, 31 | "msg": "success" 32 | } 33 | 34 | ``` 35 | 36 | 37 | **返回参数说明** 38 | 39 | |参数名|类型|说明| 40 | |:----- |:-----|----- | 41 | |code |int |返回结果状态 200表示成功,不是200则提示msg信息 | 42 | |msg |String |返回状态文本,code不是200则提示msg信息 | 43 | 44 | 45 | 46 | **备注** 47 | 48 | - 更多返回错误代码请看首页的错误代码描述 49 | 50 | 51 | -------------------------------------------------------------------------------- /Android_debugdata_webtool/webtoollibrary/src/main/java/android_debugdata_webtool/tool/itgowo/com/webtoollibrary/action/Action.java: -------------------------------------------------------------------------------- 1 | package android_debugdata_webtool.tool.itgowo.com.webtoollibrary.action; 2 | 3 | import android.content.Context; 4 | 5 | import java.io.File; 6 | import java.util.HashMap; 7 | 8 | import android_debugdata_webtool.tool.itgowo.com.webtoollibrary.HttpRequest; 9 | import android_debugdata_webtool.tool.itgowo.com.webtoollibrary.Request; 10 | import android_debugdata_webtool.tool.itgowo.com.webtoollibrary.Response; 11 | import android_debugdata_webtool.tool.itgowo.com.webtoollibrary.ResponseHandler; 12 | 13 | /** 14 | * @author lujianchao 15 | */ 16 | public interface Action { 17 | Response doAction(Context context, Request request,HttpRequest httpRequest, ResponseHandler responseHandler); 18 | } 19 | -------------------------------------------------------------------------------- /Android_debugdata_webtool/gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | org.gradle.jvmargs=-Xmx1536m 13 | 14 | # When configured, Gradle will run in incubating parallel mode. 15 | # This option should only be used with decoupled projects. More details, visit 16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 17 | # org.gradle.parallel=true 18 | -------------------------------------------------------------------------------- /Android_debugdata_webtool/webtoollibrary/src/main/java/android_debugdata_webtool/tool/itgowo/com/webtoollibrary/onDebugToolListener.java: -------------------------------------------------------------------------------- 1 | package android_debugdata_webtool.tool.itgowo.com.webtoollibrary; 2 | 3 | /** 4 | * Created by hnvfh on 2017/8/17. 5 | */ 6 | 7 | public interface onDebugToolListener { 8 | void onSystemMsg(String mS); 9 | 10 | String onObjectToJson(Object mObject); 11 | 12 | T onJsonStringToObject(String mJsonString, Class mClass); 13 | 14 | /** 15 | * 收到的所有请求 16 | * 17 | * @param mRequest 18 | */ 19 | void onGetRequest(String mRequest, HttpRequest mHttpRequest); 20 | 21 | /** 22 | * 只返回请求操作数据,不返回文件 23 | * 24 | * @param mResponse 25 | */ 26 | void onResponse(String mResponse); 27 | 28 | /** 29 | * 异常 30 | * 31 | * @param mTip 32 | * @param mThrowable 33 | */ 34 | void onError(String mTip, Throwable mThrowable); 35 | } 36 | -------------------------------------------------------------------------------- /API/getDbList.md: -------------------------------------------------------------------------------- 1 | **简要描述:** 2 | 3 | - 获取数据库列表 4 | 5 | **请求URL:** 6 | - ` / ` 7 | 8 | **请求方式:** 9 | - POST 10 | 11 | **参数:** 12 | 13 | ``` 14 | { 15 | action : getDbList 16 | } 17 | 18 | ``` 19 | 20 | |参数名|必选|类型|说明| 21 | |:---- |:---|:----- |----- | 22 | |action |是 |string |执行动作| 23 | 24 | 25 | **返回示例** 26 | 27 | ``` 28 | { 29 | code : 200, 30 | msg : success, 31 | dbList : [ 32 | { 33 | fileName: appinfo.db, 34 | path: /data/user/0/com.itgowo.tool.android_debugdata_webtool/databases/appinfo.db 35 | } 36 | ] 37 | } 38 | 39 | ``` 40 | 41 | 42 | **返回参数说明** 43 | 44 | |参数名|类型|说明| 45 | |:----- |:-----|----- | 46 | |code |int |返回结果状态 200表示成功,不是200则提示msg信息 | 47 | |msg |String |返回状态文本,code不是200则提示msg信息 | 48 | |dbList |array |返回结果,数据库文件对象数组 | 49 | |fileName |String |返回结果,文件名 | 50 | |path |String |返回结果,文件路径 | 51 | 52 | **备注** 53 | 54 | - 更多返回错误代码请看首页的错误代码描述 55 | 56 | 57 | -------------------------------------------------------------------------------- /API/getTableList.md: -------------------------------------------------------------------------------- 1 | **简要描述:** 2 | 3 | - 获取数据库表列表 4 | 5 | **请求URL:** 6 | - ` / ` 7 | 8 | **请求方式:** 9 | - POST 10 | 11 | **参数:** 12 | 13 | 14 | ``` 15 | { 16 | action : getTableList, 17 | database : appinfo.db 18 | } 19 | 20 | ``` 21 | 22 | 23 | 24 | |参数名|必选|类型|说明| 25 | |:---- |:---|:----- |----- | 26 | |action |是 |string |请求参数| 27 | |database |是 |string | 请求参数 | 28 | 29 | 30 | **返回示例** 31 | 32 | ``` 33 | 34 | { 35 | code : 200, 36 | msg : success, 37 | dbVersion : 1, 38 | tableList :[ 39 | android_metadata, 40 | historycache, 41 | sqlite_sequence 42 | ] 43 | } 44 | 45 | ``` 46 | 47 | **返回参数说明** 48 | 49 | |参数名|类型|说明| 50 | |:----- |:-----|----- | 51 | |code |int |返回结果状态 200表示成功,不是200则提示msg信息 | 52 | |msg |String |返回状态文本,code不是200则提示msg信息 | 53 | |dbVersion |int |数据库版本 | 54 | |tableList |array |数据表名字列表数组 | 55 | 56 | **备注** 57 | 58 | - 更多返回错误代码请看首页的错误代码描述 59 | 60 | 61 | -------------------------------------------------------------------------------- /Android_debugdata_webtool/app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 56 | 57 |
58 | 59 |
60 |
61 | 62 |
63 | 64 |
65 |
66 |
67 |
68 |
69 |
70 | 71 | 72 |
73 | 74 | 77 |
78 |
79 |
80 |
81 |
82 |
数据库
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
数据
95 |
96 |
97 |
98 |
99 |
100 |
101 |
数据修改成功
102 |
103 |
104 |
105 |
106 |
107 | 108 |
109 |
110 |
111 |
112 |
113 |
共享参数
114 |
115 |
116 |
117 |
118 |
119 |
120 |
数据
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 | 131 | 132 | 133 | 134 | 135 | -------------------------------------------------------------------------------- /Android_debugdata_webtool/webtoollibrary/src/main/assets/css/buttons.dataTables.min.css: -------------------------------------------------------------------------------- 1 | div.dt-button-info{position:fixed;top:50%;left:50%;width:400px;margin-top:-100px;margin-left:-200px;background-color:white;border:2px solid #111;box-shadow:3px 3px 8px rgba(0,0,0,0.3);border-radius:3px;text-align:center;z-index:21}div.dt-button-info h2{padding:0.5em;margin:0;font-weight:normal;border-bottom:1px solid #ddd;background-color:#f3f3f3}div.dt-button-info>div{padding:1em}button.dt-button,div.dt-button,a.dt-button{position:relative;display:inline-block;box-sizing:border-box;margin-right:0.333em;padding:0.5em 1em;border:1px solid #999;border-radius:2px;cursor:pointer;font-size:0.88em;color:black;white-space:nowrap;overflow:hidden;background-color:#e9e9e9;background-image:-webkit-linear-gradient(top, #fff 0%, #e9e9e9 100%);background-image:-moz-linear-gradient(top, #fff 0%, #e9e9e9 100%);background-image:-ms-linear-gradient(top, #fff 0%, #e9e9e9 100%);background-image:-o-linear-gradient(top, #fff 0%, #e9e9e9 100%);background-image:linear-gradient(top, #fff 0%, #e9e9e9 100%);filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='white', EndColorStr='#e9e9e9');-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-decoration:none;outline:none}button.dt-button.disabled,div.dt-button.disabled,a.dt-button.disabled{color:#999;border:1px solid #d0d0d0;cursor:default;background-color:#f9f9f9;background-image:-webkit-linear-gradient(top, #fff 0%, #f9f9f9 100%);background-image:-moz-linear-gradient(top, #fff 0%, #f9f9f9 100%);background-image:-ms-linear-gradient(top, #fff 0%, #f9f9f9 100%);background-image:-o-linear-gradient(top, #fff 0%, #f9f9f9 100%);background-image:linear-gradient(top, #fff 0%, #f9f9f9 100%);filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#ffffff', EndColorStr='#f9f9f9')}button.dt-button:active:not(.disabled),button.dt-button.active:not(.disabled),div.dt-button:active:not(.disabled),div.dt-button.active:not(.disabled),a.dt-button:active:not(.disabled),a.dt-button.active:not(.disabled){background-color:#e2e2e2;background-image:-webkit-linear-gradient(top, #f3f3f3 0%, #e2e2e2 100%);background-image:-moz-linear-gradient(top, #f3f3f3 0%, #e2e2e2 100%);background-image:-ms-linear-gradient(top, #f3f3f3 0%, #e2e2e2 100%);background-image:-o-linear-gradient(top, #f3f3f3 0%, #e2e2e2 100%);background-image:linear-gradient(top, #f3f3f3 0%, #e2e2e2 100%);filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#f3f3f3', EndColorStr='#e2e2e2');box-shadow:inset 1px 1px 3px #999999}button.dt-button:active:not(.disabled):hover:not(.disabled),button.dt-button.active:not(.disabled):hover:not(.disabled),div.dt-button:active:not(.disabled):hover:not(.disabled),div.dt-button.active:not(.disabled):hover:not(.disabled),a.dt-button:active:not(.disabled):hover:not(.disabled),a.dt-button.active:not(.disabled):hover:not(.disabled){box-shadow:inset 1px 1px 3px #999999;background-color:#cccccc;background-image:-webkit-linear-gradient(top, #eaeaea 0%, #ccc 100%);background-image:-moz-linear-gradient(top, #eaeaea 0%, #ccc 100%);background-image:-ms-linear-gradient(top, #eaeaea 0%, #ccc 100%);background-image:-o-linear-gradient(top, #eaeaea 0%, #ccc 100%);background-image:linear-gradient(top, #eaeaea 0%, #ccc 100%);filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#eaeaea', EndColorStr='#cccccc')}button.dt-button:hover,div.dt-button:hover,a.dt-button:hover{text-decoration:none}button.dt-button:hover:not(.disabled),div.dt-button:hover:not(.disabled),a.dt-button:hover:not(.disabled){border:1px solid #666;background-color:#e0e0e0;background-image:-webkit-linear-gradient(top, #f9f9f9 0%, #e0e0e0 100%);background-image:-moz-linear-gradient(top, #f9f9f9 0%, #e0e0e0 100%);background-image:-ms-linear-gradient(top, #f9f9f9 0%, #e0e0e0 100%);background-image:-o-linear-gradient(top, #f9f9f9 0%, #e0e0e0 100%);background-image:linear-gradient(top, #f9f9f9 0%, #e0e0e0 100%);filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#f9f9f9', EndColorStr='#e0e0e0')}button.dt-button:focus:not(.disabled),div.dt-button:focus:not(.disabled),a.dt-button:focus:not(.disabled){border:1px solid #426c9e;text-shadow:0 1px 0 #c4def1;outline:none;background-color:#79ace9;background-image:-webkit-linear-gradient(top, #bddef4 0%, #79ace9 100%);background-image:-moz-linear-gradient(top, #bddef4 0%, #79ace9 100%);background-image:-ms-linear-gradient(top, #bddef4 0%, #79ace9 100%);background-image:-o-linear-gradient(top, #bddef4 0%, #79ace9 100%);background-image:linear-gradient(top, #bddef4 0%, #79ace9 100%);filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#bddef4', EndColorStr='#79ace9')}.dt-button embed{outline:none}div.dt-buttons{position:relative;float:left}div.dt-buttons.buttons-right{float:right}div.dt-button-collection{position:absolute;top:0;left:0;width:150px;margin-top:3px;padding:8px 8px 4px 8px;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.4);background-color:white;overflow:hidden;z-index:2002;border-radius:5px;box-shadow:3px 3px 5px rgba(0,0,0,0.3);z-index:2002;-webkit-column-gap:8px;-moz-column-gap:8px;-ms-column-gap:8px;-o-column-gap:8px;column-gap:8px}div.dt-button-collection button.dt-button,div.dt-button-collection div.dt-button,div.dt-button-collection a.dt-button{position:relative;left:0;right:0;display:block;float:none;margin-bottom:4px;margin-right:0}div.dt-button-collection button.dt-button:active:not(.disabled),div.dt-button-collection button.dt-button.active:not(.disabled),div.dt-button-collection div.dt-button:active:not(.disabled),div.dt-button-collection div.dt-button.active:not(.disabled),div.dt-button-collection a.dt-button:active:not(.disabled),div.dt-button-collection a.dt-button.active:not(.disabled){background-color:#dadada;background-image:-webkit-linear-gradient(top, #f0f0f0 0%, #dadada 100%);background-image:-moz-linear-gradient(top, #f0f0f0 0%, #dadada 100%);background-image:-ms-linear-gradient(top, #f0f0f0 0%, #dadada 100%);background-image:-o-linear-gradient(top, #f0f0f0 0%, #dadada 100%);background-image:linear-gradient(top, #f0f0f0 0%, #dadada 100%);filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#f0f0f0', EndColorStr='#dadada');box-shadow:inset 1px 1px 3px #666}div.dt-button-collection.fixed{position:fixed;top:50%;left:50%;margin-left:-75px;border-radius:0}div.dt-button-collection.fixed.two-column{margin-left:-150px}div.dt-button-collection.fixed.three-column{margin-left:-225px}div.dt-button-collection.fixed.four-column{margin-left:-300px}div.dt-button-collection>*{-webkit-column-break-inside:avoid;break-inside:avoid}div.dt-button-collection.two-column{width:300px;padding-bottom:1px;-webkit-column-count:2;-moz-column-count:2;-ms-column-count:2;-o-column-count:2;column-count:2}div.dt-button-collection.three-column{width:450px;padding-bottom:1px;-webkit-column-count:3;-moz-column-count:3;-ms-column-count:3;-o-column-count:3;column-count:3}div.dt-button-collection.four-column{width:600px;padding-bottom:1px;-webkit-column-count:4;-moz-column-count:4;-ms-column-count:4;-o-column-count:4;column-count:4}div.dt-button-background{position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.7);background:-ms-radial-gradient(center, ellipse farthest-corner, rgba(0,0,0,0.3) 0%, rgba(0,0,0,0.7) 100%);background:-moz-radial-gradient(center, ellipse farthest-corner, rgba(0,0,0,0.3) 0%, rgba(0,0,0,0.7) 100%);background:-o-radial-gradient(center, ellipse farthest-corner, rgba(0,0,0,0.3) 0%, rgba(0,0,0,0.7) 100%);background:-webkit-gradient(radial, center center, 0, center center, 497, color-stop(0, rgba(0,0,0,0.3)), color-stop(1, rgba(0,0,0,0.7)));background:-webkit-radial-gradient(center, ellipse farthest-corner, rgba(0,0,0,0.3) 0%, rgba(0,0,0,0.7) 100%);background:radial-gradient(ellipse farthest-corner at center, rgba(0,0,0,0.3) 0%, rgba(0,0,0,0.7) 100%);z-index:2001}@media screen and (max-width: 640px){div.dt-buttons{float:none !important;text-align:center}} 2 | -------------------------------------------------------------------------------- /Android_debugdata_webtool/app/src/main/java/com/itgowo/tool/android_debugdata_webtool/DBManager.java: -------------------------------------------------------------------------------- 1 | package com.itgowo.tool.android_debugdata_webtool; 2 | 3 | import android.app.Application; 4 | import android.content.ContentValues; 5 | import android.content.Context; 6 | import android.database.Cursor; 7 | import android.database.sqlite.SQLiteDatabase; 8 | import android.database.sqlite.SQLiteOpenHelper; 9 | 10 | import java.lang.reflect.Field; 11 | import java.util.ArrayList; 12 | import java.util.Iterator; 13 | import java.util.List; 14 | 15 | /** 16 | * Created by lujianchao on 2017/6/14. 17 | */ 18 | 19 | public class DBManager { 20 | private static Application sApp; 21 | 22 | public static String DBName = "appinfo.db"; 23 | public static Class TableClass = HistoryCache.class; 24 | 25 | public static void init(Application mApplication,String mDBName,Class mTableClass) { 26 | DBName=mDBName; 27 | sApp = mApplication; 28 | if (mTableClass!=null){ 29 | TableClass=mTableClass; 30 | } 31 | } 32 | 33 | 34 | private static final String CREATE_CacheTABLE = "create table "+TableClass.getSimpleName()+" (id integer primary key autoincrement, key text, value text, lasttime long, bak text, flag text)"; 35 | /** 36 | * 更改类文件必须更改版本号,否则不会更新缓存结构 37 | */ 38 | public static final int DBVersion = 1; 39 | private static DBHelper mCacheDBHelper; 40 | private static SQLiteDatabase mSQLiteDatabase; 41 | 42 | /** 43 | * 删除数据库 44 | */ 45 | public synchronized static void deleteDB() { 46 | sApp.deleteDatabase(DBName); 47 | } 48 | 49 | /** 50 | * 更新缓存 51 | * 52 | * @param key 预定义名称 53 | * @param value 待缓存数据 54 | */ 55 | public synchronized static void updateCache(String key, String value) { 56 | if (mCacheDBHelper == null) { 57 | mCacheDBHelper = new DBHelper(sApp, DBName, null, DBVersion); 58 | } 59 | if (mSQLiteDatabase == null) { 60 | mSQLiteDatabase = mCacheDBHelper.getWritableDatabase(); 61 | } 62 | ContentValues m = new ContentValues(); 63 | m.put("value", value); 64 | m.put("lasttime", System.currentTimeMillis()); 65 | try { 66 | mSQLiteDatabase.update(HistoryCache.class.getSimpleName(), m, "key=?", new String[]{key}); 67 | } catch (Exception mE) { 68 | mE.printStackTrace(); 69 | } 70 | } 71 | 72 | /** 73 | * 尽量不用,数据会越来越多 74 | * 75 | * @param key 76 | * @param value 77 | */ 78 | public synchronized static void addCache(String key, String value) { 79 | if (mCacheDBHelper == null) { 80 | mCacheDBHelper = new DBHelper(sApp, DBName, null, DBVersion); 81 | } 82 | if (mSQLiteDatabase == null) { 83 | mSQLiteDatabase = mCacheDBHelper.getWritableDatabase(); 84 | } 85 | ContentValues m = new ContentValues(); 86 | m.put("key", key); 87 | m.put("value", value); 88 | m.put("lasttime", System.currentTimeMillis()); 89 | try { 90 | mSQLiteDatabase.insert(HistoryCache.class.getSimpleName(), null, m); 91 | } catch (Exception mE) { 92 | mE.printStackTrace(); 93 | } 94 | } 95 | 96 | /** 97 | * 获取缓存数据 98 | * 99 | * @param key 预定义名称 100 | * @return 缓存数据,异常或者不存在则返回null 101 | */ 102 | public static String getCache(String key) { 103 | String string = null; 104 | if (mCacheDBHelper == null) { 105 | mCacheDBHelper = new DBHelper(sApp, DBName, null, DBVersion); 106 | } 107 | if (mSQLiteDatabase == null) { 108 | mSQLiteDatabase = mCacheDBHelper.getWritableDatabase(); 109 | } 110 | Cursor mCursor = null; 111 | try { 112 | mCursor = mSQLiteDatabase.rawQuery("select * from " + HistoryCache.class.getSimpleName() + " where key=?", new String[]{key}); 113 | if (mCursor != null && mCursor.getCount() == 1) { 114 | mCursor.moveToNext(); 115 | string = mCursor.getString(2); 116 | } 117 | } catch (Exception mE) { 118 | mE.printStackTrace(); 119 | } finally { 120 | if (mCursor != null) { 121 | mCursor.close(); 122 | } 123 | return string; 124 | 125 | } 126 | 127 | } 128 | 129 | /** 130 | * Created by lujianchao on 2016/11/29. 131 | * SQLiteOpenHelper 132 | * 133 | * @author lujianchao 134 | */ 135 | public static class DBHelper extends SQLiteOpenHelper { 136 | 137 | 138 | public DBHelper(final Context context, final String name, final SQLiteDatabase.CursorFactory factory, final int version) { 139 | super(context, name, factory, version); 140 | } 141 | 142 | @Override 143 | public void onCreate(final SQLiteDatabase db) { 144 | db.execSQL(CREATE_CacheTABLE); 145 | updatetable(db, TableClass); 146 | } 147 | 148 | @Override 149 | public void onUpgrade(final SQLiteDatabase db, final int oldVersion, final int newVersion) { 150 | updatetable(db, TableClass); 151 | } 152 | 153 | /** 154 | * 传入的类名即为表名,传入的类的属性即为表内的记录,字段固定,用来实现动态增减记录,记录为缓存内容,所以数量较少, 155 | * 只需要更改实体类属性,就可以管理数据库了,动态升级。 156 | * 157 | * @param db 158 | * @param mClass 159 | */ 160 | private void updatetable(final SQLiteDatabase db, Class mClass) { 161 | /** 162 | * 通过反射拿到当前所有cache名 163 | */ 164 | List mList = new ArrayList<>(); 165 | Field[] fields = mClass.getDeclaredFields(); 166 | for (Field fd : fields) { 167 | fd.setAccessible(true); 168 | if (!fd.getName().equals("serialVersionUID") && !fd.getName().equals("$change")) { 169 | mList.add(fd.getName()); 170 | } 171 | } 172 | Cursor mCursor = db.rawQuery("select * from " + mClass.getSimpleName(), null); 173 | while (mCursor.moveToNext()) { 174 | boolean ishave = false; 175 | String string = mCursor.getString(1); 176 | Iterator mStringIterator = mList.iterator(); 177 | while (mStringIterator.hasNext()) { 178 | if (mStringIterator.next().equals(string)) { 179 | ishave = true; 180 | mStringIterator.remove(); 181 | break; 182 | } 183 | } 184 | /** 185 | * 类里没有这个缓存名就将其删掉 186 | */ 187 | if (!ishave) { 188 | db.delete(mClass.getSimpleName(), "key=?", new String[]{string}); 189 | } 190 | } 191 | mCursor.close(); 192 | for (int mI = 0; mI < mList.size(); mI++) { 193 | ContentValues values = new ContentValues(); 194 | values.put("key", mList.get(mI)); 195 | values.put("lasttime", System.currentTimeMillis()); 196 | db.insert(mClass.getSimpleName(), null, values); 197 | } 198 | } 199 | } 200 | 201 | /** 202 | * Created by lujianchao on 2016/11/29. 203 | * 数据结构 204 | * 添加或者删除属性变量值,都必须更改数据库版本号,否则不会修改 205 | * 206 | * @author lujianchao 207 | */ 208 | 209 | public static class HistoryCache { 210 | /** 211 | * 新派队首页 212 | */ 213 | public static String GetHomeInfo = "GetHomeInfo"; 214 | 215 | /** 216 | * 运动项目列表 217 | */ 218 | public static String getSportItemListByParams = "getSportItemListByParams"; 219 | public static String TestA = "TestA"; 220 | public static String TestB = "TestB"; 221 | public static String TestC = "TestC"; 222 | } 223 | } 224 | -------------------------------------------------------------------------------- /Android_debugdata_webtool/webtoollibrary/src/main/java/android_debugdata_webtool/tool/itgowo/com/webtoollibrary/DebugDataTool.java: -------------------------------------------------------------------------------- 1 | package android_debugdata_webtool.tool.itgowo.com.webtoollibrary; 2 | 3 | import android.content.Context; 4 | import android.util.Log; 5 | 6 | import java.io.File; 7 | import java.io.IOException; 8 | import java.lang.reflect.InvocationTargetException; 9 | import java.lang.reflect.Method; 10 | import java.util.HashMap; 11 | 12 | import android_debugdata_webtool.tool.itgowo.com.webtoollibrary.utils.NetworkUtils; 13 | 14 | /** 15 | * Created by lujianchao on 2017/8/22. 16 | */ 17 | 18 | public class DebugDataTool { 19 | 20 | private static final String TAG = DebugDataTool.class.getSimpleName(); 21 | public static final String WARNING_JSON = "not found fastjson,not found Gson,onDebugToolListener is null,如果使用默认方式实现Json工具的方式,请在主工程中使用fastjson或者Gson库,或者实现自定义Json方法,不然无法处理Json,此工具内部不集成任何第三方,绿色无公害(ˇˍˇ) 想~"; 22 | private static final int DEFAULT_PORT = 8080; 23 | private static ClientServer clientServer; 24 | 25 | private static String addressLog = "not available"; 26 | private static onDebugToolListener mToolListener; 27 | private static Class mFastJson = null; 28 | private static Object mGsonJson = null; 29 | private static boolean isFastJson = true; 30 | private static Method mJsonMethodToJsonString = null; 31 | private static Method mJsonMethodToJsonObject = null; 32 | 33 | 34 | private DebugDataTool() { 35 | } 36 | 37 | protected static String ObjectToJson(Object mO) { 38 | if (mO != null) { 39 | if (mToolListener == null) { 40 | if (isFastJson) { 41 | try { 42 | return (String) mJsonMethodToJsonString.invoke(null, mO); 43 | } catch (IllegalAccessException mE) { 44 | mE.printStackTrace(); 45 | } catch (InvocationTargetException mE) { 46 | mE.printStackTrace(); 47 | } 48 | } else { 49 | try { 50 | return (String) mJsonMethodToJsonString.invoke(mGsonJson, mO); 51 | } catch (IllegalAccessException mE) { 52 | mE.printStackTrace(); 53 | } catch (InvocationTargetException mE) { 54 | mE.printStackTrace(); 55 | } 56 | } 57 | } 58 | return mToolListener.onObjectToJson(mO); 59 | } 60 | return ""; 61 | } 62 | 63 | protected static T JsonToObject(String mJsonString, Class mClass) { 64 | if (mJsonString != null && mClass != null) { 65 | if (mToolListener == null) { 66 | if (isFastJson) { 67 | try { 68 | return (T) mJsonMethodToJsonObject.invoke(null, mJsonString, mClass); 69 | } catch (IllegalAccessException mE) { 70 | mE.printStackTrace(); 71 | } catch (InvocationTargetException mE) { 72 | mE.printStackTrace(); 73 | } 74 | } else { 75 | try { 76 | return (T) mJsonMethodToJsonObject.invoke(mGsonJson, mJsonString, mClass); 77 | } catch (IllegalAccessException mE) { 78 | mE.printStackTrace(); 79 | } catch (InvocationTargetException mE) { 80 | mE.printStackTrace(); 81 | } 82 | } 83 | } 84 | return mToolListener.onJsonStringToObject(mJsonString, mClass); 85 | } 86 | return null; 87 | } 88 | 89 | protected static void onRequest(String mS, HttpRequest mHttpRequest) { 90 | if (mS == null || mS.equals("")) { 91 | return; 92 | } 93 | if (mToolListener == null) { 94 | Log.d(TAG, mS + "\r\n" + mHttpRequest); 95 | } else { 96 | mToolListener.onGetRequest(mS, mHttpRequest); 97 | } 98 | } 99 | 100 | 101 | protected static void onResponse(String mS) { 102 | if (mToolListener == null) { 103 | Log.d(TAG, mS); 104 | } else { 105 | mToolListener.onResponse(mS); 106 | } 107 | } 108 | 109 | public synchronized static void initialize(Context context, int mPortNumber, boolean isMultMode, onDebugToolListener mOnDebugToolListener) { 110 | if (clientServer != null ) { 111 | try { 112 | clientServer.resetServerPort(mPortNumber); 113 | } catch (IOException mE) { 114 | mE.printStackTrace(); 115 | } catch (InterruptedException mE) { 116 | mE.printStackTrace(); 117 | } 118 | } else { 119 | mToolListener = mOnDebugToolListener; 120 | int portNumber; 121 | if (mPortNumber < 10) { 122 | portNumber = DEFAULT_PORT; 123 | } else { 124 | portNumber = mPortNumber; 125 | } 126 | if (mOnDebugToolListener == null) { 127 | onSystemMsg("未设置onDebugToolListener,自动搜索当前APP内使用的Json工具,目前支持FastJson和Gson"); 128 | if (!searchJsonTool()) { 129 | return; 130 | } 131 | } 132 | clientServer = new ClientServer(context, portNumber, isMultMode); 133 | clientServer.start(); 134 | addressLog = NetworkUtils.getAddressLog(context, portNumber); 135 | Log.d(TAG, "Open http://" + addressLog + " in your browser"); 136 | Log.d(TAG, "请用浏览器打开 http://" + addressLog); 137 | DebugDataTool.onSystemMsg("请用浏览器打开 http://" + addressLog); 138 | } 139 | // System.out.println(TAG + " 请用浏览器打开 http://" + addressLog); 140 | } 141 | 142 | /** 143 | * 用反射检查APP内集成的Json工具。 144 | * 145 | * @return 是否找到并初始化 146 | */ 147 | protected static boolean searchJsonTool() { 148 | try { 149 | mFastJson = Class.forName("com.alibaba.fastjson.JSON"); 150 | isFastJson = true; 151 | mJsonMethodToJsonString = mFastJson.getMethod("toJSONString", Object.class); 152 | mJsonMethodToJsonObject = mFastJson.getMethod("parseObject", String.class, Class.class); 153 | } catch (ClassNotFoundException mE) { 154 | 155 | } catch (NoSuchMethodException mE) { 156 | 157 | } 158 | if (mFastJson == null || mJsonMethodToJsonString == null || mJsonMethodToJsonObject == null) { 159 | isFastJson = false; 160 | try { 161 | Class mGsonClass = Class.forName("com.google.gson.Gson"); 162 | mGsonJson = mGsonClass.newInstance(); 163 | mJsonMethodToJsonObject = mGsonClass.getDeclaredMethod("fromJson", String.class, Class.class); 164 | mJsonMethodToJsonString = mGsonClass.getDeclaredMethod("toJson", Object.class); 165 | } catch (ClassNotFoundException mE) { 166 | 167 | } catch (NoSuchMethodException mE) { 168 | mE.printStackTrace(); 169 | } catch (IllegalAccessException mE) { 170 | mE.printStackTrace(); 171 | } catch (InstantiationException mE) { 172 | mE.printStackTrace(); 173 | } 174 | } 175 | if (mFastJson == null && mGsonJson == null || mJsonMethodToJsonString == null || mJsonMethodToJsonObject == null) { 176 | onError("警告", new Throwable(WARNING_JSON)); 177 | onSystemMsg(WARNING_JSON); 178 | return false; 179 | } 180 | return true; 181 | 182 | } 183 | 184 | protected static void onSystemMsg(String mS) { 185 | if (mToolListener == null) { 186 | Log.i(TAG, mS); 187 | } else { 188 | mToolListener.onSystemMsg(mS); 189 | } 190 | } 191 | 192 | protected static void onError(String mTip, Throwable mThrowable) { 193 | if (mToolListener == null) { 194 | Log.e(TAG, mTip, mThrowable); 195 | } else { 196 | mToolListener.onError(mTip, mThrowable); 197 | } 198 | } 199 | 200 | public static String getAddressLog() { 201 | Log.d(TAG, addressLog); 202 | return addressLog; 203 | } 204 | 205 | public static void shutDown() { 206 | if (clientServer != null) { 207 | clientServer.stop(); 208 | clientServer = null; 209 | } 210 | } 211 | 212 | /** 213 | * 指定appdata之外的可读数据库文件 214 | * 215 | * @param customDatabaseFiles 216 | */ 217 | public static void setCustomDatabaseFiles(HashMap customDatabaseFiles) { 218 | if (clientServer != null) { 219 | clientServer.setCustomDatabaseFiles(customDatabaseFiles); 220 | } 221 | } 222 | 223 | public static boolean isServerRunning() { 224 | return clientServer != null && clientServer.isRunning(); 225 | } 226 | 227 | } 228 | -------------------------------------------------------------------------------- /Android_debugdata_webtool/webtoollibrary/src/main/java/android_debugdata_webtool/tool/itgowo/com/webtoollibrary/RequestHandler.java: -------------------------------------------------------------------------------- 1 | 2 | 3 | package android_debugdata_webtool.tool.itgowo.com.webtoollibrary; 4 | 5 | import android.content.Context; 6 | import android.content.res.AssetManager; 7 | import android.text.TextUtils; 8 | 9 | import java.io.File; 10 | import java.io.IOException; 11 | import java.io.InputStream; 12 | import java.io.PrintStream; 13 | import java.net.Socket; 14 | import java.util.HashMap; 15 | import java.util.concurrent.ExecutorService; 16 | import java.util.concurrent.Executors; 17 | 18 | import android_debugdata_webtool.tool.itgowo.com.webtoollibrary.action.Action; 19 | import android_debugdata_webtool.tool.itgowo.com.webtoollibrary.action.ActionAddDataToDb; 20 | import android_debugdata_webtool.tool.itgowo.com.webtoollibrary.action.ActionAddDataToSp; 21 | import android_debugdata_webtool.tool.itgowo.com.webtoollibrary.action.ActionDeleteDataFromDb; 22 | import android_debugdata_webtool.tool.itgowo.com.webtoollibrary.action.ActionDeleteDataFromSp; 23 | import android_debugdata_webtool.tool.itgowo.com.webtoollibrary.action.ActionDeleteFile; 24 | import android_debugdata_webtool.tool.itgowo.com.webtoollibrary.action.ActionGetDataFromDbTable; 25 | import android_debugdata_webtool.tool.itgowo.com.webtoollibrary.action.ActionGetDataFromSpFile; 26 | import android_debugdata_webtool.tool.itgowo.com.webtoollibrary.action.ActionGetDbList; 27 | import android_debugdata_webtool.tool.itgowo.com.webtoollibrary.action.ActionGetFileList; 28 | import android_debugdata_webtool.tool.itgowo.com.webtoollibrary.action.ActionGetSpList; 29 | import android_debugdata_webtool.tool.itgowo.com.webtoollibrary.action.ActionGetTableList; 30 | import android_debugdata_webtool.tool.itgowo.com.webtoollibrary.action.ActionQuery; 31 | import android_debugdata_webtool.tool.itgowo.com.webtoollibrary.action.ActionUpdateDataToDb; 32 | import android_debugdata_webtool.tool.itgowo.com.webtoollibrary.action.ActionUpdateDataToSp; 33 | import android_debugdata_webtool.tool.itgowo.com.webtoollibrary.utils.Utils; 34 | 35 | /** 36 | * Created by lujianchao on 2017/8/22. 37 | */ 38 | 39 | public class RequestHandler { 40 | private final Context context; 41 | private final AssetManager assetManager; 42 | private HashMap dispatcher = new HashMap<>(); 43 | private ExecutorService executorService = Executors.newFixedThreadPool(3); 44 | 45 | public RequestHandler(Context context) { 46 | this.context = context; 47 | assetManager = context.getResources().getAssets(); 48 | dispatcher.put(ActionGetDbList.ACTION, new ActionGetDbList()); 49 | dispatcher.put(ActionGetSpList.ACTION, new ActionGetSpList()); 50 | dispatcher.put(ActionGetTableList.ACTION, new ActionGetTableList()); 51 | dispatcher.put(ActionGetDataFromDbTable.ACTION, new ActionGetDataFromDbTable()); 52 | dispatcher.put(ActionGetDataFromSpFile.ACTION, new ActionGetDataFromSpFile()); 53 | dispatcher.put(ActionAddDataToDb.ACTION, new ActionAddDataToDb()); 54 | dispatcher.put(ActionAddDataToSp.ACTION, new ActionAddDataToSp()); 55 | dispatcher.put(ActionUpdateDataToDb.ACTION, new ActionUpdateDataToDb()); 56 | dispatcher.put(ActionUpdateDataToSp.ACTION, new ActionUpdateDataToSp()); 57 | dispatcher.put(ActionDeleteDataFromDb.ACTION, new ActionDeleteDataFromDb()); 58 | dispatcher.put(ActionDeleteDataFromSp.ACTION, new ActionDeleteDataFromSp()); 59 | dispatcher.put(ActionQuery.ACTION, new ActionQuery()); 60 | dispatcher.put(ActionGetFileList.ACTION, new ActionGetFileList()); 61 | dispatcher.put(ActionDeleteFile.ACTION, new ActionDeleteFile()); 62 | } 63 | 64 | 65 | /** 66 | * 多线程处理 67 | * 68 | * @param socket 69 | */ 70 | public void asynHandle(final Socket socket) { 71 | executorService.execute(new Runnable() { 72 | @Override 73 | public void run() { 74 | try { 75 | syncHandle(socket); 76 | } catch (Exception mE) { 77 | DebugDataTool.onError("web server:received request error,分配并处理数据异常", mE); 78 | } 79 | } 80 | }); 81 | } 82 | 83 | public void syncHandle(Socket socket) throws Exception { 84 | InputStream inputStream = null; 85 | PrintStream printStream = null; 86 | try { 87 | int count = 0; 88 | StringBuilder stringBuilder = new StringBuilder(); 89 | inputStream = socket.getInputStream(); 90 | byte[] bytes1 = new byte[1024]; 91 | while (true) { 92 | count = inputStream.read(bytes1); 93 | if (count > 0) { 94 | stringBuilder.append(new String(bytes1, 0, count)); 95 | } 96 | if (count < 1024) { 97 | break; 98 | } 99 | } 100 | HttpRequest httpRequest = null; 101 | try { 102 | httpRequest = HttpRequest.parser(stringBuilder.toString().trim()); 103 | } catch (Exception mE) { 104 | DebugDataTool.onError("web server:RequestHandler error,http请求解析异常", mE); 105 | } 106 | if (httpRequest == null) { 107 | return; 108 | } 109 | // Output stream that we send the response to 110 | printStream = new PrintStream(socket.getOutputStream()); 111 | ResponseHandler responseHandler = new ResponseHandler(printStream); 112 | if ("OPTIONS".equalsIgnoreCase(httpRequest.getMethod())) { 113 | responseHandler.onRequestOptions(); 114 | } else if ("POST".equalsIgnoreCase(httpRequest.getMethod())) { 115 | DebugDataTool.onRequest(stringBuilder.toString(), httpRequest); 116 | onRequestPost(httpRequest, responseHandler); 117 | } else if ("GET".equalsIgnoreCase(httpRequest.getMethod())) { 118 | onRequestGet(httpRequest, responseHandler); 119 | } 120 | socket.close(); 121 | } finally { 122 | try { 123 | if (null != printStream) { 124 | printStream.close(); 125 | } 126 | if (null != inputStream) { 127 | inputStream.close(); 128 | } 129 | if (socket != null) { 130 | socket.close(); 131 | } 132 | } catch (Exception e) { 133 | DebugDataTool.onError("web server:close request error,http请求解析结束处理异常", e); 134 | } 135 | } 136 | 137 | } 138 | 139 | private void onRequestGet(HttpRequest httpRequest, ResponseHandler responseHandler) throws IOException { 140 | byte[] bytes = null; 141 | if (TextUtils.isEmpty(httpRequest.getPath())) {//index.html 142 | httpRequest.setPath("index.html"); 143 | } 144 | File file = null; 145 | //文件请求 146 | if (httpRequest.getPath().equals("downloadFile")) { 147 | file = new File(httpRequest.getParameter().get("downloadFile")); 148 | if (file.exists()) { 149 | bytes = Utils.getFile(new File(httpRequest.getParameter().get("downloadFile"))); 150 | } 151 | } else { 152 | bytes = Utils.loadContent(httpRequest.getPath(), assetManager); 153 | file = new File(httpRequest.getPath()); 154 | } 155 | DebugDataTool.onRequest(httpRequest.getPath(), httpRequest); 156 | if (null == bytes) { 157 | responseHandler.onServerNotFound("请求的资源不存在"); 158 | } else { 159 | responseHandler.onServerGetFile(!httpRequest.getPath().equals("index.html"), httpRequest.getPath(), Utils.detectMimeType(httpRequest.getPath()), bytes); 160 | } 161 | } 162 | 163 | private void onRequestPost(HttpRequest httpRequest, ResponseHandler responseHandler) throws Exception { 164 | Response response = null; 165 | //post请求数据 166 | Request request = null; 167 | try { 168 | request = DebugDataTool.JsonToObject(httpRequest.getBody(), Request.class); 169 | } catch (Exception e) { 170 | String msg = "web server:Request error,http请求解析异常 "; 171 | DebugDataTool.onError(msg, e); 172 | response = new Response().setCode(Response.code_Error).setMsg(msg + e.getMessage()); 173 | } 174 | if (response == null) { 175 | if (request == null || TextUtils.isEmpty(request.getAction())) { 176 | String msg = "web server:Request data is null or action is null,http请求没有action,无法解析操作"; 177 | DebugDataTool.onError(msg, new Throwable("action is null")); 178 | response = new Response().setCode(Response.code_Error).setMsg(msg); 179 | } 180 | } 181 | if (response == null) { 182 | try { 183 | Action action = dispatcher.get(request.getAction()); 184 | if (action != null) { 185 | action.doAction(context, request, httpRequest, responseHandler); 186 | } 187 | } catch (Exception e) { 188 | String msg = "web server:action error(" + request.getAction() + "),参数处理异常"; 189 | DebugDataTool.onError(msg, e); 190 | responseHandler.onServerPostError(msg + e.getLocalizedMessage()); 191 | } 192 | } 193 | } 194 | 195 | 196 | } 197 | -------------------------------------------------------------------------------- /Android_debugdata_webtool/webtoollibrary/src/main/java/android_debugdata_webtool/tool/itgowo/com/webtoollibrary/utils/PrefHelper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * * Copyright (C) 2016 Amit Shekhar 4 | * * Copyright (C) 2011 Android Open Source Project 5 | * * 6 | * * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * * you may not use this file except in compliance with the License. 8 | * * You may obtain a copy of the License at 9 | * * 10 | * * http://www.apache.org/licenses/LICENSE-2.0 11 | * * 12 | * * Unless required by applicable law or agreed to in writing, software 13 | * * distributed under the License is distributed on an "AS IS" BASIS, 14 | * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * * See the License for the specific language governing permissions and 16 | * * limitations under the License. 17 | * 18 | */ 19 | 20 | package android_debugdata_webtool.tool.itgowo.com.webtoollibrary.utils; 21 | 22 | import android.content.Context; 23 | import android.content.SharedPreferences; 24 | 25 | import org.json.JSONArray; 26 | 27 | import java.io.File; 28 | import java.util.ArrayList; 29 | import java.util.Collections; 30 | import java.util.HashSet; 31 | import java.util.List; 32 | import java.util.Map; 33 | import java.util.Set; 34 | import java.util.TreeMap; 35 | 36 | import android_debugdata_webtool.tool.itgowo.com.webtoollibrary.Request.RowDataRequest; 37 | import android_debugdata_webtool.tool.itgowo.com.webtoollibrary.Response; 38 | 39 | import static android_debugdata_webtool.tool.itgowo.com.webtoollibrary.utils.DatabaseHelper.BOOLEAN; 40 | import static android_debugdata_webtool.tool.itgowo.com.webtoollibrary.utils.DatabaseHelper.FLOAT; 41 | import static android_debugdata_webtool.tool.itgowo.com.webtoollibrary.utils.DatabaseHelper.INTEGER; 42 | import static android_debugdata_webtool.tool.itgowo.com.webtoollibrary.utils.DatabaseHelper.LONG; 43 | import static android_debugdata_webtool.tool.itgowo.com.webtoollibrary.utils.DatabaseHelper.STRING_SET; 44 | import static android_debugdata_webtool.tool.itgowo.com.webtoollibrary.utils.DatabaseHelper.TEXT; 45 | 46 | /** 47 | * Created by lujianchao on 2017/8/22. 48 | */ 49 | 50 | public class PrefHelper { 51 | 52 | private static final String PREFS_SUFFIX = ".xml"; 53 | 54 | private PrefHelper() { 55 | // This class in not publicly instantiable 56 | } 57 | 58 | public static TreeMap getSharedPreference(Context mContext) { 59 | TreeMap tags = new TreeMap<>(); 60 | 61 | String rootPath = mContext.getApplicationInfo().dataDir + "/shared_prefs"; 62 | File root = new File(rootPath); 63 | if (root.exists()) { 64 | for (File file : root.listFiles()) { 65 | String fileName = file.getName(); 66 | if (file.getName().endsWith(PREFS_SUFFIX)) { 67 | fileName = file.getName().substring(0, file.getName().length() - PREFS_SUFFIX.length()); 68 | } 69 | tags.put(fileName, file); 70 | } 71 | } 72 | return tags; 73 | } 74 | 75 | public static List getSharedPreferenceTags(Context context) { 76 | ArrayList tags = new ArrayList<>(); 77 | String rootPath = context.getApplicationInfo().dataDir + "/shared_prefs"; 78 | File root = new File(rootPath); 79 | if (root.exists()) { 80 | for (File file : root.listFiles()) { 81 | String fileName = file.getName(); 82 | if (fileName.endsWith(PREFS_SUFFIX)) { 83 | tags.add(new Response.FileList.FileData().setFileName(fileName.substring(0, fileName.length() - PREFS_SUFFIX.length())).setPath(file.getPath())); 84 | } 85 | } 86 | } 87 | Collections.sort(tags); 88 | return tags; 89 | } 90 | 91 | /** 92 | * 获取共享参数list 93 | * 94 | * @param context 95 | * @return 96 | */ 97 | public static Response getAllPrefData(Context context, String filename) { 98 | 99 | Response response = new Response(); 100 | response.setEditable(true); 101 | 102 | /** 103 | * 设置表结构 104 | */ 105 | Response.TableData.TableInfo keyInfo = new Response.TableData.TableInfo(); 106 | keyInfo.setPrimary(true).setTitle("Key"); 107 | Response.TableData.TableInfo valueInfo = new Response.TableData.TableInfo(); 108 | valueInfo.setPrimary(false).setTitle("Value"); 109 | Response.TableData.TableInfo typeInfo = new Response.TableData.TableInfo(); 110 | typeInfo.setPrimary(false).setTitle("DataType"); 111 | 112 | Response.TableData mTableData = new Response.TableData(); 113 | mTableData.setTableColumns(new ArrayList()); 114 | mTableData.getTableColumns().add(keyInfo); 115 | mTableData.getTableColumns().add(valueInfo); 116 | mTableData.getTableColumns().add(typeInfo); 117 | response.setTableData(mTableData); 118 | SharedPreferences preferences = context.getSharedPreferences(filename, Context.MODE_PRIVATE); 119 | Map allEntries = preferences.getAll(); 120 | 121 | mTableData.setTableDatas(new ArrayList>()); 122 | for (Map.Entry entry : allEntries.entrySet()) { 123 | List row = new ArrayList<>(); 124 | row.add(entry.getKey()); 125 | row.add(entry.getValue()); 126 | if (entry.getValue() != null) { 127 | if (entry.getValue() instanceof String) { 128 | row.add(TEXT); 129 | } else if (entry.getValue() instanceof Integer) { 130 | row.add(INTEGER); 131 | } else if (entry.getValue() instanceof Long) { 132 | row.add(LONG); 133 | } else if (entry.getValue() instanceof Float) { 134 | row.add(FLOAT); 135 | } else if (entry.getValue() instanceof Boolean) { 136 | row.add(BOOLEAN); 137 | } else if (entry.getValue() instanceof Set) { 138 | row.add(STRING_SET); 139 | } 140 | } else { 141 | row.add(TEXT); 142 | } 143 | mTableData.getTableDatas().add(row); 144 | } 145 | 146 | return response; 147 | 148 | } 149 | 150 | public static Response addOrUpdateRow(Context context, String fileName, List rowDataRequests) { 151 | Response updateRowResponse = new Response(); 152 | if (fileName == null) { 153 | return updateRowResponse.setCode(Response.code_Error).setMsg("共享参数文件名未指定"); 154 | } 155 | if (rowDataRequests == null || rowDataRequests.size() == 0) { 156 | return updateRowResponse.setCode(Response.code_Error).setMsg("rowDataRequests操作数据不存在,请确认参数是否正确"); 157 | } 158 | RowDataRequest rowDataKey = rowDataRequests.get(0); 159 | RowDataRequest rowDataValue = rowDataRequests.get(1); 160 | 161 | String key = rowDataKey.value; 162 | String value = rowDataValue.value; 163 | String dataType = rowDataValue.dataType; 164 | 165 | if (Constants.NULL.equals(value)) { 166 | value = null; 167 | } 168 | SharedPreferences preferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); 169 | try { 170 | switch (dataType) { 171 | case TEXT: 172 | preferences.edit().putString(key, value).apply(); 173 | break; 174 | case INTEGER: 175 | preferences.edit().putInt(key, Integer.valueOf(value)).apply(); 176 | break; 177 | case LONG: 178 | preferences.edit().putLong(key, Long.valueOf(value)).apply(); 179 | break; 180 | case FLOAT: 181 | preferences.edit().putFloat(key, Float.valueOf(value)).apply(); 182 | break; 183 | case BOOLEAN: 184 | preferences.edit().putBoolean(key, Boolean.valueOf(value)).apply(); 185 | break; 186 | case STRING_SET: 187 | JSONArray jsonArray = new JSONArray(value); 188 | Set stringSet = new HashSet<>(); 189 | for (int i = 0; i < jsonArray.length(); i++) { 190 | stringSet.add(jsonArray.getString(i)); 191 | } 192 | preferences.edit().putStringSet(key, stringSet).apply(); 193 | break; 194 | default: 195 | preferences.edit().putString(key, value).apply(); 196 | } 197 | } catch (Exception e) { 198 | e.printStackTrace(); 199 | updateRowResponse.setCode(Response.code_Error).setMsg("web server:SP addOrUpdateRow error,参数处理异常 " + e.getMessage()); 200 | } 201 | 202 | return updateRowResponse; 203 | } 204 | 205 | 206 | public static Response deleteRow(Context context, String fileName, List rowDataRequests) { 207 | Response updateRowResponse = new Response(); 208 | 209 | if (fileName == null) { 210 | return updateRowResponse.setCode(Response.code_Error).setMsg("共享参数文件名未指定"); 211 | } 212 | if (rowDataRequests == null || rowDataRequests.size() == 0) { 213 | return updateRowResponse.setCode(Response.code_Error).setMsg("rowDataRequests操作数据不存在,请确认参数是否正确"); 214 | } 215 | RowDataRequest rowDataKey = rowDataRequests.get(0); 216 | String key = rowDataKey.value; 217 | SharedPreferences preferences = context.getSharedPreferences(fileName, Context.MODE_PRIVATE); 218 | try { 219 | preferences.edit().remove(key).apply(); 220 | } catch (Exception ex) { 221 | updateRowResponse.setCode(Response.code_Error).setMsg("共享参数删除错误 " + ex.getMessage()); 222 | } 223 | return updateRowResponse; 224 | } 225 | } 226 | -------------------------------------------------------------------------------- /Android_debugdata_webtool/webtoollibrary/src/main/java/android_debugdata_webtool/tool/itgowo/com/webtoollibrary/Response.java: -------------------------------------------------------------------------------- 1 | package android_debugdata_webtool.tool.itgowo.com.webtoollibrary; 2 | 3 | 4 | 5 | import java.util.Comparator; 6 | import java.util.List; 7 | 8 | /** 9 | * Created by lujianchao on 2017/8/22. 10 | */ 11 | 12 | public class Response { 13 | public static final int code_OK = 200; 14 | public static final int code_Error = 201; 15 | public static final int code_SQLERROR = 202; 16 | public static final int code_SQLNODATA = 203; 17 | public static final int code_FileNotFound = 204; 18 | private int code = code_OK; 19 | private String msg = "success"; 20 | private String action; 21 | private Integer dbVersion; 22 | /** 23 | * 数据库列表 24 | */ 25 | private List dbList; 26 | /** 27 | * 共享参数列表 28 | */ 29 | private List spList; 30 | /** 31 | * 数据库中所有表 32 | */ 33 | private List tableList; 34 | 35 | 36 | private TableData tableData; 37 | 38 | 39 | /** 40 | * 是否可编辑数据 41 | */ 42 | private Boolean isEditable; 43 | private FileList fileList; 44 | 45 | public FileList getFileList() { 46 | return fileList; 47 | } 48 | 49 | public Response setFileList(FileList mFileList) { 50 | fileList = mFileList; 51 | return this; 52 | } 53 | 54 | public static class FileList{ 55 | private List fileList; 56 | private List mFileColumns; 57 | 58 | public List getFileList() { 59 | return fileList; 60 | } 61 | 62 | public FileList setFileList(List mFileList) { 63 | fileList = mFileList; 64 | return this; 65 | } 66 | 67 | public List getFileColumns() { 68 | return mFileColumns; 69 | } 70 | 71 | public FileList setFileColumns(List mFileColumns) { 72 | this.mFileColumns = mFileColumns; 73 | return this; 74 | } 75 | 76 | public static class FileColumn{ 77 | private String rootPath; 78 | private String title; 79 | private String data; 80 | 81 | public String getRootPath() { 82 | return rootPath; 83 | } 84 | 85 | public FileColumn setRootPath(String mRootPath) { 86 | rootPath = mRootPath; 87 | return this; 88 | } 89 | 90 | public String getTitle() { 91 | return title; 92 | } 93 | 94 | public FileColumn setTitle(String mTitle) { 95 | title = mTitle; 96 | return this; 97 | } 98 | 99 | public String getData() { 100 | return data; 101 | } 102 | 103 | public FileColumn setData(String mData) { 104 | data = mData; 105 | return this; 106 | } 107 | } 108 | public static class FileData implements Comparable { 109 | private Boolean IsDir ; 110 | private String path; 111 | private String rootPath; 112 | private String fileName; 113 | private String fileSize; 114 | private String fileTime; 115 | private Boolean delete; 116 | 117 | public Boolean getDelete() { 118 | return delete; 119 | } 120 | 121 | public FileData setDelete(Boolean mDelete) { 122 | delete = mDelete; 123 | return this; 124 | } 125 | 126 | public String getRootPath() { 127 | return rootPath; 128 | } 129 | 130 | public FileData setRootPath(String mRootPath) { 131 | rootPath = mRootPath; 132 | return this; 133 | } 134 | 135 | public Boolean isDir() { 136 | return IsDir; 137 | } 138 | 139 | public FileData setIsDir(Boolean mDir) { 140 | IsDir = mDir; 141 | return this; 142 | } 143 | 144 | public String getPath() { 145 | return path; 146 | } 147 | 148 | public FileData setPath(String mPath) { 149 | path = mPath; 150 | return this; 151 | } 152 | 153 | public String getFileName() { 154 | return fileName; 155 | } 156 | 157 | public FileData setFileName(String mFileName) { 158 | fileName = mFileName; 159 | return this; 160 | } 161 | 162 | public String getFileSize() { 163 | return fileSize; 164 | } 165 | 166 | public FileData setFileSize(String mFileSize) { 167 | fileSize = mFileSize; 168 | return this; 169 | } 170 | 171 | public String getFileTime() { 172 | return fileTime; 173 | } 174 | 175 | public FileData setFileTime(String mFileTime) { 176 | fileTime = mFileTime; 177 | return this; 178 | } 179 | @Override 180 | public int compareTo( FileData o) { 181 | return this.getFileName().compareTo(o.getFileName()); 182 | } 183 | } 184 | } 185 | 186 | 187 | public static class TableData { 188 | /** 189 | * 表结构信息 190 | */ 191 | private List tableColumns; 192 | /** 193 | * 表数据 194 | */ 195 | private List> tableDatas; 196 | 197 | private Long dataCount; 198 | 199 | public List getTableColumns() { 200 | return tableColumns; 201 | } 202 | 203 | public TableData setTableColumns(List mTableColumns) { 204 | tableColumns = mTableColumns; 205 | return this; 206 | } 207 | 208 | public List> getTableDatas() { 209 | return tableDatas; 210 | } 211 | 212 | public TableData setTableDatas(List> mTableDatas) { 213 | tableDatas = mTableDatas; 214 | return this; 215 | } 216 | 217 | public Long getDataCount() { 218 | return dataCount; 219 | } 220 | 221 | public TableData setDataCount(Long mDataCount) { 222 | dataCount = mDataCount; 223 | return this; 224 | } 225 | 226 | public static class TableInfo { 227 | private String title; 228 | private boolean isPrimary; 229 | private Boolean isNotNull; 230 | private String defaultValue; 231 | private String dataType; 232 | 233 | public Boolean isNotNull() { 234 | return isNotNull; 235 | } 236 | 237 | public TableInfo setNotNull(Boolean mNotNull) { 238 | isNotNull = mNotNull; 239 | return this; 240 | } 241 | 242 | public String getDefaultValue() { 243 | return defaultValue; 244 | } 245 | 246 | public TableInfo setDefaultValue(String mDefaultValue) { 247 | defaultValue = mDefaultValue; 248 | return this; 249 | } 250 | 251 | public String getTitle() { 252 | return title; 253 | } 254 | 255 | public TableInfo setTitle(String mTitle) { 256 | title = mTitle; 257 | return this; 258 | } 259 | 260 | public boolean isPrimary() { 261 | return isPrimary; 262 | } 263 | 264 | public TableInfo setPrimary(boolean mPrimary) { 265 | isPrimary = mPrimary; 266 | return this; 267 | } 268 | 269 | public String getDataType() { 270 | return dataType; 271 | } 272 | 273 | public TableInfo setDataType(String mDataType) { 274 | dataType = mDataType; 275 | return this; 276 | } 277 | 278 | 279 | } 280 | } 281 | 282 | 283 | public TableData getTableData() { 284 | return tableData; 285 | } 286 | 287 | public Response setTableData(TableData mTableData) { 288 | tableData = mTableData; 289 | return this; 290 | } 291 | 292 | public Boolean getEditable() { 293 | return isEditable; 294 | } 295 | 296 | public Boolean isEditable() { 297 | return isEditable; 298 | } 299 | 300 | public Response setEditable(Boolean mEditable) { 301 | isEditable = mEditable; 302 | return this; 303 | } 304 | 305 | 306 | public List getTableList() { 307 | return tableList; 308 | } 309 | 310 | public Response setTableList(List mTableList) { 311 | tableList = mTableList; 312 | return this; 313 | } 314 | 315 | public int getCode() { 316 | return code; 317 | } 318 | 319 | public Response setCode(int mCode) { 320 | code = mCode; 321 | return this; 322 | } 323 | 324 | public String getMsg() { 325 | return msg; 326 | } 327 | 328 | public Response setMsg(String mMsg) { 329 | msg = mMsg; 330 | return this; 331 | } 332 | 333 | public String getAction() { 334 | return action; 335 | } 336 | 337 | public Response setAction(String mAction) { 338 | action = mAction; 339 | return this; 340 | } 341 | 342 | public Integer getDbVersion() { 343 | return dbVersion; 344 | } 345 | 346 | public Response setDbVersion(Integer mDbVersion) { 347 | dbVersion = mDbVersion; 348 | return this; 349 | } 350 | 351 | public List getDbList() { 352 | return dbList; 353 | } 354 | 355 | public Response setDbList(List mDbList) { 356 | dbList = mDbList; 357 | return this; 358 | } 359 | 360 | public List getSpList() { 361 | return spList; 362 | } 363 | 364 | public Response setSpList(List mSpList) { 365 | spList = mSpList; 366 | return this; 367 | } 368 | 369 | public String toJson() { 370 | return DebugDataTool.ObjectToJson(this); 371 | } 372 | } 373 | -------------------------------------------------------------------------------- /Android_debugdata_webtool/webtoollibrary/src/main/assets/js/dataTables.responsive.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | Responsive 2.0.2 3 | 2014-2016 SpryMedia Ltd - datatables.net/license 4 | */ 5 | (function(c){"function"===typeof define&&define.amd?define(["jquery","datatables.net"],function(j){return c(j,window,document)}):"object"===typeof exports?module.exports=function(j,k){j||(j=window);if(!k||!k.fn.dataTable)k=require("datatables.net")(j,k).$;return c(k,j,j.document)}:c(jQuery,window,document)})(function(c,j,k,p){var n=c.fn.dataTable,l=function(a,b){if(!n.versionCheck||!n.versionCheck("1.10.3"))throw"DataTables Responsive requires DataTables 1.10.3 or newer";this.s={dt:new n.Api(a),columns:[], 6 | current:[]};this.s.dt.settings()[0].responsive||(b&&"string"===typeof b.details?b.details={type:b.details}:b&&!1===b.details?b.details={type:!1}:b&&!0===b.details&&(b.details={type:"inline"}),this.c=c.extend(!0,{},l.defaults,n.defaults.responsive,b),a.responsive=this,this._constructor())};c.extend(l.prototype,{_constructor:function(){var a=this,b=this.s.dt,d=b.settings()[0],e=c(j).width();b.settings()[0]._responsive=this;c(j).on("resize.dtr orientationchange.dtr",n.util.throttle(function(){var b= 7 | c(j).width();b!==e&&(a._resize(),e=b)}));d.oApi._fnCallbackReg(d,"aoRowCreatedCallback",function(e){-1!==c.inArray(!1,a.s.current)&&c("td, th",e).each(function(e){e=b.column.index("toData",e);!1===a.s.current[e]&&c(this).css("display","none")})});b.on("destroy.dtr",function(){b.off(".dtr");c(b.table().body()).off(".dtr");c(j).off("resize.dtr orientationchange.dtr");c.each(a.s.current,function(b,e){!1===e&&a._setColumnVis(b,!0)})});this.c.breakpoints.sort(function(a,b){return a.width 8 | b.width?-1:0});this._classLogic();this._resizeAuto();d=this.c.details;!1!==d.type&&(a._detailsInit(),b.on("column-visibility.dtr",function(){a._classLogic();a._resizeAuto();a._resize()}),b.on("draw.dtr",function(){a._redrawChildren()}),c(b.table().node()).addClass("dtr-"+d.type));b.on("column-reorder.dtr",function(){a._classLogic();a._resizeAuto();a._resize()});b.on("column-sizing.dtr",function(){a._resize()});b.on("init.dtr",function(){a._resizeAuto();a._resize();c.inArray(false,a.s.current)&&b.columns.adjust()}); 9 | this._resize()},_columnsVisiblity:function(a){var b=this.s.dt,d=this.s.columns,e,f,g=d.map(function(a,b){return{columnIdx:b,priority:a.priority}}).sort(function(a,b){return a.priority!==b.priority?a.priority-b.priority:a.columnIdx-b.columnIdx}),h=c.map(d,function(b){return b.auto&&null===b.minWidth?!1:!0===b.auto?"-":-1!==c.inArray(a,b.includeIn)}),m=0;e=0;for(f=h.length;eb-d[i].minWidth?(m=!0,h[i]=!1):h[i]=!0,b-=d[i].minWidth)}g=!1;e=0;for(f=d.length;e= 12 | g&&f(c,b[d].name)}else{if("not-"===i){d=0;for(i=b.length;d").append(h).appendTo(f)}c("").append(g).appendTo(e);"inline"===this.c.details.type&&c(d).addClass("dtr-inline collapsed");d=c("
").css({width:1,height:1,overflow:"hidden"}).append(d);d.insertBefore(a.table().node()); 19 | g.each(function(c){c=a.column.index("fromVisible",c);b[c].minWidth=this.offsetWidth||0});d.remove()}},_setColumnVis:function(a,b){var d=this.s.dt,e=b?"":"none";c(d.column(a).header()).css("display",e);c(d.column(a).footer()).css("display",e);d.column(a).nodes().to$().css("display",e)},_tabIndexes:function(){var a=this.s.dt,b=a.cells({page:"current"}).nodes().to$(),d=a.settings()[0],e=this.c.details.target;b.filter("[data-dtr-keyboard]").removeData("[data-dtr-keyboard]");c("number"===typeof e?":eq("+ 20 | e+")":e,a.rows({page:"current"}).nodes()).attr("tabIndex",d.iTabIndex).data("dtr-keyboard",1)}});l.breakpoints=[{name:"desktop",width:Infinity},{name:"tablet-l",width:1024},{name:"tablet-p",width:768},{name:"mobile-l",width:480},{name:"mobile-p",width:320}];l.display={childRow:function(a,b,d){if(b){if(c(a.node()).hasClass("parent"))return a.child(d(),"child").show(),!0}else{if(a.child.isShown())return a.child(!1),c(a.node()).removeClass("parent"),!1;a.child(d(),"child").show();c(a.node()).addClass("parent"); 21 | return!0}},childRowImmediate:function(a,b,d){if(!b&&a.child.isShown()||!a.responsive.hasHidden())return a.child(!1),c(a.node()).removeClass("parent"),!1;a.child(d(),"child").show();c(a.node()).addClass("parent");return!0},modal:function(a){return function(b,d,e){if(d)c("div.dtr-modal-content").empty().append(e());else{var f=function(){g.remove();c(k).off("keypress.dtr")},g=c('
').append(c('
').append(c('
').append(e())).append(c('
×
').click(function(){f()}))).append(c('
').click(function(){f()})).appendTo("body"); 22 | c(k).on("keyup.dtr",function(a){27===a.keyCode&&(a.stopPropagation(),f())})}a&&a.header&&c("div.dtr-modal-content").prepend("

"+a.header(b)+"

")}}};l.defaults={breakpoints:l.breakpoints,auto:!0,details:{display:l.display.childRow,renderer:function(a,b,d){return(a=c.map(d,function(a){return a.hidden?'
  • '+a.title+' '+a.data+"
  • ": 23 | ""}).join(""))?c('
      ').append(a):!1},target:0,type:"inline"},orthogonal:"display"};var o=c.fn.dataTable.Api;o.register("responsive()",function(){return this});o.register("responsive.index()",function(a){a=c(a);return{column:a.data("dtr-index"),row:a.parent().data("dtr-index")}});o.register("responsive.rebuild()",function(){return this.iterator("table",function(a){a._responsive&&a._responsive._classLogic()})});o.register("responsive.recalc()",function(){return this.iterator("table", 24 | function(a){a._responsive&&(a._responsive._resizeAuto(),a._responsive._resize())})});o.register("responsive.hasHidden()",function(){var a=this.context[0];return a._responsive?-1!==c.inArray(!1,a._responsive.s.current):!1});l.version="2.0.2";c.fn.dataTable.Responsive=l;c.fn.DataTable.Responsive=l;c(k).on("preInit.dt.dtr",function(a,b){if("dt"===a.namespace&&(c(b.nTable).hasClass("responsive")||c(b.nTable).hasClass("dt-responsive")||b.oInit.responsive||n.defaults.responsive)){var d=b.oInit.responsive; 25 | !1!==d&&new l(b,c.isPlainObject(d)?d:{})}});return l}); 26 | -------------------------------------------------------------------------------- /Android_debugdata_webtool/webtoollibrary/src/main/assets/js/dataTables.select.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | Select for DataTables 1.1.2 3 | 2015-2016 SpryMedia Ltd - datatables.net/license/mit 4 | */ 5 | (function(e){"function"===typeof define&&define.amd?define(["jquery","datatables.net"],function(j){return e(j,window,document)}):"object"===typeof exports?module.exports=function(j,l){j||(j=window);if(!l||!l.fn.dataTable)l=require("datatables.net")(j,l).$;return e(l,j,j.document)}:e(jQuery,window,document)})(function(e,j,l,i){function s(a){var b=a.settings()[0]._select.selector;e(a.table().body()).off("mousedown.dtSelect",b).off("mouseup.dtSelect",b).off("click.dtSelect",b);e("body").off("click.dtSelect")} 6 | function u(a){var b=e(a.table().body()),c=a.settings()[0],d=c._select.selector;b.on("mousedown.dtSelect",d,function(c){if(c.shiftKey)b.css("-moz-user-select","none").one("selectstart.dtSelect",d,function(){return!1})}).on("mouseup.dtSelect",d,function(){b.css("-moz-user-select","")}).on("click.dtSelect",d,function(c){var b=a.select.items();if(!j.getSelection||!j.getSelection().toString()){var d=a.settings()[0];if(e(c.target).closest("div.dataTables_wrapper")[0]==a.table().container()){var m=e(c.target).closest("td, th"), 7 | h=a.cell(m).index();a.cell(m).any()&&("row"===b?(b=h.row,t(c,a,d,"row",b)):"column"===b?(b=a.cell(m).index().column,t(c,a,d,"column",b)):"cell"===b&&(b=a.cell(m).index(),t(c,a,d,"cell",b)),d._select_lastCell=h)}}});e("body").on("click.dtSelect",function(b){c._select.blurable&&!e(b.target).parents().filter(a.table().container()).length&&(e(b.target).parents("div.DTE").length||q(c,!0))})}function k(a,b,c,d){if(!d||a.flatten().length)c.unshift(a),e(a.table().node()).triggerHandler(b+".dt",c)}function v(a){var b= 8 | a.settings()[0];if(b._select.info&&b.aanFeatures.i){var c=e(''),d=function(b,d){c.append(e('').append(a.i18n("select."+b+"s",{_:"%d "+b+"s selected","0":"",1:"1 "+b+" selected"},d)))};d("row",a.rows({selected:!0}).flatten().length);d("column",a.columns({selected:!0}).flatten().length);d("cell",a.cells({selected:!0}).flatten().length);e.each(b.aanFeatures.i,function(b,a){var a=e(a),d=a.children("span.select-info");d.length&&d.remove();""!==c.text()&& 9 | a.append(c)})}}function q(a,b){if(b||"single"===a._select.style){var c=new h.Api(a);c.rows({selected:!0}).deselect();c.columns({selected:!0}).deselect();c.cells({selected:!0}).deselect()}}function t(a,b,c,d,f){var n=b.select.style(),g=b[d](f,{selected:!0}).any();"os"===n?a.ctrlKey||a.metaKey?b[d](f).select(!g):a.shiftKey?"cell"===d?(d=c._select_lastCell||null,g=function(c,a){if(c>a)var d=a,a=c,c=d;var f=!1;return b.columns(":visible").indexes().filter(function(b){b===c&&(f=!0);return b===a?(f=!1, 10 | !0):f})},a=function(c,a){var d=b.rows({search:"applied"}).indexes();if(d.indexOf(c)>d.indexOf(a))var f=a,a=c,c=f;var g=!1;return d.filter(function(b){b===c&&(g=!0);return b===a?(g=!1,!0):g})},!b.cells({selected:!0}).any()&&!d?(g=g(0,f.column),d=a(0,f.row)):(g=g(d.column,f.column),d=a(d.row,f.row)),d=b.cells(d,g).flatten(),b.cells(f,{selected:!0}).any()?b.cells(d).deselect():b.cells(d).select()):(a=c._select_lastCell?c._select_lastCell[d]:null,g=b[d+"s"]({search:"applied"}).indexes(),a=e.inArray(a, 11 | g),c=e.inArray(f,g),!b[d+"s"]({selected:!0}).any()&&-1===a?g.splice(e.inArray(f,g)+1,g.length):(a>c&&(n=c,c=a,a=n),g.splice(c+1,g.length),g.splice(0,a)),b[d](f,{selected:!0}).any())?(g.splice(e.inArray(f,g),1),b[d+"s"](g).deselect()):b[d+"s"](g).select():(a=b[d+"s"]({selected:!0}),g&&1===a.flatten().length?b[d](f).deselect():(a.deselect(),b[d](f).select())):b[d](f).select(!g)}function r(a,b){return function(c){return c.i18n("buttons."+a,b)}}var h=e.fn.dataTable;h.select={};h.select.version="1.1.2"; 12 | h.select.init=function(a){var b=a.settings()[0],c=b.oInit.select,d=h.defaults.select,c=c===i?d:c,d="row",f="api",n=!1,g=!0,m="td, th",j="selected";b._select={};if(!0===c)f="os";else if("string"===typeof c)f=c;else if(e.isPlainObject(c)&&(c.blurable!==i&&(n=c.blurable),c.info!==i&&(g=c.info),c.items!==i&&(d=c.items),c.style!==i&&(f=c.style),c.selector!==i&&(m=c.selector),c.className!==i))j=c.className;a.select.selector(m);a.select.items(d);a.select.style(f);a.select.blurable(n);a.select.info(g);b._select.className= 13 | j;e.fn.dataTable.ext.order["select-checkbox"]=function(b,c){return this.api().column(c,{order:"index"}).nodes().map(function(c){return"row"===b._select.items?e(c).parent().hasClass(b._select.className):"cell"===b._select.items?e(c).hasClass(b._select.className):!1})};e(a.table().node()).hasClass("selectable")&&a.select.style("os")};e.each([{type:"row",prop:"aoData"},{type:"column",prop:"aoColumns"}],function(a,b){h.ext.selector[b.type].push(function(c,a,f){var a=a.selected,e,g=[];if(a===i)return f; 14 | for(var h=0,j=f.length;h 35 | * Ref : https://github.com/mnadeem/sql-table-name-parser 36 | */ 37 | public final class TableNameParser { 38 | 39 | private static final int NO_INDEX = -1; 40 | private static final String SPACE = " "; 41 | private static final String REGEX_SPACE = "\\s+"; 42 | 43 | private static final String TOKEN_ORACLE_HINT_START = "/*+"; 44 | private static final String TOKEN_ORACLE_HINT_END = "*/"; 45 | private static final String TOKEN_SINGLE_LINE_COMMENT = "--"; 46 | private static final String TOKEN_SEMI_COLON = ";"; 47 | private static final String TOKEN_PARAN_START = "("; 48 | private static final String TOKEN_COMMA = ","; 49 | private static final String TOKEN_SET = "set"; 50 | private static final String TOKEN_OF = "of"; 51 | private static final String TOKEN_DUAL = "dual"; 52 | private static final String TOKEN_DELETE = "delete"; 53 | private static final String TOKEN_CREATE = "create"; 54 | private static final String TOKEN_INDEX = "index"; 55 | private static final String TOKEN_ASTERICK = "*"; 56 | private static final String KEYWORD_JOIN = "join"; 57 | private static final String KEYWORD_INTO = "into"; 58 | private static final String KEYWORD_TABLE = "table"; 59 | private static final String KEYWORD_FROM = "from"; 60 | private static final String KEYWORD_USING = "using"; 61 | private static final String KEYWORD_UPDATE = "update"; 62 | private static final List concerned = Arrays.asList(KEYWORD_TABLE, KEYWORD_INTO, KEYWORD_JOIN, KEYWORD_USING, KEYWORD_UPDATE); 63 | private static final List ignored = Arrays.asList(TOKEN_PARAN_START, TOKEN_SET, TOKEN_OF, TOKEN_DUAL); 64 | private static String TOKEN_NEWLINE = "\\r\\n|\\r|\\n|\\n\\r"; 65 | private Map tables = new HashMap(); 66 | 67 | /** 68 | * Extracts table names out of SQL 69 | * 70 | * @param sql 71 | */ 72 | public TableNameParser(final String sql) { 73 | String nocomments = removeComments(sql); 74 | String normalized = normalized(nocomments); 75 | String cleansed = clean(normalized); 76 | String[] tokens = cleansed.split(REGEX_SPACE); 77 | int index = 0; 78 | 79 | String firstToken = tokens[index]; 80 | if (isOracleSpecialDelete(firstToken, tokens, index)) { 81 | handleSpecialOracleSpecialDelete(firstToken, tokens, index); 82 | } else if (isCreateIndex(firstToken, tokens, index)) { 83 | handleCreateIndex(firstToken, tokens, index); 84 | } else { 85 | while (moreTokens(tokens, index)) { 86 | String currentToken = tokens[index++]; 87 | 88 | if (isFromToken(currentToken)) { 89 | processFromToken(tokens, index); 90 | } else if (shouldProcess(currentToken)) { 91 | String nextToken = tokens[index++]; 92 | considerInclusion(nextToken); 93 | 94 | if (moreTokens(tokens, index)) { 95 | nextToken = tokens[index++]; 96 | } 97 | } 98 | } 99 | } 100 | } 101 | 102 | /** 103 | * 104 | * @param sql 105 | * @return 106 | */ 107 | private String removeComments(final String sql) { 108 | StringBuilder sb = new StringBuilder(sql); 109 | int nextCommentPosition = sb.indexOf(TOKEN_SINGLE_LINE_COMMENT); 110 | while (nextCommentPosition > -1) { 111 | int end = indexOfRegex(TOKEN_NEWLINE, sb.substring(nextCommentPosition)); 112 | if (end == -1) { 113 | return sb.substring(0, nextCommentPosition); 114 | } else { 115 | sb.replace(nextCommentPosition, end + nextCommentPosition, ""); 116 | } 117 | nextCommentPosition = sb.indexOf(TOKEN_SINGLE_LINE_COMMENT); 118 | } 119 | return sb.toString(); 120 | } 121 | 122 | /** 123 | * 124 | * @param regex 125 | * @param string 126 | * @return 127 | */ 128 | private int indexOfRegex(String regex, String string) { 129 | Pattern pattern = Pattern.compile(regex); 130 | Matcher matcher = pattern.matcher(string); 131 | return matcher.find() ? matcher.start() : -1; 132 | } 133 | 134 | private String normalized(final String sql) { 135 | String normalized = sql.trim().replaceAll(TOKEN_NEWLINE, SPACE).replaceAll(TOKEN_COMMA, " , ") 136 | .replaceAll("\\(", " ( ").replaceAll("\\)", " ) "); 137 | if (normalized.endsWith(TOKEN_SEMI_COLON)) { 138 | normalized = normalized.substring(0, normalized.length() - 1); 139 | } 140 | return normalized; 141 | } 142 | 143 | private String clean(final String normalized) { 144 | int start = normalized.indexOf(TOKEN_ORACLE_HINT_START); 145 | int end = NO_INDEX; 146 | if (start != NO_INDEX) { 147 | end = normalized.indexOf(TOKEN_ORACLE_HINT_END); 148 | if (end != NO_INDEX) { 149 | String firstHalf = normalized.substring(0, start); 150 | String secondHalf = normalized.substring(end + 2, normalized.length()); 151 | return firstHalf.trim() + SPACE + secondHalf.trim(); 152 | } 153 | } 154 | return normalized; 155 | } 156 | 157 | private boolean isOracleSpecialDelete(final String currentToken, final String[] tokens, int index) { 158 | index++;// Point to next token 159 | if (TOKEN_DELETE.equals(currentToken)) { 160 | if (moreTokens(tokens, index)) { 161 | String nextToken = tokens[index++]; 162 | if (!KEYWORD_FROM.equals(nextToken) && !TOKEN_ASTERICK.equals(nextToken)) { 163 | return true; 164 | } 165 | } 166 | } 167 | return false; 168 | } 169 | 170 | private void handleSpecialOracleSpecialDelete(final String currentToken, final String[] tokens, int index) { 171 | String tableName = tokens[index + 1]; 172 | considerInclusion(tableName); 173 | } 174 | 175 | private boolean isCreateIndex(String currentToken, String[] tokens, int index) { 176 | index++; // Point to next token 177 | if (TOKEN_CREATE.equals(currentToken.toLowerCase()) && hasIthToken(tokens, index, 3)) { 178 | String nextToken = tokens[index++]; 179 | if (TOKEN_INDEX.equals(nextToken.toLowerCase())) { 180 | return true; 181 | } 182 | 183 | } 184 | return false; 185 | } 186 | 187 | private void handleCreateIndex(String currentToken, String[] tokens, int index) { 188 | String tableName = tokens[index + 4]; 189 | considerInclusion(tableName); 190 | } 191 | 192 | private boolean hasIthToken(String[] tokens, int currentIndex, int tokenNumber) { 193 | if (moreTokens(tokens, currentIndex) && tokens.length > currentIndex + tokenNumber) { 194 | return true; 195 | } 196 | return false; 197 | } 198 | 199 | private boolean shouldProcess(final String currentToken) { 200 | return concerned.contains(currentToken.toLowerCase()); 201 | } 202 | 203 | private boolean isFromToken(final String currentToken) { 204 | return KEYWORD_FROM.equals(currentToken.toLowerCase()); 205 | } 206 | 207 | private void processFromToken(final String[] tokens, int index) { 208 | String currentToken = tokens[index++]; 209 | considerInclusion(currentToken); 210 | 211 | String nextToken = null; 212 | if (moreTokens(tokens, index)) { 213 | nextToken = tokens[index++]; 214 | } 215 | 216 | if (shouldProcessMultipleTables(nextToken)) { 217 | processNonAliasedMultiTables(tokens, index, nextToken); 218 | } else { 219 | processAliasedMultiTables(tokens, index, currentToken); 220 | } 221 | } 222 | 223 | private void processNonAliasedMultiTables(final String[] tokens, int index, String nextToken) { 224 | while (nextToken.equals(TOKEN_COMMA)) { 225 | String currentToken = tokens[index++]; 226 | considerInclusion(currentToken); 227 | if (moreTokens(tokens, index)) { 228 | nextToken = tokens[index++]; 229 | } else { 230 | break; 231 | } 232 | } 233 | } 234 | 235 | private void processAliasedMultiTables(final String[] tokens, int index, String currentToken) { 236 | String nextNextToken = null; 237 | if (moreTokens(tokens, index)) { 238 | nextNextToken = tokens[index++]; 239 | } 240 | 241 | if (shouldProcessMultipleTables(nextNextToken)) { 242 | while (moreTokens(tokens, index) && nextNextToken.equals(TOKEN_COMMA)) { 243 | if (moreTokens(tokens, index)) { 244 | currentToken = tokens[index++]; 245 | } 246 | if (moreTokens(tokens, index)) { 247 | index++; 248 | } 249 | if (moreTokens(tokens, index)) { 250 | nextNextToken = tokens[index++]; 251 | } 252 | considerInclusion(currentToken); 253 | } 254 | } 255 | } 256 | 257 | private boolean shouldProcessMultipleTables(final String nextToken) { 258 | return nextToken != null && nextToken.equals(TOKEN_COMMA); 259 | } 260 | 261 | private boolean moreTokens(final String[] tokens, int index) { 262 | return index < tokens.length; 263 | } 264 | 265 | private void considerInclusion(final String token) { 266 | if (!ignored.contains(token.toLowerCase()) && !this.tables.containsKey(token.toLowerCase())) { 267 | this.tables.put(token.toLowerCase(), token); 268 | } 269 | } 270 | 271 | /** 272 | * @return table names extracted out of sql 273 | */ 274 | public Collection tables() { 275 | return new HashSet(this.tables.values()); 276 | } 277 | } 278 | --------------------------------------------------------------------------------