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    import org.crsh.vfs.spi.file.FileDriver;
024    import org.crsh.vfs.spi.jarurl.JarURLDriver;
025    import org.crsh.vfs.spi.mount.MountDriver;
026    import org.crsh.vfs.spi.servlet.ServletContextDriver;
027    
028    import javax.servlet.ServletContext;
029    import java.io.IOException;
030    import java.net.JarURLConnection;
031    import java.net.URISyntaxException;
032    import java.net.URL;
033    import java.util.ArrayList;
034    import java.util.Enumeration;
035    import java.util.List;
036    
037    public class FS {
038    
039      /** . */
040      final List<Mount<?>> mounts;
041    
042      public FS() {
043        this.mounts = new ArrayList<Mount<?>>();
044      }
045    
046      public File get(Path path) throws IOException {
047        return new File(this, path);
048      }
049    
050      public <H> FS mount(FSDriver<H> driver, Path path) {
051        if (driver == null) {
052          throw new NullPointerException();
053        }
054        if (path.equals(Path.get("/"))) {
055          mounts.add(Mount.wrap(driver));
056        } else {
057          mounts.add(Mount.wrap(new MountDriver<H>(path, driver)));
058        }
059        return this;
060      }
061    
062      public <H> FS mount(FSDriver<H> driver, String path) {
063        return mount(driver, Path.get(path));
064      }
065    
066      public <H> FS mount(FSDriver<H> driver) {
067        return mount(driver, "/");
068      }
069    
070      public FS mount(java.io.File root) {
071        return mount(new FileDriver(root));
072      }
073    
074      public FS mount(ClassLoader cl, Path path) throws IOException, URISyntaxException {
075        if (cl == null) {
076          throw new NullPointerException();
077        }
078        if (path == null) {
079          throw new NullPointerException();
080        }
081        if (!path.isDir()) {
082          throw new IllegalArgumentException("Path " + path + " must be a dir");
083        }
084        Enumeration<URL> en = cl.getResources(path.getValue().substring(1));
085        while (en.hasMoreElements()) {
086          URL url = en.nextElement();
087          String protocol = url.getProtocol();
088          if ("file".equals(protocol)) {
089            java.io.File root = new java.io.File(url.toURI());
090            mount(root);
091          } else if ("jar".equals(protocol)) {
092            JarURLConnection conn = (JarURLConnection)url.openConnection();
093            JarURLDriver jarDriver = new JarURLDriver(cl, conn);
094            mount(jarDriver, path);
095          }
096        }
097        return this;
098      }
099    
100      public FS mount(Class<?> clazz) throws IOException, URISyntaxException {
101        if (clazz == null) {
102          throw new NullPointerException();
103        }
104        URL url = clazz.getProtectionDomain().getCodeSource().getLocation();
105        String protocol = url.getProtocol();
106        FSDriver<?> driver;
107        if (protocol.equals("file")) {
108          driver = new FileDriver(new java.io.File(url.toURI()));
109        } else if (protocol.equals("jar")) {
110          JarURLConnection conn = (JarURLConnection)url.openConnection();
111          driver = new JarURLDriver(clazz.getClassLoader(), conn);
112        } else {
113          throw new IllegalArgumentException("Protocol " + protocol + " not supported");
114        }
115        return mount(driver);
116      }
117    }