//# 0 errors, 133 messages
//#
/*
    //#photodecorator.java:1:1: class: net.sourceforge.pebble.decorator.PhotoDecorator
 * Copyright (c) 2003-2006, Simon Brown
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in
 *     the documentation and/or other materials provided with the
 *     distribution.
 *
 *   - Neither the name of Pebble nor the names of its contributors may
 *     be used to endorse or promote products derived from this software
 *     without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
package net.sourceforge.pebble.decorator;

import net.sourceforge.pebble.api.decorator.ContentDecoratorContext;
import net.sourceforge.pebble.domain.BlogEntry;
import net.sourceforge.pebble.domain.StaticPage;
import net.sourceforge.pebble.util.StringUtils;

import java.util.regex.Pattern;
import java.util.regex.Matcher;
import java.io.BufferedReader;
import java.io.StringReader;
import java.io.IOException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * Takes a simple description of photos and generates boilerplate markup.
 *
 * @author Simon Brown
 */
public class PhotoDecorator extends ContentDecoratorSupport {
    //#photodecorator.java:53: method: void net.sourceforge.pebble.decorator.PhotoDecorator.net.sourceforge.pebble.decorator.PhotoDecorator()
    //#input(void net.sourceforge.pebble.decorator.PhotoDecorator()): this
    //#photodecorator.java:53: end of method: void net.sourceforge.pebble.decorator.PhotoDecorator.net.sourceforge.pebble.decorator.PhotoDecorator()

