Source Code Cross Referenced for ResourceStoreImpl.java in  » Web-Server » Jigsaw » org » w3c » tools » resources » store » 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 » Web Server » Jigsaw » org.w3c.tools.resources.store 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        // ResourceStoreImpl.java
002:        // $Id: ResourceStoreImpl.java,v 1.17 2007/02/09 22:29:17 ylafon Exp $
003:        // (c) COPYRIGHT MIT and INRIA, 1996.
004:        // Please first read the full copyright statement in file COPYRIGHT.html
005:
006:        package org.w3c.tools.resources.store;
007:
008:        import org.w3c.tools.resources.AttributeHolder;
009:        import org.w3c.tools.resources.InvalidResourceException;
010:        import org.w3c.tools.resources.Resource;
011:
012:        import org.w3c.tools.resources.serialization.Serializer;
013:        import org.w3c.tools.resources.serialization.SerializationException;
014:        import org.w3c.util.EmptyEnumeration;
015:
016:        import java.util.Enumeration;
017:        import java.util.Hashtable;
018:        import java.util.Vector;
019:
020:        import java.io.BufferedReader;
021:        import java.io.BufferedWriter;
022:        import java.io.File;
023:        import java.io.FileReader;
024:        import java.io.FileOutputStream;
025:        import java.io.OutputStreamWriter;
026:        import java.io.IOException;
027:        import java.io.PrintStream;
028:        import java.io.Reader;
029:        import java.io.Writer;
030:
031:        /**
032:         * A generic resource store that keeps resource in a file using
033:         * the Serializer interface.
034:         */
035:
036:        public class ResourceStoreImpl implements  ResourceStore {
037:
038:            static final int writerSize = 65536;
039:
040:            class ResourceIndex {
041:
042:                boolean modified = false;
043:                String identifier = null;
044:                Resource resource = null;
045:                boolean initialized = false;
046:
047:                synchronized void markModified() {
048:                    modified = true;
049:                }
050:
051:                synchronized boolean isModified() {
052:                    return modified;
053:                }
054:
055:                synchronized Resource loadResource(Hashtable defs) {
056:                    if (initialized) {
057:                        return resource;
058:                    } else {
059:                        resource.initialize(defs);
060:                        initialized = true;
061:                        return resource;
062:                    }
063:                }
064:
065:                synchronized Resource getResource() {
066:                    return resource;
067:                }
068:
069:                void unloadResource() {
070:                    // notify the resource of unload:
071:                    resource.notifyUnload();
072:                    resource = null;
073:                }
074:
075:                synchronized String getIdentifier() {
076:                    return identifier;
077:                }
078:
079:                synchronized void setIdentifier(String identifier) {
080:                    this .identifier = identifier;
081:                }
082:
083:                ResourceIndex(Resource resource, boolean initialized) {
084:                    this .resource = resource;
085:                    this .identifier = resource.unsafeGetIdentifier();
086:                    this .modified = false;
087:                    this .initialized = initialized;
088:                }
089:
090:            }
091:
092:            /**
093:             * The store format version number.
094:             */
095:            private static final int VERSION = 2;
096:            /**
097:             * Our Resource Serializer.
098:             */
099:            protected Serializer serializer = null;
100:            /**
101:             * Our underlying associated file.
102:             */
103:            File repository = null;
104:            /**
105:             * Our resource store manager.
106:             */
107:            protected ResourceStoreManager manager = null;
108:            /**
109:             * Our token within the resource store manager.
110:             */
111:            Object token = null;
112:            /**
113:             * The resources we know about: maps identifier to resource objects.
114:             */
115:            Hashtable resources = null;
116:            /**
117:             * Has this repository been modified.
118:             */
119:            boolean modified = false;
120:
121:            /**
122:             * Mark the store as having been used recently.
123:             */
124:
125:            protected final void markUsed() {
126:                if (manager != null)
127:                    manager.markUsed(token);
128:            }
129:
130:            // be smart here
131:            // FIXME removed the synchronized to avoid a deadlock
132:            protected void markModified() {
133:                if (!modified) {
134:                    synchronized (this ) {
135:                        modified = true;
136:                    }
137:                }
138:            }
139:
140:            /**
141:             * Get the version of that resource store.
142:             * Version numbers are used to distinguish between pickling format. 
143:             * A resource store implementator has the duty of bumping the returned
144:             * number whenever it's archiving format changes.
145:             * Resource stores that relies on some external archiving mechanisms
146:             * (such as a database), may return a constant.
147:             * @return An integer version number.
148:             */
149:
150:            public int getVersion() {
151:                return VERSION;
152:            }
153:
154:            /**
155:             * Get the identifier for that store.
156:             * @return A uniq store identifier, as a String.
157:             */
158:
159:            public String getIdentifier() {
160:                return repository.getAbsolutePath();
161:            }
162:
163:            /**
164:             * Emit the given string as a warning, to whoever it is appropriate.
165:             * @param msg The warning message.
166:             */
167:
168:            protected void warning(String msg) {
169:                System.out.println("[" + getClass().getName() + "@"
170:                        + repository + "]: " + msg);
171:            }
172:
173:            /**
174:             * Restore the resource whose name is given.
175:             * This method doesn't assume that the resource will actually be restored,
176:             * it can be kept in a cache by the ResourceStore object, and the cached 
177:             * version of the resource may be returned.
178:             * @param identifier The identifier of the resource to restore.
179:             * @param defs Default attribute values. If the resource needs to be
180:             *     restored from its pickled version, this Hashtable provides
181:             *     a set of default values for some of the attributes.
182:             * @return A Resource instance, or <strong>null</strong>.
183:             * @exception InvalidResourceException If the resource could not
184:             * be restored from the store.
185:             */
186:
187:            public Resource loadResource(String identifier, Hashtable defs)
188:                    throws InvalidResourceException {
189:                loadResources();
190:                markUsed();
191:                ResourceIndex index = (ResourceIndex) resources.get(identifier);
192:                if (index == null)
193:                    return null;
194:                if (defs == null)
195:                    defs = new Hashtable(3);
196:                defs.put("store-entry", index);
197:                return index.loadResource(defs);
198:            }
199:
200:            /**
201:             * Get this resource, but only if already loaded.
202:             * The resource store may (recommended) maintain a cache of the resource
203:             * it loads from its store. If the resource having this identifier 
204:             * has already been loaded, return it, otherwise, return
205:             * <strong>null</strong>.
206:             * @param identifier The resource identifier.
207:             * @return A Resource instance, or <strong>null</strong>.
208:             */
209:
210:            public Resource lookupResource(String identifier) {
211:                loadResources();
212:                markUsed();
213:                ResourceIndex index = (ResourceIndex) resources.get(identifier);
214:                return (((index == null) || (!index.initialized)) ? null
215:                        : index.getResource());
216:            }
217:
218:            /**
219:             * Stabilize the given resource.
220:             * @param resource The resource to save.
221:             */
222:
223:            public void saveResource(Resource resource) {
224:                loadResources();
225:                ResourceIndex index = (ResourceIndex) resource.getStoreEntry();
226:                if (index == null)
227:                    throw new UnknownResourceException(resource);
228:                if (index.isModified())
229:                    save();
230:                markUsed();
231:            }
232:
233:            /**
234:             * Add this resource to this resource store.
235:             * @param resource The resource to be added.
236:             */
237:
238:            public synchronized void addResource(Resource resource) {
239:                loadResources();
240:                ResourceIndex index = new ResourceIndex(resource, true);
241:                index.markModified();
242:                resource.setValue("store-entry", index);
243:                resources.put(index.getIdentifier(), index);
244:                markModified();
245:                markUsed();
246:            }
247:
248:            /**
249:             * Remove this resource from the repository.
250:             * @param identifier The identifier of the resource to be removed.
251:             */
252:
253:            public synchronized void removeResource(String identifier) {
254:                ResourceIndex index = (ResourceIndex) resources.get(identifier);
255:                if (index != null) {
256:                    index.unloadResource();
257:                    resources.remove(identifier);
258:                    markModified();
259:                    markUsed();
260:                }
261:            }
262:
263:            /**
264:             * Rename a given resource.
265:             * @param oldid The olde resource identifier.
266:             * @param newid The new resource identifier.
267:             */
268:
269:            public synchronized void renameResource(String oldid, String newid) {
270:                ResourceIndex index = (ResourceIndex) resources.get(oldid);
271:                if (index != null) {
272:                    resources.remove(oldid);
273:                    index.setIdentifier(newid);
274:                    resources.put(newid, index);
275:                    index.markModified();
276:                    markModified();
277:                }
278:            }
279:
280:            /**
281:             * Mark this resource as modified.
282:             * @param resource The resource that has changed (and will have to be
283:             * pickled some time latter).
284:             */
285:
286:            public void markModified(Resource resource) {
287:                ResourceIndex index = (ResourceIndex) resource.getStoreEntry();
288:                if (index != null) {
289:                    index.markModified();
290:                    markModified();
291:                    markUsed();
292:                }
293:            }
294:
295:            /**
296:             * Can this resource store be unloaded now ?
297:             * This method gets called by the ResourceStoreManager before calling
298:             * the <code>shutdown</code> method, when possible. An implementation
299:             * of that method is responsible for checking the <code>acceptUnload
300:             * </code> method of all its loaded resource before returning 
301:             * <strong>true</strong>, meaning that the resource store can be unloaded.
302:             * @return A boolean <strong>true</strong> if the resource store can be
303:             * unloaded.
304:             */
305:
306:            public synchronized boolean acceptUnload() {
307:                if (resources == null) {
308:                    return true;
309:                }
310:                boolean accept = true;
311:                if ((manager != null) && (manager.getStoreSizeLimit() > 0)
312:                        && resources.size() > manager.getStoreSizeLimit()) {
313:                    accept = false;
314:                } else {
315:                    Enumeration e = resources.elements();
316:                    while (e.hasMoreElements()) {
317:                        ResourceIndex entry = (ResourceIndex) e.nextElement();
318:                        Resource resource = entry.getResource();
319:                        synchronized (entry) {
320:                            if (!resource.acceptUnload())
321:                                accept = false;
322:                        }
323:                    }
324:                }
325:                if (!accept) {
326:                    try {
327:                        if (modified)
328:                            internalSave(false);
329:                    } catch (IOException ex) {
330:                        ex.printStackTrace();
331:                        warning("internalSave failed at acceptUnload");
332:                    }
333:                }
334:                return accept;
335:            }
336:
337:            /**
338:             * Internal save: save the repository back to disk.
339:             * @param unload Should we unload any existing resources ?
340:             */
341:
342:            protected synchronized void internalSave(boolean unload)
343:                    throws IOException {
344:                //nothing to save
345:                if (resources == null) {
346:                    return;
347:                }
348:                //1st, build the resource array
349:                Enumeration e = resources.elements();
350:                Vector vres = new Vector(11);
351:                while (e.hasMoreElements()) {
352:                    Resource res = ((ResourceIndex) e.nextElement())
353:                            .getResource();
354:                    vres.addElement(res);
355:                }
356:                Resource resourcearray[] = new Resource[vres.size()];
357:                vres.copyInto(resourcearray);
358:
359:                //try to save in a temporary file
360:                File tmp = new File(repository.getParent(), repository
361:                        .getName()
362:                        + ".tmp");
363:                FileOutputStream fos = new FileOutputStream(tmp);
364:                OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");
365:                Writer writer = new BufferedWriter(osw, writerSize);
366:
367:                serializer.writeResources(resourcearray, writer);
368:
369:                //success!!
370:                String name = repository.getName();
371:                String dir = repository.getParent();
372:                File bak = new File(dir, name + ".bak");
373:                File tild = new File(dir, name + ".bak~");
374:                // 1st move: delete the ~ file if any:
375:                if (tild.exists())
376:                    tild.delete();
377:                // 2nd move rename bak to ~ (bak no longer exists)
378:                if (bak.exists()) {
379:                    bak.renameTo(tild);
380:                    bak.delete();
381:                }
382:                // 3nd move: rename the current repository to bak
383:                if (repository.exists()) {
384:                    if (!repository.renameTo(bak)) {
385:                        warning("unable to rename " + repository + " to " + bak);
386:                        tild.renameTo(bak);
387:                    }
388:                    repository.delete();
389:                }
390:                // 4th move: rename the tmp file to the repository
391:                if (!tmp.renameTo(repository)) {
392:                    bak.renameTo(repository);
393:                    tild.renameTo(bak);
394:                    warning("unable to rename " + tmp + " to " + repository);
395:                }
396:                // cleanup (erase the ~ file)
397:                tild.delete();
398:                modified = false;
399:                //unload if needed
400:                if (unload) {
401:                    for (int i = 0; i < resourcearray.length; i++)
402:                        resourcearray[i].notifyUnload();
403:                    resources = null;
404:                }
405:            }
406:
407:            /**
408:             * Shutdown this store.
409:             */
410:
411:            public synchronized void shutdown() {
412:                if (modified) {
413:                    try {
414:                        internalSave(true);
415:                    } catch (IOException ex) {
416:                        ex.printStackTrace();
417:                        warning("internalSave failed at shutdown.");
418:                    }
419:                } else {
420:                    // Just notify the unload of loaded resources:
421:                    if (resources != null) {
422:                        Enumeration entries = resources.elements();
423:                        while (entries.hasMoreElements()) {
424:                            ResourceIndex index = (ResourceIndex) entries
425:                                    .nextElement();
426:                            index.unloadResource();
427:                        }
428:                    }
429:                }
430:                // Clean-up all references we have to external objects:
431:                resources = null;
432:                manager = null;
433:            }
434:
435:            /**
436:             * Save this store.
437:             */
438:
439:            public void save() {
440:                if (modified) {
441:                    try {
442:                        internalSave(false);
443:                    } catch (IOException ex) {
444:                        warning("Save failed (IO) [" + ex.getMessage() + "]");
445:                    } catch (Exception oex) {
446:                        warning("Save failed [" + oex.getMessage() + "]");
447:                    }
448:                }
449:            }
450:
451:            /**
452:             * Enumerate all the resources saved in this store.
453:             * @return An enumeration of Strings, giving the identifier for all 
454:             *     the resources that this store knows about.
455:             */
456:
457:            public Enumeration enumerateResourceIdentifiers() {
458:                markUsed();
459:                loadResources();
460:                return resources.keys();
461:            }
462:
463:            /**
464:             * Check for the existence of a resource in this store.
465:             * @param identifier The identifier of the resource to check.
466:             * @return A boolean <strong>true</strong> if the resource exists
467:             *    in this store, <strong>false</strong> otherwise.
468:             */
469:
470:            public boolean hasResource(String identifier) {
471:                markUsed();
472:                loadResources();
473:                return resources.get(identifier) != null;
474:            }
475:
476:            protected synchronized void loadResources() {
477:                int i = 0;
478:                if (resources == null) {
479:                    try {
480:                        resources = new Hashtable(11);
481:                        if (repository.exists()) {
482:                            Reader reader = new BufferedReader(new FileReader(
483:                                    repository));
484:                            Resource resourceArray[] = serializer
485:                                    .readResources(reader);
486:                            for (i = 0; i < resourceArray.length; i++) {
487:                                ResourceIndex entry = new ResourceIndex(
488:                                        resourceArray[i], false);
489:                                if (entry != null
490:                                        && entry.getIdentifier() != null) {
491:                                    resources.put(entry.getIdentifier(), entry);
492:                                }
493:                            }
494:                        }
495:                    } catch (IOException ioex) {
496:                        ioex.printStackTrace();
497:                        warning("Unable to load resources");
498:                    } catch (SerializationException sex) {
499:                        warning(sex.getMessage());
500:                        sex.printStackTrace();
501:                    } catch (Exception ex) {
502:                        ex.printStackTrace();
503:                        String err = "Error in " + repository.getName()
504:                                + " in dir " + repository.getParent() + ": ["
505:                                + i + "] " + ex.getMessage();
506:                        warning(err);
507:                    }
508:                }
509:            }
510:
511:            /**
512:             * This resource store is being built, initialize it with the given arg.
513:             * @param manager The ResourceStoreManager instance that asks yourself
514:             * to initialize.
515:             * @param token The resource store manager key to that resource store, 
516:             * this token should be used when calling methods from the manager that
517:             * are to act on yourself.
518:             * @param repository A file, giving the location of the associated 
519:             *    repository.
520:             */
521:            public void initialize(ResourceStoreManager manager, Object token,
522:                    File repository, Serializer serializer) {
523:                this.manager = manager;
524:                this.token = token;
525:                this.repository = repository;
526:                this.serializer = serializer;
527:                this.resources = null;
528:                markUsed();
529:            }
530:
531:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.