Clover Coverage Report - Pebble 2.5-SNAPSHOT
Coverage timestamp: Sat Jun 12 2010 09:39:29 EST
../../../../../img/srcFileCovDistChart8.png 29% of files have more coverage
229   441   30   19,08
30   306   0,13   12
12     2,5  
1    
This report was generated with an evaluation server license. Purchase Clover or configure your license.
 
  FileBlogEntryDAO       Line # 25 229 0% 30 67 75,3% 0.7527675
 
  (18)
 
1    package net.sourceforge.pebble.dao.file;
2   
3    import net.sourceforge.pebble.dao.BlogEntryDAO;
4    import net.sourceforge.pebble.dao.PersistenceException;
5    import net.sourceforge.pebble.domain.*;
6    import org.apache.commons.logging.Log;
7    import org.apache.commons.logging.LogFactory;
8    import org.w3c.dom.Document;
9    import org.w3c.dom.Element;
10    import org.w3c.dom.Node;
11    import org.xml.sax.helpers.DefaultHandler;
12   
13    import javax.xml.parsers.DocumentBuilder;
14    import javax.xml.parsers.DocumentBuilderFactory;
15    import javax.xml.parsers.SAXParser;
16    import javax.xml.parsers.SAXParserFactory;
17    import javax.xml.transform.*;
18    import javax.xml.transform.dom.DOMSource;
19    import javax.xml.transform.stream.StreamResult;
20    import java.io.*;
21    import java.text.DateFormat;
22    import java.text.SimpleDateFormat;
23    import java.util.*;
24   
 