  private static final Log log = LogFactory.getLog(PhotoDecorator.class);
    //#photodecorator.java:55: method: net.sourceforge.pebble.decorator.PhotoDecorator.net.sourceforge.pebble.decorator.PhotoDecorator__static_init
    //#photodecorator.java:55: Warning: method not available
    //#    -- call on Log org.apache.commons.logging.LogFactory:getLog(Class)
    //#    severity: INFORMATIONAL
    //#    class: net.sourceforge.pebble.decorator.PhotoDecorator
    //#    method: net.sourceforge.pebble.decorator.PhotoDecorator__static_init
    //#    unanalyzed callee: Log org.apache.commons.logging.LogFactory:getLog(Class)
    //#output(net.sourceforge.pebble.decorator.PhotoDecorator__static_init): __Descendant_Table[net/sourceforge/pebble/decorator/PhotoDecorator]
    //#output(net.sourceforge.pebble.decorator.PhotoDecorator__static_init): __Dispatch_Table.decorate(Lnet/sourceforge/pebble/api/decorator/ContentDecoratorContext;Lnet/sourceforge/pebble/domain/BlogEntry;)V
    //#output(net.sourceforge.pebble.decorator.PhotoDecorator__static_init): __Dispatch_Table.decorate(Lnet/sourceforge/pebble/api/decorator/ContentDecoratorContext;Lnet/sourceforge/pebble/domain/Comment;)V
    //#output(net.sourceforge.pebble.decorator.PhotoDecorator__static_init): __Dispatch_Table.decorate(Lnet/sourceforge/pebble/api/decorator/ContentDecoratorContext;Lnet/sourceforge/pebble/domain/StaticPage;)V
    //#output(net.sourceforge.pebble.decorator.PhotoDecorator__static_init): __Dispatch_Table.decorate(Lnet/sourceforge/pebble/api/decorator/ContentDecoratorContext;Lnet/sourceforge/pebble/domain/TrackBack;)V
    //#output(net.sourceforge.pebble.decorator.PhotoDecorator__static_init): __Dispatch_Table.getBlog()Lnet/sourceforge/pebble/domain/Blog;
    //#output(net.sourceforge.pebble.decorator.PhotoDecorator__static_init): __Dispatch_Table.markup(Ljava/lang/String;)Ljava/lang/String;
    //#output(net.sourceforge.pebble.decorator.PhotoDecorator__static_init): __Dispatch_Table.setBlog(Lnet/sourceforge/pebble/domain/Blog;)V
    //#output(net.sourceforge.pebble.decorator.PhotoDecorator__static_init): log
    //#output(net.sourceforge.pebble.decorator.PhotoDecorator__static_init): net/sourceforge/pebble/api/decorator/ContentDecorator.__Descendant_Table[net/sourceforge/pebble/decorator/PhotoDecorator]
    //#output(net.sourceforge.pebble.decorator.PhotoDecorator__static_init): net/sourceforge/pebble/decorator/ContentDecoratorSupport.__Descendant_Table[net/sourceforge/pebble/decorator/PhotoDecorator]
    //#post(net.sourceforge.pebble.decorator.PhotoDecorator__static_init): __Descendant_Table[net/sourceforge/pebble/decorator/PhotoDecorator] == &__Dispatch_Table
    //#post(net.sourceforge.pebble.decorator.PhotoDecorator__static_init): net/sourceforge/pebble/api/decorator/ContentDecorator.__Descendant_Table[net/sourceforge/pebble/decorator/PhotoDecorator] == &__Dispatch_Table
    //#post(net.sourceforge.pebble.decorator.PhotoDecorator__static_init): net/sourceforge/pebble/decorator/ContentDecoratorSupport.__Descendant_Table[net/sourceforge/pebble/decorator/PhotoDecorator] == &__Dispatch_Table
    //#post(net.sourceforge.pebble.decorator.PhotoDecorator__static_init): __Dispatch_Table.decorate(Lnet/sourceforge/pebble/api/decorator/ContentDecoratorContext;Lnet/sourceforge/pebble/domain/BlogEntry;)V == &decorate
    //#post(net.sourceforge.pebble.decorator.PhotoDecorator__static_init): __Dispatch_Table.decorate(Lnet/sourceforge/pebble/api/decorator/ContentDecoratorContext;Lnet/sourceforge/pebble/domain/Comment;)V == &net/sourceforge/pebble/decorator/ContentDecoratorSupport.decorate
    //#post(net.sourceforge.pebble.decorator.PhotoDecorator__static_init): __Dispatch_Table.decorate(Lnet/sourceforge/pebble/api/decorator/ContentDecoratorContext;Lnet/sourceforge/pebble/domain/StaticPage;)V == &decorate
    //#post(net.sourceforge.pebble.decorator.PhotoDecorator__static_init): __Dispatch_Table.decorate(Lnet/sourceforge/pebble/api/decorator/ContentDecoratorContext;Lnet/sourceforge/pebble/domain/TrackBack;)V == &net/sourceforge/pebble/decorator/ContentDecoratorSupport.decorate
    //#post(net.sourceforge.pebble.decorator.PhotoDecorator__static_init): __Dispatch_Table.getBlog()Lnet/sourceforge/pebble/domain/Blog; == &net/sourceforge/pebble/decorator/ContentDecoratorSupport.getBlog
    //#post(net.sourceforge.pebble.decorator.PhotoDecorator__static_init): __Dispatch_Table.markup(Ljava/lang/String;)Ljava/lang/String; == &markup
    //#post(net.sourceforge.pebble.decorator.PhotoDecorator__static_init): __Dispatch_Table.setBlog(Lnet/sourceforge/pebble/domain/Blog;)V == &net/sourceforge/pebble/decorator/ContentDecoratorSupport.setBlog
    //#post(net.sourceforge.pebble.decorator.PhotoDecorator__static_init): init'ed(log)
    //#photodecorator.java:55: end of method: net.sourceforge.pebble.decorator.PhotoDecorator.net.sourceforge.pebble.decorator.PhotoDecorator__static_init

  private static final String PHOTOS_START_TAG = "<photos>";
  private static final String PHOTOS_END_TAG = "</photos>";

