//# 0 errors, 43 messages
//#
package net.sourceforge.pebble.dao.file;
    //#filecategorydao.java:1:1: class: net.sourceforge.pebble.dao.file.FileCategoryDAO

import net.sourceforge.pebble.dao.CategoryDAO;
import net.sourceforge.pebble.dao.PersistenceException;
import net.sourceforge.pebble.domain.Blog;
import net.sourceforge.pebble.domain.Category;
import net.sourceforge.pebble.domain.CategoryBuilder;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import java.io.File;
import java.io.FileWriter;
import java.util.List;

/**
 * DAO responsible for managing the storage of category definitions.
 *
 * @author    Simon Brown
 */
public class FileCategoryDAO implements CategoryDAO {

  /** the name of the file containing the category information */
  private static final String CATEGORIES_FILE_NAME = "categories.xml";

  /** the log used by this class */
  private static Log log = LogFactory.getLog(FileCategoryDAO.class);
    //#filecategorydao.java:30: method: net.sourceforge.pebble.dao.file.FileCategoryDAO.net.sourceforge.pebble.dao.file.FileCategoryDAO__static_init
    //#filecategorydao.java:30: Warning: method not available
    //#    -- call on Log org.apache.commons.logging.LogFactory:getLog(Class)
    //#    severity: INFORMATIONAL
    //#    class: net.sourceforge.pebble.dao.file.FileCategoryDAO
    //#    method: net.sourceforge.pebble.dao.file.FileCategoryDAO__static_init
    //#    unanalyzed callee: Log org.apache.commons.logging.LogFactory:getLog(Class)
    //#output(net.sourceforge.pebble.dao.file.FileCategoryDAO__static_init): __Descendant_Table[net/sourceforge/pebble/dao/file/FileCategoryDAO]
    //#output(net.sourceforge.pebble.dao.file.FileCategoryDAO__static_init): __Dispatch_Table.addCategory(Lnet/sourceforge/pebble/domain/Category;Lnet/sourceforge/pebble/domain/Blog;)V
    //#output(net.sourceforge.pebble.dao.file.FileCategoryDAO__static_init): __Dispatch_Table.deleteCategory(Lnet/sourceforge/pebble/domain/Category;Lnet/sourceforge/pebble/domain/Blog;)V
    //#output(net.sourceforge.pebble.dao.file.FileCategoryDAO__static_init): __Dispatch_Table.getCategories(Lnet/sourceforge/pebble/domain/Blog;)Lnet/sourceforge/pebble/domain/Category;
    //#output(net.sourceforge.pebble.dao.file.FileCategoryDAO__static_init): __Dispatch_Table.store(Lnet/sourceforge/pebble/domain/Blog;)V
    //#output(net.sourceforge.pebble.dao.file.FileCategoryDAO__static_init): __Dispatch_Table.updateCategory(Lnet/sourceforge/pebble/domain/Category;Lnet/sourceforge/pebble/domain/Blog;)V
    //#output(net.sourceforge.pebble.dao.file.FileCategoryDAO__static_init): log
    //#output(net.sourceforge.pebble.dao.file.FileCategoryDAO__static_init): net/sourceforge/pebble/dao/CategoryDAO.__Descendant_Table[net/sourceforge/pebble/dao/file/FileCategoryDAO]
    //#post(net.sourceforge.pebble.dao.file.FileCategoryDAO__static_init): __Descendant_Table[net/sourceforge/pebble/dao/file/FileCategoryDAO] == &__Dispatch_Table
    //#post(net.sourceforge.pebble.dao.file.FileCategoryDAO__static_init): net/sourceforge/pebble/dao/CategoryDAO.__Descendant_Table[net/sourceforge/pebble/dao/file/FileCategoryDAO] == &__Dispatch_Table
    //#post(net.sourceforge.pebble.dao.file.FileCategoryDAO__static_init): __Dispatch_Table.addCategory(Lnet/sourceforge/pebble/domain/Category;Lnet/sourceforge/pebble/domain/Blog;)V == &addCategory
    //#post(net.sourceforge.pebble.dao.file.FileCategoryDAO__static_init): __Dispatch_Table.deleteCategory(Lnet/sourceforge/pebble/domain/Category;Lnet/sourceforge/pebble/domain/Blog;)V == &deleteCategory
    //#post(net.sourceforge.pebble.dao.file.FileCategoryDAO__static_init): __Dispatch_Table.getCategories(Lnet/sourceforge/pebble/domain/Blog;)Lnet/sourceforge/pebble/domain/Category; == &getCategories
    //#post(net.sourceforge.pebble.dao.file.FileCategoryDAO__static_init): __Dispatch_Table.store(Lnet/sourceforge/pebble/domain/Blog;)V == &store
    //#post(net.sourceforge.pebble.dao.file.FileCategoryDAO__static_init): __Dispatch_Table.updateCategory(Lnet/sourceforge/pebble/domain/Category;Lnet/sourceforge/pebble/domain/Blog;)V == &updateCategory
    //#post(net.sourceforge.pebble.dao.file.FileCategoryDAO__static_init): init'ed(log)
    //#filecategorydao.java:30: end of method: net.sourceforge.pebble.dao.file.FileCategoryDAO.net.sourceforge.pebble.dao.file.FileCategoryDAO__static_init

