001 /* 002 * Copyright (C) 2012 eXo Platform SAS. 003 * 004 * This is free software; you can redistribute it and/or modify it 005 * under the terms of the GNU Lesser General Public License as 006 * published by the Free Software Foundation; either version 2.1 of 007 * the License, or (at your option) any later version. 008 * 009 * This software is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 012 * Lesser General Public License for more details. 013 * 014 * You should have received a copy of the GNU Lesser General Public 015 * License along with this software; if not, write to the Free 016 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 017 * 02110-1301 USA, or see the FSF site: http://www.fsf.org. 018 */ 019 020 package org.crsh.vfs; 021 022 import org.crsh.vfs.spi.FSDriver; 023 024 import java.io.IOException; 025 import java.util.ArrayList; 026 import java.util.Collections; 027 import java.util.Iterator; 028 import java.util.LinkedHashMap; 029 import java.util.LinkedList; 030 import java.util.List; 031 032 public final class File { 033 034 /** . */ 035 private final FS fs; 036 037 /** . */ 038 private final Path path; 039 040 /** . */ 041 private LinkedList<Handle<?>> handles; 042 043 /** . */ 044 private LinkedHashMap<String, File> children; 045 046 public File(FS fs, Path path) { 047 this.fs = fs; 048 this.path = path; 049 this.handles = null; 050 } 051 052 public Path getPath() { 053 return path; 054 } 055 056 public String getName() { 057 return path.getName(); 058 } 059 060 public boolean hasChildren() throws IOException { 061 return children().iterator().hasNext(); 062 } 063 064 public Resource getResource() throws IOException { 065 for (Handle handle : getHandles()) { 066 Resource resource = handle.getResource(); 067 if (resource != null) { 068 return resource; 069 } 070 } 071 return null; 072 } 073 074 public Iterable<Resource> getResources() throws IOException { 075 List<Resource> urls = Collections.emptyList(); 076 for (Handle<?> handle : getHandles()) { 077 if (urls.isEmpty()) { 078 urls = new ArrayList<Resource>(); 079 } 080 Iterator<Resource> resources = handle.getResources(); 081 while (resources.hasNext()) { 082 Resource resource = resources.next(); 083 urls.add(resource); 084 } 085 } 086 return urls; 087 } 088 089 public File child(String name) throws IOException { 090 if (children == null) { 091 children(); 092 } 093 return children.get(name); 094 } 095 096 public Iterable<File> children() throws IOException { 097 if (children == null) { 098 LinkedHashMap<String, File> children = new LinkedHashMap<String, File>(); 099 for (Handle<?> handle : getHandles()) { 100 for (Handle<?> childHandle : handle.children()) { 101 File child = children.get(childHandle.name); 102 if (child == null) { 103 child = new File(fs, path.append(childHandle.name, false)); 104 children.put(childHandle.name, child); 105 } 106 if (child.handles == null) { 107 child.handles = new LinkedList<Handle<?>>(); 108 } 109 child.handles.add(childHandle); 110 } 111 } 112 this.children = children; 113 } 114 return children.values(); 115 } 116 117 LinkedList<Handle<?>> getHandles() { 118 if (handles == null) { 119 LinkedList<Handle<?>> handles = new LinkedList<Handle<?>>(); 120 for (FSDriver<?> driver : fs.drivers) { 121 Handle<?> handle = null; 122 try { 123 handle = getHandle(driver, path); 124 } 125 catch (IOException e) { 126 e.printStackTrace(); 127 } 128 if (handle != null) { 129 handles.add(handle); 130 } 131 } 132 this.handles = handles; 133 } 134 return handles; 135 } 136 137 <H> Handle<H> getHandle(FSDriver<H> driver, Path path) throws IOException { 138 H current = resolve(driver, driver.root(), path); 139 if (current != null) { 140 return new Handle<H>(driver, current); 141 } else { 142 return null; 143 } 144 } 145 146 private <H> H resolve(FSDriver<H> driver, H current, Path path) throws IOException { 147 int index = 0; 148 while (current != null && index < path.getSize()) { 149 String name = path.nameAt(index++); 150 current = driver.child(current, name); 151 } 152 return current; 153 } 154 155 @Override 156 public String toString() { 157 return "File[path=" + path.getValue() + "]"; 158 } 159 }