abstractblog.java

### File Source: abstractblog.java

             /*
        P/P   *  Method: net.sourceforge.pebble.domain.AbstractBlog__static_init
              *
              *  Postconditions:
              *    init'ed(log)
              */
         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
             /*
        P/P   *  Method: void net.sourceforge.pebble.domain.AbstractBlog(String)
              *
              *  Postconditions:
              *    this.blog == null
              *    this.messages == &new LinkedList(AbstractBlog#1)
              *    this.root == root
              *    init'ed(this.root)
              *    new LinkedList(AbstractBlog#1) num objects == 1
              */
        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    public AbstractBlog(String root) {
        87      super(null);
        88      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     */
               /*
        P/P     *  Method: void init()
                *
                *  Preconditions:
                *    init'ed(this.root)
                *    (soft) log != null
                *
                *  Postconditions:
                *    this.properties == &new Properties(loadProperties#1)
                *    new Properties(loadProperties#1) num objects == 1
                */
        98    protected void init() {
        99      loadProperties();
       100    }
       101
       102    /**
       103     * Loads the properties for this blog, from the blog.properties file
       104     * in the root directory.
       105     */
               /*
        P/P     *  Method: void loadProperties()
                *
                *  Preconditions:
                *    init'ed(this.root)
                *    (soft) log != null
                *
                *  Postconditions:
                *    this.properties == One-of{&new Properties(loadProperties#1), old this.properties}
                *    new Properties(loadProperties#1) num objects <= 1
                *
                *  Test Vectors:
                *    java.io.File:exists(...)@111: {1}, {0}
                */
       106    protected void loadProperties() {
       107      try {
       108        this.properties = new Properties(getDefaultProperties());
       109
       110        File blogPropertiesFile = new File(getRoot(), BLOG_PROPERTIES_FILE);
       111        if (!blogPropertiesFile.exists()) {
       112          return;
       113        }
       114
       115        FileInputStream fin = new FileInputStream(blogPropertiesFile);
       116        properties.load(fin);
       117        fin.close();
       118      } catch (IOException ioe) {
       119        log.error("A blog.properties file at " + getRoot() + " cannot be loaded", ioe);
       120      }
       121    }
       122
               /*
        P/P     *  Method: bool isConfigured()
                *
                *  Preconditions:
                *    init'ed(this.root)
                *
                *  Postconditions:
                *    init'ed(return_value)
                */
       123    public boolean isConfigured() {
       124      File blogPropertiesFile = new File(getRoot(), BLOG_PROPERTIES_FILE);
       125      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     */
               /*
        P/P     *  Method: String getRoot()
                *
                *  Preconditions:
                *    init'ed(this.root)
                *
                *  Postconditions:
                *    return_value == this.root
                *    init'ed(return_value)
                */
       147    public String getRoot() {
       148      return root;
       149    }
       150
       151    /**
       152     * Sets the filesystem root for this blog.
       153     *
       154     * @param root    a String representing the absolute path
       155     */
               /*
        P/P     *  Method: void setRoot(String)
                *
                *  Postconditions:
                *    this.root == root
                *    init'ed(this.root)
                */
       156    protected void setRoot(String root) {
       157      this.root = root;
       158    }
       159
       160    /**
       161     * Gets the properties associated with this blog.
       162     *
       163     * @return  a java.util.Properties object
       164     */
               /*
        P/P     *  Method: Properties getProperties()
                *
                *  Preconditions:
                *    this.properties != null
                *
                *  Postconditions:
                *    return_value != null
                */
       165    public Properties getProperties() {
       166      return (Properties)properties.clone();
       167    }
       168
       169    /**
       170     * Gets a named property for this blog.
       171     *
       172     * @param key     the property name/key
       173     */
               /*
        P/P     *  Method: String getProperty(String)
                *
                *  Preconditions:
                *    this.properties != null
                *
                *  Postconditions:
                *    init'ed(return_value)
                */
       174    public String getProperty(String key) {
       175      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     */
               /*
        P/P     *  Method: void setProperty(String, String)
                *
                *  Preconditions:
                *    (soft) this.properties != null
                *
                *  Test Vectors:
                *    key: Addr_Set{null}, Inverse{null}
                *    value: Addr_Set{null}, Inverse{null}
                */
       184    public void setProperty(String key, String value) {
       185      if (key != null) {
       186        if (value != null) {
       187          properties.setProperty(key, value);
       188        } else {
       189          removeProperty(key);
       190        }
       191      }
       192    }
       193
       194    /**
       195     * Removes a named property for this blog.
       196     *
       197     * @param key     the property name/key
       198     */
               /*
        P/P     *  Method: void removeProperty(String)
                *
                *  Preconditions:
                *    this.properties != null
                */
       199    public void removeProperty(String key) {
       200      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     */
               /*
        P/P     *  Method: void storeProperties()
                *
                *  Preconditions:
                *    (soft) log != null
                *    (soft) this.properties != null
                *    (soft) init'ed(this.root)
                */
       208    public void storeProperties() throws BlogServiceException {
       209      try {
       210        FileOutputStream fout = new FileOutputStream(new File(getRoot(), BLOG_PROPERTIES_FILE));
       211        properties.store(fout, "Properties for " + getName());
       212        fout.flush();
       213        fout.close();
       214      } catch (IOException ioe) {
       215        log.error(ioe);
       216      }
       217    }
       218
       219    /**
       220     * Gets the name of this blog.
       221     *
       222     * @return    the name
       223     */
               /*
        P/P     *  Method: String getName()
                *
                *  Preconditions:
                *    this.properties != null
                *
                *  Postconditions:
                *    init'ed(return_value)
                */
       224    public String getName() {
       225      return properties.getProperty(NAME_KEY);
       226    }
       227
       228    /**
       229     * Gets the author of this blog.
       230     *
       231     * @return    the author
       232     */
               /*
        P/P     *  Method: String getAuthor()
                *
                *  Preconditions:
                *    this.properties != null
                *
                *  Postconditions:
                *    init'ed(return_value)
                */
       233    public String getAuthor() {
       234      return properties.getProperty(AUTHOR_KEY);
       235    }
       236
       237    /**
       238     * Gets the description of this blog.
       239     *
       240     * @return    the description
       241     */
               /*
        P/P     *  Method: String getDescription()
                *
                *  Preconditions:
                *    this.properties != null
                *
                *  Postconditions:
                *    init'ed(return_value)
                */
       242    public String getDescription() {
       243      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     */
               /*
        P/P     *  Method: String getImage()
                *
                *  Preconditions:
                *    this.properties != null
                *
                *  Postconditions:
                *    init'ed(return_value)
                */
       251    public String getImage() {
       252      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     */
               /*
        P/P     *  Method: String getDomainName()
                *
                *  Presumptions:
                *    net.sourceforge.pebble.PebbleContext:getConfiguration(...)@275 != null
                *    net.sourceforge.pebble.PebbleContext:getInstance(...)@275 != null
                *
                *  Postconditions:
                *    return_value != null
                */
       274    public String getDomainName() {
       275      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     */
               /*
        P/P     *  Method: String getProtocol()
                *
                *  Presumptions:
                *    java.lang.String:indexOf(...)@285 <= 232-4
                *    net.sourceforge.pebble.PebbleContext:getConfiguration(...).url@284 != null
                *    net.sourceforge.pebble.PebbleContext:getConfiguration(...)@284 != null
                *    net.sourceforge.pebble.PebbleContext:getInstance(...)@284 != null
                *
                *  Postconditions:
                *    return_value != null
                */
       283    public String getProtocol() {
       284      String url = PebbleContext.getInstance().getConfiguration().getUrl();
       285      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     */
               /*
        P/P     *  Method: String getContext()
                *
                *  Presumptions:
                *    java.lang.String:indexOf(...)@295 <= 232-4
                *    net.sourceforge.pebble.PebbleContext:getConfiguration(...).url@294 != null
                *    net.sourceforge.pebble.PebbleContext:getConfiguration(...)@294 != null
                *    net.sourceforge.pebble.PebbleContext:getInstance(...)@294 != null
                *
                *  Postconditions:
                *    return_value != null
                *
                *  Test Vectors:
                *    java.lang.String:indexOf(...)@295: {-231..-2, 0..232-1}, {-1}
                */
       293    public String getContext() {
       294      String url = PebbleContext.getInstance().getConfiguration().getUrl();
       295      int index = url.indexOf("/", url.indexOf("://")+3);
       296      if (index == -1) {
       297        return "/";
       298      } else {
       299        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     */
               /*
        P/P     *  Method: String getTimeZoneId()
                *
                *  Preconditions:
                *    this.properties != null
                *
                *  Postconditions:
                *    init'ed(return_value)
                */
       308    public String getTimeZoneId() {
       309      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     */
               /*
        P/P     *  Method: TimeZone getTimeZone()
                *
                *  Preconditions:
                *    this.properties != null
                *
                *  Postconditions:
                *    init'ed(return_value)
                */
       317    public TimeZone getTimeZone() {
       318      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     */
               /*
        P/P     *  Method: Calendar getCalendar()
                *
                *  Preconditions:
                *    this.properties != null
                *
                *  Postconditions:
                *    init'ed(return_value)
                */
       328    public Calendar getCalendar() {
       329      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     */
               /*
        P/P     *  Method: int getRecentBlogEntriesOnHomePage()
                *
                *  Preconditions:
                *    this.properties != null
                *
                *  Postconditions:
                *    init'ed(return_value)
                */
       337    public int getRecentBlogEntriesOnHomePage() {
       338      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     */
               /*
        P/P     *  Method: int getRecentResponsesOnHomePage()
                *
                *  Preconditions:
                *    this.properties != null
                *
                *  Postconditions:
                *    init'ed(return_value)
                */
       346    public int getRecentResponsesOnHomePage() {
       347      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     */
               /*
        P/P     *  Method: String getCharacterEncoding()
                *
                *  Preconditions:
                *    this.properties != null
                *
                *  Postconditions:
                *    init'ed(return_value)
                */
       355    public String getCharacterEncoding() {
       356      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     */
               /*
        P/P     *  Method: String getLanguage()
                *
                *  Preconditions:
                *    this.properties != null
                *
                *  Postconditions:
                *    init'ed(return_value)
                */
       364    public String getLanguage() {
       365      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     */
               /*
        P/P     *  Method: String getCountry()
                *
                *  Preconditions:
                *    this.properties != null
                *
                *  Postconditions:
                *    init'ed(return_value)
                */
       373    public String getCountry() {
       374      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     */
               /*
        P/P     *  Method: Locale getLocale()
                *
                *  Preconditions:
                *    this.properties != null
                *
                *  Postconditions:
                *    return_value == &new Locale(getLocale#1)
                *    new Locale(getLocale#1) num objects == 1
                */
       382    public Locale getLocale() {
       383      return new Locale(getLanguage(), getCountry());
       384    }
       385
       386    /**
       387     * Gets the theme being used.
       388     *
       389     * @return  a theme name as a String
       390     */
               /*
        P/P     *  Method: String getTheme()
                *
                *  Preconditions:
                *    this.properties != null
                *
                *  Postconditions:
                *    init'ed(return_value)
                */
       391    public String getTheme() {
       392      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     */
               /*
        P/P     *  Method: String getImagesDirectory()
                *
                *  Preconditions:
                *    init'ed(this.root)
                *
                *  Presumptions:
                *    init'ed(java.io.File.separator)
                *
                *  Postconditions:
                *    return_value != null
                */
       400    public String getImagesDirectory() {
       401      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     */
               /*
        P/P     *  Method: String getIndexesDirectory()
                *
                *  Preconditions:
                *    init'ed(this.root)
                *
                *  Presumptions:
                *    init'ed(java.io.File.separator)
                *
                *  Postconditions:
                *    return_value != null
                */
       409    public String getIndexesDirectory() {
       410      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     */
               /*
        P/P     *  Method: String getSearchIndexDirectory()
                *
                *  Preconditions:
                *    init'ed(this.root)
                *
                *  Presumptions:
                *    init'ed(java.io.File.separator)
                *
                *  Postconditions:
                *    return_value != null
                */
       418    public String getSearchIndexDirectory() {
       419      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     */
               /*
        P/P     *  Method: String getLogsDirectory()
                *
                *  Preconditions:
                *    init'ed(this.root)
                *
                *  Presumptions:
                *    init'ed(java.io.File.separator)
                *
                *  Postconditions:
                *    return_value != null
                */
       427    public String getLogsDirectory() {
       428      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     */
               /*
        P/P     *  Method: List getRecentBlogEntries()
                *
                *  Preconditions:
                *    this.properties != null
                *
                *  Postconditions:
                *    init'ed(return_value)
                *    new ArrayList(getRecentBlogEntries#2*) num objects <= 1
                *    new ArrayList(getRecentBlogEntries#4*) num objects <= 1
                */
       446    public List getRecentBlogEntries() {
       447      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     */
               /*
        P/P     *  Method: void setRecentBlogEntries(List)
                */
       456    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     */
               /*
        P/P     *  Method: String toString()
                *
                *  Preconditions:
                *    this.properties != null
                *
                *  Postconditions:
                *    init'ed(return_value)
                */
       472    public String toString() {
       473      return getName();
       474    }
       475
               /*
        P/P     *  Method: void info(String)
                *
                *  Preconditions:
                *    log != null
                *    this.messages != null
                *
                *  Postconditions:
                *    init'ed(this.messages)
                */
       476    public synchronized void info(String text) {
       477      Message message = new Message(MessageType.INFO, text);
       478      messages.add(0, message);
       479      log.info(message.getText());
       480      truncateMessages();
       481    }
       482
               /*
        P/P     *  Method: void warn(String)
                *
                *  Preconditions:
                *    log != null
                *    this.messages != null
                *
                *  Postconditions:
                *    init'ed(this.messages)
                */
       483    public synchronized void warn(String text) {
       484      Message message = new Message(MessageType.WARN, text);
       485      messages.add(0, message);
       486      log.warn(message.getText());
       487      truncateMessages();
       488    }
       489
               /*
        P/P     *  Method: void error(String)
                *
                *  Preconditions:
                *    log != null
                *    this.messages != null
                *
                *  Postconditions:
                *    init'ed(this.messages)
                */
       490    public synchronized void error(String text) {
       491      Message message = new Message(MessageType.ERROR, text);
       492      messages.add(0, message);
       493      log.error(message.getText());
       494      truncateMessages();
       495    }
       496
               /*
        P/P     *  Method: void truncateMessages()
                *
                *  Preconditions:
                *    this.messages != null
                *
                *  Postconditions:
                *    init'ed(this.messages)
                *
                *  Test Vectors:
                *    java.util.List:size(...)@498: {-231..20}, {21..232-1}
                */
       497    private void truncateMessages() {
       498      if (messages.size() > MAXIMUM_MESSAGES) {
       499        messages = messages.subList(0, MAXIMUM_MESSAGES);
       500      }
       501    }
       502
               /*
        P/P     *  Method: void clearMessages()
                *
                *  Preconditions:
                *    this.messages != null
                */
       503    public synchronized void clearMessages() {
       504      messages.clear();
       505    }
       506
               /*
        P/P     *  Method: List getMessages()
                *
                *  Preconditions:
                *    init'ed(this.messages)
                *
                *  Postconditions:
                *    return_value == &new ArrayList(getMessages#1)
                *    new ArrayList(getMessages#1) num objects == 1
                */
       507    public List<Message> getMessages() {
       508      return new ArrayList<Message>(messages);
       509    }
       510
               /*
        P/P     *  Method: int getNumberOfMessages()
                *
                *  Preconditions:
                *    this.messages != null
                *
                *  Postconditions:
                *    init'ed(return_value)
                */
       511    public int getNumberOfMessages() {
       512      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  }

SofCheck Inspector Build Version : 2.22510

abstractblog.java | 2010-Jun-25 19:40:32
abstractblog.class | 2010-Jul-19 20:23:40