1 19 package org.netbeans.lib.java.storagebuilder; 20 21 import java.beans.PropertyVetoException ; 22 import java.io.File ; 23 import java.io.IOException ; 24 import java.lang.ref.Reference ; 25 import java.lang.ref.SoftReference ; 26 import java.net.URL ; 27 import java.net.URLEncoder ; 28 import java.net.URLDecoder ; 29 import java.net.URI ; 30 import java.net.URISyntaxException ; 31 import java.util.Enumeration ; 32 import java.util.HashMap ; 33 import java.util.Map ; 34 import java.util.StringTokenizer ; 35 import org.openide.ErrorManager; 36 import org.openide.filesystems.*; 37 38 public class ArchiveURLMapper extends URLMapper { 39 40 private static final String JAR_PROTOCOL = "jar"; 42 private static ArchiveURLMapper instance; 43 44 private static Map mountRoots = new HashMap (); 45 46 public URL getURL(FileObject fo, int type) { 47 assert fo != null; 48 if (type == URLMapper.EXTERNAL || type == URLMapper.INTERNAL) { 49 if (fo.isValid()) { 50 try { 51 FileSystem fs = fo.getFileSystem(); 52 if (fs instanceof JarFileSystem) { 53 JarFileSystem jfs = (JarFileSystem) fs; 54 File archiveFile = jfs.getJarFile(); 55 if (this.isRoot(archiveFile)) { 56 return new URL ("jar:"+archiveFile.toURI()+"!/"+fo.getPath()+ ((fo.isFolder() && !fo.isRoot()) ? "/" : "")); } 73 } 74 } catch (IOException e) { 75 ErrorManager.getDefault().notify(e); 76 } 77 } 78 } 79 return null; 80 } 81 82 public FileObject[] getFileObjects(URL url) { 83 assert url != null; 84 String protocol = url.getProtocol (); 85 if (JAR_PROTOCOL.equals (protocol)) { 86 String path = url.getPath(); 87 int index = path.lastIndexOf ('!'); 88 if (index>=0) { 89 try { 90 URI archiveFileURI = new URI (path.substring(0,index)); 91 if (!archiveFileURI.isAbsolute() || archiveFileURI.isOpaque()) { 92 return null; } 94 FileObject fo = URLMapper.findFileObject (archiveFileURI.toURL()); 95 if (fo == null || fo.isVirtual()) { 96 return null; 97 } 98 File archiveFile = FileUtil.toFile (fo); 99 if (archiveFile == null) { 100 return null; 101 } 102 String offset = path.length()>index+2 ? URLDecoder.decode(path.substring(index+2),"UTF-8"): ""; JarFileSystem fs = getFileSystem(archiveFile); 104 FileObject resource = fs.findResource(offset); 105 if (resource != null) { 106 return new FileObject[] {resource}; 107 } 108 } catch (IOException e) { 109 ErrorManager.getDefault().log (ErrorManager.WARNING, e.getLocalizedMessage()); 112 } 113 catch (URISyntaxException e) { 114 ErrorManager.getDefault().notify(e); 115 } 116 } 117 } 118 return null; 119 } 120 121 public static FileObject getArchiveRoot (FileObject fo) throws IOException { 122 if (fo.isVirtual()) { 123 return null; 124 } 125 File file = FileUtil.toFile (fo); 126 return getFileSystem(file).getRoot(); 127 } 128 129 130 private static synchronized boolean isRoot (File file) { 131 return mountRoots.containsKey(file); 132 } 133 134 private static synchronized JarFileSystem getFileSystem (File file) throws IOException { 135 Reference reference = (Reference ) mountRoots.get (file); 136 JarFileSystem jfs = null; 137 if (reference==null || (jfs=(JarFileSystem)reference.get())==null) { 138 jfs = findJarFileSystemInRepository(file); 139 if (jfs == null) { 140 try { 141 jfs = new JarFileSystem(); 142 File aRoot = FileUtil.normalizeFile(file); 143 jfs.setJarFile(aRoot); 144 } catch (PropertyVetoException pve) { 145 throw new AssertionError (pve); 146 } 147 } 148 mountRoots.put(file, new JFSReference(jfs)); 149 } 150 return jfs; 151 } 152 153 private static JarFileSystem findJarFileSystemInRepository(File jarFile) { 155 Enumeration en = Repository.getDefault().getFileSystems(); 156 while (en.hasMoreElements()) { 157 FileSystem fs = (FileSystem)en.nextElement(); 158 if (fs instanceof JarFileSystem) { 159 JarFileSystem jfs = (JarFileSystem)fs; 160 if (jarFile.equals(jfs.getJarFile())) { 161 return jfs; 162 } 163 } 164 } 165 return null; 166 } 167 168 172 private static class JFSReference extends SoftReference { 173 private FileChangeListener fcl; 174 public JFSReference(JarFileSystem jfs) { 175 super(jfs); 176 final File root = jfs.getJarFile(); 177 FileObject rootFo = FileUtil.toFileObject(root); 178 if (rootFo != null) { 179 fcl = new FileChangeAdapter() { 180 public void fileDeleted(FileEvent fe) { 181 releaseMe(root); 182 } 183 184 public void fileRenamed(FileRenameEvent fe) { 185 releaseMe(root); 186 } 187 188 189 190 }; 191 rootFo.addFileChangeListener(FileUtil.weakFileChangeListener(fcl, rootFo)); 192 193 } 194 } 195 196 void releaseMe (final File root) { 197 JarFileSystem jfs = (JarFileSystem)get (); 198 if (jfs != null) { 199 synchronized (ArchiveURLMapper.class) { 200 File keyToRemove = (root != null) ? root : jfs.getJarFile(); 201 mountRoots.remove(keyToRemove); 202 } 203 } 204 } 205 } 206 207 } 208 | Popular Tags |