KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > core > startup > layers > ArchiveURLMapper


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.core.startup.layers;
21
22 import java.beans.PropertyVetoException JavaDoc;
23 import java.io.File JavaDoc;
24 import java.io.IOException JavaDoc;
25 import java.lang.ref.Reference JavaDoc;
26 import java.lang.ref.SoftReference JavaDoc;
27 import java.net.URI JavaDoc;
28 import java.net.URISyntaxException JavaDoc;
29 import java.net.URL JavaDoc;
30 import java.net.URLDecoder JavaDoc;
31 import java.util.Enumeration JavaDoc;
32 import java.util.HashMap JavaDoc;
33 import java.util.Map JavaDoc;
34 import java.util.logging.Level JavaDoc;
35 import org.openide.filesystems.FileChangeAdapter;
36 import org.openide.filesystems.FileChangeListener;
37 import org.openide.filesystems.FileEvent;
38 import org.openide.filesystems.FileObject;
39 import org.openide.filesystems.FileRenameEvent;
40 import org.openide.filesystems.FileSystem;
41 import org.openide.filesystems.FileUtil;
42 import org.openide.filesystems.JarFileSystem;
43 import org.openide.filesystems.Repository;
44 import org.openide.filesystems.URLMapper;
45 import org.openide.util.Exceptions;
46
47 public class ArchiveURLMapper extends URLMapper {
48
49     private static final String JavaDoc JAR_PROTOCOL = "jar"; //NOI18N
50

51     private static Map JavaDoc<File JavaDoc,SoftReference JavaDoc<JarFileSystem>> mountRoots = new HashMap JavaDoc<File JavaDoc,SoftReference JavaDoc<JarFileSystem>>();
52
53     public URL JavaDoc getURL(FileObject fo, int type) {
54         assert fo != null;
55         if (type == URLMapper.EXTERNAL || type == URLMapper.INTERNAL) {
56             if (fo.isValid()) {
57                 try {
58                     FileSystem fs = fo.getFileSystem();
59                     if (fs instanceof JarFileSystem) {
60                         JarFileSystem jfs = (JarFileSystem) fs;
61                         File JavaDoc archiveFile = jfs.getJarFile();
62                         if (isRoot(archiveFile)) {
63 // XXX: commented out to create same URLs as URLMapper.DefaultURLMapper.
64
// StringTokenizer tk = new StringTokenizer (fo.getPath(),"/"); //NOI18N
65
// StringBuffer offset = new StringBuffer ();
66
// while (tk.hasMoreTokens()) {
67
// offset.append('/'); //NOI18N
68
// // The encoding is needed to create a valid URI.
69
// // Otherwise the URI constructor throws URISyntaxException
70
// // Todo: It causes problems with JarURLConnection
71
// // which determines the entryName by String.substring(int,int)
72
// offset.append(URLEncoder.encode(tk.nextToken(),"UTF-8")); //NOI18N
73
// }
74
// if (offset.length()==0) {
75
// offset.append('/'); //NOI18N
76
// }
77
return new URL JavaDoc ("jar:"+archiveFile.toURI()+"!/"+fo.getPath()+
78                                     ((fo.isFolder() && !fo.isRoot()) ? "/" : "")); // NOI18N
79
}
80                     }
81                 } catch (IOException JavaDoc e) {
82                     Exceptions.printStackTrace(e);
83                 }
84             }
85         }
86         return null;
87     }
88
89     public FileObject[] getFileObjects(URL JavaDoc url) {
90         assert url != null;
91         String JavaDoc protocol = url.getProtocol ();
92         if (JAR_PROTOCOL.equals (protocol)) {
93             String JavaDoc path = url.getPath();
94             int index = path.lastIndexOf ('!');
95             if (index>=0) {
96                 try {
97                     URI JavaDoc archiveFileURI = new URI JavaDoc(path.substring(0,index));
98                     if (!archiveFileURI.isAbsolute() || archiveFileURI.isOpaque()) {
99                         return null; //Better than to throw IllegalArgumentException
100
}
101                     FileObject fo = URLMapper.findFileObject (archiveFileURI.toURL());
102                     if (fo == null || fo.isVirtual()) {
103                         return null;
104                     }
105                     File JavaDoc archiveFile = FileUtil.toFile (fo);
106                     if (archiveFile == null) {
107                         return null;
108                     }
109                     String JavaDoc offset = path.length()>index+2 ? URLDecoder.decode(path.substring(index+2),"UTF-8"): ""; //NOI18N
110
JarFileSystem fs = getFileSystem(archiveFile);
111                     FileObject resource = fs.findResource(offset);
112                     if (resource != null) {
113                         return new FileObject[] {resource};
114                     }
115                 } catch (IOException JavaDoc e) {
116                     // Can easily happen if the JAR file is corrupt etc,
117
// it is better for user to log localized message than to dump stack
118
ModuleLayeredFileSystem.err.log(Level.WARNING, null, e);
119                 }
120                 catch (URISyntaxException JavaDoc e) {
121                     Exceptions.printStackTrace(e);
122                 }
123             }
124         }
125         return null;
126     }
127
128     private static synchronized boolean isRoot (File JavaDoc file) {
129         return mountRoots.containsKey(file);
130     }
131
132     private static synchronized JarFileSystem getFileSystem (File JavaDoc file) throws IOException JavaDoc {
133         Reference JavaDoc<JarFileSystem> reference = mountRoots.get(file);
134         JarFileSystem jfs = null;
135         if (reference == null || (jfs = reference.get()) == null) {
136             jfs = findJarFileSystemInRepository(file);
137             if (jfs == null) {
138                 try {
139                     jfs = new JarFileSystem();
140                     File JavaDoc aRoot = FileUtil.normalizeFile(file);
141                     jfs.setJarFile(aRoot);
142                 } catch (PropertyVetoException JavaDoc pve) {
143                     throw new AssertionError JavaDoc(pve);
144                 }
145             }
146             mountRoots.put(file, new JFSReference(jfs));
147         }
148         return jfs;
149     }
150
151     // More or less copied from URLMapper:
152
private static JarFileSystem findJarFileSystemInRepository(File JavaDoc jarFile) {
153         @SuppressWarnings JavaDoc("deprecation") // for compat only
154
Enumeration JavaDoc<? extends FileSystem> en = Repository.getDefault().getFileSystems();
155         while (en.hasMoreElements()) {
156             FileSystem fs = en.nextElement();
157             if (fs instanceof JarFileSystem) {
158                 JarFileSystem jfs = (JarFileSystem)fs;
159                 if (jarFile.equals(jfs.getJarFile())) {
160                     return jfs;
161                 }
162             }
163         }
164         return null;
165     }
166
167     /**
168      * After deleting and recreating of jar file there must be properly
169      * refreshed cached map "mountRoots".
170      */

171     private static class JFSReference extends SoftReference JavaDoc<JarFileSystem> {
172         private FileChangeListener fcl;
173         public JFSReference(JarFileSystem jfs) {
174             super(jfs);
175             final File JavaDoc root = jfs.getJarFile();
176             FileObject rootFo = FileUtil.toFileObject(root);
177             if (rootFo != null) {
178                 fcl = new FileChangeAdapter() {
179                     public void fileDeleted(FileEvent fe) {
180                         releaseMe(root);
181                     }
182
183                 public void fileRenamed(FileRenameEvent fe) {
184                         releaseMe(root);
185                 }
186                     
187                     
188                     
189                 };
190                 rootFo.addFileChangeListener(FileUtil.weakFileChangeListener(fcl, rootFo));
191                 
192             }
193         }
194         
195         void releaseMe (final File JavaDoc root) {
196             JarFileSystem jfs = get();
197             if (jfs != null) {
198                 synchronized (ArchiveURLMapper.class) {
199                     File JavaDoc keyToRemove = (root != null) ? root : jfs.getJarFile();
200                     mountRoots.remove(keyToRemove);
201                 }
202             }
203         }
204     }
205
206 }
207
Popular Tags