File Source: category.java

     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.Serializable;
    38  import java.util.*;
    39  
    40  import net.sourceforge.pebble.comparator.ReverseBlogEntryIdComparator;
    41  
    42  /**
    43   * Represents a blog category.
    44   *
    45   * @author    Simon Brown
    46   */
    47  public class Category implements Permalinkable, Comparable, Serializable {
    48  
    49    /** the log used by this class */
           /* 
    P/P     *  Method: net.sourceforge.pebble.domain.Category__static_init
            * 
            *  Postconditions:
            *    init'ed(log)
            */
    50    private static final Log log = LogFactory.getLog(Category.class);
    51  
    52    /** the root category identifier */
    53    private static final String ROOT_CATEGORY_IDENTIFIER = "/";
    54  
    55    /** the owning blog */
    56    private transient Blog blog;
    57  
    58    /** the id of the category */
    59    private String id = "";
    60  
    61    /** the name of the category */
    62    private String name = "";
    63  
    64    /** the parent category, if applicable */
    65    private Category parent = null;
    66  
    67    /** the set of tags for this category */
    68    private String tags = "";
    69  
    70    /** the list of tags for this category */
    71    private List tagsAsList = new ArrayList();
    72  
    73    /** the sub-categories */
    74    private List subCategories = new ArrayList();
    75  
    76    /** the blog entries associated with this category */
    77    private List<String> blogEntries = new ArrayList<String>();
    78  
    79    /**
    80     * Default, no args constructor.
    81     */
           /* 
    P/P     *  Method: void net.sourceforge.pebble.domain.Category()
            * 
            *  Postconditions:
            *    this.blogEntries == &new ArrayList(Category#3)
            *    this.id == &""
            *    this.name == &""
            *    this.tags == &""
            *    this.parent == null
            *    this.subCategories == &new ArrayList(Category#2)
            *    this.tagsAsList == &new ArrayList(Category#1)
            *    new ArrayList(Category#1) num objects == 1
            *    new ArrayList(Category#2) num objects == 1
            *    new ArrayList(Category#3) num objects == 1
            */
    82    public Category() {
    83    }
    84  
    85    /**
    86     * Creates a new category with the specified properties.
    87     *
    88     * @param id          the id
    89     * @param name          the name
    90     */
           /* 
    P/P     *  Method: void net.sourceforge.pebble.domain.Category(String, String)
            * 
            *  Postconditions:
            *    this.blogEntries == &new ArrayList(Category#3)
            *    this.id != null
            *    this.name == name
            *    init'ed(this.name)
            *    init'ed(this.parent)
            *    this.subCategories == &new ArrayList(Category#2)
            *    this.tags == &""
            *    this.tagsAsList == &new ArrayList(Category#1)
            *    new ArrayList(Category#1) num objects == 1
            *    new ArrayList(Category#2) num objects == 1
            *    ...
            */
    91    public Category(String id, String name) {
    92      setId(id);
    93  
    94      this.name = name;
    95    }
    96  
    97    /**
    98     * Gets the id of this category.
    99     *
   100     * @return    the id as a String
   101     */
   102    public String getId() {
             /* 
    P/P       *  Method: String getId()
              * 
              *  Preconditions:
              *    init'ed(this.id)
              * 
              *  Postconditions:
              *    return_value == this.id
              *    init'ed(return_value)
              */
   103      return id;
   104    }
   105  
   106    /**
   107     * Sets the id of this category.
   108     *
   109     * @param id    the id as a String
   110     */
   111    public void setId(String id) {
             /* 
    P/P       *  Method: void setId(String)
              * 
              *  Postconditions:
              *    this.id != null
              * 
              *  Test Vectors:
              *    id: Addr_Set{null}, Inverse{null}
              *    java.lang.String:startsWith(...)@113: {1}, {0}
              */
   112      this.id = id;
   113      if (this.id == null || !this.id.startsWith("/")) {
   114        this.id = "/" + this.id;
   115      }
   116    }
   117  
   118    /**
   119     * Gets the name of this category.
   120     *
   121     * @return    the name as a String
   122     */
   123    public String getName() {
             /* 
    P/P       *  Method: String getName()
              * 
              *  Preconditions:
              *    init'ed(this.name)
              * 
              *  Postconditions:
              *    return_value == this.name
              *    init'ed(return_value)
              */
   124      return name;
   125    }
   126  
   127    /**
   128     * Sets the name of this category.
   129     *
   130     * @param name    the new category name
   131     */
   132    public void setName(String name) {
             /* 
    P/P       *  Method: void setName(String)
              * 
              *  Postconditions:
              *    this.name == name
              *    init'ed(this.name)
              */
   133      this.name = name;
   134    }
   135  
   136    /**
   137     * Determines whether this category is a root category.
   138     *
   139     * @return  true if the ID is "/", false otherwise
   140     */
   141    public boolean isRootCategory() {
             /* 
    P/P       *  Method: bool isRootCategory()
              * 
              *  Preconditions:
              *    this.id != null
              * 
              *  Postconditions:
              *    init'ed(return_value)
              */
   142      return id.equals(ROOT_CATEGORY_IDENTIFIER);
   143    }
   144  
   145    /**
   146     * Gets the parent of thie category.
   147     *
   148     * @return  a Category instance, or null if this category has no parent
   149     */
   150    public Category getParent() {
             /* 
    P/P       *  Method: Category getParent()
              * 
              *  Preconditions:
              *    init'ed(this.parent)
              * 
              *  Postconditions:
              *    return_value == this.parent
              *    init'ed(return_value)
              */
   151      return this.parent;
   152    }
   153  
   154    /**
   155     * Determines whether this category has the specified parent.
   156     *
   157     * @param category    a Category to test for
   158     * @return  true if this category has the specified category as one of its
   159     *          parents, false otherwise
   160     */
   161    public boolean hasParent(Category category) {
             /* 
    P/P       *  Method: bool hasParent(Category)
              * 
              *  Preconditions:
              *    init'ed(this.parent)
              *    (soft) category.id != null
              *    (soft) init'ed(this...id)
              *    (soft) init'ed(this...parent)
              * 
              *  Postconditions:
              *    init'ed(return_value)
              */
   162      Category parent = getParent();
   163      while (parent != null) {
   164        if (parent.equals(category)) {
   165          return true;
   166        } else {
   167          parent = parent.getParent();
   168        }
   169      }
   170  
   171      return false;
   172    }
   173  
   174    /**
   175     * Sets the parent of this category.
   176     *
   177     * @param parent  a Category instance
   178     */
   179    public void setParent(Category parent) {
             /* 
    P/P       *  Method: void setParent(Category)
              * 
              *  Postconditions:
              *    this.parent == parent
              *    init'ed(this.parent)
              */
   180      this.parent = parent;
   181    }
   182  
   183    /**
   184     * Gets the number of parents that this category has.
   185     *
   186     * @return  the number of parents this category has, or 0 if it is
   187     *          the root category
   188     */
   189    public int getNumberOfParents() {
             /* 
    P/P       *  Method: int getNumberOfParents()
              * 
              *  Preconditions:
              *    init'ed(this.parent)
              *    (soft) init'ed(this...parent)
              * 
              *  Postconditions:
              *    return_value >= 0
              */
   190      int parents = 0;
   191      Category parent = getParent();
   192      while (parent != null) {
   193        parents++;
   194        parent = parent.getParent();
   195      }
   196  
   197      return parents;
   198    }
   199  
   200    /**
   201     * Adds a sub-category.
   202     *
   203     * @param category    a Category instance
   204     */
   205    public synchronized void addSubCategory(Category category) {
             /* 
    P/P       *  Method: void addSubCategory(Category)
              * 
              *  Preconditions:
              *    init'ed(this.subCategories)
              *    (soft) category != null
              * 
              *  Postconditions:
              *    category.parent == One-of{old category.parent, this}
              * 
              *  Test Vectors:
              *    this.subCategories: Addr_Set{null}, Inverse{null}
              *    java.util.List:contains(...)@206: {1}, {0}
              */
   206      if (subCategories != null && !subCategories.contains(category)) {
   207        subCategories.add(category);
   208        category.setParent(this);
   209      }
   210    }
   211  
   212    /**
   213     * Removes a sub-category.
   214     *
   215     * @param category    a Category instance
   216     */
   217    public synchronized void removeSubCategory(Category category) {
             /* 
    P/P       *  Method: void removeSubCategory(Category)
              * 
              *  Preconditions:
              *    init'ed(this.subCategories)
              *    (soft) category != null
              * 
              *  Postconditions:
              *    category.parent == One-of{old category.parent, null}
              * 
              *  Test Vectors:
              *    this.subCategories: Addr_Set{null}, Inverse{null}
              *    java.util.List:contains(...)@218: {0}, {1}
              */
   218      if (subCategories != null && subCategories.contains(category)) {
   219        subCategories.remove(category);
   220        category.setParent(null);
   221      }
   222    }
   223  
   224    /**
   225     * Gets the list of sub-categories.
   226     *
   227     * @return  a List of Category instances
   228     */
   229    public List getSubCategories() {
             /* 
    P/P       *  Method: List getSubCategories()
              * 
              *  Preconditions:
              *    init'ed(this.subCategories)
              * 
              *  Postconditions:
              *    init'ed(return_value)
              */
   230      return Collections.unmodifiableList(subCategories);
   231    }
   232  
   233    /**
   234     * Gets the tags associated with this category.
   235     *
   236     * @return  a list of tags
   237     */
   238    public String getTags() {
             /* 
    P/P       *  Method: String getTags()
              * 
              *  Preconditions:
              *    init'ed(this.tags)
              * 
              *  Postconditions:
              *    return_value == this.tags
              *    init'ed(return_value)
              */
   239      return this.tags;
   240    }
   241  
   242    /**
   243     * Gets the tags associated with this category, as a List.
   244     *
   245     * @return  a List of tags
   246     */
   247    public List getTagsAsList() {
             /* 
    P/P       *  Method: List getTagsAsList()
              * 
              *  Preconditions:
              *    init'ed(this.tagsAsList)
              * 
              *  Postconditions:
              *    return_value == this.tagsAsList
              *    init'ed(return_value)
              */
   248      return this.tagsAsList;
   249    }
   250  
   251    /**
   252     * Gets the tags associated with this category and its parents.
   253     *
   254     * @return  a list of tags
   255     */
   256    public List getAllTags() {
             /* 
    P/P       *  Method: List getAllTags()
              * 
              *  Preconditions:
              *    init'ed(this.parent)
              *    init'ed(this.tagsAsList)
              *    (soft) init'ed(this...parent)
              *    (soft) init'ed(this...tagsAsList)
              * 
              *  Postconditions:
              *    return_value == &new ArrayList(getAllTags#1)
              *    new ArrayList(getAllTags#1) num objects == 1
              */
   257      List l = new ArrayList();
   258  
   259      l.addAll(getTagsAsList());
   260      Category parent = getParent();
   261      while (parent != null) {
   262        l.addAll(parent.getTagsAsList());
   263        parent = parent.getParent();
   264      }
   265  
   266      return l;
   267    }
   268  
   269    /**
   270     * Sets the set of tags associated with this category.
   271     *
   272     * @param newTags    a set of tags
   273     */
   274    public void setTags(String newTags) {
             /* 
    P/P       *  Method: void setTags(String)
              * 
              *  Preconditions:
              *    init'ed(this.blog)
              * 
              *  Postconditions:
              *    init'ed(this.tags)
              *    this.tagsAsList == &new ArrayList(parse#1)
              *    new ArrayList(parse#1) num objects == 1
              * 
              *  Test Vectors:
              *    newTags: Addr_Set{null}, Inverse{null}
              *    java.lang.String:indexOf(...)@275: {-231..-1}, {0..232-1}
              */
   275      if (newTags != null && newTags.indexOf(",") > -1) {
   276        // if the tags have been comma separated, convert them to
   277        // whitespace separated by
   278        // - remove whitespace
   279        // - convert commas to whitespace
   280        newTags = newTags.replaceAll(" ", "").replaceAll(",", " ");
   281      }
   282      this.tags = newTags;
   283      this.tagsAsList = Tag.parse(blog, tags);
   284    }
   285  
   286    /**
   287     * Sets the owning blog.
   288     *
   289     * @param blog    a Blog instance
   290     */
   291    public void setBlog(Blog blog) {
             /* 
    P/P       *  Method: void setBlog(Blog)
              * 
              *  Postconditions:
              *    this.blog == blog
              *    init'ed(this.blog)
              */
   292      this.blog = blog;
   293    }
   294  
   295    /**
   296     * Gets the permalink for this object.
   297     *
   298     * @return  a URL as a String
   299     */
   300    public String getPermalink() {
             /* 
    P/P       *  Method: String getPermalink()
              * 
              *  Preconditions:
              *    this.blog != null
              *    this.id != null
              * 
              *  Postconditions:
              *    return_value != null
              * 
              *  Test Vectors:
              *    java.lang.String:equals(...)@142: {0}, {1}
              * 
              *  Preconditions:
              *    (soft) net/sourceforge/pebble/domain/BlogManager.instance != null
              *    (soft) init'ed(net/sourceforge/pebble/domain/BlogManager.instance.multiBlog)
              *    (soft) init'ed(this.blog.id)
              */
   301      if (isRootCategory()) {
   302        return blog.getUrl() + "categories/";
   303      } else {
   304        return blog.getUrl() + "categories" + id + "/";
   305      }
   306    }
   307  
   308    /**
   309     * Gets the hashcode of this object.
   310     *
   311     * @return  the hashcode as an int
   312     */
   313    public int hashCode() {
             /* 
    P/P       *  Method: int hashCode()
              * 
              *  Preconditions:
              *    this.id != null
              * 
              *  Postconditions:
              *    init'ed(return_value)
              */
   314      return id.hashCode();
   315    }
   316  
   317    /**
   318     * Determines whether the specified object is equal to this one.
   319     *
   320     * @param o   the object to compare against
   321     * @return    true if Object o represents the same category, false otherwise
   322     */
   323    public boolean equals(Object o) {
             /* 
    P/P       *  Method: bool equals(Object)
              * 
              *  Preconditions:
              *    (soft) o.id != null
              *    (soft) init'ed(this.id)
              * 
              *  Postconditions:
              *    init'ed(return_value)
              */
   324      if (!(o instanceof Category)) {
   325        return false;
   326      }
   327  
   328      Category cat = (Category)o;
   329      return (cat.getId().equals(id));
   330    }
   331  
   332    /**
   333     * Compares this object with the specified object for order.  Returns a
   334     * negative integer, zero, or a positive integer as this object is less
   335     * than, equal to, or greater than the specified object.<p>
   336     *
   337     * @param   o the Object to be compared.
   338     * @return  a negative integer, zero, or a positive integer as this object
   339     *		is less than, equal to, or greater than the specified object.
   340     *
   341     * @throws ClassCastException if the specified object's type prevents it
   342     *         from being compared to this Object.
   343     */
   344    public int compareTo(Object o) {
             /* 
    P/P       *  Method: int compareTo(Object)
              * 
              *  Preconditions:
              *    o != null
              *    init'ed(o.id)
              *    this.id != null
              * 
              *  Postconditions:
              *    init'ed(return_value)
              */
   345      Category category = (Category)o;
   346      return getId().compareTo(category.getId());
   347    }
   348  
   349    /**
   350     * Returns a String representation of this object.
   351     *
   352     * @return  a String
   353     */
   354    public String toString() {
             /* 
    P/P       *  Method: String toString()
              * 
              *  Preconditions:
              *    init'ed(this.name)
              * 
              *  Postconditions:
              *    return_value == this.name
              *    init'ed(return_value)
              */
   355      return this.name;
   356    }
   357  
   358    /**
   359     * Gets the blog entries associated with this category.
   360     *
   361     * @return  a Collection of BlogEntry instances
   362     */
   363    public List<String> getBlogEntries() {
             /* 
    P/P       *  Method: List getBlogEntries()
              * 
              *  Preconditions:
              *    init'ed(this.blogEntries)
              * 
              *  Postconditions:
              *    return_value == &new ArrayList(getBlogEntries#1)
              *    new ArrayList(getBlogEntries#1) num objects == 1
              */
   364      return new ArrayList<String>(blogEntries);
   365    }
   366  
   367    /**
   368     * Adds a blog entry to this category.
   369     *
   370     * @param blogEntry   a blog entry id
   371     */
   372    public synchronized void addBlogEntry(String blogEntry) {
             /* 
    P/P       *  Method: void addBlogEntry(String)
              * 
              *  Preconditions:
              *    (soft) this...blogEntries != null
              *    (soft) init'ed(this...parent)
              *    (soft) this.blogEntries != null
              *    (soft) init'ed(this.parent)
              * 
              *  Test Vectors:
              *    blogEntry: Addr_Set{null}, Inverse{null}
              *    this.parent: Addr_Set{null}, Inverse{null}
              *    java.util.List:contains(...)@373: {1}, {0}
              */
   373      if (blogEntry != null && !blogEntries.contains(blogEntry)) {
   374        blogEntries.add(blogEntry);
   375        Collections.sort(blogEntries, new ReverseBlogEntryIdComparator());
   376  
   377        if (getParent() != null) {
   378          getParent().addBlogEntry(blogEntry);
   379        }
   380      }
   381    }
   382  
   383    /**
   384     * Removes a blog entry from this category.
   385     *
   386     * @param blogEntry   a blog entry id
   387     */
   388    public synchronized void removeBlogEntry(String blogEntry) {
             /* 
    P/P       *  Method: void removeBlogEntry(String)
              * 
              *  Preconditions:
              *    (soft) this...blogEntries != null
              *    (soft) init'ed(this...parent)
              *    (soft) this.blogEntries != null
              *    (soft) init'ed(this.parent)
              * 
              *  Test Vectors:
              *    blogEntry: Addr_Set{null}, Inverse{null}
              *    this.parent: Addr_Set{null}, Inverse{null}
              */
   389      if (blogEntry != null) {
   390        blogEntries.remove(blogEntry);
   391  
   392        if (getParent() != null) {
   393          getParent().removeBlogEntry(blogEntry);
   394        }
   395      }
   396    }
   397  
   398    /**
   399     * Removes all blog entries from this category.
   400     */
   401    public synchronized void removeAllBlogEntries() {
             /* 
    P/P       *  Method: void removeAllBlogEntries()
              * 
              *  Postconditions:
              *    this.blogEntries == &new ArrayList(removeAllBlogEntries#1)
              *    new ArrayList(removeAllBlogEntries#1) num objects == 1
              */
   402      blogEntries = new ArrayList<String>();
   403    }
   404  
   405    /**
   406     * Gets the number of blog entries associated with this category.
   407     *
   408     * @return  an int
   409     */
   410    public int getNumberOfBlogEntries() {
             /* 
    P/P       *  Method: int getNumberOfBlogEntries()
              * 
              *  Preconditions:
              *    this.blogEntries != null
              * 
              *  Postconditions:
              *    init'ed(return_value)
              */
   411      return this.blogEntries.size();
   412    }
   413  
   414  }








SofCheck Inspector Build Version : 2.22510
category.java 2010-Jun-25 19:40:32
category.class 2010-Jul-19 20:23:40