KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > lib > java > storagebuilder > 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 package org.netbeans.lib.java.storagebuilder;
20
21 import java.beans.PropertyVetoException JavaDoc;
22 import java.io.File JavaDoc;
23 import java.io.IOException JavaDoc;
24 import java.lang.ref.Reference JavaDoc;
25 import java.lang.ref.SoftReference JavaDoc;
26 import java.net.URL JavaDoc;
27 import java.net.URLEncoder JavaDoc;
28 import java.net.URLDecoder JavaDoc;
29 import java.net.URI JavaDoc;
30 import java.net.URISyntaxException JavaDoc;
31 import java.util.Enumeration JavaDoc;
32 import java.util.HashMap JavaDoc;
33 import java.util.Map JavaDoc;
34 import java.util.StringTokenizer JavaDoc;
35 import org.openide.ErrorManager;
36 import org.openide.filesystems.*;
37
38 public class ArchiveURLMapper extends URLMapper {
39
40     private static final String JavaDoc JAR_PROTOCOL = "jar"; //NOI18N
41

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

172     private static class JFSReference extends SoftReference JavaDoc {
173         private FileChangeListener fcl;
174         public JFSReference(JarFileSystem jfs) {
175             super(jfs);
176             final File JavaDoc 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 JavaDoc root) {
197             JarFileSystem jfs = (JarFileSystem)get ();
198             if (jfs != null) {
199                 synchronized (ArchiveURLMapper.class) {
200                     File JavaDoc keyToRemove = (root != null) ? root : jfs.getJarFile();
201                     mountRoots.remove(keyToRemove);
202                 }
203             }
204         }
205     }
206
207 }
208
Popular Tags