Source Code Cross Referenced for ServletPreferences.java in  » Swing-Library » wings3 » org » wings » prefs » 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 » Swing Library » wings3 » org.wings.prefs 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * @(#)FileSystemPreferences.java	1.21 05/11/17
003:         *
004:         * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
005:         * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
006:         */
007:
008:        package org.wings.prefs;
009:
010:        import org.w3c.dom.Element;
011:        import org.w3c.dom.NodeList;
012:
013:        import javax.servlet.http.*;
014:        import javax.xml.parsers.DocumentBuilder;
015:        import javax.xml.parsers.DocumentBuilderFactory;
016:        import javax.xml.transform.Transformer;
017:        import javax.xml.transform.TransformerFactory;
018:        import javax.xml.transform.dom.DOMSource;
019:        import javax.xml.transform.stream.StreamResult;
020:        import java.io.*;
021:        import java.util.*;
022:        import java.util.logging.Logger;
023:        import java.util.prefs.*;
024:
025:        /**
026:         * ClientPreferences implementation for Servlets.  ClientPreferences are stored in the file
027:         * system, with one directory per preferences node.  All of the preferences
028:         * at each node are stored in a single file.  Atomic file system operations
029:         * (e.g. File.renameTo) are used to ensure integrity.  An in-memory cache of
030:         * the "explored" portion of the tree is maintained for performance, and
031:         * written back to the disk periodically.  File-locking is used to ensure
032:         * reasonable behavior when multiple VMs are running at the same time.
033:         * (The file lock is obtained only for sync(), flush() and removeNode().)
034:         *
035:         * @author Christian
036:         * @version 1.21, 11/17/05
037:         * @see Preferences
038:         * @since 1.4
039:         */
040:        public class ServletPreferences extends
041:                java.util.prefs.AbstractPreferences {
042:
043:            /**
044:             * Name for the cookies containing the users' state
045:             */
046:            private static String COOKIE_NAME = "PreferencesCookie";
047:
048:            /**
049:             * Key for the next unused User ID in the System ClientPreferences
050:             */
051:            private static String NEXT_FREE_USER_ID = "nextFreeUserID";
052:            static final ThreadLocal<HttpServletRequest> requests = new ThreadLocal<HttpServletRequest>();
053:            static final ThreadLocal<HttpServletResponse> responses = new ThreadLocal<HttpServletResponse>();
054:
055:            /**
056:             * Returns logger for error messages. Backing store exceptions are logged at
057:             * WARNING level.
058:             */
059:            private static Logger getLogger() {
060:                return Logger.getLogger("java.util.prefs");
061:            }
062:
063:            /**
064:             * Directory for system preferences.
065:             */
066:            private static File systemRootDir;
067:
068:            /*
069:             * Flag, indicating whether systemRoot  directory is writable
070:             */
071:            private static boolean isSystemRootWritable;
072:
073:            /**
074:             * the user roots
075:             */
076:            private static Map<String, ServletPreferences> userRoots = new HashMap<String, ServletPreferences>();
077:
078:            static synchronized Preferences getUserRoot() {
079:                String userName = resolveUserName();
080:
081:                if (userRoots.containsKey(userName))
082:                    return userRoots.get(userName);
083:
084:                ServletPreferences userRoot = new ServletPreferences(true);
085:                userRoots.put(userName, userRoot);
086:                return userRoot;
087:
088:            }
089:
090:            private static synchronized String resolveUserName() {
091:                String userName = "user/";
092:
093:                HttpServletRequest request = requests.get();
094:                //if authorized user, use this name
095:                if (request.getUserPrincipal() != null
096:                        && request.getUserPrincipal().getName() != null) {
097:                    userName = request.getUserPrincipal().getName();
098:
099:                } else {
100:                    boolean isAlreadyKnown = false;
101:                    userName = (String) request.getSession().getAttribute(
102:                            COOKIE_NAME);
103:                    if (userName != null)
104:                        isAlreadyKnown = true;
105:                    else {
106:                        Cookie[] cookies = request.getCookies();
107:                        if (cookies != null) {
108:                            for (int i = 0; i < cookies.length; i++) {
109:                                if (cookies[i].getName().equals(COOKIE_NAME)) {
110:                                    //pref = ClientPreferences.userRoot().node(cookies[i].getValue());
111:                                    userName = cookies[i].getValue();
112:                                    request.getSession().setAttribute(
113:                                            COOKIE_NAME, userName);
114:                                    isAlreadyKnown = true;
115:                                    break;
116:                                }
117:                            }
118:                        }
119:                    }
120:
121:                    if (!isAlreadyKnown) {
122:                        //pref = ClientPreferences.userRoot().node(userID.toString());
123:                        int userID = getSystemRoot().getInt(NEXT_FREE_USER_ID,
124:                                0);
125:                        userName = ((Integer) userID).toString();
126:
127:                        //Set the cookie
128:                        Cookie cookie = new Cookie(COOKIE_NAME, userName);
129:                        cookie.setMaxAge(1000000000);
130:                        responses.get().addCookie(cookie);
131:                        request.getSession()
132:                                .setAttribute(COOKIE_NAME, userName);
133:
134:                        userID++;
135:                        getSystemRoot().putInt(NEXT_FREE_USER_ID, userID);
136:
137:                        try {
138:                            getSystemRoot().flush();
139:
140:                        } catch (Exception ex) {
141:                            ex.printStackTrace();
142:                        }
143:
144:                    }
145:
146:                }
147:
148:                return userName;
149:
150:            }
151:
152:            private static File setupUserRoot(String userName) {
153:
154:                File userRootDir = new File("./Prefs/" + userName);
155:                //                      new File(System.getProperty("java.util.prefs.userRoot",
156:                //                      System.getProperty("user.home")), ".java/.userPrefs");
157:                // Attempt to create root dir if it does not yet exist.
158:                if (!userRootDir.exists()) {
159:                    if (userRootDir.mkdirs()) {
160:
161:                        getLogger().info("Created user preferences directory.");
162:                    } else
163:                        getLogger()
164:                                .warning(
165:                                        "Couldn't create user preferences"
166:                                                + " directory. User preferences are unusable.");
167:                }
168:
169:                String USER_NAME = System.getProperty("user.name");
170:                userLockFile = new File(userRootDir, ".user.lock." + USER_NAME);
171:                userRootModFile = new File(userRootDir, ".userRootModFile."
172:                        + USER_NAME);
173:                if (!userRootModFile.exists())
174:                    try {
175:                        // create if does not exist.
176:                        userRootModFile.createNewFile();
177:                    } catch (IOException e) {
178:                        getLogger().warning(e.toString());
179:                    }
180:                userRootModTime = userRootModFile.lastModified();
181:                return userRootDir;
182:            }
183:
184:            /**
185:             * The system root.
186:             */
187:            static Preferences systemRoot;
188:
189:            static synchronized Preferences getSystemRoot() {
190:                if (systemRoot == null) {
191:                    setupSystemRoot();
192:                    systemRoot = new ServletPreferences(false);
193:                }
194:                return systemRoot;
195:            }
196:
197:            private static void setupSystemRoot() {
198:                String systemPrefsDirName = "./Prefs/system/";
199:
200:                //(String)System.getProperty("java.util.prefs.systemRoot","/etc/.java");
201:
202:                systemRootDir = new File(systemPrefsDirName);//, ".systemPrefs");
203:                // Attempt to create root dir if it does not yet exist.
204:                //if (!systemRootDir.exists()) {
205:                // system root does not exist in /etc/.java
206:                // Switching  to java.home
207:                //systemRootDir = new File(System.getProperty("java.home"),".systemPrefs");
208:                if (!systemRootDir.exists()) {
209:                    if (systemRootDir.mkdirs()) {
210:                        getLogger().info(
211:                                "Created system preferences directory " + "in "
212:                                        + systemPrefsDirName);
213:
214:                    } else {
215:                        getLogger()
216:                                .warning(
217:                                        "Could not create "
218:                                                + "system preferences directory. System "
219:                                                + "preferences are unusable.");
220:                    }
221:
222:                }
223:                isSystemRootWritable = systemRootDir.canWrite();
224:                systemLockFile = new File(systemRootDir, ".system.lock");
225:                systemRootModFile = new File(systemRootDir,
226:                        ".systemRootModFile");
227:                if (!systemRootModFile.exists() && isSystemRootWritable)
228:                    try {
229:                        // create if does not exist.
230:                        systemRootModFile.createNewFile();
231:
232:                    } catch (IOException e) {
233:                        getLogger().warning(e.toString());
234:                    }
235:                systemRootModTime = systemRootModFile.lastModified();
236:
237:            }
238:
239:            /**
240:             * The lock file for the user tree.
241:             */
242:            static File userLockFile;
243:
244:            /**
245:             * The lock file for the system tree.
246:             */
247:            static File systemLockFile;
248:
249:            /**
250:             * The directory representing this preference node.  There is no guarantee
251:             * that this directory exits, as another VM can delete it at any time
252:             * that it (the other VM) holds the file-lock.  While the root node cannot
253:             * be deleted, it may not yet have been created, or the underlying
254:             * directory could have been deleted accidentally.
255:             */
256:            private final File dir;
257:
258:            /**
259:             * The file representing this preference node's preferences.
260:             * The file format is undocumented, and subject to change
261:             * from release to release, but I'm sure that you can figure
262:             * it out if you try real hard.
263:             */
264:            private final File prefsFile;
265:
266:            /**
267:             * A temporary file used for saving changes to preferences.  As part of
268:             * the sync operation, changes are first saved into this file, and then
269:             * atomically renamed to prefsFile.  This results in an atomic state
270:             * change from one valid set of preferences to another.  The
271:             * the file-lock is held for the duration of this transformation.
272:             */
273:            private final File tmpFile;
274:
275:            /**
276:             * File, which keeps track of global modifications of userRoot.
277:             */
278:            private static File userRootModFile;
279:
280:            /**
281:             * Flag, which indicated whether userRoot was modified by another VM
282:             */
283:            private static boolean isUserRootModified = false;
284:
285:            /**
286:             * Keeps track of userRoot modification time. This time is reset to
287:             * zero after UNIX reboot, and is increased by 1 second each time
288:             * userRoot is modified.
289:             */
290:            private static long userRootModTime;
291:
292:            /*
293:             * File, which keeps track of global modifications of systemRoot
294:             */
295:            private static File systemRootModFile;
296:            /*
297:             * Flag, which indicates whether systemRoot was modified by another VM
298:             */
299:            private static boolean isSystemRootModified = false;
300:
301:            /**
302:             * Keeps track of systemRoot modification time. This time is reset to
303:             * zero after system reboot, and is increased by 1 second each time
304:             * systemRoot is modified.
305:             */
306:            private static long systemRootModTime;
307:
308:            /**
309:             * Locally cached preferences for this node (includes uncommitted
310:             * changes).  This map is initialized with from disk when the first get or
311:             * put operation occurs on this node.  It is synchronized with the
312:             * corresponding disk file (prefsFile) by the sync operation.  The initial
313:             * value is read *without* acquiring the file-lock.
314:             */
315:            private Map<String, String> prefsCache = null;
316:
317:            /**
318:             * The last modification time of the file backing this node at the time
319:             * that prefCache was last synchronized (or initially read).  This
320:             * value is set *before* reading the file, so it's conservative; the
321:             * actual timestamp could be (slightly) higher.  A value of zero indicates
322:             * that we were unable to initialize prefsCache from the disk, or
323:             * have not yet attempted to do so.  (If prefsCache is non-null, it
324:             * indicates the former; if it's null, the latter.)
325:             */
326:            private long lastSyncTime = 0;
327:
328:            /**
329:             * A list of all uncommitted preference changes.  The elements in this
330:             * list are of type PrefChange.  If this node is concurrently modified on
331:             * disk by another VM, the two sets of changes are merged when this node
332:             * is sync'ed by overwriting our prefsCache with the preference map last
333:             * written out to disk (by the other VM), and then replaying this change
334:             * log against that map.  The resulting map is then written back
335:             * to the disk.
336:             */
337:            final List<Change> changeLog = new ArrayList<Change>();
338:
339:            public static void set(HttpServletRequest servletRequest,
340:                    HttpServletResponse servletResponse) {
341:                requests.set(servletRequest);
342:                responses.set(servletResponse);
343:            }
344:
345:            public static void unset() {
346:                requests.set(null);
347:                responses.set(null);
348:            }
349:
350:            /**
351:             * Represents a change to a preference.
352:             */
353:            private abstract class Change {
354:                /**
355:                 * Reapplies the change to prefsCache.
356:                 */
357:                abstract void replay();
358:            }
359:
360:            ;
361:
362:            /**
363:             * Represents a preference put.
364:             */
365:            private class Put extends Change {
366:                String key, value;
367:
368:                Put(String key, String value) {
369:                    this .key = key;
370:                    this .value = value;
371:                }
372:
373:                void replay() {
374:                    prefsCache.put(key, value);
375:                }
376:            }
377:
378:            /**
379:             * Represents a preference remove.
380:             */
381:            private class Remove extends Change {
382:                String key;
383:
384:                Remove(String key) {
385:                    this .key = key;
386:                }
387:
388:                void replay() {
389:                    prefsCache.remove(key);
390:                }
391:            }
392:
393:            /**
394:             * Represents the creation of this node.
395:             */
396:            private class NodeCreate extends Change {
397:                /**
398:                 * Performs no action, but the presence of this object in changeLog
399:                 * will force the node and its ancestors to be made permanent at the
400:                 * next sync.
401:                 */
402:                void replay() {
403:                }
404:            }
405:
406:            /**
407:             * NodeCreate object for this node.
408:             */
409:            NodeCreate nodeCreate = null;
410:
411:            /**
412:             * Replay changeLog against prefsCache.
413:             */
414:            private void replayChanges() {
415:                for (int i = 0, n = changeLog.size(); i < n; i++)
416:                    ((Change) changeLog.get(i)).replay();
417:            }
418:
419:            private final boolean isUserNode;
420:
421:            /**
422:             * Special constructor for roots (both user and system).  This constructor
423:             * will only be called twice, by the static initializer.
424:             */
425:            private ServletPreferences(boolean user) {
426:                super (null, "");
427:                isUserNode = user;
428:
429:                dir = (user ? setupUserRoot(resolveUserName()) : systemRootDir);
430:
431:                prefsFile = new File(dir, "prefs.xml");
432:
433:                tmpFile = new File(dir, "prefs.tmp");
434:
435:                if (newNode) {
436:                    // These 2 things guarantee node will get wrtten at next flush/sync
437:                    prefsCache = new TreeMap<String, String>();
438:                    nodeCreate = new NodeCreate();
439:                    changeLog.add(nodeCreate);
440:                }
441:            }
442:
443:            /**
444:             * Construct a new FileSystemPreferences instance with the specified
445:             * parent node and name.  This constructor, called from childSpi,
446:             * is used to make every node except for the two //roots.
447:             */
448:            private ServletPreferences(ServletPreferences parent, String name) {
449:                super (parent, name);
450:                isUserNode = parent.isUserNode;
451:                dir = new File(parent.dir, name);
452:                prefsFile = new File(dir, "prefs.xml");
453:                tmpFile = new File(dir, "prefs.tmp");
454:                newNode = !dir.exists();
455:                //this.initCacheIfNecessary();
456:
457:                if (newNode) {
458:                    // These 2 things guarantee node will get wrtten at next flush/sync
459:                    prefsCache = new TreeMap<String, String>();
460:                    nodeCreate = new NodeCreate();
461:                    changeLog.add(nodeCreate);
462:                }
463:
464:            }
465:
466:            public boolean isUserNode() {
467:                return isUserNode;
468:            }
469:
470:            protected void putSpi(String key, String value) {
471:                initCacheIfNecessary();
472:                changeLog.add(new Put(key, value));
473:                prefsCache.put(key, value);
474:            }
475:
476:            protected String getSpi(String key) {
477:                initCacheIfNecessary();
478:                return (String) prefsCache.get(key);
479:            }
480:
481:            protected void removeSpi(String key) {
482:                initCacheIfNecessary();
483:                changeLog.add(new Remove(key));
484:                prefsCache.remove(key);
485:            }
486:
487:            /**
488:             * Initialize prefsCache if it has yet to be initialized.  When this method
489:             * returns, prefsCache will be non-null.  If the data was successfully
490:             * read from the file, lastSyncTime will be updated.  If prefsCache was
491:             * null, but it was impossible to read the file (because it didn't
492:             * exist or for any other reason) prefsCache will be initialized to an
493:             * empty, modifiable Map, and lastSyncTime remain zero.
494:             */
495:            private void initCacheIfNecessary() {
496:                if (prefsCache != null)
497:                    return;
498:
499:                prefsCache = new HashMap<String, String>();
500:                try {
501:                    loadCache();
502:                } catch (Exception e) {
503:                    // assert lastSyncTime == 0;
504:                    prefsCache = new TreeMap<String, String>();
505:                }
506:            }
507:
508:            /**
509:             * Attempt to load prefsCache from the backing store.  If the attempt
510:             * succeeds, lastSyncTime will be updated (the new value will typically
511:             * correspond to the data loaded into the map, but it may be less,
512:             * if another VM is updating this node concurrently).  If the attempt
513:             * fails, a BackingStoreException is thrown and both prefsCache and
514:             * lastSyncTime are unaffected by the call.
515:             */
516:            private void loadCache() throws BackingStoreException {
517:
518:                long newLastSyncTime = 0;
519:
520:                try {
521:
522:                    newLastSyncTime = prefsFile.lastModified();
523:
524:                    DocumentBuilder docBuilder = javax.xml.parsers.DocumentBuilderFactory
525:                            .newInstance().newDocumentBuilder();
526:                    org.w3c.dom.Document doc = null;
527:
528:                    doc = docBuilder.parse(prefsFile);
529:
530:                    NodeList entries = doc.getElementsByTagName("entry");
531:
532:                    for (int i = 0; i < entries.getLength(); i++) {
533:                        Element entry = (Element) entries.item(i);
534:
535:                        String key = entry.getAttribute("key");
536:
537:                        String value = entry.getAttribute("value");
538:
539:                        prefsCache.put(key, value);
540:                    }
541:
542:                } catch (Exception e) {
543:                    if (e instanceof  InvalidPreferencesFormatException) {
544:                        getLogger().warning(
545:                                "Invalid preferences format in "
546:                                        + prefsFile.getPath());
547:                        prefsFile.renameTo(new File(prefsFile.getParentFile(),
548:                                "IncorrectFormatPrefs.xml"));
549:
550:                    } else if (e instanceof  FileNotFoundException) {
551:                        getLogger().warning(
552:                                "Prefs file removed in background "
553:                                        + prefsFile.getPath());
554:                    } else {
555:                        throw new BackingStoreException(e);
556:                    }
557:                }
558:                // Attempt succeeded; update state
559:
560:                lastSyncTime = newLastSyncTime;
561:
562:            }
563:
564:            /**
565:             * Attempt to write back prefsCache to the backing store.  If the attempt
566:             * succeeds, lastSyncTime will be updated (the new value will correspond
567:             * exactly to the data thust written back, as we hold the file lock, which
568:             * prevents a concurrent write.  If the attempt fails, a
569:             * BackingStoreException is thrown and both the backing store (prefsFile)
570:             * and lastSyncTime will be unaffected by this call.  This call will
571:             * NEVER leave prefsFile in a corrupt state.
572:             */
573:            private void writeBackCache() throws BackingStoreException {
574:                OutputStream os;
575:                FileOutputStream fos;
576:
577:                try {
578:                    if (!dir.exists() && !dir.mkdirs())
579:                        throw new BackingStoreException(dir + " create failed.");
580:                    fos = new FileOutputStream(prefsFile);
581:                    os = new BufferedOutputStream(fos);
582:                    //exportSubtree(os);
583:
584:                    DocumentBuilderFactory f = DocumentBuilderFactory
585:                            .newInstance();
586:                    DocumentBuilder build = f.newDocumentBuilder();
587:
588:                    org.w3c.dom.Document doc = build.newDocument();
589:                    Element root = doc.createElement("PREFS");
590:                    doc.appendChild(root);
591:
592:                    for (String key : prefsCache.keySet()) {
593:                        Element e = doc.createElement("entry");
594:                        e.setAttribute("key", key);
595:                        e.setAttribute("value", prefsCache.get(key));
596:                        root.appendChild(e);
597:
598:                    }
599:
600:                    Transformer trans = TransformerFactory.newInstance()
601:                            .newTransformer();
602:                    DOMSource source = new DOMSource(doc);
603:                    StreamResult result = new StreamResult(os);
604:                    trans.transform(source, result);
605:
606:                    os.close();
607:                    fos.close();
608:
609:                } catch (Exception e) {
610:                    if (e instanceof  BackingStoreException)
611:                        throw (BackingStoreException) e;
612:                    throw new BackingStoreException(e);
613:                }
614:
615:            }
616:
617:            protected String[] keysSpi() {
618:                initCacheIfNecessary();
619:                return (String[]) prefsCache.keySet().toArray(
620:                        new String[prefsCache.size()]);
621:            }
622:
623:            protected String[] childrenNamesSpi() {
624:
625:                List<String> result = new ArrayList<String>();
626:                File[] dirContents = dir.listFiles();
627:                if (dirContents != null) {
628:                    for (int i = 0; i < dirContents.length; i++)
629:                        if (dirContents[i].isDirectory())
630:                            result.add(dirContents[i].getName());
631:                }
632:                return result.toArray(EMPTY_STRING_ARRAY);
633:
634:            }
635:
636:            private static final String[] EMPTY_STRING_ARRAY = new String[0];
637:
638:            protected AbstractPreferences childSpi(String name) {
639:                return new ServletPreferences(this , name);
640:            }
641:
642:            public void removeNode() throws BackingStoreException {
643:                synchronized (isUserNode() ? userLockFile : systemLockFile) {
644:                    // to remove a node we need an exclusive lock
645:                    super .removeNode();
646:                }
647:            }
648:
649:            /**
650:             * Called with file lock held (in addition to node locks).
651:             */
652:            protected void removeNodeSpi() throws BackingStoreException {
653:
654:                if (changeLog.contains(nodeCreate)) {
655:                    changeLog.remove(nodeCreate);
656:                    nodeCreate = null;
657:                    return;// null;
658:                }
659:                if (!dir.exists())
660:                    return;
661:                //                        return null;
662:                prefsFile.delete();
663:                tmpFile.delete();
664:                // dir should be empty now.  If it's not, empty it
665:                File[] junk = dir.listFiles();
666:                if (junk.length != 0) {
667:                    getLogger().warning(
668:                            "Found extraneous files when removing node: "
669:                                    + Arrays.asList(junk));
670:                    for (int i = 0; i < junk.length; i++) {
671:                        junk[i].delete();
672:                    }
673:
674:                }
675:                if (!dir.delete())
676:                    throw new BackingStoreException("Couldn't delete dir: "
677:                            + dir);
678:
679:            }
680:
681:            public synchronized void sync() throws BackingStoreException {
682:
683:                synchronized (isUserNode() ? userLockFile : systemLockFile) {
684:                    final Long newModTime;
685:
686:                    if (isUserNode()) {
687:                        newModTime = userRootModFile.lastModified();
688:                        isUserRootModified = userRootModTime == newModTime;
689:                    } else {
690:                        newModTime = systemRootModFile.lastModified();
691:                        isSystemRootModified = systemRootModTime == newModTime;
692:                    }
693:
694:                    super .sync();
695:
696:                    if (isUserNode()) {
697:                        userRootModTime = newModTime.longValue() + 1000;
698:                        userRootModFile.setLastModified(userRootModTime);
699:                    } else {
700:                        systemRootModTime = newModTime.longValue() + 1000;
701:                        systemRootModFile.setLastModified(systemRootModTime);
702:                    }
703:                }
704:            }
705:
706:            protected void syncSpi() throws BackingStoreException {
707:
708:                syncSpiPrivileged();
709:
710:            }
711:
712:            private void syncSpiPrivileged() throws BackingStoreException {
713:                if (isRemoved())
714:                    throw new IllegalStateException("Node has been removed");
715:                if (prefsCache == null)
716:                    return; // We've never been used, don't bother syncing
717:                long lastModifiedTime;
718:                if ((isUserNode() ? isUserRootModified : isSystemRootModified)) {
719:                    lastModifiedTime = prefsFile.lastModified();
720:                    if (lastModifiedTime != lastSyncTime) {
721:                        // Prefs at this node were externally modified; read in node and
722:                        // playback any local mods since last sync
723:                        loadCache();
724:                        replayChanges();
725:                        lastSyncTime = lastModifiedTime;
726:                    }
727:                } else if (lastSyncTime != 0 && !dir.exists()) {
728:                    // This node was removed in the background.  Playback any changes
729:                    // against a virgin (empty) Map.
730:                    prefsCache = new TreeMap<String, String>();
731:                    replayChanges();
732:                }
733:                if (!changeLog.isEmpty()) {
734:                    writeBackCache(); // Creates directory & file if necessary
735:                    /*
736:                     * Attempt succeeded; it's barely possible that the call to
737:                     * lastModified might fail (i.e., return 0), but this would not
738:                     * be a disaster, as lastSyncTime is allowed to lag.
739:                     */
740:                    lastModifiedTime = prefsFile.lastModified();
741:                    /* If lastSyncTime did not change, or went back
742:                     * increment by 1 second. Since we hold the lock
743:                     * lastSyncTime always monotonically encreases in the
744:                     * atomic sense.
745:                     */
746:                    if (lastSyncTime <= lastModifiedTime) {
747:                        lastSyncTime = lastModifiedTime + 1000;
748:                        prefsFile.setLastModified(lastSyncTime);
749:                    }
750:                    changeLog.clear();
751:                }
752:            }
753:
754:            public void flush() throws BackingStoreException {
755:                if (isRemoved())
756:                    return;
757:                sync();
758:            }
759:
760:            protected void flushSpi() throws BackingStoreException {
761:                // assert false;
762:            }
763:
764:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.