package fitnesse.wiki.fs; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; import fitnesse.util.Clock; import fitnesse.util.StringUtils; import util.FileUtil; public class MemoryFileSystem implements FileSystem { public static final String DIRECTORY_PLACEHOLDER = "*This is a directory*"; private final Map<String, Payload> files = new LinkedHashMap<>(); @Override public void makeFile(File file, String content) { files.put(file.getPath(), payload(content)); } @Override public void makeFile(File file, InputStream content) throws IOException { ByteArrayOutputStream buf = new ByteArrayOutputStream(); FileUtil.copyBytes(content, buf); makeFile(file, buf.toString(FileUtil.CHARENCODING)); } @Override public void makeDirectory(File path) { files.put(path.getPath(), payload(DIRECTORY_PLACEHOLDER)); if (path.getParentFile() != null && files.containsKey(path.getParent())) { makeDirectory(path.getParentFile()); } } @Override public boolean exists(File file) { return getPayload(file) != null; } public Payload getPayload(File file) { String path = file.getPath(); for (String filePath: files.keySet()) { if (filePath.equals(path)) return files.get(filePath); // Part is matching, assume a directory. if (filePath.startsWith(path)) return new Payload(DIRECTORY_PLACEHOLDER); } return null; } @Override public String[] list(File file) { String path = file.getPath(); Collection<String> result = new ArrayList<>(); for (String filePath: files.keySet()) { if (!filePath.startsWith(path)) continue; if (filePath.equals(path)) continue; String rest = filePath.substring(path.length() + 1); int size = rest.indexOf(File.separator); if (size < 0) size = rest.length(); String newPath = rest.substring(0, size); if (!StringUtils.isBlank(newPath) && !result.contains(newPath)) result.add(newPath); } return result.toArray(new String[result.size()]); } @Override public String getContent(File file) { return files.get(file.getPath()).payload; } @Override public InputStream getInputStream(File file) throws IOException { return new ByteArrayInputStream(files.get(file.getPath()).payload.getBytes(FileUtil.CHARENCODING)); } @Override public void delete(File fileToDelete) { String pathToDelete = fileToDelete.getPath(); for (Iterator<String> iter = files.keySet().iterator(); iter.hasNext(); ) { String f = iter.next(); if (f.startsWith(pathToDelete)) iter.remove(); } } @Override public long lastModified(File file) { Payload payload = files.get(file.getPath()); return payload != null ? payload.lastModified : Clock.currentTimeInMillis(); } @Override public void rename(File file, File originalFile) { throw new IllegalStateException("FileSystem.rename() has not been implemented for Memory file system."); } @Override public boolean isDirectory(File file) { Payload payload = getPayload(file); return (payload != null && DIRECTORY_PLACEHOLDER.equals(payload.payload)); } private Payload payload(String payload) { return new Payload(payload); } private static class Payload { private final String payload; private final long lastModified; private Payload(String payload) { this.payload = payload; this.lastModified = new Date().getTime(); } } }