/* * 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.ram; import juzu.impl.common.Resource; import juzu.impl.common.Timestamped; import juzu.impl.common.Tools; import juzu.impl.fs.spi.PathType; import juzu.impl.fs.spi.ReadWriteFileSystem; import java.io.File; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Iterator; /** @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a> */ public class RAMFileSystem extends ReadWriteFileSystem<String[]> { /** . */ private final RAMDir root; /** . */ private final URL contextURL; public RAMFileSystem() { try { this.root = new RAMDir(this); this.contextURL = new URL("juzu", null, 0, "/", new RAMURLStreamHandler(this)); } catch (MalformedURLException e) { AssertionError ae = new AssertionError("Unexpected exception"); ae.initCause(e); throw ae; } } @Override public Class<String[]> getType() { return String[].class; } @Override public String getDescription() { return "ram[]"; } @Override public String[] makePath(String[] parent, String name) throws IOException { String[] path = Arrays.copyOf(parent, parent.length + 1); path[path.length - 1] = name; return path; } private RAMPath get(String[] path) { RAMPath current = root; for (String name : path) { if (current instanceof RAMDir) { current = ((RAMDir)current).children.get(name); } else { return null; } } return current; } @Override public void createDir(String[] dir) throws IOException { long lastModified = System.currentTimeMillis(); RAMDir current = root; for (String name : dir) { RAMPath next = current.children.get(name); if (next == null) { next = new RAMDir(current, name, lastModified); current.children.put(name, next); next.parent = current; current = (RAMDir)next; } else if (next instanceof RAMDir) { current = (RAMDir)next; } else { throw new IOException("A file already exist"); } } } @Override public long updateResource(String[] file, Resource resource) throws IOException { long lastModified = System.currentTimeMillis(); RAMDir current = root; for (int i = 0;i < file.length;i++) { String name = file[i]; RAMPath next = current.children.get(name); if (i == file.length - 1) { if (next == null) { current.children.put(name, next = new RAMFile(current, name, resource)); next.parent = current; } else if (next instanceof RAMFile) { ((RAMFile)next).resource = new Timestamped<Resource>(lastModified, resource); } else { throw new IOException("A file already exist"); } return next.getLastModified(); } else { if (next == null) { current.children.put(name, next = new RAMDir(current, name, lastModified)); next.parent = current; current = (RAMDir)next; } else if (next instanceof RAMDir) { current = (RAMDir)next; } else { throw new IOException("A file already exist"); } } } throw new IOException(); } @Override public Timestamped<Resource> getResource(String[] file) throws IOException { if (file == null) { throw new NullPointerException("No null file argument accepted"); } RAMPath path = get(file); return path instanceof RAMFile ? ((RAMFile)path).resource : null; } @Override public boolean equals(String[] left, String[] right) { return Arrays.equals(left, right); } @Override public String getName(String[] path) { return path.length > 0 ? path[path.length - 1] : ""; } @Override public Iterable<String> getNames(String[] path) { return Tools.iterable(path); } @Override public Iterator<String[]> getChildren(String[] dir) throws IOException { RAMPath path = get(dir); if (path instanceof RAMDir) { RAMDir a = (RAMDir)path; ArrayList<String[]> children = new ArrayList<String[]>(a.children.size()); for (RAMPath child : a.children.values()) { children.add(child.names); } return children.iterator(); } else { return Collections.<String[]>emptyList().iterator(); } } @Override public String[] getChild(String[] dir, String name) throws IOException { RAMPath path = get(dir); if (path instanceof RAMDir) { RAMPath child = ((RAMDir)path).children.get(name); return child != null ? child.names : null; } else { return null; } } @Override public PathType typeOf(String[] path) throws IOException { RAMPath foo = get(path); if (foo instanceof RAMDir) { return PathType.DIR; } else if (foo instanceof RAMFile) { return PathType.FILE; } else { return null; } } @Override public long getLastModified(String[] path) throws IOException { RAMPath foo = get(path); return foo != null ? foo.getLastModified() : 0; } @Override public File getFile(String[] path) { return null; } @Override public URL getURL(String[] path) throws NullPointerException, IOException { if (path == null) { throw new NullPointerException("No null path accepted"); } return new URL(contextURL, Tools.join('/', path)); } @Override public boolean removePath(String[] path) throws IOException { RAMPath foo = get(path); if (foo != null) { foo.parent.children.remove(foo.name); foo.parent = null; } return true; } @Override public String[] getRoot() throws IOException { return root.names; } /* @Override public void setContent(RAMPath file, Content content) throws IOException { if (file == null) { throw new NullPointerException("No null file"); } if (file instanceof RAMFile) { setContent((RAMFile)file, content); } else { throw new IOException("Cannot set content of a directory"); } } private void setContent(RAMFile file, Content content) { if (content == null) { throw new NullPointerException("No null content"); } if (file.parent.lastModified == 0) { file.parent.touch(); } file.content = content; } @Override public void removePath(RAMPath path) throws IOException { if (path == root) { throw new IOException("Cannot remove root file"); } if (path.parent == null) { throw new IOException("Cannot remove removed file"); } path.parent.children.remove(path.name); path.parent = null; } public boolean equals(RAMPath left, RAMPath right) { return left == right; } public String[] getRoot() { return EMPTY; } public RAMDir getParent(RAMPath path) { return path.parent; } public String getName(RAMPath path) { return path.name; } public Iterator<RAMPath> getChildren(RAMPath dir) throws IOException { if (dir instanceof RAMDir) { return new ArrayList<RAMPath>(((RAMDir)dir).children.values()).iterator(); } else { throw new IOException("Cannot list file"); } } public RAMPath getChild(RAMPath dir, String name) throws IOException { if (dir instanceof RAMDir) { return ((RAMDir)dir).children.get(name); } else { throw new IOException("Cannot list file"); } } public boolean isDir(RAMPath path) throws IOException { return path instanceof RAMDir; } public boolean isFile(RAMPath path) throws IOException { return path instanceof RAMFile; } public Content getContent(RAMPath file) throws IOException { return ((RAMFile)file).getContent(); } public long getLastModified(RAMPath path) { if (path instanceof RAMDir) { RAMDir dir = (RAMDir)path; return dir.lastModified; } else { RAMFile file = (RAMFile)path; return file.content == null ? 0 : file.content.getLastModified(); } } */ /* @Override public URL getURL(RAMPath path) throws IOException { if (path == null) { throw new NullPointerException("No null path accepted"); } StringBuilder sb = new StringBuilder(); pathOf(path, '/', sb); String spec = sb.toString(); return new URL(contextURL, spec); } */ }