category.java

### 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