Source Code Cross Referenced for DataPersister.java in  » RSS-RDF » curn » org » clapper » curn » 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 » RSS RDF » curn » org.clapper.curn 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*---------------------------------------------------------------------------*\
002:          $Id: DataPersister.java 6498 2006-10-02 21:13:33Z bmc $
003:        \*---------------------------------------------------------------------------*/
004:
005:        package org.clapper.curn;
006:
007:        import java.net.URL;
008:        import java.util.ArrayList;
009:        import java.util.Collection;
010:        import java.util.HashMap;
011:        import java.util.Map;
012:        import org.clapper.util.logging.Logger;
013:
014:        /**
015:         * Persists data to the <i>curn</i> persistent data store, whatever that may
016:         * be.
017:         *
018:         * @version <tt>$Revision: 6498 $</tt>
019:         */
020:        public abstract class DataPersister {
021:            /*----------------------------------------------------------------------*\
022:                                     Public Interfaces
023:            \*----------------------------------------------------------------------*/
024:
025:            /**
026:             * Used to define a callback for handling loaded data.
027:             */
028:            public interface LoadedDataHandler {
029:                /**
030:                 * Called by the subclass when it has finished loading data for a feed.
031:                 *
032:                 * @param feedData the loaded feed (and item) data
033:                 *
034:                 * @throws CurnException on error
035:                 */
036:                public void feedLoaded(PersistentFeedData feedData)
037:                        throws CurnException;
038:
039:                /**
040:                 * Called by the subclass when it has finished loading the extra
041:                 * metadata for a particular namespace.
042:                 *
043:                 * @param metadataGroup  the metadata for the namespace
044:                 *
045:                 * @throws CurnException on error
046:                 */
047:                public void extraMetadataLoaded(
048:                        PersistentMetadataGroup metadataGroup)
049:                        throws CurnException;
050:            }
051:
052:            /*----------------------------------------------------------------------*\
053:                                    Private Data Items
054:            \*----------------------------------------------------------------------*/
055:
056:            /**
057:             * Map of interested PersistentDataClient objects, indexed by namespace
058:             */
059:            private Map<String, PersistentDataClient> persistentDataClients = new HashMap<String, PersistentDataClient>();
060:
061:            /**
062:             * For logging
063:             */
064:            private static final Logger log = new Logger(DataPersister.class);
065:
066:            /*----------------------------------------------------------------------*\
067:                                           Constructor
068:            \*----------------------------------------------------------------------*/
069:
070:            protected DataPersister() {
071:            }
072:
073:            /*----------------------------------------------------------------------*\
074:                                        Public Methods
075:            \*----------------------------------------------------------------------*/
076:
077:            /**
078:             * Save the feed metadata. The configuration is passed in, so that
079:             * the persister can obtain, from the configuration, whatever
080:             * data it needs to find the persisted metadata to read.
081:             *
082:             * @param feedCache {@link FeedCache} object to save
083:             *
084:             * @throws CurnException on error
085:             */
086:            public final void saveData(FeedCache feedCache)
087:                    throws CurnException {
088:                if (isEnabled()) {
089:                    // First, retrieve all entries from the cache and reorganize them.
090:
091:                    Collection<FeedCacheEntry> cacheEntries = feedCache
092:                            .getAllEntries();
093:                    Map<URL, PersistentFeedData> cacheDataByFeed = getCacheDataByFeed(cacheEntries);
094:
095:                    // Now that everything's in the right order, gather the additional
096:                    // metadata for each feed and its items. We don't need the map
097:                    // any more.
098:
099:                    Collection<PersistentFeedData> persistentDataByFeed = cacheDataByFeed
100:                            .values();
101:                    cacheDataByFeed = null;
102:
103:                    for (PersistentFeedData feedData : persistentDataByFeed)
104:                        getFeedMetadataForFeed(feedData);
105:
106:                    // Now, gather any extra metadata that isn't attached to a feed or
107:                    // item.
108:
109:                    Collection<PersistentMetadataGroup> extraMetadata = new ArrayList<PersistentMetadataGroup>();
110:
111:                    for (PersistentDataClient client : persistentDataClients
112:                            .values()) {
113:                        String namespace = client.getMetatdataNamespace();
114:                        PersistentMetadataGroup metadata;
115:                        Map<String, String> nameValuePairs = client
116:                                .getExtraFeedMetadata();
117:                        if ((nameValuePairs != null)
118:                                && (nameValuePairs.size() > 0)) {
119:                            metadata = new PersistentMetadataGroup(namespace);
120:                            metadata.addMetadata(nameValuePairs);
121:                            extraMetadata.add(metadata);
122:                        }
123:                    }
124:
125:                    // Let the saving begin.
126:
127:                    startSaveOperation();
128:
129:                    for (PersistentFeedData feedData : persistentDataByFeed)
130:                        saveFeedData(feedData);
131:
132:                    saveExtraMetadata(extraMetadata);
133:                    endSaveOperation();
134:                }
135:            }
136:
137:            /**
138:             * Load the cache and metadata.
139:             *
140:             * @param feedCache the {@link FeedCache} object to fill
141:             *
142:             * @throws CurnException on error
143:             */
144:            public void loadData(final FeedCache feedCache)
145:                    throws CurnException {
146:                if (isEnabled()) {
147:                    startLoadOperation();
148:
149:                    doLoad(new LoadedDataHandler() {
150:                        public void feedLoaded(PersistentFeedData feedData)
151:                                throws CurnException {
152:                            processLoadedFeed(feedData, feedCache);
153:                        }
154:
155:                        public void extraMetadataLoaded(
156:                                PersistentMetadataGroup metadataGroup)
157:                                throws CurnException {
158:                            String namespace = metadataGroup.getNamespace();
159:                            PersistentDataClient client = persistentDataClients
160:                                    .get(namespace);
161:                            if (client == null) {
162:                                log
163:                                        .warn("No plug-in or other class has registered "
164:                                                + "interest in extra metadata namespace \""
165:                                                + namespace
166:                                                + "\". "
167:                                                + "Ignoring the metadata.");
168:                            }
169:
170:                            else {
171:                                Map<String, String> nameValuePairs = metadataGroup
172:                                        .getMetadata();
173:                                for (Map.Entry<String, String> entry : nameValuePairs
174:                                        .entrySet()) {
175:                                    client.parseExtraMetadata(entry.getKey(),
176:                                            entry.getValue());
177:                                }
178:                            }
179:                        }
180:                    });
181:
182:                    endLoadOperation();
183:                    feedCache.optimizeAfterLoad();
184:                }
185:            }
186:
187:            /**
188:             * Register a {@link PersistentDataClient} object with this registry.
189:             * When data for that client is read, this object will call the
190:             * client's <tt>process</tt> methods. When it's time to save the metadata,
191:             * this object will call the client's <tt>get</tt> methods. Multiple
192:             * {@link PersistentDataClient} objects may be registered with this object.
193:             *
194:             * @param client the {@link PersistentDataClient} object
195:             */
196:            public final void addPersistentDataClient(
197:                    PersistentDataClient client) {
198:                persistentDataClients.put(client.getMetatdataNamespace(),
199:                        client);
200:            }
201:
202:            /**
203:             * Called when the <tt>DataPersister</tt> is first instantiated. Useful
204:             * for retrieving configuration values, etc.
205:             *
206:             * @param curnConfig  the configuration
207:             *
208:             * @throws CurnException on error
209:             */
210:            public abstract void init(CurnConfig curnConfig)
211:                    throws CurnException;
212:
213:            /*----------------------------------------------------------------------*\
214:                                      Protected Methods
215:            \*----------------------------------------------------------------------*/
216:
217:            /**
218:             * Determine whether the data persister subclass is enabled or not (i.e.,
219:             * whether or not metadata is to be loaded and saved). The configuration
220:             * usually determines whether or not the data persister is enabled.
221:             *
222:             * @return <tt>true</tt> if enabled, <tt>false</tt> if disabled.
223:             */
224:            protected abstract boolean isEnabled();
225:
226:            /**
227:             * Called at the beginning of the load operation to initialize
228:             * the load.
229:             *
230:             * @throws CurnException on error
231:             */
232:            protected abstract void startLoadOperation() throws CurnException;
233:
234:            /**
235:             * Called at the end of the load operation to close files, clean
236:             * up, etc.
237:             *
238:             * @throws CurnException on error
239:             */
240:            protected abstract void endLoadOperation() throws CurnException;
241:
242:            /**
243:             * The actual load method; only called if the object is enabled.
244:             *
245:             * @param loadedDataHandler object to receive data as it's loaded
246:             *
247:             * @throws CurnException on error
248:             */
249:            protected abstract void doLoad(LoadedDataHandler loadedDataHandler)
250:                    throws CurnException;
251:
252:            /**
253:             * Called at the beginning of the actual save operation to initialize
254:             * the save, etc.
255:             *
256:             * @throws CurnException on error
257:             */
258:            protected abstract void startSaveOperation() throws CurnException;
259:
260:            /**
261:             * Called at the end of the actual save operation to flush files, clean
262:             * up, etc.
263:             *
264:             * @throws CurnException on error
265:             */
266:            protected abstract void endSaveOperation() throws CurnException;
267:
268:            /**
269:             * Save the data for one feed, including the items.
270:             *
271:             * @param feedData  the feed data to be saved
272:             *
273:             * @throws CurnException on error
274:             */
275:            protected abstract void saveFeedData(PersistentFeedData feedData)
276:                    throws CurnException;
277:
278:            /**
279:             * Save any extra metadata (i.e., metadata that isn't attached to a
280:             * specific feed or a specific item).
281:             *
282:             * @param metadata the collection of metadata items
283:             *
284:             * @throws CurnException on error
285:             */
286:            protected abstract void saveExtraMetadata(
287:                    Collection<PersistentMetadataGroup> metadata)
288:                    throws CurnException;
289:
290:            /*----------------------------------------------------------------------*\
291:                                        Private Methods
292:            \*----------------------------------------------------------------------*/
293:
294:            /**
295:             * Get the persistent metadata for one feed. Also handles getting
296:             * the data for the items.
297:             *
298:             * @param feedData the PersistentFeedData object into which to store
299:             *                 the metadata
300:             *
301:             * @throws CurnException on error
302:             */
303:            private void getFeedMetadataForFeed(PersistentFeedData feedData)
304:                    throws CurnException {
305:                for (PersistentDataClient client : persistentDataClients
306:                        .values()) {
307:                    String namespace = client.getMetatdataNamespace();
308:                    PersistentMetadataGroup metadata;
309:
310:                    // First the feed-specific metadata
311:
312:                    FeedCacheEntry feedCacheEntry = feedData
313:                            .getFeedCacheEntry();
314:                    Map<String, String> nameValuePairs = client
315:                            .getMetadataForFeed(feedCacheEntry);
316:                    if ((nameValuePairs != null) && (nameValuePairs.size() > 0)) {
317:                        metadata = new PersistentMetadataGroup(namespace);
318:                        metadata.addMetadata(nameValuePairs);
319:                        feedData.addFeedMetadataGroup(metadata);
320:                    }
321:
322:                    // Now the metadata for each item.
323:
324:                    for (PersistentFeedItemData itemData : feedData
325:                            .getPersistentFeedItems()) {
326:                        FeedCacheEntry itemCacheEntry = itemData
327:                                .getFeedCacheEntry();
328:                        nameValuePairs = client.getMetadataForItem(
329:                                itemCacheEntry, feedCacheEntry);
330:                        if ((nameValuePairs != null)
331:                                && (nameValuePairs.size() > 0)) {
332:                            metadata = new PersistentMetadataGroup(namespace);
333:                            metadata.addMetadata(nameValuePairs);
334:                            itemData.addItemMetadataGroup(metadata);
335:                        }
336:                    }
337:                }
338:            }
339:
340:            private Map<URL, PersistentFeedData> getCacheDataByFeed(
341:                    final Collection<FeedCacheEntry> cacheEntries) {
342:
343:                Map<URL, PersistentFeedData> cacheDataByFeed = new HashMap<URL, PersistentFeedData>();
344:
345:                for (FeedCacheEntry entry : cacheEntries) {
346:                    URL channelURL = entry.getChannelURL();
347:                    PersistentFeedData feedData = cacheDataByFeed
348:                            .get(channelURL);
349:                    if (feedData == null) {
350:                        feedData = new PersistentFeedData();
351:                        cacheDataByFeed.put(channelURL, feedData);
352:                    }
353:
354:                    if (entry.isChannelEntry()) {
355:                        feedData.setFeedCacheEntry(entry);
356:                    }
357:
358:                    else // It's an item entry
359:                    {
360:                        PersistentFeedItemData itemData = new PersistentFeedItemData(
361:                                entry);
362:                        feedData.addPersistentFeedItem(itemData);
363:                    }
364:                }
365:                return cacheDataByFeed;
366:            }
367:
368:            private void processLoadedFeed(final PersistentFeedData feedData,
369:                    final FeedCache feedCache) throws CurnException {
370:                // Add the feed cache entry to the feed cache.
371:
372:                FeedCacheEntry feedCacheEntry = feedData.getFeedCacheEntry();
373:                log.debug("processLoadedFeed: Processing loaded feed data for "
374:                        + feedCacheEntry.getChannelURL());
375:                feedCache.loadFeedCacheEntry(feedCacheEntry);
376:
377:                // Dispatch the feed metadata to the appropriate places.
378:
379:                for (PersistentMetadataGroup mg : feedData.getFeedMetadata()) {
380:                    String namespace = mg.getNamespace();
381:                    PersistentDataClient client = persistentDataClients
382:                            .get(namespace);
383:                    if (client == null) {
384:                        log
385:                                .warn("No plug-in or other class has registered "
386:                                        + "interest in feed metadata namespace \""
387:                                        + namespace
388:                                        + "\". "
389:                                        + "Ignoring the metadata.");
390:                    }
391:
392:                    else {
393:                        log.debug("Dispatching feed metadata in namespace \""
394:                                + namespace + "\" to instance of class "
395:                                + client.getClass().toString());
396:                        Map<String, String> nameValuePairs = mg.getMetadata();
397:                        for (Map.Entry<String, String> entry : nameValuePairs
398:                                .entrySet()) {
399:                            client.parseFeedMetadata(entry.getKey(), entry
400:                                    .getValue(), feedCacheEntry);
401:                        }
402:                    }
403:                }
404:
405:                // Process the items.
406:
407:                for (PersistentFeedItemData itemData : feedData
408:                        .getPersistentFeedItems()) {
409:                    // Add the item's feed cache entry to the cache.
410:
411:                    FeedCacheEntry itemCacheEntry = itemData
412:                            .getFeedCacheEntry();
413:                    log.debug("processLoadedFeed: adding item "
414:                            + itemData.getFeedCacheEntry().getEntryURL()
415:                            + " to cache.");
416:                    feedCache.loadFeedCacheEntry(itemCacheEntry);
417:                    log.debug("processLoadedFeed: Processing item metadata");
418:
419:                    // Now process the metadata.
420:
421:                    for (PersistentMetadataGroup mg : feedData
422:                            .getFeedMetadata()) {
423:                        String namespace = mg.getNamespace();
424:                        PersistentDataClient client = persistentDataClients
425:                                .get(namespace);
426:                        if (client == null) {
427:                            log
428:                                    .warn("No plug-in or other class has registered "
429:                                            + "interest in item metadata namespace \""
430:                                            + namespace
431:                                            + "\". "
432:                                            + "Ignoring the metadata.");
433:                        }
434:
435:                        else {
436:                            log
437:                                    .debug("Dispatching item metadata in namespace \""
438:                                            + namespace
439:                                            + "\" to instance of class "
440:                                            + client.getClass().toString());
441:                            Map<String, String> nameValuePairs = mg
442:                                    .getMetadata();
443:                            for (Map.Entry<String, String> entry : nameValuePairs
444:                                    .entrySet()) {
445:                                client.parseItemMetadata(entry.getKey(), entry
446:                                        .getValue(), itemCacheEntry);
447:                            }
448:                        }
449:                    }
450:                }
451:            }
452:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.