/* * $Id$ * * Copyright (C) 2003-2015 JNode.org * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This library 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 Lesser General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; If not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ package org.jnode.fs.hfsplus; import java.io.IOException; import org.jnode.fs.FSAccessRights; import org.jnode.fs.FSDirectory; import org.jnode.fs.FSEntry; import org.jnode.fs.FSEntryCreated; import org.jnode.fs.FSEntryLastAccessed; import org.jnode.fs.FSFile; import org.jnode.fs.FileSystem; import org.jnode.fs.hfsplus.catalog.CatalogFile; import org.jnode.fs.hfsplus.catalog.CatalogFolder; import org.jnode.fs.hfsplus.tree.LeafRecord; import org.jnode.fs.spi.AbstractFSEntry; import org.jnode.fs.spi.UnixFSAccessRights; public class HfsPlusEntry implements FSEntry, FSEntryCreated, FSEntryLastAccessed { protected HfsPlusFileSystem fs; protected HfsPlusDirectory parent; protected String name; protected LeafRecord record; private int type; protected boolean valid; protected boolean dirty; protected FSAccessRights rights; /** * @param fs * @param parent * @param name * @param record */ public HfsPlusEntry(HfsPlusFileSystem fs, HfsPlusDirectory parent, String name, LeafRecord record) { this.fs = fs; this.parent = parent; this.name = name; this.record = record; this.type = getFSEntryType(); this.rights = new UnixFSAccessRights(fs); } private int getFSEntryType() { int mode = record.getType(); if ("/".equals(name)) { return AbstractFSEntry.ROOT_ENTRY; } else if (mode == CatalogFolder.RECORD_TYPE_FOLDER) { return AbstractFSEntry.DIR_ENTRY; } else if (mode == CatalogFile.RECORD_TYPE_FILE) { CatalogFile catalogFile = new CatalogFile(getData()); if (catalogFile.getUserInfo().getFileType() == CatalogFolder.HARDLINK_FOLDER_TYPE && catalogFile.getUserInfo().getFileCreator() == CatalogFolder.HARDLINK_CREATOR) { // The file type and creator match the folder hardlink constants, this file is a placeholder for a // hard-linked directory return AbstractFSEntry.DIR_ENTRY; } else { return AbstractFSEntry.FILE_ENTRY; } } else { return AbstractFSEntry.OTHER_ENTRY; } } @Override public FSAccessRights getAccessRights() throws IOException { return rights; } @Override public HfsPlusDirectory getDirectory() throws IOException { if (!isDirectory()) { throw new IOException("It is not a Directory"); } return new HfsPlusDirectory(this); } @Override public FSFile getFile() throws IOException { if (!isFile()) { throw new IOException("It is not a file"); } return new HfsPlusFile(this); } @Override public long getLastModified() throws IOException { if (isFile()) { CatalogFile catalogFile = new CatalogFile(getData()); return catalogFile.getContentModDate(); } else { CatalogFolder catalogFolder = new CatalogFolder(getData()); return catalogFolder.getContentModDate(); } } @Override public String getId() { try { if (isFile()) { HfsPlusFile hfsPlusFile = (HfsPlusFile) getFile(); return Long.toString(hfsPlusFile.getCatalogFile().getFileId().getId()); } else { return getDirectory().getDirectoryId(); } } catch (IOException e) { throw new IllegalStateException("Error getting ID", e); } } @Override public String getName() { return name; } @Override public FSDirectory getParent() { return parent; } @Override public boolean isDirectory() { return (type == AbstractFSEntry.DIR_ENTRY || type == AbstractFSEntry.ROOT_ENTRY); } @Override public boolean isDirty() throws IOException { return dirty; } public void setDirty() { dirty = true; } public void resetDirty() { dirty = false; } @Override public boolean isFile() { return (type == AbstractFSEntry.FILE_ENTRY); } public CatalogFile createCatalogFile() { if (!isFile()) { throw new IllegalStateException("Attempted to create a catalog file but this entry is not a file!"); } return new CatalogFile(getData()); } public CatalogFolder createCatalogFolder() { if (isFile()) { throw new IllegalStateException("Attempted to create a catalog folder but this entry is not a directory!"); } return new CatalogFolder(getData()); } @Override public void setLastModified(long lastModified) throws IOException { if (isFile()) { CatalogFile catalogFile = new CatalogFile(getData()); // catalogFile.setContentModDate(); throw new UnsupportedOperationException("Not implemented yet."); } else { CatalogFolder catalogFolder = new CatalogFolder(getData()); catalogFolder.setContentModDate(lastModified); } } @Override public void setName(String newName) throws IOException { if (type == AbstractFSEntry.ROOT_ENTRY) { throw new IOException("Cannot change name of root directory"); } if (parent.rename(name, newName) < 0) { throw new IOException("Cannot change name"); } this.name = newName; } @Override public FileSystem<?> getFileSystem() { return fs; } @Override public boolean isValid() { return valid; } public byte[] getData() { return this.record.getData(); } @Override public long getCreated() throws IOException { if (isFile()) { CatalogFile catalogFile = new CatalogFile(getData()); return catalogFile.getCreateDate(); } else { CatalogFolder catalogFolder = new CatalogFolder(getData()); return catalogFolder.getCreateDate(); } } @Override public long getLastAccessed() throws IOException { if (isFile()) { CatalogFile catalogFile = new CatalogFile(getData()); return catalogFile.getAccessDate(); } else { CatalogFolder catalogFolder = new CatalogFolder(getData()); return catalogFolder.getAccessDate(); } } @Override public final String toString() { return String.format("HfsPlusEntry:[cnid:%s %s:'%s']", getId(), isFile() ? "file" : "directory", getName()); } }