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