25    public class FileBlogEntryDAO implements BlogEntryDAO {
26   
27    /** timezone to use for calculating paths on disk, etc */
28    private static final TimeZone GMT = TimeZone.getTimeZone("GMT");
29   
30    /**
31    * the log used by this class
32    */
33    private static Log log = LogFactory.getLog(FileBlogEntryDAO.class);
34   
 
35  2456 toggle public FileBlogEntryDAO() {
36    }
37   
38    /** the date/time format used when persisting dates */
39    static final String OLD_PERSISTENT_DATETIME_FORMAT = "dd MMM yyyy HH:mm:ss z";
40    static final String NEW_PERSISTENT_DATETIME_FORMAT = "dd MMM yyyy HH:mm:ss:S Z";
41    static final String REGEX_FOR_YEAR = "\\d\\d\\d\\d";
42   
43    /**
44    * Loads a specific blog entry.
45    *
46    * @param blogEntryId the blog entry ID
47    * @return a BlogEntry instance
48    * @throws net.sourceforge.pebble.dao.PersistenceException
49    * if the specified blog entry cannot be loaded
50    */
 
51  50 toggle public BlogEntry loadBlogEntry(Blog blog, String blogEntryId) throws PersistenceException {
52  50 File path = new File(getPath(blog, blogEntryId, GMT));
53  50 File file = new File(path, blogEntryId + ".xml");
54  50 return loadBlogEntry(blog, file);
55    }
56   
57    /**
58    * Loads a blog entry from the specified file.
59    *
60    * @param source the File pointing to the source
61    * @throws net.sourceforge.pebble.dao.PersistenceException
62    * if the blog entry can't be loaded
63    */
 
64  68 toggle private BlogEntry loadBlogEntry(Blog blog, File source) throws PersistenceException {
65  68 if (source.exists()) {
66  52 log.debug("Loading " + source.getAbsolutePath());
67  52 BlogEntry blogEntry = new BlogEntry(blog);
68   
69  52 try {
70  52 DefaultHandler handler = new BlogEntryHandler(blogEntry);
71  52 SAXParserFactory saxFactory = SAXParserFactory.newInstance();
72  52 saxFactory.setValidating(false);
73  52 saxFactory.setNamespaceAware(true);
74  52 SAXParser parser = saxFactory.newSAXParser();
75  52 parser.parse(source, handler);
76   
77    } catch (Exception e) {
78  0 log.error(e.getMessage() + " while loading blog enty from " + source.getAbsolutePath(), e);
79  0 e.printStackTrace();
80  0 throw new PersistenceException(e.getMessage());
81    }
82   
83  52 return blogEntry;
84    } else {
85  16 return null;
86    }
87    }
88   
89    /**
90    * Loads all blog entries.
91    *
92    * @param blog the Blog to load all entries for
93    * @return a List of BlogEntry objects
94    * @throws net.sourceforge.pebble.dao.PersistenceException
95    * if the blog entries cannot be loaded
96    */
 
97  18 toggle public Collection<BlogEntry> loadBlogEntries(Blog blog) throws PersistenceException {
98  18 List<BlogEntry> list = new ArrayList<BlogEntry>();
99   
100  18 File root = new File(blog.getRoot());
101  18 File years[] = root.listFiles(new FourDigitFilenameFilter());
102  18 for (File year : years) {
103  18 File months[] = year.listFiles(new TwoDigitFilenameFilter());
104  18 for (File month : months) {
105  18 File days[] = month.listFiles(new TwoDigitFilenameFilter());
106  18 for (File day : days) {
107  18 File blogEntryFiles[] = day.listFiles(new BlogEntryFilenameFilter());
108  18 for (File blogEntryFile : blogEntryFiles) {
109  18 list.add(loadBlogEntry(blog, blogEntryFile));
110    }
111    }
112    }
113    }
114   
115  18 return list;
116    }
117   
118    /**
119    * Stores the specified blog entry.
120    *
121    * @param blogEntry the blog entry to store
122    * @throws PersistenceException if something goes wrong storing the entry
123    */
 
124  64 toggle public void storeBlogEntry(BlogEntry blogEntry) throws PersistenceException {
125  64 File outputDir = new File(getPath(blogEntry.getBlog(), blogEntry.getId(), GMT));
126  64 if (!outputDir.exists()) {
127  16 outputDir.mkdirs();
128    }
129   
130  64 File outputFile = new File(outputDir, blogEntry.getId() + ".xml");
131  64 storeBlogEntry(blogEntry, outputFile);
132    }
133   
134   
135    /**
136    * Stores a blog entry to the specified file.
137    *
138    * @param blogEntry the BlogEntry that is being stored
139    * @param destination the File pointing to the destination
140    * @throws PersistenceException if something goes wrong storing the entry
141    */
 
142  64 toggle private void storeBlogEntry(BlogEntry blogEntry, File destination) throws PersistenceException {
143  64 File backupFile = new File(destination.getParentFile(), destination.getName() + ".bak");
144  64 try {
145  64 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
146  64 factory.setValidating(false);
147  64 factory.setNamespaceAware(true);
148  64 factory.setIgnoringElementContentWhitespace(true);
149  64 factory.setIgnoringComments(true);
150   
151  64 DocumentBuilder builder = factory.newDocumentBuilder();
152  64 Document doc = builder.newDocument();
153   
154  64 Element root = doc.createElement("blogEntry");
155  64 doc.appendChild(root);
156   
157  64 Element titleNode = doc.createElement("title");
158  64 Element subtitleNode = doc.createElement("subtitle");
159  64 Element excerptNode = doc.createElement("excerpt");
160  64 Element bodyNode = doc.createElement("body");
161  64 Element categoryNode;
162  64 Element tagsNode = doc.createElement("tags");
163  64 Element dateNode = doc.createElement("date");
164  64 Element timeZoneNode = doc.createElement("timeZone");
165  64 Element stateNode = doc.createElement("state");
166  64 Element authorNode = doc.createElement("author");
167  64 Element staticNameNode = doc.createElement("staticName");
168  64 Element commentsEnabledNode = doc.createElement("commentsEnabled");
169  64 Element trackBacksEnabledNode = doc.createElement("trackBacksEnabled");
170  64 Element attachmentNode = doc.createElement("attachment");
171   
172  64 root.appendChild(titleNode);
173  64 root.appendChild(subtitleNode);
174  64 root.appendChild(excerptNode);
175  64 root.appendChild(bodyNode);
176  64 root.appendChild(dateNode);
177  64 root.appendChild(timeZoneNode);
178  64 root.appendChild(stateNode);
179  64 root.appendChild(authorNode);
180  64 root.appendChild(staticNameNode);
181   
182  64 if (blogEntry.isAggregated()) {
183  0 Element permalinkNode = doc.createElement("originalPermalink");
184  0 permalinkNode.appendChild(doc.createTextNode(blogEntry.getOriginalPermalink()));
185  0 root.appendChild(permalinkNode);
186    }
187   
188  64 titleNode.appendChild(doc.createTextNode(blogEntry.getTitle()));
189  64 subtitleNode.appendChild(doc.createTextNode(blogEntry.getSubtitle()));
190  64 bodyNode.appendChild(doc.createCDATASection(blogEntry.getBody()));
191   
192  64 if (blogEntry.getExcerpt() != null) {
193  64 excerptNode.appendChild(doc.createCDATASection(blogEntry.getExcerpt()));
194    }
195   
196  64 root.appendChild(commentsEnabledNode);
197  64 commentsEnabledNode.appendChild(doc.createTextNode("" + blogEntry.isCommentsEnabled()));
198   
199  64 root.appendChild(trackBacksEnabledNode);
200  64 trackBacksEnabledNode.appendChild(doc.createTextNode("" + blogEntry.isTrackBacksEnabled()));
201   
202  64 Iterator it = blogEntry.getCategories().iterator();
203  64 Category category;
204  128 while (it.hasNext()) {
205  64 category = (Category) it.next();
206  64 categoryNode = doc.createElement("category");
207  64 categoryNode.appendChild(doc.createTextNode(category.getId()));
208  64 root.appendChild(categoryNode);
209    }
210   
211  64 if (blogEntry.getTags() != null) {
212  64 root.appendChild(tagsNode);
213  64 tagsNode.appendChild(doc.createTextNode(blogEntry.getTags()));
214    }
215   
216  64 if (blogEntry.getAuthor() != null) {
217  64 authorNode.appendChild(doc.createTextNode(blogEntry.getAuthor()));
218    }
219   
220  64 SimpleDateFormat sdf = new SimpleDateFormat(NEW_PERSISTENT_DATETIME_FORMAT, Locale.ENGLISH);
221  64 sdf.setTimeZone(GMT);
222  64 dateNode.appendChild(doc.createTextNode(sdf.format(blogEntry.getDate())));
223   
224  64 timeZoneNode.appendChild(doc.createTextNode(blogEntry.getTimeZoneId()));
225   
226  64 stateNode.appendChild(createTextNode(doc, blogEntry.getState().getName()));
227   
228  64 Attachment attachment = blogEntry.getAttachment();
229  64 if (attachment != null) {
230  0 root.appendChild(attachmentNode);
231  0 Element attachmentUrlNode = doc.createElement("url");
232  0 attachmentUrlNode.appendChild(createTextNode(doc, attachment.getUrl()));
233  0 attachmentNode.appendChild(attachmentUrlNode);
234  0 Element attachmentSizeNode = doc.createElement("size");
235  0 attachmentSizeNode.appendChild(createTextNode(doc, "" + attachment.getSize()));
236  0 attachmentNode.appendChild(attachmentSizeNode);
237  0 Element attachmentTypeNode = doc.createElement("type");
238  0 attachmentTypeNode.appendChild(createTextNode(doc, attachment.getType()));
239  0 attachmentNode.appendChild(attachmentTypeNode);
240    }
241   
242    // and now store the comments
243  64 it = blogEntry.getComments().iterator();
244  72 while (it.hasNext()) {
245  8 Comment comment = (Comment) it.next();
246  8 storeComment(comment, doc, root);
247    }
248   
249    // and finally the trackbacks
250  64 it = blogEntry.getTrackBacks().iterator();
251  64 while (it.hasNext()) {
252  0 TrackBack trackBack = (TrackBack) it.next();
253  0 storeTrackBack(trackBack, doc, root);
254    }
255   
256    // write the XMl to a String, and then write this string to a file
257    // (if the XML format fails, we don't corrupt the file)
258  64 StringWriter sw = new StringWriter();
259  64 Source source = new DOMSource(doc);
260  64 Result result = new StreamResult(sw);
261  64 Transformer xformer = TransformerFactory.newInstance().newTransformer();
262  64 xformer.setOutputProperty(OutputKeys.METHOD, "xml");
263  64 xformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
264  64 xformer.setOutputProperty(OutputKeys.MEDIA_TYPE, "text/xml");
265  64 xformer.setOutputProperty(OutputKeys.CDATA_SECTION_ELEMENTS, "body");
266  64 xformer.setOutputProperty(OutputKeys.INDENT, "yes");
267  64 xformer.transform(source, result);
268   
269    // now take a backup of the correct file
270  64 if (destination.exists() && destination.length() > 0) {
271  48 log.debug("Backing up to " + backupFile.getAbsolutePath());
272  48 destination.renameTo(backupFile);
273    }
274   
275  64 log.debug("Saving to " + destination.getAbsolutePath());
276  64 BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(destination), "UTF-8"));
277  64 bw.write(sw.getBuffer().toString());
278  64 bw.flush();
279  64 bw.close();
280    } catch (Exception e) {
281  0 log.error(e.getMessage(), e);
282  0 e.printStackTrace();
283  0 throw new PersistenceException(e.getMessage());
284    }
285    }
286   
287    /**
288    * Helper method to store an individual comment.
289    *
290    * @param comment the Comment being stored
291    * @param doc the Document into which the comment is to be inserted
292    * @param root the root Node for the comment
293    * @throws java.lang.Exception if something goes wrong
294    */
 
