Source Code Cross Referenced for FileStateManager.java in  » IDE-Netbeans » library » org » netbeans » core » projects » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE Netbeans » library » org.netbeans.core.projects 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003:         *
004:         * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005:         *
006:         * The contents of this file are subject to the terms of either the GNU
007:         * General Public License Version 2 only ("GPL") or the Common
008:         * Development and Distribution License("CDDL") (collectively, the
009:         * "License"). You may not use this file except in compliance with the
010:         * License. You can obtain a copy of the License at
011:         * http://www.netbeans.org/cddl-gplv2.html
012:         * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013:         * specific language governing permissions and limitations under the
014:         * License.  When distributing the software, include this License Header
015:         * Notice in each file and include the License file at
016:         * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
017:         * particular file as subject to the "Classpath" exception as provided
018:         * by Sun in the GPL Version 2 section of the License file that
019:         * accompanied this code. If applicable, add the following below the
020:         * License Header, with the fields enclosed by brackets [] replaced by
021:         * your own identifying information:
022:         * "Portions Copyrighted [year] [name of copyright owner]"
023:         *
024:         * Contributor(s):
025:         *
026:         * The Original Software is NetBeans. The Initial Developer of the Original
027:         * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028:         * Microsystems, Inc. All Rights Reserved.
029:         *
030:         * If you wish your version of this file to be governed by only the CDDL
031:         * or only the GPL Version 2, indicate your decision by adding
032:         * "[Contributor] elects to include this software in this distribution
033:         * under the [CDDL or GPL Version 2] license." If you do not indicate a
034:         * single choice of license, a recipient has the option to distribute
035:         * your version of this file under either the CDDL, the GPL Version 2 or
036:         * to extend the choice of license to its licensees as provided above.
037:         * However, if you add GPL Version 2 code and therefore, elected the GPL
038:         * Version 2 license, then the option applies only if the new code is
039:         * made subject to such option by the copyright holder.
040:         */
041:
042:        package org.netbeans.core.projects;
043:
044:        import java.beans.PropertyChangeEvent;
045:        import java.beans.PropertyChangeListener;
046:        import java.io.IOException;
047:        import java.lang.ref.WeakReference;
048:        import java.util.HashMap;
049:        import java.util.Iterator;
050:        import java.util.LinkedList;
051:        import java.util.Map.Entry;
052:        import java.util.WeakHashMap;
053:        import org.netbeans.core.startup.layers.SessionManager;
054:        import org.openide.filesystems.FileChangeAdapter;
055:        import org.openide.filesystems.FileChangeListener;
056:        import org.openide.filesystems.FileEvent;
057:        import org.openide.filesystems.FileLock;
058:        import org.openide.filesystems.FileObject;
059:        import org.openide.filesystems.FileRenameEvent;
060:        import org.openide.filesystems.FileStateInvalidException;
061:        import org.openide.filesystems.FileSystem;
062:        import org.openide.filesystems.FileUtil;
063:        import org.openide.filesystems.Repository;
064:
065:        /** Scans positions of FileObject-delegates for FileObjects from SystemFileSystem. Each
066:         *
067:         * @author  Vitezslav Stejskal
068:         */
069:        final class FileStateManager {
070:
071:            /** Identification of filesystem representing Session */
072:            public static final int LAYER_SESSION = 1;
073:            /** Identification of filesystem representing XML-layers from all installed modules */
074:            public static final int LAYER_MODULES = 2;
075:
076:            /** File State - file is defined on the layer (top-most layer containing the file) */
077:            public static final int FSTATE_DEFINED = 0;
078:            /** File State - file is ignored on the layer (higher layer contains file too) */
079:            public static final int FSTATE_IGNORED = 1;
080:            /** File State - file is inherited on the layer (file doesn't exist on the layer and exists on lower layer) */
081:            public static final int FSTATE_INHERITED = 2;
082:            /** File State - file is not defined on the layer (file doesn't exist on the layer and exists on higher layer) */
083:            public static final int FSTATE_UNDEFINED = 3;
084:
085:            /** Singleton instance of FileStateManager */
086:            private static FileStateManager manager = null;
087:            /** Cache of collected information */
088:            private WeakHashMap<FileObject, FileInfo> info = new WeakHashMap<FileObject, FileInfo>();
089:            /** Number of layers on {@link SystemFileSystem} */
090:            private static final int LAYERS_COUNT = 3;
091:            /** Layers of {@link SystemFileSystem}, LAYER_* constants can be used as indexes. */
092:            private FileSystem layers[] = new FileSystem[LAYERS_COUNT];
093:            /** List of listeners listening on changes in file state */
094:            private HashMap<FileStatusListener, LinkedList<FileObject>> listeners = new HashMap<FileStatusListener, LinkedList<FileObject>>(
095:                    10);
096:            /** Listener attached to SessionManager, it refreshes list of layers if some are added or removed */
097:            private PropertyChangeListener propL = null;
098:
099:            public static synchronized FileStateManager getDefault() {
100:                if (manager == null) {
101:                    manager = new FileStateManager();
102:                }
103:                return manager;
104:            }
105:
106:            /** Creates new FileStateManager */
107:            private FileStateManager() {
108:                // set layers
109:                getLayers();
110:
111:                // listen on changes of layers made through the SessionManager
112:                propL = new PropL();
113:                SessionManager.getDefault().addPropertyChangeListener(
114:                        org.openide.util.WeakListeners.propertyChange(propL,
115:                                SessionManager.getDefault()));
116:            }
117:
118:            public void define(final FileObject mfo, int layer, boolean revert)
119:                    throws IOException {
120:                // ignore request when file is already defined on layer
121:                if (FSTATE_DEFINED == getFileState(mfo, layer))
122:                    return;
123:
124:                FileSystem fsLayer = getLayer(layer);
125:                if (fsLayer == null)
126:                    throw new IllegalArgumentException("Invalid layer " + layer); //NOI18N
127:
128:                // find file on specified layer
129:                FileObject fo = fsLayer.findResource(mfo.getPath());
130:
131:                // remove the file if it exists and current definition should be preserved
132:                if (fo != null && !revert) {
133:                    deleteImpl(mfo, fsLayer);
134:                    fo = null;
135:                }
136:
137:                // create file on specified layer if it doesn't exist
138:                if (fo == null) {
139:                    String parent = mfo.getParent().getPath();
140:                    final FileObject fparent = FileUtil.createFolder(fsLayer
141:                            .getRoot(), parent);
142:                    fparent.getFileSystem().runAtomicAction(
143:                            new FileSystem.AtomicAction() {
144:                                public void run() throws IOException {
145:                                    mfo.copy(fparent, mfo.getName(), mfo
146:                                            .getExt());
147:                                }
148:                            });
149:                }
150:
151:                // remove above defined files
152:                for (int i = 0; i < layer; i++) {
153:                    FileSystem fsl = getLayer(i);
154:                    if (fsl != null)
155:                        deleteImpl(mfo, fsl);
156:                }
157:            }
158:
159:            public void delete(FileObject mfo, int layer) throws IOException {
160:                FileSystem fsLayer = getLayer(layer);
161:                if (fsLayer == null)
162:                    throw new IllegalArgumentException("Invalid layer " + layer); //NOI18N
163:
164:                deleteImpl(mfo, fsLayer);
165:            }
166:
167:            public int getFileState(FileObject mfo, int layer) {
168:                // check if the FileObject is from SystemFileSystem
169:                FileSystem fs = null;
170:                FileInfo finf = null;
171:
172:                try {
173:                    fs = mfo.getFileSystem();
174:                } catch (FileStateInvalidException e) {
175:                    // ignore, will be handled later
176:                }
177:
178:                if (fs == null
179:                        || !Repository.getDefault().getDefaultFileSystem()
180:                                .equals(fs))
181:                    throw new IllegalArgumentException(
182:                            "FileObject has to be from DefaultFileSystem - "
183:                                    + mfo);
184:
185:                synchronized (info) {
186:                    if (null == (finf = info.get(mfo))) {
187:                        finf = new FileInfo(mfo);
188:                        info.put(mfo, finf);
189:                    }
190:                }
191:
192:                return finf.getState(layer);
193:            }
194:
195:            public final void addFileStatusListener(FileStatusListener l,
196:                    FileObject mfo) {
197:                synchronized (listeners) {
198:                    LinkedList<FileObject> lst = null;
199:                    if (!listeners.containsKey(l)) {
200:                        lst = new LinkedList<FileObject>();
201:                        listeners.put(l, lst);
202:                    } else
203:                        lst = listeners.get(l);
204:
205:                    if (!lst.contains(mfo))
206:                        lst.add(mfo);
207:                }
208:            }
209:
210:            public final void removeFileStatusListener(FileStatusListener l,
211:                    FileObject mfo) {
212:                synchronized (listeners) {
213:                    if (mfo == null)
214:                        listeners.remove(l);
215:                    else {
216:                        LinkedList<FileObject> lst = listeners.get(l);
217:                        if (lst != null) {
218:                            lst.remove(mfo);
219:                            if (lst.isEmpty())
220:                                listeners.remove(l);
221:                        }
222:                    }
223:                }
224:            }
225:
226:            @SuppressWarnings("unchecked")
227:            private void fireFileStatusChanged(FileObject mfo) {
228:                HashMap<FileStatusListener, LinkedList<FileObject>> h = null;
229:
230:                synchronized (listeners) {
231:                    h = (HashMap<FileStatusListener, LinkedList<FileObject>>) listeners
232:                            .clone();
233:                }
234:
235:                for (Entry<FileStatusListener, LinkedList<FileObject>> entry : h
236:                        .entrySet()) {
237:                    FileStatusListener l = entry.getKey();
238:                    LinkedList<FileObject> lst = entry.getValue();
239:                    if (lst.contains(mfo))
240:                        l.fileStatusChanged(mfo);
241:                }
242:            }
243:
244:            private void deleteImpl(FileObject mfo, FileSystem fsLayer)
245:                    throws IOException {
246:                FileObject fo = fsLayer.findResource(mfo.getPath());
247:                if (fo != null) {
248:                    FileLock lock = null;
249:                    try {
250:                        lock = fo.lock();
251:                        fo.delete(lock);
252:                    } finally {
253:                        if (lock != null)
254:                            lock.releaseLock();
255:                    }
256:                }
257:            }
258:
259:            private void discard(FileObject mfo) {
260:                synchronized (info) {
261:                    info.remove(mfo);
262:                }
263:            }
264:
265:            private void getLayers() {
266:                layers[LAYER_SESSION] = SessionManager.getDefault().getLayer(
267:                        SessionManager.LAYER_SESSION);
268:                layers[LAYER_MODULES] = SessionManager.getDefault().getLayer(
269:                        SessionManager.LAYER_INSTALL);
270:            }
271:
272:            private FileSystem getLayer(int layer) {
273:                return layers[layer];
274:            }
275:
276:            private class PropL implements  PropertyChangeListener {
277:                PropL() {
278:                }
279:
280:                public void propertyChange(PropertyChangeEvent evt) {
281:                    if (SessionManager.PROP_OPEN.equals(evt.getPropertyName())) {
282:                        FileObject mfos[] = null;
283:
284:                        synchronized (info) {
285:                            mfos = (FileObject[]) info.keySet().toArray(
286:                                    new FileObject[info.size()]);
287:
288:                            // invalidate all existing FileInfos
289:                            for (int i = 0; i < mfos.length; i++) {
290:                                FileInfo finf = info.get(mfos[i]);
291:
292:                                if (finf != null)
293:                                    finf.invalidate();
294:                            }
295:
296:                            // clear the cache
297:                            info.clear();
298:
299:                            // [PENDING] this should be better synchronized
300:                            getLayers();
301:                        }
302:
303:                        for (int i = 0; i < mfos.length; i++)
304:                            fireFileStatusChanged(mfos[i]);
305:                    }
306:                }
307:            }
308:
309:            public static interface FileStatusListener {
310:                public void fileStatusChanged(FileObject mfo);
311:            }
312:
313:            private class FileInfo extends FileChangeAdapter {
314:                private WeakReference<FileObject> file = null;
315:
316:                private int state[] = new int[LAYERS_COUNT];
317:                private final Object LOCK = new Object();
318:
319:                private FileObject notifiers[] = new FileObject[LAYERS_COUNT];
320:                private FileChangeListener weakL[] = new FileChangeListener[LAYERS_COUNT];
321:
322:                public FileInfo(FileObject mfo) {
323:                    file = new WeakReference<FileObject>(mfo);
324:
325:                    // get initial state
326:                    for (int i = 0; i < LAYERS_COUNT; i++) {
327:                        state[i] = getStateImpl(mfo, i);
328:                    }
329:
330:                    // attach FileInfo to interesting FileObject on each layer
331:                    for (int i = 0; i < LAYERS_COUNT; i++) {
332:                        attachNotifier(mfo, i);
333:                    }
334:                }
335:
336:                public void invalidate() {
337:                    detachAllNotifiers();
338:                    synchronized (LOCK) {
339:                        for (int i = 0; i < LAYERS_COUNT; i++)
340:                            state[i] = FSTATE_UNDEFINED;
341:                    }
342:                }
343:
344:                public int getState(int layer) {
345:                    synchronized (LOCK) {
346:                        return state[layer];
347:                    }
348:                }
349:
350:                private void rescan(FileObject mfo) {
351:                    boolean changed = false;
352:
353:                    synchronized (LOCK) {
354:                        for (int i = 0; i < LAYERS_COUNT; i++) {
355:                            int ns = getStateImpl(mfo, i);
356:                            if (state[i] != ns) {
357:                                state[i] = ns;
358:                                changed = true;
359:                            }
360:                        }
361:                    }
362:
363:                    if (changed)
364:                        fireFileStatusChanged(mfo);
365:                }
366:
367:                private int getStateImpl(FileObject mfo, int layer) {
368:                    boolean above = false;
369:                    boolean below = false;
370:
371:                    // scan higher layers
372:                    for (int i = 0; i < layer; i++) {
373:                        if (isOnLayer(mfo, i)) {
374:                            above = true;
375:                            break;
376:                        }
377:                    }
378:
379:                    // scan lower layers
380:                    for (int i = layer + 1; i < LAYERS_COUNT; i++) {
381:                        if (isOnLayer(mfo, i)) {
382:                            below = true;
383:                            break;
384:                        }
385:                    }
386:
387:                    if (isOnLayer(mfo, layer)) {
388:                        return above ? FSTATE_IGNORED : FSTATE_DEFINED;
389:                    } else {
390:                        return below && !above ? FSTATE_INHERITED
391:                                : FSTATE_UNDEFINED;
392:                    }
393:                }
394:
395:                private boolean isOnLayer(FileObject mfo, int layer) {
396:                    FileSystem fsLayer = getLayer(layer);
397:                    return fsLayer == null ? false : null != fsLayer
398:                            .findResource(mfo.getPath());
399:                }
400:
401:                /**
402:                 * @param mfo FileObject from default file system
403:                 * @param layer the layer where notifier will be searched on
404:                 * @return true if attached notifier is the delegate FO
405:                 */
406:                private synchronized boolean attachNotifier(FileObject mfo,
407:                        int layer) {
408:                    FileSystem fsLayer = getLayer(layer);
409:                    String fn = mfo.getPath();
410:                    FileObject fo = null;
411:                    boolean isDelegate = true;
412:
413:                    if (fsLayer == null)
414:                        return false;
415:
416:                    // find new notifier - the FileObject with closest match to getFile ()
417:                    while (fn.length() > 0
418:                            && null == (fo = fsLayer.findResource(fn))) {
419:                        int pos = fn.lastIndexOf('/');
420:                        isDelegate = false;
421:
422:                        if (-1 == pos)
423:                            break;
424:
425:                        fn = fn.substring(0, pos);
426:                    }
427:
428:                    if (fo == null)
429:                        fo = fsLayer.getRoot();
430:
431:                    if (fo != notifiers[layer]) {
432:                        // remove listener from existing notifier if any
433:                        if (notifiers[layer] != null)
434:                            notifiers[layer]
435:                                    .removeFileChangeListener(weakL[layer]);
436:
437:                        // create new listener and attach it to new notifier
438:                        weakL[layer] = FileUtil
439:                                .weakFileChangeListener(this , fo);
440:                        fo.addFileChangeListener(weakL[layer]);
441:                        notifiers[layer] = fo;
442:                    }
443:
444:                    return isDelegate;
445:                }
446:
447:                private synchronized void detachAllNotifiers() {
448:                    for (int i = 0; i < LAYERS_COUNT; i++) {
449:                        if (notifiers[i] != null) {
450:                            notifiers[i].removeFileChangeListener(weakL[i]);
451:                            notifiers[i] = null;
452:                            weakL[i] = null;
453:                        }
454:                    }
455:                }
456:
457:                private int layerOfFile(FileObject fo) {
458:                    try {
459:                        FileSystem fs = fo.getFileSystem();
460:                        for (int i = 0; i < LAYERS_COUNT; i++) {
461:                            if (fs.equals(getLayer(i)))
462:                                return i;
463:                        }
464:                    } catch (FileStateInvalidException e) {
465:                        throw (IllegalStateException) new IllegalStateException(
466:                                "Invalid file - " + fo).initCause(e); // NOI18N
467:                    }
468:                    return -1;
469:                    //            throw new IllegalStateException ("File isn't from any layer in DefaultFileSystem - " + fo); // NOI18N
470:                }
471:
472:                // ---------------------- FileChangeListener events -----------------------------
473:
474:                public void fileRenamed(FileRenameEvent fe) {
475:                    // rename can be caused either by renaming fo or by deleting mfo,
476:                    // thus the safe way is to discard this FileInfo from the map and
477:                    // notify listeners about the change 
478:                    FileObject mfo = file.get();
479:                    if (mfo != null && mfo.isValid()) {
480:                        discard(mfo);
481:                        fireFileStatusChanged(mfo);
482:                    } else
483:                        detachAllNotifiers();
484:                }
485:
486:                public void fileDataCreated(FileEvent fe) {
487:                    FileObject mfo = file.get();
488:                    if (mfo != null && mfo.isValid()) {
489:                        String created = fe.getFile().getPath();
490:                        String mfoname = mfo.getPath();
491:
492:                        if (created.equals(mfoname)) {
493:                            int layer;
494:                            if (-1 != (layer = layerOfFile(fe.getFile())))
495:                                attachNotifier(mfo, layer);
496:
497:                            rescan(mfo);
498:                        }
499:                    } else
500:                        detachAllNotifiers();
501:                }
502:
503:                public void fileFolderCreated(FileEvent fe) {
504:                    FileObject mfo = file.get();
505:                    if (mfo != null && mfo.isValid()) {
506:                        String created = fe.getFile().getPath();
507:                        String mfoname = mfo.getPath();
508:
509:                        if (mfoname.startsWith(created)) {
510:                            int layer;
511:                            if (-1 != (layer = layerOfFile(fe.getFile())))
512:                                if (attachNotifier(mfo, layer)) {
513:                                    // delegate was created -> rescan
514:                                    rescan(mfo);
515:                                }
516:                        }
517:                    } else
518:                        detachAllNotifiers();
519:                }
520:
521:                public void fileDeleted(FileEvent fe) {
522:                    FileObject mfo = file.get();
523:                    if (mfo != null && mfo.isValid()) {
524:                        String deleted = fe.getFile().getPath();
525:                        String mfoname = mfo.getPath();
526:
527:                        if (deleted.equals(mfoname)) {
528:                            int layer;
529:                            if (-1 != (layer = layerOfFile(fe.getFile())))
530:                                attachNotifier(mfo, layer);
531:
532:                            rescan(mfo);
533:                        }
534:                    } else
535:                        detachAllNotifiers();
536:                }
537:            }
538:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.