  /**
   * Decorates the specified blog entry.
   *
   * @param context   the context in which the decoration is running
   * @param blogEntry the blog entry to be decorated
   */
  public void decorate(ContentDecoratorContext context, BlogEntry blogEntry) {
    blogEntry.setBody(markup(blogEntry.getBody()));
    //#photodecorator.java:67: method: void net.sourceforge.pebble.decorator.PhotoDecorator.decorate(ContentDecoratorContext, BlogEntry)
    //#input(void decorate(ContentDecoratorContext, BlogEntry)): blogEntry
    //#input(void decorate(ContentDecoratorContext, BlogEntry)): blogEntry.__Tag
    //#input(void decorate(ContentDecoratorContext, BlogEntry)): blogEntry.body
    //#input(void decorate(ContentDecoratorContext, BlogEntry)): blogEntry.excerpt
    //#input(void decorate(ContentDecoratorContext, BlogEntry)): blogEntry.propertyChangeSupport
    //#input(void decorate(ContentDecoratorContext, BlogEntry)): log
    //#input(void decorate(ContentDecoratorContext, BlogEntry)): net/sourceforge/pebble/domain/BlogEntry.__Descendant_Table[net/sourceforge/pebble/domain/BlogEntry]
    //#input(void decorate(ContentDecoratorContext, BlogEntry)): net/sourceforge/pebble/domain/BlogEntry.__Descendant_Table[others]
    //#input(void decorate(ContentDecoratorContext, BlogEntry)): net/sourceforge/pebble/domain/BlogEntry.__Dispatch_Table.getBody()Ljava/lang/String;
    //#input(void decorate(ContentDecoratorContext, BlogEntry)): net/sourceforge/pebble/domain/BlogEntry.__Dispatch_Table.getExcerpt()Ljava/lang/String;
    //#input(void decorate(ContentDecoratorContext, BlogEntry)): net/sourceforge/pebble/domain/BlogEntry.__Dispatch_Table.setBody(Ljava/lang/String;)V
    //#input(void decorate(ContentDecoratorContext, BlogEntry)): net/sourceforge/pebble/domain/BlogEntry.__Dispatch_Table.setExcerpt(Ljava/lang/String;)V
    //#input(void decorate(ContentDecoratorContext, BlogEntry)): this
    //#output(void decorate(ContentDecoratorContext, BlogEntry)): blogEntry.body
    //#output(void decorate(ContentDecoratorContext, BlogEntry)): blogEntry.excerpt
    //#pre[1] (void decorate(ContentDecoratorContext, BlogEntry)): blogEntry != null
    //#pre[2] (void decorate(ContentDecoratorContext, BlogEntry)): blogEntry.__Tag == net/sourceforge/pebble/domain/BlogEntry
    //#pre[3] (void decorate(ContentDecoratorContext, BlogEntry)): blogEntry.propertyChangeSupport != null
    //#pre[4] (void decorate(ContentDecoratorContext, BlogEntry)): init'ed(blogEntry.body)
    //#pre[5] (void decorate(ContentDecoratorContext, BlogEntry)): init'ed(blogEntry.excerpt)
    //#post(void decorate(ContentDecoratorContext, BlogEntry)): blogEntry.body != null
    //#post(void decorate(ContentDecoratorContext, BlogEntry)): init'ed(blogEntry.excerpt)
    //#unanalyzed(void decorate(ContentDecoratorContext, BlogEntry)): Effects-of-calling:java.lang.String:length
    //#unanalyzed(void decorate(ContentDecoratorContext, BlogEntry)): Effects-of-calling:java.util.regex.Pattern:compile
    //#unanalyzed(void decorate(ContentDecoratorContext, BlogEntry)): Effects-of-calling:java.util.regex.Pattern:matcher
    //#unanalyzed(void decorate(ContentDecoratorContext, BlogEntry)): Effects-of-calling:java.util.regex.Matcher:find
    //#unanalyzed(void decorate(ContentDecoratorContext, BlogEntry)): Effects-of-calling:java.util.regex.Matcher:start
    //#unanalyzed(void decorate(ContentDecoratorContext, BlogEntry)): Effects-of-calling:java.util.regex.Matcher:end
    //#unanalyzed(void decorate(ContentDecoratorContext, BlogEntry)): Effects-of-calling:java.lang.String:substring
    //#unanalyzed(void decorate(ContentDecoratorContext, BlogEntry)): Effects-of-calling:java.lang.StringBuffer
    //#unanalyzed(void decorate(ContentDecoratorContext, BlogEntry)): Effects-of-calling:java.lang.StringBuffer:append
    //#unanalyzed(void decorate(ContentDecoratorContext, BlogEntry)): Effects-of-calling:java.io.StringReader
    //#unanalyzed(void decorate(ContentDecoratorContext, BlogEntry)): Effects-of-calling:java.io.BufferedReader
    //#unanalyzed(void decorate(ContentDecoratorContext, BlogEntry)): Effects-of-calling:java.io.BufferedReader:readLine
    //#unanalyzed(void decorate(ContentDecoratorContext, BlogEntry)): Effects-of-calling:java.lang.String:trim
    //#unanalyzed(void decorate(ContentDecoratorContext, BlogEntry)): Effects-of-calling:java.lang.String:equals
    //#unanalyzed(void decorate(ContentDecoratorContext, BlogEntry)): Effects-of-calling:java.lang.String:split
    //#unanalyzed(void decorate(ContentDecoratorContext, BlogEntry)): Effects-of-calling:org.apache.commons.logging.Log:warn
    //#unanalyzed(void decorate(ContentDecoratorContext, BlogEntry)): Effects-of-calling:java.lang.String:valueOf
    //#unanalyzed(void decorate(ContentDecoratorContext, BlogEntry)): Effects-of-calling:java.lang.StringBuilder
    //#unanalyzed(void decorate(ContentDecoratorContext, BlogEntry)): Effects-of-calling:java.lang.StringBuffer:toString
    //#unanalyzed(void decorate(ContentDecoratorContext, BlogEntry)): Effects-of-calling:java.lang.StringBuilder:append
    //#unanalyzed(void decorate(ContentDecoratorContext, BlogEntry)): Effects-of-calling:java.lang.StringBuilder:toString
    //#unanalyzed(void decorate(ContentDecoratorContext, BlogEntry)): Effects-of-calling:java.beans.PropertyChangeSupport:firePropertyChange
    blogEntry.setExcerpt(markup(blogEntry.getExcerpt()));
  }
    //#photodecorator.java:69: end of method: void net.sourceforge.pebble.decorator.PhotoDecorator.decorate(ContentDecoratorContext, BlogEntry)

