Coverage Report - net.sourceforge.pebble.util.Utilities
 
Classes in this File Line Coverage Branch Coverage Complexity
Utilities
0%
0/192
0%
0/68
4.154
Utilities$1
0%
0/2
N/A
4.154
 
 1  
 /*
 2  
  * Copyright (c) 2003-2011, 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.util;
 33  
 
 34  
 import net.sourceforge.pebble.Configuration;
 35  
 import net.sourceforge.pebble.PebbleContext;
 36  
 import net.sourceforge.pebble.dao.CategoryDAO;
 37  
 import net.sourceforge.pebble.dao.DAOFactory;
 38  
 import net.sourceforge.pebble.dao.file.*;
 39  
 import net.sourceforge.pebble.domain.*;
 40  
 import net.sourceforge.pebble.api.event.comment.CommentEvent;
 41  
 import net.sourceforge.pebble.api.event.trackback.TrackBackEvent;
 42  
 import net.sourceforge.pebble.event.response.IpAddressListener;
 43  
 import org.apache.commons.logging.Log;
 44  
 import org.apache.commons.logging.LogFactory;
 45  
 
 46  
 import java.io.File;
 47  
 import java.io.FileInputStream;
 48  
 import java.io.FilenameFilter;
 49  
 import java.util.*;
 50  
 import java.text.SimpleDateFormat;
 51  
 
 52  
 /**
 53  
  * Utilities for the current blog, such as those useful for moving
 54  
  * between versions of Pebble.
 55  
  *
 56  
  * @author    Simon Brown
 57  
  */
 58  0
 public class Utilities {
 59  
 
 60  
   /** the logger used by this action */
 61  0
   private static final Log log = LogFactory.getLog(Utilities.class);
 62  
 
 63  
   /**
 64  
    * Builds the indexes for the given blog.
 65  
    *
 66  
    * @param blog    a Blog instance
 67  
    */
 68  
   public static void buildIndexes(Blog blog) {
 69  0
     log.info("Reindexing blog");
 70  0
     blog.reindex();
 71  0
   }
 72  
 
 73  
   /**
 74  
    * Builds the blacklist and whitelist of IP addresses from all responses
 75  
    * for the given blog.
 76  
    *
 77  
    * @param blog    a Blog instance
 78  
    */
 79  
   public static void buildIpAddressLists(Blog blog) {
 80  0
     Iterator blogEntries = blog.getBlogEntries().iterator();
 81  0
     IpAddressListener ipAddressListener = new IpAddressListener();
 82  
 
 83  0
     while (blogEntries.hasNext()) {
 84  0
       BlogEntry blogEntry = (BlogEntry)blogEntries.next();
 85  0
       log.info("Processing " + blogEntry.getTitle() + " (" + blogEntry.getDate() + ")");
 86  0
       Iterator comments = blogEntry.getComments().iterator();
 87  0
       while (comments.hasNext()) {
 88  0
         Comment comment = (Comment)comments.next();
 89  0
         if (comment.isApproved()) {
 90  0
           CommentEvent event = new CommentEvent(comment, CommentEvent.COMMENT_APPROVED);
 91  0
           ipAddressListener.commentApproved(event);
 92  0
         } else if (comment.isRejected()) {
 93  0
           CommentEvent event = new CommentEvent(comment, CommentEvent.COMMENT_REJECTED);
 94  0
           ipAddressListener.commentRejected(event);
 95  
         }
 96  0
       }
 97  
 
 98  0
       Iterator trackbacks = blogEntry.getTrackBacks().iterator();
 99  0
       while (trackbacks.hasNext()) {
 100  0
         TrackBack trackback = (TrackBack)trackbacks.next();
 101  0
         if (trackback.isApproved()) {
 102  0
           TrackBackEvent event = new TrackBackEvent(trackback, TrackBackEvent.TRACKBACK_APPROVED);
 103  0
           ipAddressListener.trackBackApproved(event);
 104  0
         } else if (trackback.isRejected()) {
 105  0
           TrackBackEvent event = new TrackBackEvent(trackback, TrackBackEvent.TRACKBACK_REJECTED);
 106  0
           ipAddressListener.trackBackRejected(event);
 107  
         }
 108  0
       }
 109  
 //
 110  
 //      try {
 111  
 //        blogEntry.store();
 112  
 //      } catch (BlogServiceException e) {
 113  
 //        log.error("Error storing " + blogEntry.getTitle() + " (" + blogEntry.getDate() + ")");
 114  
 //      }
 115  0
     }
 116  0
   }
 117  
 
 118  
   /**
 119  
    * Fixes HTML escaping of comment and TrackBack content for the given blog.
 120  
    *
 121  
    * @param blog    a Blog instance
 122  
    */
 123  
   public static void fixHtmlInResponses(Blog blog) {
 124  0
     Iterator blogEntries = blog.getBlogEntries().iterator();
 125  0
     while (blogEntries.hasNext()) {
 126  0
       BlogEntry blogEntry = (BlogEntry)blogEntries.next();
 127  0
       log.info("Processing " + blogEntry.getTitle() + " (" + blogEntry.getDate() + ")");
 128  0
       Iterator comments = blogEntry.getComments().iterator();
 129  0
       while (comments.hasNext()) {
 130  0
         Comment comment = (Comment)comments.next();
 131  0
         if (comment.getBody() != null) {
 132  0
           comment.setBody(comment.getBody().replaceAll("&", "&"));
 133  0
           comment.setBody(comment.getBody().replaceAll("&lt;", "<"));
 134  0
           comment.setBody(comment.getBody().replaceAll("&gt;", ">"));
 135  
         }
 136  0
       }
 137  0
       Iterator trackbacks = blogEntry.getTrackBacks().iterator();
 138  0
       while (trackbacks.hasNext()) {
 139  0
         TrackBack trackback = (TrackBack)trackbacks.next();
 140  0
         if (trackback.getExcerpt() != null) {
 141  0
           trackback.setExcerpt(trackback.getExcerpt().replaceAll("&amp;", "&"));
 142  0
           trackback.setExcerpt(trackback.getExcerpt().replaceAll("&lt;", "<"));
 143  0
           trackback.setExcerpt(trackback.getExcerpt().replaceAll("&gt;", ">"));
 144  
         }
 145  0
       }
 146  
       try {
 147  0
         BlogService service = new BlogService();
 148  0
         service.putBlogEntry(blogEntry);
 149  0
       } catch (BlogServiceException e) {
 150  0
         log.error("Error storing " + blogEntry.getTitle() + " (" + blogEntry.getDate() + ")");
 151  0
       }
 152  0
     }
 153  0
   }
 154  
 
 155  
   /**
 156  
    * Converts flat categories to hierarchical categories.
 157  
    *
 158  
    * @param blog    a Blog instance
 159  
    */
 160  
   public static void convertCategories(Blog blog) {
 161  0
     Properties categories = new Properties();
 162  
     try {
 163  0
       FileInputStream in = new FileInputStream(new File(blog.getRoot(), "blog.categories"));
 164  0
       categories.load(in);
 165  0
       in.close();
 166  
 
 167  0
       Iterator it = categories.keySet().iterator();
 168  0
       while (it.hasNext()) {
 169  0
         String id = (String)it.next();
 170  0
         String name = categories.getProperty(id);
 171  
         Category category;
 172  
 
 173  0
         if (!id.startsWith("/")) {
 174  0
           category = new Category("/" + id, name);
 175  
         } else {
 176  0
           category = new Category(id, name);
 177  
         }
 178  
 
 179  0
         blog.addCategory(category);
 180  0
         DAOFactory factory = DAOFactory.getConfiguredFactory();
 181  0
         CategoryDAO dao = factory.getCategoryDAO();
 182  0
         dao.addCategory(category, blog);
 183  0
       }
 184  0
     } catch (Exception e) {
 185  0
       log.error("Exception encountered", e);
 186  0
     }
 187  0
   }
 188  
 
 189  
   /**
 190  
    * Moves blog entries from one category to another.
 191  
    *
 192  
    * @param blog    a Blog instance
 193  
    */
 194  
   public static void moveBlogEntriesFromCategory(Blog blog, Category from, Category to) {
 195  0
     Iterator blogEntries = blog.getBlogEntries().iterator();
 196  0
     while (blogEntries.hasNext()) {
 197  0
       BlogEntry blogEntry = (BlogEntry)blogEntries.next();
 198  0
       log.info("Processing " + blogEntry.getTitle() + " (" + blogEntry.getDate() + ")");
 199  
 
 200  0
       Collection categories = blogEntry.getCategories();
 201  0
       if (categories.contains(from)) {
 202  0
         categories.remove(from);
 203  0
         categories.add(to);
 204  0
         blogEntry.setCategories(categories);
 205  
 
 206  
         try {
 207  0
           BlogService service = new BlogService();
 208  0
           service.putBlogEntry(blogEntry);
 209  0
         } catch (BlogServiceException e) {
 210  0
           log.info("Error storing " + blogEntry.getTitle() + " (" + blogEntry.getDate() + ")");
 211  0
         }
 212  
       }
 213  0
     }
 214  0
   }
 215  
 
 216  
   /**
 217  
    * Resets the theme of a blog to "default".
 218  
    */
 219  
   public static void resetTheme(Blog blog) {
 220  0
     log.info("Resetting theme to default");
 221  
     try {
 222  0
       blog.removeProperty(Blog.THEME_KEY);
 223  0
       blog.storeProperties();
 224  0
     } catch (BlogServiceException e) {
 225  0
       e.printStackTrace();
 226  0
     }
 227  0
   }
 228  
 
 229  
   /**
 230  
    * Blasts the blog specific theme and overwrites it with the default theme.
 231  
    */
 232  
   public static void restoreTheme(Blog blog, String themeName) {
 233  0
     log.info("Restoring theme to " + themeName);
 234  0
     blog.getEditableTheme().restoreToSpecifiedTheme(themeName);
 235  0
   }
 236  
 
 237  
   /**
 238  
    * Resets the plugins back to their defaults.
 239  
    */
 240  
   public static void resetPlugins(Blog blog) {
 241  0
     log.info("Resetting plugins to the default configuration");
 242  
     try {
 243  0
       blog.removeProperty(Blog.PERMALINK_PROVIDER_KEY);
 244  0
       blog.removeProperty(Blog.CONTENT_DECORATORS_KEY);
 245  0
       blog.removeProperty(Blog.BLOG_LISTENERS_KEY);
 246  0
       blog.removeProperty(Blog.BLOG_ENTRY_LISTENERS_KEY);
 247  0
       blog.removeProperty(Blog.COMMENT_LISTENERS_KEY);
 248  0
       blog.removeProperty(Blog.COMMENT_CONFIRMATION_STRATEGY_KEY);
 249  0
       blog.removeProperty(Blog.TRACKBACK_LISTENERS_KEY);
 250  0
       blog.removeProperty(Blog.TRACKBACK_CONFIRMATION_STRATEGY_KEY);
 251  0
       blog.removeProperty(Blog.LUCENE_ANALYZER_KEY);
 252  0
       blog.removeProperty(Blog.LOGGER_KEY);
 253  0
       blog.removeProperty(Blog.PAGE_DECORATORS_KEY);
 254  0
       blog.removeProperty(Blog.OPEN_ID_COMMENT_AUTHOR_PROVIDERS_KEY);
 255  0
       blog.storeProperties();
 256  0
     } catch (BlogServiceException e) {
 257  0
       e.printStackTrace();
 258  0
     }
 259  0
   }
 260  
 
 261  
   /**
 262  
    * Moves blog entries from one category to another.
 263  
    *
 264  
    * @param blog    a Blog instance
 265  
    */
 266  
   public static void restructureBlogToGMT(Blog blog) {
 267  0
     log.info("Restructuring blog entries into GMT directory hierarchy");
 268  0
     TimeZone gmt = TimeZone.getTimeZone("GMT");
 269  0
     FileBlogEntryDAO dao = new FileBlogEntryDAO();
 270  0
     File root = new File(blog.getRoot());
 271  0
     File years[] = root.listFiles(new FourDigitFilenameFilter());
 272  0
     for (File year : years) {
 273  0
       File months[] = year.listFiles(new TwoDigitFilenameFilter());
 274  0
       for (File month : months) {
 275  0
         File days[] = month.listFiles(new TwoDigitFilenameFilter());
 276  0
         for (File day : days) {
 277  0
           File blogEntryFiles[] = day.listFiles(new BlogEntryFilenameFilter());
 278  0
           for (File blogEntryFile : blogEntryFiles) {
 279  0
             String filename = blogEntryFile.getName();
 280  0
             String id = filename.substring(0, filename.indexOf('.'));
 281  0
             File oldFile = blogEntryFile;
 282  0
             File newDirectory = new File(dao.getPath(blog, id, gmt));
 283  0
             File newFile = new File(newDirectory, filename);
 284  
 
 285  0
             if (!oldFile.equals(newFile)) {
 286  0
               log.info("Moving " + id + " to " + newFile.getAbsolutePath() + " from " + oldFile.getAbsolutePath());
 287  0
               newDirectory.mkdirs();
 288  0
               oldFile.renameTo(newFile);
 289  
             }
 290  
           }
 291  
         }
 292  
       }
 293  
     }
 294  0
   }
 295  
 
 296  
   /**
 297  
    * Restructures how static pages are stored on disk.
 298  
    *
 299  
    * @param blog    a Blog instance
 300  
    */
 301  
   public static void restructureStaticPages(Blog blog) {
 302  0
     log.info("Restructuring static pages");
 303  0
     File root = new File(blog.getRoot(), "pages");
 304  
     // Upon first start this directory does not exist yet 
 305  0
     if(!root.isDirectory()) {
 306  0
             root.mkdir();
 307  
     }
 308  
 
 309  0
     File files[] = root.listFiles(new FilenameFilter() {
 310  
         public boolean accept(File dir, String name) {
 311  0
           return name.matches("(\\d+\\.xml)|(\\d+\\.xml\\.bak)");
 312  
         }
 313  
     });
 314  
 
 315  0
     for (File file : files) {
 316  0
       if (file.getName().endsWith(".xml")) {
 317  0
         File staticPageDirectory = new File(root, file.getName().substring(0, file.getName().indexOf(".xml")));
 318  0
         if (!staticPageDirectory.exists()) {
 319  0
           log.info("Creating static page directory at " + staticPageDirectory.getAbsolutePath());
 320  0
           staticPageDirectory.mkdir();
 321  
         }
 322  0
         File destination = new File(staticPageDirectory, file.getName());
 323  0
         log.info("Moving " + file.getAbsolutePath() + " to " + destination.getAbsolutePath());
 324  0
         file.renameTo(destination);
 325  0
       } else {
 326  0
         File staticPageDirectory = new File(root, file.getName().substring(0, file.getName().indexOf(".xml")));
 327  0
         if (!staticPageDirectory.exists()) {
 328  0
           log.info("Creating static page directory at " + staticPageDirectory.getAbsolutePath());
 329  0
           staticPageDirectory.mkdir();
 330  
         }
 331  0
         SimpleDateFormat archiveFileExtension = new SimpleDateFormat("yyyyMMdd-HHmmss");
 332  0
         archiveFileExtension.setTimeZone(blog.getTimeZone());
 333  0
         File destination = new File(staticPageDirectory, file.getName().substring(0, file.getName().length()-3) + archiveFileExtension.format(new Date(file.lastModified())));
 334  0
         log.info("Moving " + file.getAbsolutePath() + " to " + destination.getAbsolutePath());
 335  0
         file.renameTo(destination);
 336  
       }
 337  
     }
 338  0
   }
 339  
 
 340  
   public static void main(String[] args) throws Exception {
 341  0
     if (args.length != 2) {
 342  0
       System.out.println("Usage : pebble.util.Utilities %1 %2");
 343  0
       System.out.println("   %1 : location of Pebble blog");
 344  0
       System.out.println("   %2 : [ipAddressListener|fixHtmlInResponses|convertCategories]");
 345  
 
 346  0
       return;
 347  
     }
 348  
 
 349  0
     DAOFactory.setConfiguredFactory(new FileDAOFactory());
 350  0
     Blog blog = new Blog(args[0]);
 351  
 
 352  0
     String action = args[1];
 353  0
     if (action == null) {
 354  
       // do nothing
 355  0
     } else if (action.equalsIgnoreCase("ipAddressListener")) {
 356  0
       buildIpAddressLists(blog);
 357  0
     } else if (action.equalsIgnoreCase("fixHtmlInResponses")) {
 358  0
       fixHtmlInResponses(blog);
 359  0
     } else if (action.equalsIgnoreCase("buildIndexes")) {
 360  0
       buildIndexes(blog);
 361  0
     } else if (action.equalsIgnoreCase("convertCategories")) {
 362  0
       convertCategories(blog);
 363  
     }
 364  
 
 365  0
   }
 366  
   /**
 367  
    * this is a very simple way to honor https transfer. As
 368  
    * the frontend depends upon setting a base url in the html/head block, it
 369  
    * should at least contain the https scheme if the current page has been
 370  
    * requested through https. 
 371  
    * If there is no https involved, pebbles previous behaviour 
 372  
    * (as of version 2.3.1) does not change. This change implies also changing 
 373  
    * several frontend jsps WEB-INF/tags/page.tag to use the value calculated
 374  
    * here instead of ${blog.url}. In the context of the patch that introduced
 375  
    * this method, the values have been named ${blogUrl} and ${multiBlogUrl}
 376  
 
 377  
    * @param currentScheme the scheme the current request has been sent through (e.g. request.getScheme())
 378  
    * @param blogUrl the ordinary blog url that might be changed to the secure one.
 379  
    * @return value to be used as base url for the blog named in blogUrl
 380  
    */
 381  
   public static String calcBaseUrl(String currentScheme, String blogUrl) {
 382  0
           Configuration configuration = PebbleContext.getInstance().getConfiguration();
 383  0
           if ("https".equals(currentScheme) && configuration.getSecureUrl().startsWith("https")) {
 384  0
                 return blogUrl.replace(configuration.getUrl(), configuration.getSecureUrl());
 385  
         } 
 386  0
           return blogUrl;
 387  
   }
 388  
 
 389  
 }