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