/* * This file is a part of Alchemy OS project. * Copyright (C) 2011-2013, Sergey Basalaev <sbasalaev@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package alchemy.fs.jsr75; import alchemy.fs.Filesystem; import alchemy.fs.FSDriver; import alchemy.util.ArrayList; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Enumeration; import javax.microedition.io.Connector; import javax.microedition.io.file.FileConnection; /** * Driver for JSR 75 file system. * * @author Sergey Basalaev */ public class Driver extends FSDriver { /** Root prefix. */ private String root; /** If true then root directory is also device root. * If false, then it is a regular directory. */ private boolean isSysRoot; /** * Constructor to load through the reflection. * <code>init()</code> should be called before * filesystem can be used. */ public Driver() { } /** * Creates new <code>JSR75Filesystem</code> using * given string as root directory. * @param root root directory */ public void init(String root) { String rootpath = Filesystem.normalize(root); if (rootpath.length() == 0) throw new RuntimeException("Root is not specified"); isSysRoot = rootpath.indexOf('/', 1) < 0; this.root = "file://"+rootpath; } /** * Converts file path to native path. */ public String getNativeURL(String file) { if (isSysRoot && file.length() == 0) return root+'/'; else return root+file; } public OutputStream append(String file) throws IOException { FileConnection fc = (FileConnection)Connector.open(getNativeURL(file), Connector.READ_WRITE); try { if (!fc.exists()) fc.create(); return fc.openOutputStream(fc.fileSize()); } finally { fc.close(); } } public OutputStream write(String file) throws IOException { FileConnection fc = (FileConnection)Connector.open(getNativeURL(file), Connector.READ_WRITE); try { if (!fc.exists()) fc.create(); fc.truncate(0); return fc.openOutputStream(); } finally { fc.close(); } } public InputStream read(String file) throws IOException { FileConnection fc = (FileConnection)Connector.open(getNativeURL(file), Connector.READ); try { return fc.openInputStream(); } finally { fc.close(); } } public boolean canExec(String file) { return true; } public boolean canRead(String file) { if (file.length() == 0) return true; try { FileConnection fc = (FileConnection)Connector.open(getNativeURL(file), Connector.READ); try { return fc.canRead(); } finally { fc.close(); } } catch (IOException e) { return false; } } public boolean canWrite(String file) { if (file.length() == 0) return true; try { FileConnection fc = (FileConnection)Connector.open(getNativeURL(file), Connector.READ); try { return fc.canWrite(); } finally { fc.close(); } } catch (IOException e) { return false; } } public void create(String file) throws IOException { FileConnection fc = (FileConnection)Connector.open(getNativeURL(file), Connector.WRITE); try { fc.create(); } finally { fc.close(); } } public void mkdir(String file) throws IOException { FileConnection fc = (FileConnection)Connector.open(getNativeURL(file)+'/', Connector.READ_WRITE); try { fc.mkdir(); } finally { fc.close(); } } public void remove(String file) throws IOException { if (file.length() == 0) throw new IOException("Cannot remove mounted directory."); FileConnection fc = (FileConnection)Connector.open(getNativeURL(file), Connector.READ_WRITE); try { if (fc.exists()) fc.delete(); } finally { fc.close(); } } public boolean exists(String file) { if (file.length() == 0) return true; try { FileConnection fc = (FileConnection)Connector.open(getNativeURL(file), Connector.READ); try { return fc.exists(); } finally { fc.close(); } } catch (IOException e) { return false; } } public boolean isDirectory(String file) { if (file.length() == 0) return true; try { FileConnection fc = (FileConnection)Connector.open(getNativeURL(file), Connector.READ); try { return fc.isDirectory(); } finally { fc.close(); } } catch (IOException e) { return false; } } public long size(String file) throws IOException { FileConnection fc = (FileConnection)Connector.open(getNativeURL(file), Connector.READ); try { if (fc.isDirectory()) return 0l; else return fc.fileSize(); } finally { fc.close(); } } public long lastModified(String file) throws IOException { FileConnection fc = (FileConnection)Connector.open(getNativeURL(file), Connector.READ); try { return fc.lastModified(); } finally { fc.close(); } } public String[] list(String file) throws IOException { String path = getNativeURL(file); if (!path.endsWith("/")) path += "/"; FileConnection fc = (FileConnection)Connector.open(path, Connector.READ); try { Enumeration e = fc.list("*", false); ArrayList v = new ArrayList(); while (e.hasMoreElements()) v.add(e.nextElement()); int size = v.size(); String[] files = new String[size]; for (int i=0; i<size; i++) { files[i] = (String)v.get(i); } return files; } finally { fc.close(); } } public void setExec(String file, boolean on) throws IOException { return; } public void setRead(String file, boolean on) throws IOException { FileConnection fc = (FileConnection)Connector.open(getNativeURL(file), Connector.READ_WRITE); try { fc.setReadable(on); } finally { fc.close(); } } public void setWrite(String file, boolean on) throws IOException { FileConnection fc = (FileConnection)Connector.open(getNativeURL(file), Connector.READ_WRITE); try { fc.setWritable(on); } finally { fc.close(); } } public void move(String source, String dest) throws IOException { if (source.length() == 0) throw new IOException("Cannot move mounted directory"); if (exists(dest)) throw new IOException("File already exists: "+dest); String sparent = Filesystem.fileParent(source); String dparent = Filesystem.fileParent(dest); if (sparent.equals(dparent)) { FileConnection fc = (FileConnection)Connector.open(getNativeURL(source), Connector.READ_WRITE); try { fc.rename(Filesystem.fileName(dest)); } finally { fc.close(); } } else { super.move(source, dest); } } public long spaceFree() { try { FileConnection fc = (FileConnection)Connector.open(getNativeURL("")+'/', Connector.READ); try { return fc.availableSize(); } finally { fc.close(); } } catch (IOException e) { return 0l; } } public long spaceTotal() { try { FileConnection fc = (FileConnection)Connector.open(getNativeURL("")+'/', Connector.READ); try { return fc.totalSize(); } finally { fc.close(); } } catch (IOException e) { return 0l; } } public long spaceUsed() { try { FileConnection fc = (FileConnection)Connector.open(getNativeURL("")+'/', Connector.READ); try { return fc.usedSize(); } finally { fc.close(); } } catch (IOException e) { return 0l; } } }