/* * Copyright 2013 eXo Platform SAS * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package juzu.impl.fs.spi.disk; import juzu.impl.common.Name; import juzu.impl.common.Resource; import juzu.impl.common.Timestamped; import juzu.impl.fs.spi.PathType; import juzu.impl.fs.spi.ReadWriteFileSystem; import juzu.impl.common.Tools; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FilenameFilter; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.nio.charset.Charset; import java.util.Arrays; import java.util.Iterator; import java.util.LinkedList; /** @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a> */ public class DiskFileSystem extends ReadWriteFileSystem<File> { /** . */ private final File root; /** . */ private FilenameFilter filter; /** . */ private Charset encoding; public DiskFileSystem(File root) { this(root, new FilenameFilter() { public boolean accept(File dir, String name) { return true; } }); } public DiskFileSystem(File root, FilenameFilter filter) { this.root = root; this.filter = filter; this.encoding = Charset.defaultCharset(); } public DiskFileSystem(final File root, final Name path) { this(root, new FilterImpl(root, path)); } public DiskFileSystem(final File root, final String path) { this(root, new FilterImpl(root, Name.parse(path))); } public void applyFilter(String path) { filter = new FilterImpl(root, Name.parse(path)); } @Override public Class<File> getType() { return File.class; } @Override public String getDescription() { return "disk[" + root.getAbsolutePath() + "]"; } @Override public boolean equals(File left, File right) { return left.equals(right); } @Override public File getRoot() { return root; } @Override public PathType typeOf(File path) throws IOException { if (path.isDirectory()) { return PathType.DIR; } else if (path.isFile()) { return PathType.FILE; } else { return null; } } @Override public String getName(File path) { if (path.equals(root)) { return ""; } else { return path.getName(); } } @Override public Iterable<String> getNames(File path) { LinkedList<String> names = new LinkedList<String>(); while (!path.equals(root)) { names.addFirst(path.getName()); path = path.getParentFile(); } return names; } @Override public Iterator<File> getChildren(File dir) throws IOException { File[] children = dir.listFiles(filter); return children == null ? Tools.<File>emptyIterator() : Arrays.asList(children).iterator(); } @Override public File getChild(File dir, String name) throws IOException { if (filter.accept(dir, name)) { File child = new File(dir, name); if (child.exists()) { return child; } } return null; } @Override public Timestamped<Resource> getResource(File file) throws IOException { FileInputStream in = new FileInputStream(file); try { ByteArrayOutputStream resource = new ByteArrayOutputStream(); byte[] buffer = new byte[256]; for (int l = in.read(buffer);l != -1;l = in.read(buffer)) { resource.write(buffer, 0, l); } return new Timestamped<Resource>(file.lastModified(), new Resource(resource.toByteArray(), encoding)); } finally { Tools.safeClose(in); } } @Override public long getLastModified(File path) throws IOException { return path.lastModified(); } @Override public URL getURL(File path) throws IOException { return path.toURI().toURL(); } @Override public File getFile(File path) { return path; } @Override public File makePath(File parent, String name) throws IOException { return new File(parent, name); } @Override public void createDir(File dir) throws IOException { if (dir.exists()) { if (dir.isDirectory()) { // Ok } else { throw new IOException("Dir already exists and is a file " + dir.getCanonicalPath()); } } else { if (dir.mkdirs()) { // Ok } else { throw new IOException("Could not create dir " + dir.getCanonicalPath()); } } } @Override public long updateResource(File file, Resource resource) throws IOException { File parent = file.getParentFile(); if (parent != null) { if (!parent.exists()) { if (!parent.mkdirs()) { throw new IOException("Could not create parent directory " + parent.getCanonicalPath()); } } } InputStream in = resource.getInputStream(); FileOutputStream out = new FileOutputStream(file); try { Tools.copy(in, out); } finally { Tools.safeClose(out); } return file.lastModified(); } @Override public boolean removePath(File path) throws IOException { return path.delete(); } @Override public String toString() { return "DiskFileSystem[root=" + root.getAbsolutePath() + "]"; } }