PageRenderTime 53ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

/pushWithPythonServer/pushnotification/plugins/org.apache.cordova.file/src/android/ContentFilesystem.java

https://gitlab.com/bsan/ionicDev
Java | 319 lines | 260 code | 31 blank | 28 comment | 47 complexity | cfe7bfefd8d1a9f61e74a4b936e92409 MD5 | raw file
  1. /*
  2. Licensed to the Apache Software Foundation (ASF) under one
  3. or more contributor license agreements. See the NOTICE file
  4. distributed with this work for additional information
  5. regarding copyright ownership. The ASF licenses this file
  6. to you under the Apache License, Version 2.0 (the
  7. "License"); you may not use this file except in compliance
  8. with the License. You may obtain a copy of the License at
  9. http://www.apache.org/licenses/LICENSE-2.0
  10. Unless required by applicable law or agreed to in writing,
  11. software distributed under the License is distributed on an
  12. "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  13. KIND, either express or implied. See the License for the
  14. specific language governing permissions and limitations
  15. under the License.
  16. */
  17. package org.apache.cordova.file;
  18. import java.io.File;
  19. import java.io.FileNotFoundException;
  20. import java.io.IOException;
  21. import java.io.OutputStream;
  22. import java.lang.reflect.Field;
  23. import java.lang.reflect.Method;
  24. import java.lang.reflect.InvocationTargetException;
  25. import org.apache.cordova.CordovaInterface;
  26. import org.apache.cordova.CordovaResourceApi;
  27. import org.apache.cordova.CordovaWebView;
  28. import org.apache.cordova.PluginManager;
  29. import org.json.JSONArray;
  30. import org.json.JSONException;
  31. import org.json.JSONObject;
  32. import android.content.ContentResolver;
  33. import android.database.Cursor;
  34. import android.net.Uri;
  35. import android.provider.MediaStore;
  36. import android.provider.OpenableColumns;
  37. public class ContentFilesystem extends Filesystem {
  38. private CordovaInterface cordova;
  39. private CordovaResourceApi resourceApi;
  40. public ContentFilesystem(CordovaInterface cordova, CordovaWebView webView) {
  41. super(Uri.parse("content://"), "content");
  42. this.cordova = cordova;
  43. Class webViewClass = webView.getClass();
  44. PluginManager pm = null;
  45. try {
  46. Method gpm = webViewClass.getMethod("getPluginManager");
  47. pm = (PluginManager) gpm.invoke(webView);
  48. } catch (NoSuchMethodException e) {
  49. } catch (IllegalAccessException e) {
  50. } catch (InvocationTargetException e) {
  51. }
  52. if (pm == null) {
  53. try {
  54. Field pmf = webViewClass.getField("pluginManager");
  55. pm = (PluginManager)pmf.get(webView);
  56. } catch (NoSuchFieldException e) {
  57. } catch (IllegalAccessException e) {
  58. }
  59. }
  60. this.resourceApi = new CordovaResourceApi(webView.getContext(), pm);
  61. }
  62. @Override
  63. public JSONObject getEntryForLocalURL(LocalFilesystemURL inputURL) throws IOException {
  64. if ("/".equals(inputURL.fullPath)) {
  65. return LocalFilesystem.makeEntryForURL(inputURL, true, inputURL.URL.toString());
  66. }
  67. // Get the cursor to validate that the file exists
  68. Cursor cursor = openCursorForURL(inputURL);
  69. String filePath = null;
  70. try {
  71. if (cursor == null || !cursor.moveToFirst()) {
  72. throw new FileNotFoundException();
  73. }
  74. filePath = filesystemPathForCursor(cursor);
  75. } finally {
  76. if (cursor != null)
  77. cursor.close();
  78. }
  79. if (filePath == null) {
  80. filePath = inputURL.URL.toString();
  81. } else {
  82. filePath = "file://" + filePath;
  83. }
  84. return makeEntryForPath(inputURL.fullPath, inputURL.filesystemName, false /*fp.isDirectory()*/, filePath);
  85. }
  86. @Override
  87. public JSONObject getFileForLocalURL(LocalFilesystemURL inputURL,
  88. String fileName, JSONObject options, boolean directory) throws IOException, TypeMismatchException, JSONException {
  89. if (options != null) {
  90. if (options.optBoolean("create")) {
  91. throw new IOException("Cannot create content url");
  92. }
  93. }
  94. LocalFilesystemURL requestedURL = new LocalFilesystemURL(Uri.withAppendedPath(inputURL.URL, fileName));
  95. File fp = new File(this.filesystemPathForURL(requestedURL));
  96. if (!fp.exists()) {
  97. throw new FileNotFoundException("path does not exist");
  98. }
  99. if (directory) {
  100. if (fp.isFile()) {
  101. throw new TypeMismatchException("path doesn't exist or is file");
  102. }
  103. } else {
  104. if (fp.isDirectory()) {
  105. throw new TypeMismatchException("path doesn't exist or is directory");
  106. }
  107. }
  108. // Return the directory
  109. return makeEntryForPath(requestedURL.fullPath, requestedURL.filesystemName, directory, Uri.fromFile(fp).toString());
  110. }
  111. @Override
  112. public boolean removeFileAtLocalURL(LocalFilesystemURL inputURL)
  113. throws NoModificationAllowedException {
  114. String filePath = filesystemPathForURL(inputURL);
  115. File file = new File(filePath);
  116. try {
  117. this.cordova.getActivity().getContentResolver().delete(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
  118. MediaStore.Images.Media.DATA + " = ?",
  119. new String[] { filePath });
  120. } catch (UnsupportedOperationException t) {
  121. // Was seeing this on the File mobile-spec tests on 4.0.3 x86 emulator.
  122. // The ContentResolver applies only when the file was registered in the
  123. // first case, which is generally only the case with images.
  124. }
  125. return file.delete();
  126. }
  127. @Override
  128. public boolean recursiveRemoveFileAtLocalURL(LocalFilesystemURL inputURL)
  129. throws NoModificationAllowedException {
  130. throw new NoModificationAllowedException("Cannot remove content url");
  131. }
  132. @Override
  133. public JSONArray readEntriesAtLocalURL(LocalFilesystemURL inputURL)
  134. throws FileNotFoundException {
  135. // TODO Auto-generated method stub
  136. return null;
  137. }
  138. @Override
  139. public JSONObject getFileMetadataForLocalURL(LocalFilesystemURL inputURL) throws FileNotFoundException {
  140. Integer size = null;
  141. Integer lastModified = null;
  142. Cursor cursor = openCursorForURL(inputURL);
  143. try {
  144. if (cursor != null && cursor.moveToFirst()) {
  145. size = resourceSizeForCursor(cursor);
  146. lastModified = lastModifiedDateForCursor(cursor);
  147. } else {
  148. throw new FileNotFoundException();
  149. }
  150. } finally {
  151. if (cursor != null)
  152. cursor.close();
  153. }
  154. JSONObject metadata = new JSONObject();
  155. try {
  156. metadata.put("size", size);
  157. metadata.put("type", resourceApi.getMimeType(inputURL.URL));
  158. metadata.put("name", inputURL.filesystemName);
  159. metadata.put("fullPath", inputURL.fullPath);
  160. metadata.put("lastModifiedDate", lastModified);
  161. } catch (JSONException e) {
  162. return null;
  163. }
  164. return metadata;
  165. }
  166. @Override
  167. public JSONObject copyFileToURL(LocalFilesystemURL destURL, String newName,
  168. Filesystem srcFs, LocalFilesystemURL srcURL, boolean move)
  169. throws IOException, InvalidModificationException, JSONException,
  170. NoModificationAllowedException, FileExistsException {
  171. if (LocalFilesystem.class.isInstance(srcFs)) {
  172. /* Same FS, we can shortcut with CordovaResourceApi operations */
  173. // Figure out where we should be copying to
  174. final LocalFilesystemURL destinationURL = makeDestinationURL(newName, srcURL, destURL);
  175. OutputStream os = resourceApi.openOutputStream(destURL.URL);
  176. CordovaResourceApi.OpenForReadResult ofrr = resourceApi.openForRead(srcURL.URL);
  177. if (move && !srcFs.canRemoveFileAtLocalURL(srcURL)) {
  178. throw new NoModificationAllowedException("Cannot move file at source URL");
  179. }
  180. try {
  181. resourceApi.copyResource(ofrr, os);
  182. } catch (IOException e) {
  183. throw new IOException("Cannot read file at source URL");
  184. }
  185. if (move) {
  186. srcFs.removeFileAtLocalURL(srcURL);
  187. }
  188. return makeEntryForURL(destinationURL, false, destinationURL.URL.toString());
  189. } else {
  190. // Need to copy the hard way
  191. return super.copyFileToURL(destURL, newName, srcFs, srcURL, move);
  192. }
  193. }
  194. @Override
  195. public void readFileAtURL(LocalFilesystemURL inputURL, long start, long end,
  196. ReadFileCallback readFileCallback) throws IOException {
  197. CordovaResourceApi.OpenForReadResult ofrr = resourceApi.openForRead(inputURL.URL);
  198. if (end < 0) {
  199. end = ofrr.length;
  200. }
  201. long numBytesToRead = end - start;
  202. try {
  203. if (start > 0) {
  204. ofrr.inputStream.skip(start);
  205. }
  206. LimitedInputStream inputStream = new LimitedInputStream(ofrr.inputStream, numBytesToRead);
  207. readFileCallback.handleData(inputStream, ofrr.mimeType);
  208. } finally {
  209. ofrr.inputStream.close();
  210. }
  211. }
  212. @Override
  213. public long writeToFileAtURL(LocalFilesystemURL inputURL, String data,
  214. int offset, boolean isBinary) throws NoModificationAllowedException {
  215. throw new NoModificationAllowedException("Couldn't write to file given its content URI");
  216. }
  217. @Override
  218. public long truncateFileAtURL(LocalFilesystemURL inputURL, long size)
  219. throws NoModificationAllowedException {
  220. throw new NoModificationAllowedException("Couldn't truncate file given its content URI");
  221. }
  222. protected Cursor openCursorForURL(LocalFilesystemURL url) {
  223. ContentResolver contentResolver = this.cordova.getActivity().getContentResolver();
  224. Cursor cursor = contentResolver.query(url.URL, null, null, null, null);
  225. return cursor;
  226. }
  227. protected String filesystemPathForCursor(Cursor cursor) {
  228. final String[] LOCAL_FILE_PROJECTION = { MediaStore.Images.Media.DATA };
  229. int columnIndex = cursor.getColumnIndex(LOCAL_FILE_PROJECTION[0]);
  230. if (columnIndex != -1) {
  231. return cursor.getString(columnIndex);
  232. }
  233. return null;
  234. }
  235. protected Integer resourceSizeForCursor(Cursor cursor) {
  236. int columnIndex = cursor.getColumnIndex(OpenableColumns.SIZE);
  237. if (columnIndex != -1) {
  238. String sizeStr = cursor.getString(columnIndex);
  239. if (sizeStr != null) {
  240. return Integer.parseInt(sizeStr,10);
  241. }
  242. }
  243. return null;
  244. }
  245. protected Integer lastModifiedDateForCursor(Cursor cursor) {
  246. final String[] LOCAL_FILE_PROJECTION = { MediaStore.MediaColumns.DATE_MODIFIED };
  247. int columnIndex = cursor.getColumnIndex(LOCAL_FILE_PROJECTION[0]);
  248. if (columnIndex != -1) {
  249. String dateStr = cursor.getString(columnIndex);
  250. if (dateStr != null) {
  251. return Integer.parseInt(dateStr,10);
  252. }
  253. }
  254. return null;
  255. }
  256. @Override
  257. public String filesystemPathForURL(LocalFilesystemURL url) {
  258. Cursor cursor = openCursorForURL(url);
  259. try {
  260. if (cursor != null && cursor.moveToFirst()) {
  261. return filesystemPathForCursor(cursor);
  262. }
  263. } finally {
  264. if (cursor != null)
  265. cursor.close();
  266. }
  267. return null;
  268. }
  269. @Override
  270. public LocalFilesystemURL URLforFilesystemPath(String path) {
  271. // Returns null as we don't support reverse mapping back to content:// URLs
  272. return null;
  273. }
  274. @Override
  275. public boolean canRemoveFileAtLocalURL(LocalFilesystemURL inputURL) {
  276. String path = filesystemPathForURL(inputURL);
  277. File file = new File(path);
  278. return file.exists();
  279. }
  280. @Override
  281. OutputStream getOutputStreamForURL(LocalFilesystemURL inputURL)
  282. throws IOException {
  283. OutputStream os = resourceApi.openOutputStream(inputURL.URL);
  284. return os;
  285. }
  286. }