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.FSMountFactory; 024 import org.crsh.vfs.spi.Mount; 025 import org.crsh.vfs.spi.file.FileDriver; 026 import org.crsh.vfs.spi.url.ClassPathMountFactory; 027 import org.crsh.vfs.spi.url.URLDriver; 028 029 import java.io.IOException; 030 import java.net.URISyntaxException; 031 import java.net.URL; 032 import java.util.ArrayList; 033 import java.util.HashMap; 034 import java.util.Iterator; 035 import java.util.List; 036 037 /** 038 * The file system provides a federated view of {@link org.crsh.vfs.spi.FSDriver} mounts. 039 */ 040 public class FS { 041 042 public static class Builder { 043 044 /** . */ 045 private HashMap<String, FSMountFactory<?>> resolvers; 046 047 /** . */ 048 private ArrayList<Mount<?>> mounts = new ArrayList<Mount<?>>(); 049 050 public Builder() { 051 this.resolvers = new HashMap<String, FSMountFactory<?>>(); 052 } 053 054 /** 055 * Register a resolver. 056 * 057 * @param name the registration name 058 * @param resolver the resolver implementation 059 */ 060 public Builder register(String name, FSMountFactory<?> resolver) { 061 resolvers.put(name, resolver); 062 return this; 063 } 064 065 public Builder mount(String name, Path path) throws IOException, IllegalArgumentException { 066 FSMountFactory<?> resolver = resolvers.get(name); 067 if (resolver == null) { 068 throw new IllegalArgumentException("Unknown driver " + name); 069 } else { 070 Mount<?> mount = resolver.create(path); 071 mounts.add(mount); 072 return this; 073 } 074 } 075 076 public Builder mount(String mountPointConfig) throws IOException { 077 int prev = 0; 078 while (true) { 079 int next = mountPointConfig.indexOf(';', prev); 080 if (next == -1) { 081 next = mountPointConfig.length(); 082 } 083 if (next > prev) { 084 String mount = mountPointConfig.substring(prev, next); 085 int index = mount.indexOf(':'); 086 String name; 087 String path; 088 if (index == -1) { 089 name = "classpath"; 090 path = mount; 091 } else { 092 name = mount.substring(0, index); 093 path = mount.substring(index + 1); 094 } 095 mount(name, Path.get(path)); 096 prev = next + 1; 097 } else { 098 break; 099 } 100 } 101 return this; 102 } 103 104 public List<Mount<?>> getMounts() { 105 return mounts; 106 } 107 108 public FS build() throws IOException { 109 FS fs = new FS(); 110 for (Mount<?> mount : mounts) { 111 fs.mount(mount.getDriver()); 112 } 113 return fs; 114 } 115 116 @Override 117 public String toString() { 118 StringBuilder sb = new StringBuilder(); 119 for (Iterator<Mount<?>> i = mounts.iterator();i.hasNext();) { 120 Mount<?> mount = i.next(); 121 sb.append(mount.getValue()); 122 if (i.hasNext()) { 123 sb.append(';'); 124 } 125 } 126 return sb.toString(); 127 } 128 } 129 130 /** . */ 131 final List<FSDriver<?>> drivers; 132 133 public FS() { 134 this.drivers = new ArrayList<FSDriver<?>>(); 135 } 136 137 public File get(Path path) throws IOException { 138 return new File(this, path); 139 } 140 141 public FS mount(FSDriver<?> driver) throws IOException { 142 if (driver == null) { 143 throw new NullPointerException(); 144 } 145 drivers.add(driver); 146 return this; 147 } 148 149 public FS mount(java.io.File root) throws IOException { 150 return mount(new FileDriver(root)); 151 } 152 153 public FS mount(ClassLoader cl, Path path) throws IOException, URISyntaxException { 154 if (cl == null) { 155 throw new NullPointerException(); 156 } else { 157 return mount(new ClassPathMountFactory(cl).create(path).getDriver()); 158 } 159 } 160 161 public FS mount(Class<?> clazz) throws IOException, URISyntaxException { 162 if (clazz == null) { 163 throw new NullPointerException(); 164 } 165 URL url = clazz.getProtectionDomain().getCodeSource().getLocation(); 166 URLDriver driver = new URLDriver(); 167 driver.merge(url); 168 return mount(driver); 169 } 170 }