295  8 toggle private void storeComment(Comment comment, Document doc, Node root) throws Exception {
296  8 Element commentNode = doc.createElement("comment");
297  8 root.appendChild(commentNode);
298   
299  8 Element titleNode = doc.createElement("title");
300  8 Element bodyNode = doc.createElement("body");
301  8 Element authorNode = doc.createElement("author");
302  8 Element emailNode = doc.createElement("email");
303  8 Element websiteNode = doc.createElement("website");
304  8 Element ipAddressNode = doc.createElement("ipAddress");
305  8 Element dateNode = doc.createElement("date");
306  8 Element parentNode = doc.createElement("parent");
307  8 Element stateNode = doc.createElement("state");
308  8 Element authenticatedNode = doc.createElement("authenticated");
309   
310  8 commentNode.appendChild(titleNode);
311  8 commentNode.appendChild(bodyNode);
312  8 commentNode.appendChild(authorNode);
313  8 commentNode.appendChild(emailNode);
314  8 commentNode.appendChild(websiteNode);
315  8 commentNode.appendChild(ipAddressNode);
316  8 commentNode.appendChild(dateNode);
317  8 commentNode.appendChild(stateNode);
318  8 commentNode.appendChild(authenticatedNode);
319   
320  8 titleNode.appendChild(createTextNode(doc, comment.getTitle()));
321  8 bodyNode.appendChild(createCDATASection(doc, comment.getBody()));
322  8 authorNode.appendChild(createTextNode(doc, comment.getAuthor()));
323  8 emailNode.appendChild(createTextNode(doc, comment.getEmail()));
324  8 websiteNode.appendChild(createTextNode(doc, comment.getWebsite()));
325  8 ipAddressNode.appendChild(createTextNode(doc, comment.getIpAddress()));
326  8 SimpleDateFormat sdf = new SimpleDateFormat(NEW_PERSISTENT_DATETIME_FORMAT, Locale.ENGLISH);
327  8 sdf.setTimeZone(GMT);
328  8 dateNode.appendChild(createTextNode(doc, sdf.format(comment.getDate())));
329  8 stateNode.appendChild(createTextNode(doc, comment.getState().getName()));
330  8 authenticatedNode.appendChild(createTextNode(doc, "" + comment.isAuthenticated()));
331   
332  8 if (comment.getParent() != null) {
333  0 commentNode.appendChild(parentNode);
334  0 parentNode.appendChild(createTextNode(doc, "" + comment.getParent().getId()));
335    }
336    }
337   
 
