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.slf4j.Logger;
023    import org.slf4j.LoggerFactory;
024    
025    import java.io.IOException;
026    import java.util.ArrayList;
027    import java.util.Collections;
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 static final Logger log = LoggerFactory.getLogger(Resource.class);
036    
037      /** . */
038      private final FS fs;
039    
040      /** . */
041      private final Path path;
042    
043      /** . */
044      private LinkedList<Handle<?>> handles;
045    
046      /** . */
047      private LinkedHashMap<Key, File> children;
048    
049      public File(FS fs, Path path) {
050        this.fs = fs;
051        this.path = path;
052        this.handles = null;
053      }
054    
055      public Path getPath() {
056        return path;
057      }
058    
059      public boolean isDir() {
060        return path.isDir();
061      }
062    
063      public String getName() {
064        return path.getName();
065      }
066    
067      public Resource getResource() throws IOException {
068        if (path.isDir()) {
069          throw new IllegalStateException("Cannot get url of a dir");
070        }
071        Handle handle = getHandles().peekFirst();
072        return handle != null ? handle.getResource() : null;
073    
074      }
075    
076      public Iterable<Resource> getResources() throws IOException {
077        if (path.isDir()) {
078          throw new IllegalStateException("Cannot get url of a dir");
079        }
080        List<Resource> urls = Collections.emptyList();
081        for (Handle handle : getHandles()) {
082          if (urls.isEmpty()) {
083            urls = new ArrayList<Resource>();
084          }
085          Resource resource = handle.getResource();
086          urls.add(resource);
087        }
088        return urls;
089      }
090    
091      public File child(String name, boolean dir) throws IOException {
092        if (children == null) {
093          children();
094        }
095        return children.get(new Key(name, dir));
096      }
097    
098      public Iterable<File> children() throws IOException {
099        if (children == null) {
100          LinkedHashMap<Key, File> children = new LinkedHashMap<Key, File>();
101          for (Handle<?> handle : getHandles()) {
102            for (Handle<?> childHandle : handle.children()) {
103              File child = children.get(childHandle.key);
104              if (child == null) {
105                child = new File(fs, Path.get(path, childHandle.key.name, childHandle.key.dir));
106                children.put(childHandle.key, child);
107              }
108              if (child.handles == null) {
109                child.handles = new LinkedList<Handle<?>>();
110              }
111              child.handles.add(childHandle);
112            }
113          }
114          this.children = children;
115        }
116        return children.values();
117      }
118    
119      LinkedList<Handle<?>> getHandles() {
120        if (handles == null) {
121          LinkedList<Handle<?>> handles = new LinkedList<Handle<?>>();
122          for (Mount<?> mount : fs.mounts) {
123            Handle<?> handle = null;
124            try {
125              handle = mount.getHandle(path);
126            }
127            catch (IOException e) {
128              e.printStackTrace();
129            }
130            if (handle != null) {
131              handles.add(handle);
132            }
133          }
134          this.handles = handles;
135        }
136        return handles;
137      }
138    
139      @Override
140      public String toString() {
141        return "File[path=" + path.getValue() + "]";
142      }
143    }