  private JAXBContext jaxbContext;

  /**
   * Default, no args constructor.
   */
  public FileCategoryDAO() {
    //#filecategorydao.java:37: method: void net.sourceforge.pebble.dao.file.FileCategoryDAO.net.sourceforge.pebble.dao.file.FileCategoryDAO()
    //#input(void net.sourceforge.pebble.dao.file.FileCategoryDAO()): this
    //#output(void net.sourceforge.pebble.dao.file.FileCategoryDAO()): this.jaxbContext
    //#presumption(void net.sourceforge.pebble.dao.file.FileCategoryDAO()): java.lang.Class:getPackage(...)@39 != null
    //#presumption(void net.sourceforge.pebble.dao.file.FileCategoryDAO()): java.lang.Object:getClass(...)@39 != null
    //#post(void net.sourceforge.pebble.dao.file.FileCategoryDAO()): possibly_updated(this.jaxbContext)
    try {
      jaxbContext = JAXBContext.newInstance(getClass().getPackage().getName());
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
    //#filecategorydao.java:43: end of method: void net.sourceforge.pebble.dao.file.FileCategoryDAO.net.sourceforge.pebble.dao.file.FileCategoryDAO()

  /**
   * Gets the categories for a particular blog.
   *
   * @param blog    the owning Blog instance
   * @return  a Collection of Category instances
   * @throws  PersistenceException    if categories cannot be loaded
   */
  public Category getCategories(Blog blog) throws PersistenceException {
    CategoryBuilder categoryBuilder = new CategoryBuilder(blog);
    File source = new File(blog.getRoot(), CATEGORIES_FILE_NAME);
    if (source.exists()) {
      try {
        Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
        JAXBElement<CategoriesType> controller = (JAXBElement)unmarshaller.unmarshal(source);
        CategoriesType categoriesType = controller.getValue();

        for (CategoryType categoryType : categoriesType.getCategory()) {
          Category category = new Category(categoryType.getId(), categoryType.getName());
          category.setBlog(blog);
          category.setTags(categoryType.getTags());

          categoryBuilder.addCategory(category);
        }
      } catch (Exception e) {
        log.error(e.getMessage(), e);
        e.printStackTrace();
        throw new PersistenceException(e.getMessage());
      }
    }                                                           

    return categoryBuilder.getRootCategory();
  }

  /**
   * Adds the specified category.
   *
   * @param category    the Category instance to be added
   * @param blog    the owning blog
   * @throws PersistenceException   if something goes wrong storing the category
   */
  public void addCategory(Category category, Blog blog) throws PersistenceException {
    store(blog);
    //#filecategorydao.java:86: method: void net.sourceforge.pebble.dao.file.FileCategoryDAO.addCategory(Category, Blog)
    //#filecategorydao.java:86: Warning: method not available
    //#    -- call on void store(Blog)
    //#    severity: INFORMATIONAL
    //#    class: net.sourceforge.pebble.dao.file.FileCategoryDAO
    //#    method: void addCategory(Category, Blog)
    //#    unanalyzed callee: void store(Blog)
    //#input(void addCategory(Category, Blog)): blog
    //#input(void addCategory(Category, Blog)): this
  }
    //#filecategorydao.java:87: end of method: void net.sourceforge.pebble.dao.file.FileCategoryDAO.addCategory(Category, Blog)

  /**
   * Updates the specified category.
   *
   * @param updatedCategory   the Category instance to be updated
   * @param blog    the owning blog
   * @throws PersistenceException   if something goes wrong storing the category
   */
  public void updateCategory(Category updatedCategory, Blog blog) throws PersistenceException {
    store(blog);
    //#filecategorydao.java:97: method: void net.sourceforge.pebble.dao.file.FileCategoryDAO.updateCategory(Category, Blog)
    //#filecategorydao.java:97: Warning: method not available
    //#    -- call on void store(Blog)
    //#    severity: INFORMATIONAL
    //#    class: net.sourceforge.pebble.dao.file.FileCategoryDAO
    //#    method: void updateCategory(Category, Blog)
    //#    unanalyzed callee: void store(Blog)
    //#input(void updateCategory(Category, Blog)): blog
    //#input(void updateCategory(Category, Blog)): this
  }
    //#filecategorydao.java:98: end of method: void net.sourceforge.pebble.dao.file.FileCategoryDAO.updateCategory(Category, Blog)

  /**
   * Removes the specified category.
   *
   * @param category    the Category instance to be removed
   * @param blog    the owning blog
   * @throws PersistenceException   if something goes wrong removing the category
   */
  public void deleteCategory(Category category, Blog blog) throws PersistenceException {
    store(blog);
    //#filecategorydao.java:108: method: void net.sourceforge.pebble.dao.file.FileCategoryDAO.deleteCategory(Category, Blog)
    //#filecategorydao.java:108: Warning: method not available
    //#    -- call on void store(Blog)
    //#    severity: INFORMATIONAL
    //#    class: net.sourceforge.pebble.dao.file.FileCategoryDAO
    //#    method: void deleteCategory(Category, Blog)
    //#    unanalyzed callee: void store(Blog)
    //#input(void deleteCategory(Category, Blog)): blog
    //#input(void deleteCategory(Category, Blog)): this
  }
    //#filecategorydao.java:109: end of method: void net.sourceforge.pebble.dao.file.FileCategoryDAO.deleteCategory(Category, Blog)

  /**
   * Helper method to store all categories for a given blog.
   *
   * @param blog      the blog to which the categories belong
   * @throws  PersistenceException    if the categories cannnot be stored
   */
  private void store(Blog blog) throws PersistenceException {
    List<Category> categories = blog.getCategories();
    File destination = new File(blog.getRoot(), CATEGORIES_FILE_NAME);
    try {
      Marshaller marshaller = jaxbContext.createMarshaller();
      CategoriesType categoriesType = new CategoriesType();

      for (Category category : categories) {
        CategoryType categoryType = new CategoryType();
        categoryType.setId(category.getId());
        categoryType.setName(category.getName());
        categoryType.setTags(category.getTags());
        categoriesType.getCategory().add(categoryType);
      }

      log.debug("Saving to " + destination.getAbsolutePath());
      ObjectFactory objectFactory = new ObjectFactory();
      JAXBElement jaxbElement = objectFactory.createCategories(categoriesType);

      marshaller.setProperty("jaxb.formatted.output", true);
      marshaller.setProperty("jaxb.encoding", blog.getCharacterEncoding());
      FileWriter writer = new FileWriter(destination);
      marshaller.marshal(jaxbElement, writer);
      writer.flush();
      writer.close();
    } catch (Exception e) {
      log.error(e.getMessage(), e);
      e.printStackTrace();
      throw new PersistenceException(e.getMessage());
    }
  }

}    //#filecategorydao.java:: end of class: net.sourceforge.pebble.dao.file.FileCategoryDAO