  /**
   * Decorates the specified static page.
   *
   * @param context    the context in which the decoration is running
   * @param staticPage the static page to be decorated
   */
  public void decorate(ContentDecoratorContext context, StaticPage staticPage) {
    staticPage.setBody(markup(staticPage.getBody()));
    //#photodecorator.java:78: method: void net.sourceforge.pebble.decorator.PhotoDecorator.decorate(ContentDecoratorContext, StaticPage)
    //#input(void decorate(ContentDecoratorContext, StaticPage)): log
    //#input(void decorate(ContentDecoratorContext, StaticPage)): net/sourceforge/pebble/domain/StaticPage.__Descendant_Table[net/sourceforge/pebble/domain/StaticPage]
    //#input(void decorate(ContentDecoratorContext, StaticPage)): net/sourceforge/pebble/domain/StaticPage.__Descendant_Table[others]
    //#input(void decorate(ContentDecoratorContext, StaticPage)): net/sourceforge/pebble/domain/StaticPage.__Dispatch_Table.getBody()Ljava/lang/String;
    //#input(void decorate(ContentDecoratorContext, StaticPage)): net/sourceforge/pebble/domain/StaticPage.__Dispatch_Table.setBody(Ljava/lang/String;)V
    //#input(void decorate(ContentDecoratorContext, StaticPage)): staticPage
    //#input(void decorate(ContentDecoratorContext, StaticPage)): staticPage.__Tag
    //#input(void decorate(ContentDecoratorContext, StaticPage)): staticPage.body
    //#input(void decorate(ContentDecoratorContext, StaticPage)): staticPage.propertyChangeSupport
    //#input(void decorate(ContentDecoratorContext, StaticPage)): this
    //#output(void decorate(ContentDecoratorContext, StaticPage)): staticPage.body
    //#pre[1] (void decorate(ContentDecoratorContext, StaticPage)): init'ed(staticPage.body)
    //#pre[2] (void decorate(ContentDecoratorContext, StaticPage)): staticPage != null
    //#pre[3] (void decorate(ContentDecoratorContext, StaticPage)): staticPage.__Tag == net/sourceforge/pebble/domain/StaticPage
    //#pre[4] (void decorate(ContentDecoratorContext, StaticPage)): staticPage.propertyChangeSupport != null
    //#post(void decorate(ContentDecoratorContext, StaticPage)): staticPage.body != null
    //#unanalyzed(void decorate(ContentDecoratorContext, StaticPage)): Effects-of-calling:java.lang.String:length
    //#unanalyzed(void decorate(ContentDecoratorContext, StaticPage)): Effects-of-calling:java.util.regex.Pattern:compile
    //#unanalyzed(void decorate(ContentDecoratorContext, StaticPage)): Effects-of-calling:java.util.regex.Pattern:matcher
    //#unanalyzed(void decorate(ContentDecoratorContext, StaticPage)): Effects-of-calling:java.util.regex.Matcher:find
    //#unanalyzed(void decorate(ContentDecoratorContext, StaticPage)): Effects-of-calling:java.util.regex.Matcher:start
    //#unanalyzed(void decorate(ContentDecoratorContext, StaticPage)): Effects-of-calling:java.util.regex.Matcher:end
    //#unanalyzed(void decorate(ContentDecoratorContext, StaticPage)): Effects-of-calling:java.lang.String:substring
    //#unanalyzed(void decorate(ContentDecoratorContext, StaticPage)): Effects-of-calling:java.lang.StringBuffer
    //#unanalyzed(void decorate(ContentDecoratorContext, StaticPage)): Effects-of-calling:java.lang.StringBuffer:append
    //#unanalyzed(void decorate(ContentDecoratorContext, StaticPage)): Effects-of-calling:java.io.StringReader
    //#unanalyzed(void decorate(ContentDecoratorContext, StaticPage)): Effects-of-calling:java.io.BufferedReader
    //#unanalyzed(void decorate(ContentDecoratorContext, StaticPage)): Effects-of-calling:java.io.BufferedReader:readLine
    //#unanalyzed(void decorate(ContentDecoratorContext, StaticPage)): Effects-of-calling:java.lang.String:trim
    //#unanalyzed(void decorate(ContentDecoratorContext, StaticPage)): Effects-of-calling:java.lang.String:equals
    //#unanalyzed(void decorate(ContentDecoratorContext, StaticPage)): Effects-of-calling:java.lang.String:split
    //#unanalyzed(void decorate(ContentDecoratorContext, StaticPage)): Effects-of-calling:org.apache.commons.logging.Log:warn
    //#unanalyzed(void decorate(ContentDecoratorContext, StaticPage)): Effects-of-calling:java.lang.String:valueOf
    //#unanalyzed(void decorate(ContentDecoratorContext, StaticPage)): Effects-of-calling:java.lang.StringBuilder
    //#unanalyzed(void decorate(ContentDecoratorContext, StaticPage)): Effects-of-calling:java.lang.StringBuffer:toString
    //#unanalyzed(void decorate(ContentDecoratorContext, StaticPage)): Effects-of-calling:java.lang.StringBuilder:append
    //#unanalyzed(void decorate(ContentDecoratorContext, StaticPage)): Effects-of-calling:java.lang.StringBuilder:toString
    //#unanalyzed(void decorate(ContentDecoratorContext, StaticPage)): Effects-of-calling:java.beans.PropertyChangeSupport:firePropertyChange
  }
    //#photodecorator.java:79: end of method: void net.sourceforge.pebble.decorator.PhotoDecorator.decorate(ContentDecoratorContext, StaticPage)

