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.spi.jarurl;
021
022 import org.crsh.vfs.spi.AbstractFSDriver;
023
024 import java.io.IOException;
025 import java.io.InputStream;
026 import java.net.JarURLConnection;
027 import java.net.URL;
028 import java.util.Collections;
029 import java.util.HashMap;
030 import java.util.Map;
031 import java.util.jar.JarEntry;
032 import java.util.jar.JarFile;
033
034 public class JarURLDriver extends AbstractFSDriver<Handle> {
035
036 /** . */
037 final ClassLoader loader;
038
039 /** . */
040 final Handle root;
041
042 /** . */
043 final URL jarURL;
044
045 private static Handle get(JarURLDriver driver, Map<String, Handle> handles, String path) {
046 Handle handle = handles.get(path);
047 if (handle == null) {
048 handle = new Handle(driver, path);
049 int to = path.length();
050 if (path.charAt(to - 1) == '/') {
051 to--;
052 }
053 int from = -1;
054 for (int i = to - 1;i >= 0;i--) {
055 if (path.charAt(i) == '/') {
056 from = i;
057 break;
058 }
059 }
060 String name;
061 Handle parent;
062 if (from == -1) {
063 parent = handles.get("");
064 name = path.substring(0, to);
065 } else {
066 parent = get(driver, handles, path.substring(0, from));
067 name = path.substring(from + 1, to);
068 }
069 parent.children.put(name, handle);
070 handles.put(path.substring(0, to), handle);
071 }
072 return handle;
073 }
074
075 public JarURLDriver(ClassLoader loader, JarURLConnection conn) throws IOException {
076 JarFile file = conn.getJarFile();
077 Map<String, Handle> handles = new HashMap<String, Handle>();
078 handles.put("", root = new Handle(this, ""));
079 for (JarEntry entry : Collections.list(file.entries())) {
080 Handle handle = get(this, handles, entry.getName());
081 handle.entry = entry;
082 }
083
084 //
085 this.jarURL = conn.getJarFileURL();
086 this.loader = loader;
087 }
088
089 public Handle root() throws IOException {
090 return root;
091 }
092
093 public String name(Handle handle) throws IOException {
094 return handle.path.getName();
095 }
096
097 public boolean isDir(Handle handle) throws IOException {
098 return handle.path.isDir();
099 }
100
101 public Iterable<Handle> children(Handle handle) throws IOException {
102 return handle.children.values();
103 }
104
105 public long getLastModified(Handle handle) throws IOException {
106 return 0;
107 }
108
109 public InputStream open(Handle handle) throws IOException {
110 return loader.getResourceAsStream(handle.entry.getName());
111 }
112 }