Clover Coverage Report - Pebble 2.5-SNAPSHOT
Coverage timestamp: Sat Jun 12 2010 09:39:29 EST
../../../../img/srcFileCovDistChart7.png 33% of files have more coverage
74   522   49   1,76
10   206   0,66   42
42     1,17  
1    
This report was generated with an evaluation server license. Purchase Clover or configure your license.
 
  AbstractBlog       Line # 47 74 0% 49 40 68,3% 0.6825397
 
  (530)
 
1    /*
2    * Copyright (c) 2003-2006, Simon Brown
3    * All rights reserved.
4    *
5    * Redistribution and use in source and binary forms, with or without
6    * modification, are permitted provided that the following conditions are met:
7    *
8    * - Redistributions of source code must retain the above copyright
9    * notice, this list of conditions and the following disclaimer.
10    *
11    * - Redistributions in binary form must reproduce the above copyright
12    * notice, this list of conditions and the following disclaimer in
13    * the documentation and/or other materials provided with the
14    * distribution.
15    *
16    * - Neither the name of Pebble nor the names of its contributors may
17    * be used to endorse or promote products derived from this software
18    * without specific prior written permission.
19    *
20    * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21    * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22    * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23    * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24    * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25    * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26    * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27    * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28    * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29    * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30    * POSSIBILITY OF SUCH DAMAGE.
31    */
32    package net.sourceforge.pebble.domain;
33   
34    import org.apache.commons.logging.Log;
35    import org.apache.commons.logging.LogFactory;
36   
37    import java.io.File;
38    import java.io.FileInputStream;
39    import java.io.FileOutputStream;
40    import java.io.IOException;
41    import java.util.*;
42   
43    import net.sourceforge.pebble.PebbleContext;
44   
45    import javax.servlet.http.HttpServletRequest;
46   
 