  private String markup(String content) {
    // is there work to do?
    if (content == null || content.length() == 0) {
    //#photodecorator.java:83: method: String net.sourceforge.pebble.decorator.PhotoDecorator.markup(String)
    //#input(String markup(String)): content
    //#input(String markup(String)): log
    //#output(String markup(String)): return_value
    //#presumption(String markup(String)): java.lang.String:length(...)@102 - java.lang.String:length(...)@102 in -4_294_967_295..2_147_483_648
    //#presumption(String markup(String)): java.util.regex.Pattern:compile(...)@91 != null
    //#presumption(String markup(String)): java.util.regex.Pattern:matcher(...)@93 != null
    //#presumption(String markup(String)): org.apache.commons.logging.LogFactory:getLog(...)@55 != null
    //#presumption(String markup(String)): tokens.length@119 >= 1
    //#post(String markup(String)): return_value != null
    //#test_vector(String markup(String)): content: Addr_Set{null}, Inverse{null}
    //#test_vector(String markup(String)): java.lang.String:equals(...)@113: {0}, {1}
    //#test_vector(String markup(String)): java.lang.String:length(...)@83: {1..4_294_967_295}, {0}
    //#test_vector(String markup(String)): java.util.regex.Matcher:find(...)@96: {1}, {0}
    //#test_vector(String markup(String)): tokens.length@119: {1, 3..+Inf}, {2}
      return "";
    }

    // this pattern says "take the shortest match you can find where there are
    // one or more characters between escape tags"
    //  - the match is case insensitive and DOTALL means that newlines are
    //  - considered as a character match
    Pattern p = Pattern.compile(PHOTOS_START_TAG + ".+?" + PHOTOS_END_TAG,
        Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
    Matcher m = p.matcher(content);

    // while there are blocks to be escaped
    while (m.find()) {
      int start = m.start();
      int end = m.end();

      // grab the text, strip off the "photos" tags and transform it
      String textToMarkup = content.substring(start, end);
      textToMarkup = textToMarkup.substring(PHOTOS_START_TAG.length(), textToMarkup.length() - PHOTOS_END_TAG.length());

      StringBuffer buf = new StringBuffer();
      buf.append("<div class=\"photos\">\n");

      try {
        BufferedReader reader = new BufferedReader(new StringReader(textToMarkup));
        String line = reader.readLine();
        buf.append("<div>\n");
        boolean foundPhotos = false;
        while (line != null) {
          if (line.trim().equals("")) {
            if (foundPhotos) {
              buf.append("</div>\n");
              buf.append("<div>\n");
            }
          } else {
            String[] tokens = line.split("\\|");
            buf.append("<img src=\"");
            buf.append(tokens[0]);
            buf.append("\" class=\"photo\" alt=\"");
            if (tokens.length == 2) {
              buf.append(tokens[1]);
            }
            buf.append("\" />\n");
            foundPhotos = true;
          }

          line = reader.readLine();
        }
        buf.append("</div>\n");
      } catch (IOException ioe) {
        log.warn(ioe);
    //#photodecorator.java:134: Warning: method not available
    //#    -- call on void org.apache.commons.logging.Log:warn(Object)
    //#    severity: INFORMATIONAL
    //#    class: net.sourceforge.pebble.decorator.PhotoDecorator
    //#    method: String markup(String)
    //#    unanalyzed callee: void org.apache.commons.logging.Log:warn(Object)
      }

      buf.append("</div>");

      // now add it back into the original text
      content = content.substring(0, start) + buf.toString() + content.substring(end, content.length());
      m = p.matcher(content);
    }

    return content;
    //#photodecorator.java:144: end of method: String net.sourceforge.pebble.decorator.PhotoDecorator.markup(String)
  }

}
    //#photodecorator.java:: end of class: net.sourceforge.pebble.decorator.PhotoDecorator
