KickJava   Java API By Example, From Geeks To Geeks.

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


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 java.io.IOException JavaDoc;
23 import java.io.File JavaDoc;
24 import java.lang.ref.Reference JavaDoc;
25 import java.lang.ref.WeakReference JavaDoc;
26 import java.util.Collection JavaDoc;
27 import java.util.HashMap JavaDoc;
28 import java.util.Iterator JavaDoc;
29 import java.util.Map JavaDoc;
30 import java.util.WeakHashMap JavaDoc;
31 import org.netbeans.modules.masterfs.filebasedfs.fileobjects.WriteLock;
32 import org.netbeans.modules.masterfs.filebasedfs.fileobjects.WriteLockFactory;
33 import org.openide.filesystems.FileAlreadyLockedException;
34 import org.openide.filesystems.FileChangeListener;
35 import org.openide.filesystems.FileLock;
36 import org.openide.filesystems.FileObject;
37 import org.openide.filesystems.FileUtil;
38 import org.netbeans.modules.masterfs.filebasedfs.fileobjects.WriteLockUtils;
39 import org.openide.util.Exceptions;
40 import org.openide.util.WeakListeners;
41
42 /**
43  * @author Radek Matous
44  */

45 final class Delegate {
46     private FileObject delegate;
47     private FileObject secondDelegate;
48     private FileChangeListener weakListener;
49     final private FileChangeListener fListener;
50     private Reference JavaDoc lock = null;
51
52     private int attribs = 0;
53
54     static final int SECOND_DELEGATE = 1;
55     static final int BEST_DELEGATE = 0;
56     private final MasterFileObject mfo;
57
58     Delegate(final FileObject fo, final FileChangeListener fListener, MasterFileObject mfo) {
59         this.fListener = fListener;
60         this.mfo = mfo;
61     }
62
63     FileObject get() {
64         ResourcePath resPath = mfo.getResource();
65         FileObject retVal = delegate;
66         if (delegate instanceof InvalidDelegate) {
67             retVal = null;
68         } else {
69             if (retVal == null) {
70                 retVal = resolve(resPath, true);
71                 set(retVal);
72             }
73         }
74         return retVal;
75     }
76
77     FileObject get(boolean maybeInvalid) {
78         FileObject retVal = get ();
79         if (maybeInvalid && retVal == null) {
80             retVal = delegate;
81         }
82         return retVal;
83     }
84     
85     static FileObject resolve(final ResourcePath resPath) {
86         return resolve(resPath, true);
87     }
88     
89     private static FileObject resolve(final ResourcePath resPath, final boolean bestDelegate) {
90         FileObject retVal;
91         String JavaDoc normalizedPath = resPath.getNormalizedPath();
92         if (WriteLockUtils.hasActiveLockFileSigns(normalizedPath)) {
93             File JavaDoc f = new ResourcePath(normalizedPath).getFile();
94             if (WriteLockUtils.hasActiveLockFileSigns(f.getName())) {
95                 return null;
96             }
97         }
98         
99         if (bestDelegate) {
100             retVal = MountTable.getDefault().resolveBestDelegate(normalizedPath);
101         } else {
102             retVal = MountTable.getDefault().resolveSecondDelegate(normalizedPath);
103         }
104
105         if (retVal == null) {
106             retVal = SpecialDelegates.get(resPath);
107         } else {
108             // reloads table from file .nbattrs. Changed values
109
// may be cached, but previous delegate may change some values
110
retVal.getAttribute("--hack--");//NOI18N
111
}
112         return retVal;
113     }
114
115     static FileLock getLockForDelegate(final FileLock testedLock, final FileObject delegate) throws IOException JavaDoc {
116         if (testedLock == null)
117             throw new IOException JavaDoc();
118
119         if (!(testedLock instanceof FileLockImpl))
120             throw new IOException JavaDoc();
121
122         FileLockImpl fLockImpl = (FileLockImpl) testedLock;
123         Delegate del = fLockImpl.getDelegate();
124
125         if (del.getFileLockImpl() != fLockImpl) {
126             throw new IOException JavaDoc();
127         }
128
129         FileLock retVal = fLockImpl.get(delegate);
130         if (retVal == null)
131             throw new IOException JavaDoc();
132
133         return retVal;
134     }
135     
136     FileObject getPrefered() {
137         final FileObject retVal = get();
138         FileObject secRetVal = null;
139         if (retVal != null) {
140             if (retVal.isRoot()) {
141                 secRetVal = getSecond();
142             }
143         }
144         return (secRetVal != null) ? secRetVal : retVal;
145     }
146
147     void reset(final ResourcePath resPath) {
148         FileObject lastDelegate = delegate;
149         set(null);
150         setSecond(null);
151         if (get() == null) {
152             boolean folder = (lastDelegate != null) ? lastDelegate.isFolder() : false;
153             delegate = new InvalidDelegate(resPath, folder);
154         } else {
155             getSecond();
156             attribs = 0;
157             try {
158                 reLock();
159             } catch (IOException JavaDoc e) {
160                 Exceptions.printStackTrace(e);
161             }
162         }
163     }
164
165     boolean isValid() {
166         return (delegate != null) && (delegate.isValid());
167     }
168
169     FileLock lock() throws IOException JavaDoc {
170         FileLockImpl lck;
171         String JavaDoc path = mfo.getPath ();
172
173         synchronized (Delegate.class) {
174             lck = getFileLockImpl();
175             if (lck != null) throw new FileAlreadyLockedException(path);
176             lock = new WeakReference JavaDoc(lck = new FileLockImpl());
177         }
178
179         lck.initLock(mfo.getResource().getFile(), get(), getPrefered());
180         return lck;
181     }
182
183     boolean hasMountAbleFlag() {
184         //TODO: evaluate commented code for Automount mode
185
/*
186         String path = mfo.getPath ();
187         if ((attribs & MNTPOINTFLAG_SUPPRESS) == MNTPOINTFLAG_SUPPRESS) return false;
188         if ((attribs & MNTPOINTFLAG) == MNTPOINTFLAG) return true;
189         if ((attribs & MNTPOINTFLAG_RESOLVED) == MNTPOINTFLAG_RESOLVED) return false;
190
191         attribs |= MNTPOINTFLAG_RESOLVED;
192
193
194         if (ProviderCall.isMountAble(path)) {
195             attribs |= MNTPOINTFLAG;
196             return true;
197         }
198 */

199
200         return false;
201     }
202
203     void set(final FileObject fo) {
204         synchronized (this) {
205             FileChangeListener oldListener = weakListener;
206             FileObject oldDelegate = delegate;
207             if (oldDelegate == fo) return;
208
209             if (oldListener != null && oldDelegate != null)
210                 oldDelegate.removeFileChangeListener(oldListener);
211
212             delegate = fo;
213             if (fo != null) {
214                 // the following is not typesafe, it is not nice,
215
// and very likely it is not even correct, however until
216
// there is a proper API for "priority listeners" in openide/fs
217
// there is not much to do about this
218
Class JavaDoc realClass;
219                 try {
220                     realClass = Class.forName("org.openide.filesystems.FileObject$PriorityFileChangeListener");
221                 } catch (ClassNotFoundException JavaDoc ex) {
222                     throw (IllegalStateException JavaDoc)new IllegalStateException JavaDoc(ex.getMessage()).initCause(ex);
223                 }
224                 weakListener = (FileChangeListener)WeakListeners.create(realClass, FileChangeListener.class, fListener, fo);
225                 fo.addFileChangeListener(weakListener);
226             }
227         }
228     }
229
230     private void reLock() throws IOException JavaDoc {
231         final FileLockImpl lck = getFileLockImpl();
232         if (lck != null) {
233             lck.lock(delegate);
234             lck.lock(secondDelegate);
235         }
236     }
237
238     private FileLockImpl getFileLockImpl() {
239         FileLockImpl lck;
240         synchronized (Delegate.class) {
241             lck = (FileLockImpl) ((lock == null) ? null : lock.get());
242         }
243         return lck;
244     }
245
246     private void setSecond(final FileObject fo) {
247         synchronized (this) {
248             secondDelegate = fo;
249         }
250     }
251
252     private FileObject getSecond() {
253         ResourcePath resPath = mfo.getResource();
254         FileObject retVal = secondDelegate;
255         if (retVal == null) {
256             retVal = resolve(resPath, false);
257             setSecond(retVal);
258         }
259         return retVal;
260     }
261
262     private final class FileLockImpl extends FileLock {
263         private final Map JavaDoc lockList = new WeakHashMap JavaDoc();
264 /*
265         there is some ugly piece of code around mandatoryLock that ensures that also
266         VCS support will use the same locking mechanism as FileBasedFileSystem does
267 */

268         private FileLock/**ever must be WriteLock*/ mandatoryLock;
269
270         FileLockImpl() {
271         }
272         
273         private void initLock(File JavaDoc file, final FileObject delegate, final FileObject prefered) throws IOException JavaDoc {
274             try {
275                 lock(delegate);
276                 lock(prefered);
277                 if (mandatoryLock == null && file != null) {
278                     if ((delegate != null && delegate.isData()) || (prefered != null && prefered.isData()))
279                     mandatoryLock = WriteLockFactory.tryLock(file, false);
280                 }
281             } catch (IOException JavaDoc e) {
282                 releaseLock();
283                 throw e;
284             }
285         }
286         
287         public void releaseLock() {
288             if (this.isValid()) {
289                 super.releaseLock();
290                 if (mandatoryLock != null) {
291                     mandatoryLock.releaseLock();
292                 }
293                 final Collection JavaDoc locks = lockList.values();
294                 for (Iterator JavaDoc iterator = locks.iterator(); iterator.hasNext();) {
295                     FileLock fLock = (FileLock) iterator.next();
296                     fLock.releaseLock();
297                 }
298
299                 if (getCurrentLock () == this) {
300                     synchronized (Delegate.class) {
301                         lock = null;
302                     }
303                 }
304             }
305         }
306
307         private FileLock getCurrentLock () {
308             return (lock != null) ? (FileLock)lock.get() : null;
309         }
310         
311         private void lock(final FileObject delegate) throws IOException JavaDoc {
312             if (delegate != null && this.get(delegate) == null) {
313                 FileLock fLock = delegate.lock();
314                 if (mandatoryLock == null && fLock instanceof WriteLock) {
315                     mandatoryLock = fLock;
316                 }
317                 lockList.put(delegate, fLock);
318             }
319         }
320
321         private FileLock get(final FileObject delegate) {
322             return (FileLock) lockList.get(delegate);
323         }
324
325         private Delegate getDelegate() {
326             return Delegate.this;
327         }
328     }
329     private static class TestLockException extends IOException JavaDoc {
330         Map JavaDoc m = new HashMap JavaDoc ();
331
332         void put (FileLockImpl impl, String JavaDoc msg) {
333            m.put(impl, new Exception JavaDoc(msg));
334         }
335
336         public void printStackTrace(FileLockImpl tested, FileLockImpl current) {
337             Exception JavaDoc exc = (Exception JavaDoc)m.get(tested);
338             if (exc != null) {
339                 System.err.println("-------- "+exc.getLocalizedMessage() + " ----------");
340                 exc.printStackTrace();
341             }
342             Exception JavaDoc exc2 = (Exception JavaDoc)m.get(current);
343             if (exc2 != null) {
344                 System.err.println("-------- "+exc2.getLocalizedMessage() + " ----------");
345                 exc2.printStackTrace();
346             }
347
348         }
349     }
350     
351     private static class InvalidDelegate extends InvalidDummy {
352         private final boolean isFolder;
353
354         protected InvalidDelegate(ResourcePath resourcePath, boolean isFolder) {
355             super(resourcePath);
356             this.isFolder = isFolder;
357         }
358
359         public boolean isData() {
360             return !isFolder;
361         }
362
363         public boolean isFolder() {
364             return isFolder;
365         }
366     }
367 }
368
Popular Tags