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