KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > masterfs > MountTable


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.modules.masterfs;
21
22 import org.netbeans.modules.masterfs.providers.MountSupport;
23 import org.netbeans.modules.masterfs.filebasedfs.FileBasedFileSystem;
24 import org.netbeans.modules.masterfs.filebasedfs.fileobjects.WriteLockUtils;
25 import org.openide.filesystems.*;
26
27 import java.io.File JavaDoc;
28 import java.io.IOException JavaDoc;
29 import java.util.*;
30
31 /**
32  * Encapsulates access to mount table, which can be considered as set
33  * of pairs <mountPoint, FileSystem>. Method mount adds new pair and
34  * method unmount removes one. Every MasterFileObject delegates its functionality
35  * and FileSystems, that are held in mout table, provide such delgates.
36  * Method resolveBestDelegate is responsible for finding the best delegate to
37  * requested resource path. There may be possible to find more than one delagate to
38  * requested path. So, there also exist method resolveSecondDelegate.
39  *
40  *
41  * @author Radek Matous
42  */

43 final class MountTable implements InternalMountSupport {
44     /** maps <String rootName, FileSystem fs>*/
45     final private static Map res2fsMap = Collections.synchronizedMap(new HashMap());
46     final private static MountTable instance = new MountTable();
47     final static MountSupport mountSupport = APIAccess.DEFAULT.createMountSupport(instance);
48
49     /***
50      * @return one shared instance of MountTable
51      */

52     static MountTable getDefault() {
53         return instance;
54     }
55
56     private MountTable() {
57     }
58
59     /**
60      * Mounts new pair <mountPointPath, mount>.
61      * @param mountPointPath resource path associated with mounted filesystem mount
62      * @param mount mounted filesystem
63      * @throws IOException is thrown if mount can't be mounted (e.g.: if already mounted)
64      */

65     public void mount(final String JavaDoc mountPointPath, final FileSystem mount) throws IOException JavaDoc {
66         /*if (!(mount instanceof LocalFileSystem || mount instanceof JarFileSystem))
67             return;*/

68         final boolean syncNeeded = !(mount instanceof ExLocalFileSystem);
69         
70         final String JavaDoc normName = ResourcePath.getNormalizedPath(mountPointPath);
71
72         MasterFileSystem.getDefault().runAtomicAction(new FileSystem.AtomicAction() {
73             public void run() throws IOException JavaDoc {
74                 if (syncNeeded) {
75                     SyncSection.getDefault().enterExclusiveSection();
76                     try {
77                         mountIt(normName, mount, mountPointPath);
78                     } finally {
79                         SyncSection.getDefault().finishExclusiveSection();
80                     }
81                 } else {
82                     mountIt(normName, mount, mountPointPath);
83                 }
84             }
85         });
86
87         mount.addFileStatusListener(MasterFileSystem.getDefault());
88         mount.addNotify();
89     }
90
91     private void mountIt(final String JavaDoc normName, final FileSystem mount, final String JavaDoc mountPointPath) throws IOException JavaDoc {
92         FileSystem oldFs = (FileSystem) res2fsMap.put(normName, mount);
93         if (oldFs != null) handleAlreadyMounted(oldFs, mount, normName);
94         else refreshAfterMount(getMountEnumeration(mountPointPath));
95     }
96
97     /**
98      * Unmounts already mounted filesystem mount.
99      * @param mount filesystem requested to unmount
100      * @throws IOException is thrown if fs2Mount can't be unmounted
101      * (e.g.: haven't been mounted yet)
102      */

103     public void unmount(final FileSystem mount) throws IOException JavaDoc {
104         MasterFileSystem.getDefault().runAtomicAction(new FileSystem.AtomicAction() {
105             public void run() throws IOException JavaDoc {
106                 SyncSection.getDefault().enterExclusiveSection();
107                 try {
108                     if (!removeFileSystem(mount)) {
109                         String JavaDoc errMsg = Utils.formatString("EXC_CannotUnMount",
110                                 new Object JavaDoc[]{mount.getDisplayName()});
111                         throw new IOException JavaDoc(errMsg);
112                     }
113                 } finally {
114                     SyncSection.getDefault().finishExclusiveSection();
115                 }
116             }
117         });
118
119         mount.removeFileStatusListener(MasterFileSystem.getDefault());
120         mount.removeNotify();
121     }
122
123     /**
124      * Tries to find the best delegate to requested resourcePath.
125      * @param resourcePath
126      * @return the best delegate or null if delegate doesn't exist
127      */

128     FileObject resolveBestDelegate(final String JavaDoc resourcePath) {
129         return resolveDelegate(resourcePath, Delegate.BEST_DELEGATE);
130     }
131
132     /**
133      * Tries to find the second possible delegate to requested resourcePath.
134      * There may be possible to find more than one delagate to requested path.
135      * If the second one is not found, then the best one is returned.
136      * @param resourcePath
137      * @return the second possible delegate if found or best delegate or null
138      * (in mentioned order)
139      */

140     FileObject resolveSecondDelegate(final String JavaDoc resourcePath) {
141         return resolveDelegate(resourcePath, Delegate.SECOND_DELEGATE);
142     }
143
144     void unmount(final String JavaDoc mountPointPath) throws IOException JavaDoc {
145         final FileSystem fs = getMountedFileSystem(mountPointPath);
146         if (fs != null)
147             MountTable.getDefault().unmount(fs);
148     }
149
150     /**
151      * Gets all mounted filesystems
152      * @return enumeration of mounted filesystems
153      */

154     Enumeration geAllFileSystems() {
155         final ArrayList qE = new ArrayList ();
156         final Collection values = res2fsMap.values();
157         //SyncSection.getDefault().enterExclusiveSection();
158
SyncSection.getDefault().enterSection();
159         try {
160             synchronized (res2fsMap) {
161                 for (Iterator it = values.iterator(); it.hasNext();) {
162                     FileSystem fs = (FileSystem) it.next();
163                     if (fs != null)
164                         qE.add (fs);
165                 }
166             }
167         } finally {
168             //SyncSection.getDefault().finishExclusiveSection();
169
SyncSection.getDefault().finishSection();
170         }
171         return Collections.enumeration (qE);
172     }
173
174     /**
175      * Gets mount point, if mount is mounted. Else null is returned.
176      *
177      * @param mount filesystem of which mount point is looked for
178      * @return mount point or null */

179     boolean isMounted(final FileSystem mount) {
180         ResourcePath resource = findResourcePath(mount);
181         FileSystem fsTest = (FileSystem) res2fsMap.get(resource.getNormalizedPath());
182         return (mount == fsTest) ? true : false;
183     }
184
185     private ResourcePath findResourcePath(final FileSystem fs) {
186         final File JavaDoc f = FileUtil.toFile(fs.getRoot());
187         return Utils.getResource(f);
188     }
189
190     private FileObject resolveDelegate(String JavaDoc resourcePath, final int delegateLevel) {
191         FileSystem fs;
192         String JavaDoc bestMountPoint = "";
193
194         final LinkedList retValList = new LinkedList();
195         resourcePath = ResourcePath.getNormalizedPath(resourcePath);
196
197         if (WriteLockUtils.hasActiveLockFileSigns(resourcePath)) {
198             File JavaDoc f = new ResourcePath(resourcePath).getFile();
199             if (WriteLockUtils.hasActiveLockFileSigns(f.getAbsolutePath())) {
200                 return null;
201             }
202         }
203
204         synchronized (res2fsMap) {
205             final List sortedList = new ArrayList(res2fsMap.keySet());
206             Collections.sort(sortedList);
207
208             for (Iterator it = sortedList.iterator(); it.hasNext();) {
209                 String JavaDoc mountPoint = (String JavaDoc) it.next();
210                 if (resourcePath.startsWith(mountPoint) &&
211                         mountPoint.length() > bestMountPoint.length()) {
212                     boolean isMountPoint = mountPoint.length() == resourcePath.length() ||
213                             resourcePath.charAt(mountPoint.length()) == '/';
214                     if (isMountPoint || new ResourcePath (mountPoint).isRoot()) {
215                         bestMountPoint = mountPoint;
216                         retValList.addLast(bestMountPoint);
217                     }
218                 }
219             }
220             if (retValList.size() == 0) return null;
221
222             int idx = retValList.size() - (delegateLevel + 1);
223             if (idx < 0) idx = 0;
224
225             bestMountPoint = (String JavaDoc) retValList.get(idx);
226             fs = (FileSystem) res2fsMap.get(bestMountPoint);
227         }
228         FileObject retVal;
229         if (fs instanceof FileBasedFileSystem) {
230             File JavaDoc f = new ResourcePath (resourcePath).getFile();
231             retVal = fs.findResource(f.getAbsolutePath());
232         } else {
233             retVal = fs.findResource(resourcePath.substring(bestMountPoint.length()));
234         }
235         
236
237         return retVal;
238     }
239
240     private static void refreshAfterMount(final Enumeration changeList) {
241         final Set toReset = new LinkedHashSet();
242         while (changeList.hasMoreElements()) {
243             MasterFileObject hfo = (MasterFileObject) changeList.nextElement();
244             refreshAfterMount(hfo);
245             toReset.add(hfo);
246         }
247         resetAfterMount(toReset);
248         MasterFileSystem masterFs = MasterFileSystem.getDefault();
249         masterFs.fireFileStatus(new FileStatusEvent(masterFs,toReset, true, true ));
250     }
251
252     static void refreshAfterMount(MasterFileObject hfo) {
253         //if (true) return;
254
FileObject oldDelegate = hfo.getDelegate().get();
255         if (oldDelegate == null) return;
256         FileObject newDelegate = MountTable.getDefault().resolveBestDelegate(hfo.getResource().getNormalizedPath());
257         if (oldDelegate == newDelegate) return;
258         MasterFileObject.refreshAfterMount(newDelegate, oldDelegate, hfo);
259     }
260
261     private static void resetAfterMount(final Set toReset) {
262         Iterator it = toReset.iterator();
263         while (it.hasNext()) {
264             MasterFileObject hfo = (MasterFileObject) it.next();
265             hfo.getDelegate().reset(hfo.getResource());
266         }
267     }
268
269     static void renameCachedFileObjects(final String JavaDoc oldName, final String JavaDoc newName) {
270         final Enumeration en = Cache.getDefault().getAll();
271         while (en.hasMoreElements()) {
272             MasterFileObject fo = (MasterFileObject) en.nextElement();
273             String JavaDoc oldResPath = fo.getResource().getNormalizedPath();
274             if (oldResPath.startsWith(newName)) {
275                 continue;
276             }
277             if (oldResPath.startsWith(oldName)) {
278                 ResourcePath newResPath = new ResourcePath(newName + oldResPath.substring(oldName.length()));
279                 fo.setResource(newResPath);
280                 Cache.getDefault().replace(oldResPath, fo);
281             }
282         }
283     }
284
285     private Enumeration getMountEnumeration(final String JavaDoc mountPointPath) {
286         class Mnt implements org.openide.util.Enumerations.Processor {
287             public Object JavaDoc process (Object JavaDoc o, Collection ignore) {
288                 final MasterFileObject hfo = (MasterFileObject) o;
289                 String JavaDoc normalizedMountPoint = ResourcePath.getNormalizedPath(mountPointPath);
290                 String JavaDoc normalizedResourcePath = hfo.getResource().getNormalizedPath();
291                 
292                 if (normalizedResourcePath.startsWith(normalizedMountPoint) && hfo.isValid()) {
293                     return o;
294                 }
295                 return null;
296             }
297         }
298         return org.openide.util.Enumerations.filter (
299             Cache.getDefault().getAll(),
300             new Mnt ()
301         );
302     }
303
304     private static Enumeration getUnMountEnumeration(final FileSystem fs2Umount) {
305         class UnMnt implements org.openide.util.Enumerations.Processor {
306             public Object JavaDoc process (Object JavaDoc o, Collection ignore) {
307                 final MasterFileObject hfo = (MasterFileObject) o;
308                 if (hfo != null && hfo.isValid()) {
309                     FileSystem delgFs = hfo.getDelegateFileSystem();
310                     if (delgFs == fs2Umount)
311                         return o;
312
313                 }
314                 return null;
315             }
316         }
317         return org.openide.util.Enumerations.filter (
318             Cache.getDefault().getAll(),
319             new UnMnt ()
320         );
321     }
322
323     FileSystem getMountedFileSystem(String JavaDoc resName) {
324         resName = ResourcePath.getNormalizedPath(resName);
325         final FileSystem fsTest = (FileSystem) res2fsMap.get(resName);
326         return fsTest;
327     }
328
329     private void handleAlreadyMounted(FileSystem originalFs, final FileSystem newFs, final String JavaDoc name) throws IOException JavaDoc {
330         /** already registered another filesystem. First must be unregistered*/
331         res2fsMap.put(name, originalFs);
332 /*
333         Object[] params = new Object[]{newFs.getDisplayName(), name, originalFs.getDisplayName()};
334         IOException iex = new IOException(Utils.formatString("EXC_AlreadyMounted", params));
335         iex.printStackTrace();
336         throw iex;
337 */

338     }
339
340     private boolean removeFileSystem(final FileSystem fs) {
341         Iterator it = res2fsMap.entrySet().iterator();
342         while (it.hasNext()) {
343             Map.Entry entry = (Map.Entry) it.next();
344             FileSystem fsValue = (FileSystem) entry.getValue();
345             if (fsValue == fs) {
346                 it.remove();
347                 refreshAfterMount(getUnMountEnumeration(fs));
348                 return true;
349             }
350         }
351         return false;
352     }
353
354 }
355
Popular Tags