/*
* Copyright 2010 Google Inc.
*
* 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 java.io;
import java.util.ArrayList;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.corp.localstorage.LocalStorage;
/**
* LocalStorage based File implementation for GWT. Should probably have used Harmony as a
* starting point instead of writing this from scratch.
*
* @author Stefan Haustein
*/
public class File {
public static final File ROOT = new File("");
public static final char separatorChar = '/';
public static final String separator = "" + separatorChar;
public static final char pathSeparatorChar = ':';
public static final String pathSeparator = "" + pathSeparatorChar;
File parent;
String name;
boolean absolute;
public File(String pathname) {
while (pathname.endsWith(separator) && pathname.length() > 0) {
pathname = pathname.substring(0, pathname.length() - 1);
}
int cut = pathname.lastIndexOf(separatorChar);
if (cut == -1) {
name = pathname;
} else if (cut == 0) {
name = pathname.substring(cut);
parent = name.equals("") ? null : ROOT;
} else {
name = pathname.substring(cut + 1);
parent = new File(pathname.substring(0, cut));
}
// Compatibility.println("new File ('"+pathname+ "'); canonical name: '" + getCanonicalPath() + "'");
}
public File(String parent, String child) {
this(new File(parent), child);
}
public File(File parent, String child) {
this.parent = parent;
this.name = child;
}
/*
public File(URI uri) {
}
*/
public String getName() {
return name;
}
public String getParent() {
return parent == null ? "" : parent.getPath();
}
public File getParentFile() {
return parent;
}
public String getPath() {
return parent == null ? name : (parent.getPath() +
separatorChar + name);
}
private boolean isRoot() {
return name.equals("") && parent == null;
}
public boolean isAbsolute() {
if (isRoot()) {
return true;
}
if(parent == null) {
return false;
}
return parent.isAbsolute();
}
public String getAbsolutePath() {
String path = getAbsoluteFile().getPath();
return path.length() == 0 ? "/" : path;
}
public File getAbsoluteFile() {
if (isAbsolute()) {
return this;
}
if (parent == null) {
return new File(ROOT, name);
}
return new File(parent.getAbsoluteFile(), name);
}
public String getCanonicalPath() {
return getCanonicalFile().getAbsolutePath();
}
public File getCanonicalFile() {
File cParent = parent == null ? null : parent.getCanonicalFile();
if (name.equals (".")) {
return cParent == null ? ROOT : cParent;
}
if (cParent != null && cParent.name.equals("")) {
cParent = null;
}
if (name.equals("..")) {
if (cParent == null) {
return ROOT;
}
if (cParent.parent == null) {
return ROOT;
}
return cParent.parent;
}
if (cParent == null && !name.equals("")) {
return new File(ROOT, name);
}
return new File(cParent, name);
}
/*
public URL toURL() throws MalformedURLException {
}
public URI toURI() {
}
*/
public boolean canRead() {
return true;
}
public boolean canWrite() {
return true;
}
public boolean exists() {
try {
return LocalStorage.getItem(getCanonicalPath()) != null;
} catch (IOException e) {
return false;
}
}
public boolean isDirectory() {
try {
String s = LocalStorage.getItem(getCanonicalPath());
return s != null && s.startsWith("{");
} catch (IOException e) {
return false;
}
}
public boolean isFile() {
try {
String s = LocalStorage.getItem(getCanonicalPath());
return s != null && !s.startsWith("{");
} catch (IOException e) {
return false;
}
}
public boolean isHidden() {
return false;
}
public long lastModified() {
return 0;
}
public long length() {
try {
if (!exists()) {
return 0;
}
RandomAccessFile raf = new RandomAccessFile(this, "r");
long len = raf.length();
raf.close();
return len;
} catch (IOException e) {
return 0;
}
}
public boolean createNewFile() throws IOException {
if (exists()) return false;
if (!parent.exists()) return false;
LocalStorage.setItem(getCanonicalPath(), RandomAccessFile.btoa(""));
return true;
}
public boolean delete() {
try {
if (!exists()) {
return false;
}
LocalStorage.removeItem(getCanonicalPath());
return true;
} catch (IOException e) {
return false;
}
}
public void deleteOnExit() {
throw new RuntimeException("NYI: File.deleteOnExit()");
}
public String[] list() {
throw new RuntimeException("NYI: File.list()");
}
/*
public String[] list(FilenameFilter filter) {
return null;
}
*/
public File[] listFiles() {
return listFiles(null);
}
public File[] listFiles(FilenameFilter filter) {
ArrayList<File> files = new ArrayList<File>();
try {
String prefix = getCanonicalPath();
if (!prefix.endsWith(separator)) {
prefix += separatorChar;
}
int cut = prefix.length();
int cnt = LocalStorage.length();
for (int i = 0; i < cnt; i++) {
String key = LocalStorage.key(i);
if (key.startsWith(prefix) && key.indexOf(separatorChar, cut) == -1) {
String name = key.substring(cut);
if (filter == null || filter.accept(this, name)) {
files.add(new File(this, name));
}
}
}
} catch (IOException e) {
System.err.println("lisFiles() exception: " + e);
}
return files.toArray(new File[files.size()]);
}
/*
public File[] listFiles(FileFilter filter) {
return null;
}
*/
public boolean mkdir() {
try {
if (parent != null && !parent.exists()) {
return false;
}
if (exists()) {
return false;
}
// We may want to make this a JS map
LocalStorage.setItem(getCanonicalPath(), "{}");
return true;
} catch (IOException e) {
return false;
}
}
public boolean mkdirs() {
if (parent != null) {
parent.mkdirs();
}
return mkdir();
}
public boolean renameTo(File dest) {
throw new RuntimeException("renameTo()");
}
public boolean setLastModified(long time) {
return false;
}
public boolean setReadOnly() {
return false;
}
public static File[] listRoots() {
return new File[]{ROOT};
}
public static File createTempFile(String prefix, String suffix, File directory)
throws IOException {
throw new RuntimeException("NYI: createTempFile");
}
public static File createTempFile(String prefix, String suffix)
throws IOException {
throw new RuntimeException("NYI: createTempFile");
}
public int compareTo(File pathname) {
throw new RuntimeException("NYI: File.compareTo()");
}
public boolean equals(Object obj) {
if (!(obj instanceof File)) {
return false;
}
return getPath().equals(((File) obj).getPath());
}
public int hashCode() {
return parent != null ? parent.hashCode() + name.hashCode() :
name.hashCode();
}
public String toString() {
return name;
}
}