47    public abstract class AbstractBlog extends TimePeriod {
48   
49    /** the name of the file containing blog properties */
50    public static final String BLOG_PROPERTIES_FILE = "blog.properties";
51   
52    private static final int MAXIMUM_MESSAGES = 20;
53   
54    /** the log used by this class */
55    private static Log log = LogFactory.getLog(AbstractBlog.class);
56   
57    /** the filesystem root of this blog */
58    private String root;
59   
60    protected static final String FALSE = "false";
61    protected static final String TRUE = "true";
62   
63    public static final String NAME_KEY = "name";
64    public static final String AUTHOR_KEY = "author";
65    public static final String DESCRIPTION_KEY = "description";
66    public static final String IMAGE_KEY = "image";
67    public static final String TIMEZONE_KEY = "timeZone";
68    public static final String RECENT_BLOG_ENTRIES_ON_HOME_PAGE_KEY = "recentBlogEntriesOnHomePage";
69    public static final String RECENT_RESPONSES_ON_HOME_PAGE_KEY = "recentResponsesOnHomePage";
70    public static final String LANGUAGE_KEY = "language";
71    public static final String COUNTRY_KEY = "country";
72    public static final String CHARACTER_ENCODING_KEY = "characterEncoding";
73    public static final String THEME_KEY = "theme";
74   
75    private List<Message> messages = new LinkedList<Message>();
76   
77    /** the properties for this blog */
78    protected Properties properties;
79   
80    /**
81    * Creates a new Blog instance, based at the specified location.
82    * Note: You must call init() before being able to use this object -
83    *
84    * @param root an absolute path pointing to the root directory of the blog
85    */
 
86  1344 toggle public AbstractBlog(String root) {
87  1344 super(null);
88  1344 this.root = root;
89    // see javadoc comment about why init cannot be called here.
90    // init();
91    }
92   
93    /**
94    * Call this method to initialize this object before using it. As this method
95    * may call some abstract methods, it should be called either last from the
96    * topmost constructor or from the outside just after construction.
97    */
 
98  1344 toggle protected void init() {
99  1344 loadProperties();
100    }
101   
102    /**
103    * Loads the properties for this blog, from the blog.properties file
104    * in the root directory.
105    */
 
106  1344 toggle protected void loadProperties() {
107  1344 try {
108  1344 this.properties = new Properties(getDefaultProperties());
109   
110  1344 File blogPropertiesFile = new File(getRoot(), BLOG_PROPERTIES_FILE);
111  1344 if (!blogPropertiesFile.exists()) {
112  1344 return;
113    }
114   
115  0 FileInputStream fin = new FileInputStream(blogPropertiesFile);
116  0 properties.load(fin);
117  0 fin.close();
118    } catch (IOException ioe) {
119  0 log.error("A blog.properties file at " + getRoot() + " cannot be loaded", ioe);
120    }
121    }
122   
 
123  0 toggle public boolean isConfigured() {
124  0 File blogPropertiesFile = new File(getRoot(), BLOG_PROPERTIES_FILE);
125  0 return blogPropertiesFile.exists();
126    }
127   
128    /**
129    * Gets the default properties for a blog.
130    *
131    * @return a Properties instance
132    */
133    protected abstract Properties getDefaultProperties();
134   
135    /**
136    * Gets the ID of this blog.
137    *
138    * @return the ID as a String
139    */
140    public abstract String getId();
141   
142    /**
143    * Gets the filesystem root for this blog.
144    *
145    * @return a String representing an absolute path
146    */
 
147  36048 toggle public String getRoot() {
148  36048 return root;
149    }
150   
151    /**
152    * Sets the filesystem root for this blog.
153    *
154    * @param root a String representing the absolute path
155    */
 
156  0 toggle protected void setRoot(String root) {
157  0 this.root = root;
158    }
159   
160    /**
161    * Gets the properties associated with this blog.
162    *
163    * @return a java.util.Properties object
164    */
 
165  2 toggle public Properties getProperties() {
166  2 return (Properties)properties.clone();
167    }
168   
169    /**
170    * Gets a named property for this blog.
171    *
172    * @param key the property name/key
173    */
 
174  10694 toggle public String getProperty(String key) {
175  10694 return properties.getProperty(key);
176    }
177   
178    /**
179    * Sets a named property for this blog.
180    *
181    * @param key the property name/key
182    * @param value the property value
183    */
 
184  1412 toggle public void setProperty(String key, String value) {
185  1412 if (key != null) {
186  1412 if (value != null) {
187  1412 properties.setProperty(key, value);
188    } else {
189  0 removeProperty(key);
190    }
191    }
192    }
193   
194    /**
195    * Removes a named property for this blog.
196    *
197    * @param key the property name/key
198    */
 
199  10 toggle public void removeProperty(String key) {
200  10 properties.remove(key);
201    }
202   
203    /**
204    * Stores the properties associated with this blog.
205    *
206    * @throws BlogServiceException if the properties can't be stored
207    */
 
208  0 toggle public void storeProperties() throws BlogServiceException {
209  0 try {
210  0 FileOutputStream fout = new FileOutputStream(new File(getRoot(), BLOG_PROPERTIES_FILE));
211  0 properties.store(fout, "Properties for " + getName());
212  0 fout.flush();
213  0 fout.close();
214    } catch (IOException ioe) {
215  0 log.error(ioe);
216    }
217    }
218   
219    /**
220    * Gets the name of this blog.
221    *
222    * @return the name
223    */
 
224  14 toggle public String getName() {
225  14 return properties.getProperty(NAME_KEY);
226    }
227   
228    /**
229    * Gets the author of this blog.
230    *
231    * @return the author
232    */
 
233  2 toggle public String getAuthor() {
234  2 return properties.getProperty(AUTHOR_KEY);
235    }
236   
237    /**
238    * Gets the description of this blog.
239    *
240    * @return the description
241    */
 
242  2 toggle public String getDescription() {
243  2 return properties.getProperty(DESCRIPTION_KEY);
244    }
245   
246    /**
247    * Gets the image for this blog.
248    *
249    * @return a URL pointing to an image
250    */
 
251  0 toggle public String getImage() {
252  0 return properties.getProperty(IMAGE_KEY);
253    }
254   
255    /**
256    * Gets the URL where this blog is deployed.
257    *
258    * @return a URL as a String
259    */
260    public abstract String getUrl();
261   
262    /**
263    * Gets the relative URL where this blog is deployed.
264    *
265    * @return a URL as a String
266    */
267    public abstract String getRelativeUrl();
268   
269    /**
270    * Gets the domain name where this blog is deployed.
271    *
272    * @return a domain name as a String
273    */
 
274  4 toggle public String getDomainName() {
275  4 return PebbleContext.getInstance().getConfiguration().getDomainName();
276    }
277   
278    /**
279    * Gets the protocol where this blog is deployed.
280    *
281    * @return a protocol as a String
282    */
 
283  2 toggle public String getProtocol() {
284  2 String url = PebbleContext.getInstance().getConfiguration().getUrl();
285  2 return url.substring(0, url.indexOf("://")+3);
286    }
287   
288    /**
289    * Gets the context where Pebble is deployed.
290    *
291    * @return the webapp context
292    */
 
293  6 toggle public String getContext() {
294  6 String url = PebbleContext.getInstance().getConfiguration().getUrl();
295  6 int index = url.indexOf("/", url.indexOf("://")+3);
296  6 if (index == -1) {
297  0 return "/";
298    } else {
299  6 return url.substring(index);
300    }
301    }
302   
303    /**
304    * Gets the ID of the time zone for the blog.
305    *
306    * @return a String (Europe/London by default)
307    */
 
308  145552 toggle public String getTimeZoneId() {
309  145552 return properties.getProperty(TIMEZONE_KEY);
310    }
311   
312    /**
313    * Gets the TimeZone instance representing the timezone for the blog.
314    *
315    * @return a TimeZone instance
316    */
 
317  145488 toggle public TimeZone getTimeZone() {
318  145488 return TimeZone.getTimeZone(getTimeZoneId());
319    }
320   
321    /**
322    * Gets a Calendar instance representing the current moment in time,
323    * with the timezone and locale set to be the same as that specified
324    * for this blog.
325    *
326    * @return a Calendar instance
327    */
 
328  141860 toggle public Calendar getCalendar() {
329  141860 return Calendar.getInstance(getTimeZone(), getLocale());
330    }
331   
332    /**
333    * Gets the number of recent blog entries that are displayed on the home page.
334    *
335    * @return an int (3 by default)
336    */
 
337  32 toggle public int getRecentBlogEntriesOnHomePage() {
338  32 return Integer.parseInt(properties.getProperty(RECENT_BLOG_ENTRIES_ON_HOME_PAGE_KEY));
339    }
340   
341    /**
342    * Gets the number of recent comments that are displayed on the home page.
343    *
344    * @return an int (0 by default)
345    */
 
346  2 toggle public int getRecentResponsesOnHomePage() {
347  2 return Integer.parseInt(properties.getProperty(RECENT_RESPONSES_ON_HOME_PAGE_KEY));
348    }
349   
350    /**
351    * Gets the character encoding in use by this blog.
352    *
353    * @return the character encoding as an IANA registered character set code
354    */
 
355  32 toggle public String getCharacterEncoding() {
356  32 return properties.getProperty(CHARACTER_ENCODING_KEY);
357    }
358   
359    /**
360    * Gets string instance representing the language for the blog.
361    *
362    * @return a two-letter ISO language code (en by default)
363    */
 
364  143370 toggle public String getLanguage() {
365  143370 return properties.getProperty(LANGUAGE_KEY);
366    }
367   
368    /**
369    * Gets string instance representing the country for the blog.
370    *
371    * @return a two-letter ISO country code (GB by default)
372    */
 
373  143370 toggle public String getCountry() {
374  143370 return properties.getProperty(COUNTRY_KEY);
375    }
376   
377    /**
378    * Gets the Locale instance for the blog.
379    *
380    * @return a Locale instance based upon the language and country.
381    */
 
382  143368 toggle public Locale getLocale() {
383  143368 return new Locale(getLanguage(), getCountry());
384    }
385   
386    /**
387    * Gets the theme being used.
388    *
389    * @return a theme name as a String
390    */
 
391  0 toggle public String getTheme() {
392  0 return properties.getProperty(THEME_KEY);
393    }
394   
395    /**
396    * Gets the location where the blog images are stored.
397    *
398    * @return an absolute, local path on the filing system
399    */
 
400  1340 toggle public String getImagesDirectory() {
401  1340 return getRoot() + File.separator + "images";
402    }
403   
404    /**
405    * Gets the location where the blog search indexes are stored.
406    *
407    * @return an absolute, local path on the filing system
408    */
 
409  17640 toggle public String getIndexesDirectory() {
410  17640 return getRoot() + File.separator + "indexes";
411    }
412   
413    /**
414    * Gets the location where the blog search indexes are stored.
415    *
416    * @return an absolute, local path on the filing system
417    */
 
418  344 toggle public String getSearchIndexDirectory() {
419  344 return getIndexesDirectory() + File.separator + "search";
420    }
421   
422    /**
423    * Gets the location where the blog logs are stored.
424    *
425    * @return an absolute, local path on the filing system
426    */
 
427  2050 toggle public String getLogsDirectory() {
428  2050 return getRoot() + File.separator + "logs";
429    }
430   
431    /**
432    * Gets the most recent blog entries, the number
433    * of which is specified.
434    *
435    * @param numberOfEntries the number of entries to get
436    * @return a List containing the most recent blog entries
437    */
438    public abstract List getRecentBlogEntries(int numberOfEntries);
439   
440    /**
441    * Gets the most recent blog entries, the number of which is taken from
442    * the recentBlogEntriesOnHomePage property.
443    *
444    * @return a List containing the most recent blog entries
445    */
 
446  6 toggle public List getRecentBlogEntries() {
447  6 return getRecentBlogEntries(getRecentBlogEntriesOnHomePage());
448    }
449   
450    /**
451    * Setter method for the recentBlogEntries property - this is here so that
452    * the property complies with the JavaBeans standard.
453    *
454    * @param entries
455    */
 
456  0 toggle public void setRecentBlogEntries(List entries) {
457    // do nothing
458    }
459   
460    /**
461    * Gets the date that this blog was last updated.
462    *
463    * @return a Date instance representing the time of the most recent entry
464    */
465    public abstract Date getLastModified();
466   
467    /**
468    * Gets a string representation of this object.
469    *
470    * @return a String
471    */
 
472  0 toggle public String toString() {
473  0 return getName();
474    }
475   
 
476  54 toggle public synchronized void info(String text) {
477  54 Message message = new Message(MessageType.INFO, text);
478  54 messages.add(0, message);
479  54 log.info(message.getText());
480  54 truncateMessages();
481    }
482   
 
483  0 toggle public synchronized void warn(String text) {
484  0 Message message = new Message(MessageType.WARN, text);
485  0 messages.add(0, message);
486  0 log.warn(message.getText());
487  0 truncateMessages();
488    }
489   
 
490  2 toggle public synchronized void error(String text) {
491  2 Message message = new Message(MessageType.ERROR, text);
492  2 messages.add(0, message);
493  2 log.error(message.getText());
494  2 truncateMessages();
495    }
496   
 
497  56 toggle private void truncateMessages() {
498  56 if (messages.size() > MAXIMUM_MESSAGES) {
499  0 messages = messages.subList(0, MAXIMUM_MESSAGES);
500    }
501    }
502   
 
503  0 toggle public synchronized void clearMessages() {
504  0 messages.clear();
505    }
506   
 
507  4 toggle public List<Message> getMessages() {
508  4 return new ArrayList<Message>(messages);
509    }
510   
 
511  0 toggle public int getNumberOfMessages() {
512  0 return messages.size();
513    }
514   
515    /**
516    * Logs this request for blog.
517    *
518    * @param request the HttpServletRequest instance for this request
519    */
520    public abstract void log(HttpServletRequest request, int status);
521   
522    }