338  8 toggle private Node createCDATASection(Document doc, String text) {
339  8 if (text != null) {
340  8 return doc.createCDATASection(text);
341    } else {
342  0 return doc.createCDATASection("");
343    }
344    }
345   
 
346  128 toggle private Node createTextNode(Document doc, String text) {
347  128 if (text != null) {
348  112 return doc.createTextNode(text);
349    } else {
350  16 return doc.createTextNode("");
351    }
352    }
353   
354    /**
355    * Helper method to store an individual trackback.
356    *
357    * @param trackBack the TrackBack being stored
358    * @param doc the Document into which the trackback is to be inserted
359    * @param root the root Node for the comment
360    * @throws java.lang.Exception if something goes wrong
361    */
 
362  0 toggle private void storeTrackBack(TrackBack trackBack, Document doc, Node root) throws Exception {
363  0 Element commentNode = doc.createElement("trackback");
364  0 root.appendChild(commentNode);
365   
366  0 Element titleNode = doc.createElement("title");
367  0 Element excerptNode = doc.createElement("excerpt");
368  0 Element urlNode = doc.createElement("url");
369  0 Element blogNameNode = doc.createElement("blogName");
370  0 Element ipAddressNode = doc.createElement("ipAddress");
371  0 Element dateNode = doc.createElement("date");
372  0 Element stateNode = doc.createElement("state");
373   
374  0 commentNode.appendChild(titleNode);
375  0 commentNode.appendChild(excerptNode);
376  0 commentNode.appendChild(urlNode);
377  0 commentNode.appendChild(blogNameNode);
378  0 commentNode.appendChild(ipAddressNode);
379  0 commentNode.appendChild(dateNode);
380  0 commentNode.appendChild(stateNode);
381   
382  0 titleNode.appendChild(createTextNode(doc, trackBack.getTitle()));
383  0 excerptNode.appendChild(createCDATASection(doc, trackBack.getExcerpt()));
384  0 urlNode.appendChild(createTextNode(doc, trackBack.getUrl()));
385  0 blogNameNode.appendChild(createTextNode(doc, trackBack.getBlogName()));
386  0 ipAddressNode.appendChild(createTextNode(doc, trackBack.getIpAddress()));
387  0 SimpleDateFormat sdf = new SimpleDateFormat(NEW_PERSISTENT_DATETIME_FORMAT, Locale.ENGLISH);
388  0 sdf.setTimeZone(GMT);
389  0 dateNode.appendChild(doc.createTextNode(sdf.format(trackBack.getDate())));
390  0 stateNode.appendChild(createTextNode(doc, trackBack.getState().getName()));
391    }
392   
393    /**
394    * Removes the specified blog entry.
395    *
396    * @param blogEntry the blog entry to remove
397    * @throws PersistenceException if something goes wrong removing the entry
398    */
 
