1/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.googlecode.android_scripting;
18
19import android.content.Context;
20import android.content.res.AssetManager;
21import android.os.Environment;
22
23import java.io.BufferedReader;
24import java.io.File;
25import java.io.FileOutputStream;
26import java.io.FileReader;
27import java.io.IOException;
28import java.io.InputStream;
29import java.io.InputStreamReader;
30import java.io.OutputStream;
31import java.lang.reflect.Method;
32
33/**
34 * Utility functions for handling files.
35 *
36 */
37public class FileUtils {
38
39  private FileUtils() {
40    // Utility class.
41  }
42
43  static public boolean externalStorageMounted() {
44    String state = Environment.getExternalStorageState();
45    return Environment.MEDIA_MOUNTED.equals(state)
46        || Environment.MEDIA_MOUNTED_READ_ONLY.equals(state);
47  }
48
49  public static int chmod(File path, int mode) throws Exception {
50    Class<?> fileUtils = Class.forName("android.os.FileUtils");
51    Method setPermissions =
52        fileUtils.getMethod("setPermissions", String.class, int.class, int.class, int.class);
53    return (Integer) setPermissions.invoke(null, path.getAbsolutePath(), mode, -1, -1);
54  }
55
56  public static boolean recursiveChmod(File root, int mode) throws Exception {
57    boolean success = chmod(root, mode) == 0;
58    for (File path : root.listFiles()) {
59      if (path.isDirectory()) {
60        success = recursiveChmod(path, mode);
61      }
62      success &= (chmod(path, mode) == 0);
63    }
64    return success;
65  }
66
67  public static boolean delete(File path) {
68    boolean result = true;
69    if (path.exists()) {
70      if (path.isDirectory()) {
71        for (File child : path.listFiles()) {
72          result &= delete(child);
73        }
74        result &= path.delete(); // Delete empty directory.
75      }
76      if (path.isFile()) {
77        result &= path.delete();
78      }
79      if (!result) {
80        Log.e("Delete failed;");
81      }
82      return result;
83    } else {
84      Log.e("File does not exist.");
85      return false;
86    }
87  }
88
89  public static File copyFromStream(String name, InputStream input) {
90    if (name == null || name.length() == 0) {
91      Log.e("No script name specified.");
92      return null;
93    }
94    File file = new File(name);
95    if (!makeDirectories(file.getParentFile(), 0755)) {
96      return null;
97    }
98    try {
99      OutputStream output = new FileOutputStream(file);
100      IoUtils.copy(input, output);
101    } catch (Exception e) {
102      Log.e(e);
103      return null;
104    }
105    return file;
106  }
107
108  public static boolean makeDirectories(File directory, int mode) {
109    File parent = directory;
110    while (parent.getParentFile() != null && !parent.exists()) {
111      parent = parent.getParentFile();
112    }
113    if (!directory.exists()) {
114      Log.v("Creating directory: " + directory.getName());
115      if (!directory.mkdirs()) {
116        Log.e("Failed to create directory.");
117        return false;
118      }
119    }
120    try {
121      recursiveChmod(parent, mode);
122    } catch (Exception e) {
123      Log.e(e);
124      return false;
125    }
126    return true;
127  }
128
129  public static File getExternalDownload() {
130    try {
131      Class<?> c = Class.forName("android.os.Environment");
132      Method m = c.getDeclaredMethod("getExternalStoragePublicDirectory", String.class);
133      String download = c.getDeclaredField("DIRECTORY_DOWNLOADS").get(null).toString();
134      return (File) m.invoke(null, download);
135    } catch (Exception e) {
136      return new File(Environment.getExternalStorageDirectory(), "Download");
137    }
138  }
139
140  public static boolean rename(File file, String name) {
141    return file.renameTo(new File(file.getParent(), name));
142  }
143
144  public static String readToString(File file) throws IOException {
145    if (file == null || !file.exists()) {
146      return null;
147    }
148    FileReader reader = new FileReader(file);
149    StringBuilder out = new StringBuilder();
150    char[] buffer = new char[1024 * 4];
151    int numRead = 0;
152    while ((numRead = reader.read(buffer)) > -1) {
153      out.append(String.valueOf(buffer, 0, numRead));
154    }
155    reader.close();
156    return out.toString();
157  }
158
159  public static String readFromAssetsFile(Context context, String name) throws IOException {
160    AssetManager am = context.getAssets();
161    BufferedReader reader = new BufferedReader(new InputStreamReader(am.open(name)));
162    String line;
163    StringBuilder builder = new StringBuilder();
164    while ((line = reader.readLine()) != null) {
165      builder.append(line);
166    }
167    reader.close();
168    return builder.toString();
169  }
170
171}
172