1/*
2 * Copyright (C) 2014 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 android.support.v4.provider;
18
19import android.net.Uri;
20import android.util.Log;
21import android.webkit.MimeTypeMap;
22
23import java.io.File;
24import java.io.IOException;
25import java.util.ArrayList;
26
27class RawDocumentFile extends DocumentFile {
28    private File mFile;
29
30    RawDocumentFile(DocumentFile parent, File file) {
31        super(parent);
32        mFile = file;
33    }
34
35    @Override
36    public DocumentFile createFile(String mimeType, String displayName) {
37        // Tack on extension when valid MIME type provided
38        final String extension = MimeTypeMap.getSingleton().getExtensionFromMimeType(mimeType);
39        if (extension != null) {
40            displayName += "." + extension;
41        }
42        final File target = new File(mFile, displayName);
43        try {
44            target.createNewFile();
45            return new RawDocumentFile(this, target);
46        } catch (IOException e) {
47            Log.w(TAG, "Failed to createFile: " + e);
48            return null;
49        }
50    }
51
52    @Override
53    public DocumentFile createDirectory(String displayName) {
54        final File target = new File(mFile, displayName);
55        if (target.isDirectory() || target.mkdir()) {
56            return new RawDocumentFile(this, target);
57        } else {
58            return null;
59        }
60    }
61
62    @Override
63    public Uri getUri() {
64        return Uri.fromFile(mFile);
65    }
66
67    @Override
68    public String getName() {
69        return mFile.getName();
70    }
71
72    @Override
73    public String getType() {
74        if (mFile.isDirectory()) {
75            return null;
76        } else {
77            return getTypeForName(mFile.getName());
78        }
79    }
80
81    @Override
82    public boolean isDirectory() {
83        return mFile.isDirectory();
84    }
85
86    @Override
87    public boolean isFile() {
88        return mFile.isFile();
89    }
90
91    @Override
92    public long lastModified() {
93        return mFile.lastModified();
94    }
95
96    @Override
97    public long length() {
98        return mFile.length();
99    }
100
101    @Override
102    public boolean canRead() {
103        return mFile.canRead();
104    }
105
106    @Override
107    public boolean canWrite() {
108        return mFile.canWrite();
109    }
110
111    @Override
112    public boolean delete() {
113        deleteContents(mFile);
114        return mFile.delete();
115    }
116
117    @Override
118    public boolean exists() {
119        return mFile.exists();
120    }
121
122    @Override
123    public DocumentFile[] listFiles() {
124        final ArrayList<DocumentFile> results = new ArrayList<DocumentFile>();
125        final File[] files = mFile.listFiles();
126        if (files != null) {
127            for (File file : files) {
128                results.add(new RawDocumentFile(this, file));
129            }
130        }
131        return results.toArray(new DocumentFile[results.size()]);
132    }
133
134    @Override
135    public boolean renameTo(String displayName) {
136        final File target = new File(mFile.getParentFile(), displayName);
137        if (mFile.renameTo(target)) {
138            mFile = target;
139            return true;
140        } else {
141            return false;
142        }
143    }
144
145    private static String getTypeForName(String name) {
146        final int lastDot = name.lastIndexOf('.');
147        if (lastDot >= 0) {
148            final String extension = name.substring(lastDot + 1).toLowerCase();
149            final String mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
150            if (mime != null) {
151                return mime;
152            }
153        }
154
155        return "application/octet-stream";
156    }
157
158    private static boolean deleteContents(File dir) {
159        File[] files = dir.listFiles();
160        boolean success = true;
161        if (files != null) {
162            for (File file : files) {
163                if (file.isDirectory()) {
164                    success &= deleteContents(file);
165                }
166                if (!file.delete()) {
167                    Log.w(TAG, "Failed to delete " + file);
168                    success = false;
169                }
170            }
171        }
172        return success;
173    }
174}
175