package org.rr.jeborker.gui.model; import java.io.IOException; import java.util.ArrayList; import java.util.Enumeration; import java.util.Iterator; import java.util.List; import java.util.logging.Level; import javax.swing.tree.MutableTreeNode; import javax.swing.tree.TreeNode; import org.rr.commons.log.LoggerFactory; import org.rr.commons.mufs.IResourceHandler; import org.rr.commons.mufs.ResourceNameFilter; import org.rr.commons.swing.components.tree.NamedNode; import org.rr.jeborker.gui.action.ActionUtils; public class FileSystemNode implements MutableTreeNode, NamedNode, Comparable<FileSystemNode> { private IResourceHandler pathResource; private int hashCode; private List<IResourceHandler> subFolders; private List<FileSystemNode> childNodes; private TreeNode parent; private boolean showFiles = true; private Boolean isLeaf; FileSystemNode(IResourceHandler pathResource, TreeNode parent) { this.pathResource = pathResource; this.parent = parent; this.hashCode = pathResource.toString().hashCode(); } FileSystemNode(IResourceHandler pathResource, TreeNode parent, boolean showFiles) { this.pathResource = pathResource; this.parent = parent; this.showFiles = showFiles; this.hashCode = pathResource.toString().hashCode(); } @Override public TreeNode getChildAt(int childIndex) { final List<FileSystemNode> childResources = createChildren(); return childResources.get(childIndex); } @Override public int getChildCount() { final List<IResourceHandler> childResources = getChildResources(); return childResources.size(); } @Override public TreeNode getParent() { return this.parent; } @Override public int getIndex(TreeNode node) { final List<IResourceHandler> childResources = getChildResources(); for(int i = 0; i < childResources.size(); i++) { IResourceHandler resource = childResources.get(i); if(((FileSystemNode)node).pathResource.equals(resource)) { return i; } } return -1; } @Override public boolean getAllowsChildren() { return true; } @Override public boolean isLeaf() { if(isLeaf == null) { isLeaf = Boolean.valueOf(this.pathResource.isFileResource()); } return isLeaf.booleanValue(); } private List<FileSystemNode> createChildren() { if(childNodes == null) { final List<IResourceHandler> childResources = getChildResources(); childNodes = new ArrayList<>(childResources.size()); for(int i = 0; i < childResources.size(); i++) { IResourceHandler resource = childResources.get(i); childNodes.add(new FileSystemNode(resource, this, showFiles)); } } return childNodes; } public void reset() { subFolders = null; childNodes = null; } @SuppressWarnings("rawtypes") @Override public Enumeration children() { final List<FileSystemNode> childResources = createChildren(); final Iterator<FileSystemNode> childResourcesIterator = childResources.iterator(); return new Enumeration() { @Override public boolean hasMoreElements() { return childResourcesIterator.hasNext(); } @Override public Object nextElement() { return childResourcesIterator.next(); } }; } private List<IResourceHandler> getChildResources() { if(subFolders == null) { try { final ArrayList<IResourceHandler> subFolder = new ArrayList<>(); final ArrayList<IResourceHandler> subFiles = new ArrayList<>(); pathResource.listResources(new ResourceNameFilter() { @Override public boolean accept(IResourceHandler resource) { if(!resource.isHidden()) { if(resource.isFileResource()) { if(showFiles && ActionUtils.isSupportedEbookFormat(resource, false)) { subFiles.add(resource); } } else { subFolder.add(resource); } } return false; } }); subFolders = new ArrayList<>(); subFolders.addAll(subFolder); subFolders.addAll(subFiles); } catch (IOException e) { LoggerFactory.getLogger(this).log(Level.WARNING, "Failed to list " + pathResource, e); subFolders = new ArrayList<>(0); } } return subFolders; } @Override public void insert(MutableTreeNode child, int index) { final List<IResourceHandler> childResources = getChildResources(); childResources.add(index, ((FileSystemNode)child).pathResource); } @Override public void remove(int index) { final List<IResourceHandler> childResources = getChildResources(); childResources.remove(index); } @Override public void remove(MutableTreeNode node) { final List<IResourceHandler> childResources = getChildResources(); int index = this.getIndex(node); childResources.remove(index); } @Override public void setUserObject(Object userObject) { } @Override public void removeFromParent() { ((MutableTreeNode)this.parent).remove(this); } @Override public void setParent(MutableTreeNode newParent) { this.parent = newParent; } public String toString() { return this.pathResource.getName(); } public IResourceHandler getResource() { return this.pathResource; } @Override public String getName() { return pathResource.toString(); } public void renameTo(IResourceHandler newPathName) throws IOException { this.pathResource.moveTo(newPathName, false); this.pathResource = newPathName; } @Override public int compareTo(FileSystemNode o) { return o.pathResource.compareTo(pathResource); } public boolean equals(Object o) { if(this == o) { return true; } else if(o instanceof FileSystemNode) { return this.compareTo((FileSystemNode)o) == 0; } return false; } @Override public int hashCode() { return hashCode; } }