1 package org.robolectric.res; 2 3 import com.google.common.annotations.VisibleForTesting; 4 import java.io.BufferedInputStream; 5 import java.io.File; 6 import java.io.FileInputStream; 7 import java.io.IOException; 8 import java.io.InputStream; 9 import java.util.regex.Pattern; 10 import javax.annotation.Nonnull; 11 import org.robolectric.util.Util; 12 13 public class FileFsFile implements FsFile { 14 @VisibleForTesting 15 static String FILE_SEPARATOR = File.separator; 16 17 private final File file; 18 FileFsFile(File file)19 FileFsFile(File file) { 20 this.file = file; 21 } 22 FileFsFile(String path)23 FileFsFile(String path) { 24 this.file = new File(path); 25 } 26 27 @Override exists()28 public boolean exists() { 29 return file.exists(); 30 } 31 32 @Override isDirectory()33 public boolean isDirectory() { 34 return file.isDirectory(); 35 } 36 37 @Override isFile()38 public boolean isFile() { 39 return file.isFile(); 40 } 41 42 @Override listFiles()43 public FsFile[] listFiles() { 44 return asFsFiles(file.listFiles()); 45 } 46 47 @Override listFiles(final Filter filter)48 public FsFile[] listFiles(final Filter filter) { 49 return asFsFiles(file.listFiles(pathname -> filter.accept(new FileFsFile(pathname)))); 50 } 51 52 @Override listFileNames()53 public String[] listFileNames() { 54 File[] files = file.listFiles(); 55 if (files == null) return null; 56 String[] strings = new String[files.length]; 57 for (int i = 0; i < files.length; i++) { 58 strings[i] = files[i].getName(); 59 } 60 return strings; 61 } 62 63 @Override getParent()64 public FsFile getParent() { 65 File parentFile = file.getParentFile(); 66 return parentFile == null ? null : Fs.newFile(parentFile); 67 } 68 69 @Override getName()70 public String getName() { 71 return file.getName(); 72 } 73 74 @Override getInputStream()75 public InputStream getInputStream() throws IOException { 76 return new BufferedInputStream(new FileInputStream(file)); 77 } 78 79 @Override getBytes()80 public byte[] getBytes() throws IOException { 81 return Util.readBytes(new FileInputStream(file)); 82 } 83 84 @Override join(String... pathParts)85 public FsFile join(String... pathParts) { 86 File f = file; 87 for (String pathPart : pathParts) { 88 for (String part : pathPart.split(Pattern.quote(FILE_SEPARATOR), 0)) { 89 if (!part.equals(".")) { 90 f = new File(f, part); 91 } 92 } 93 } 94 95 return Fs.newFile(f); 96 } 97 getFile()98 public File getFile() { 99 return file; 100 } 101 102 @Override toString()103 public String toString() { 104 return file.getPath(); 105 } 106 107 @Override equals(Object o)108 public boolean equals(Object o) { 109 if (this == o) return true; 110 if (o == null || getClass() != o.getClass()) return false; 111 112 FileFsFile fsFile = (FileFsFile) o; 113 114 return file.equals(fsFile.file); 115 } 116 117 @Override hashCode()118 public int hashCode() { 119 return file.hashCode(); 120 } 121 122 @Override getBaseName()123 public String getBaseName() { 124 String name = getName(); 125 int dotIndex = name.indexOf("."); 126 return dotIndex >= 0 ? name.substring(0, dotIndex) : name; 127 } 128 129 @Override getPath()130 public String getPath() { 131 return file.getPath(); 132 } 133 134 @Override length()135 public long length() { 136 return file.length(); 137 } 138 asFsFiles(File[] files)139 private FsFile[] asFsFiles(File[] files) { 140 if (files == null) return null; 141 FsFile[] fsFiles = new FsFile[files.length]; 142 for (int i = 0; i < files.length; i++) { 143 fsFiles[i] = Fs.newFile(files[i]); 144 } 145 return fsFiles; 146 } 147 148 /** 149 * Construct an FileFsFile from a series of path components. Path components that are 150 * null or empty string will be ignored. 151 * 152 * @param paths Array of path components. 153 * @return New FileFsFile. 154 */ 155 @Nonnull from(String... paths)156 public static FileFsFile from(String... paths) { 157 File file = null; 158 for (String path : paths) { 159 if (path != null && path.length() > 0) { 160 for (String part : path.split(Pattern.quote(FILE_SEPARATOR), 0)) { 161 if (file != null && part.equals(".")) continue; 162 file = (file == null) 163 ? new File(part) 164 : new File(file, part); 165 } 166 } 167 } 168 return new FileFsFile(file); 169 } 170 } 171