399  0 toggle public void removeBlogEntry(BlogEntry blogEntry) throws PersistenceException {
400  0 File path = new File(getPath(blogEntry.getBlog(), blogEntry.getId(), GMT));
401  0 File file = new File(path, blogEntry.getId() + ".xml");
402  0 log.debug("Removing " + blogEntry.getGuid());
403   
404  0 boolean success = file.delete();
405  0 if (!success) {
406  0 throw new PersistenceException("Deletion of blog entry " + blogEntry.getGuid() + " failed");
407    }
408    }
409   
410    /**
411    * Given a blog and blog entry ID, this method determines the path where
412    * that blog entry is stored.
413    *
414    * @param blog the owning Blog
415    * @param blogEntryId the ID of the blog entry
416    * @return a String of the form blogroot/yyyy/MM/dd
417    */
 
418  114 toggle public String getPath(Blog blog, String blogEntryId, TimeZone timeZone) {
419  114 DateFormat year = new SimpleDateFormat("yyyy");
420  114 year.setTimeZone(timeZone);
421  114 DateFormat month = new SimpleDateFormat("MM");
422  114 month.setTimeZone(timeZone);
423  114 DateFormat day = new SimpleDateFormat("dd");
424  114 day.setTimeZone(timeZone);
425   
426  114 long dateInMillis = Long.parseLong(blogEntryId);
427  114 Date date = new Date(dateInMillis);
428   
429  114 StringBuffer buf = new StringBuffer();
430  114 buf.append(blog.getRoot());
431  114 buf.append(File.separator);
432  114 buf.append(year.format(date));
433  114 buf.append(File.separator);
434  114 buf.append(month.format(date));
435  114 buf.append(File.separator);
436  114 buf.append(day.format(date));
437   
438  114 return buf.toString();
439    }
440   
441    }