//# 0 errors, 106 messages
//#
package net.sourceforge.pebble.decorator;
    //#escapemarkupdecorator.java:1:1: class: net.sourceforge.pebble.decorator.EscapeMarkupDecorator
    //#escapemarkupdecorator.java:1:1: method: net.sourceforge.pebble.decorator.EscapeMarkupDecorator.net.sourceforge.pebble.decorator.EscapeMarkupDecorator__static_init

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

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Escapes &lt; and &gt; tags in the excerpt/body of blog entries and
 * the body of static pages.
 * 
 * @author Simon Brown
 */
public class EscapeMarkupDecorator extends ContentDecoratorSupport {
    //#escapemarkupdecorator.java:17: method: void net.sourceforge.pebble.decorator.EscapeMarkupDecorator.net.sourceforge.pebble.decorator.EscapeMarkupDecorator()
    //#input(void net.sourceforge.pebble.decorator.EscapeMarkupDecorator()): this
    //#escapemarkupdecorator.java:17: end of method: void net.sourceforge.pebble.decorator.EscapeMarkupDecorator.net.sourceforge.pebble.decorator.EscapeMarkupDecorator()

  private static final String ESCAPE_START_TAG = "<escape>";
  private static final String ESCAPE_END_TAG = "</escape>";

  /**
   * 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) {
    String escapedBody = escape(blogEntry.getBody());
    //#escapemarkupdecorator.java:29: method: void net.sourceforge.pebble.decorator.EscapeMarkupDecorator.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)): 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:net.sourceforge.pebble.util.StringUtils:transformHTML
    //#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.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
    //#unanalyzed(void decorate(ContentDecoratorContext, BlogEntry)): Effects-of-calling:java.lang.String:trim
    blogEntry.setBody(escapedBody);

    String escapedExcerpt = escape(blogEntry.getExcerpt());
    blogEntry.setExcerpt(escapedExcerpt);
  }
    //#escapemarkupdecorator.java:34: end of method: void net.sourceforge.pebble.decorator.EscapeMarkupDecorator.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) {
    String escapedBody = escape(staticPage.getBody());
    //#escapemarkupdecorator.java:43: method: void net.sourceforge.pebble.decorator.EscapeMarkupDecorator.decorate(ContentDecoratorContext, StaticPage)
    //#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:net.sourceforge.pebble.util.StringUtils:transformHTML
    //#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.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
    staticPage.setBody(escapedBody);
  }
    //#escapemarkupdecorator.java:45: end of method: void net.sourceforge.pebble.decorator.EscapeMarkupDecorator.decorate(ContentDecoratorContext, StaticPage)

  private String escape(String content) {
    // is there work to do?
    if (content == null || content.length() == 0) {
    //#escapemarkupdecorator.java:49: method: String net.sourceforge.pebble.decorator.EscapeMarkupDecorator.escape(String)
    //#input(String escape(String)): content
    //#output(String escape(String)): return_value
    //#presumption(String escape(String)): java.lang.String:length(...)@68 - java.lang.String:length(...)@68 in -4_294_967_295..2_147_483_648
    //#presumption(String escape(String)): java.util.regex.Pattern:compile(...)@57 != null
    //#presumption(String escape(String)): java.util.regex.Pattern:matcher(...)@59 != null
    //#post(String escape(String)): return_value != null
    //#test_vector(String escape(String)): content: Addr_Set{null}, Inverse{null}
    //#test_vector(String escape(String)): java.lang.String:length(...)@49: {1..4_294_967_295}, {0}
    //#test_vector(String escape(String)): java.util.regex.Matcher:find(...)@62: {1}, {0}
      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(ESCAPE_START_TAG + ".+?" + ESCAPE_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 escape tags and transform it
      String textToEscape = content.substring(start, end);
      textToEscape = textToEscape.substring(ESCAPE_START_TAG.length(), textToEscape.length() - ESCAPE_END_TAG.length());
      textToEscape = StringUtils.transformHTML(textToEscape);
    //#escapemarkupdecorator.java:69: Warning: method not available
    //#    -- call on String net.sourceforge.pebble.util.StringUtils:transformHTML(String)
    //#    severity: INFORMATIONAL
    //#    class: net.sourceforge.pebble.decorator.EscapeMarkupDecorator
    //#    method: String escape(String)
    //#    unanalyzed callee: String net.sourceforge.pebble.util.StringUtils:transformHTML(String)

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

    return content;
    //#escapemarkupdecorator.java:76: end of method: String net.sourceforge.pebble.decorator.EscapeMarkupDecorator.escape(String)
  }

}
    //#output(net.sourceforge.pebble.decorator.EscapeMarkupDecorator__static_init): __Descendant_Table[net/sourceforge/pebble/decorator/EscapeMarkupDecorator]
    //#output(net.sourceforge.pebble.decorator.EscapeMarkupDecorator__static_init): __Dispatch_Table.decorate(Lnet/sourceforge/pebble/api/decorator/ContentDecoratorContext;Lnet/sourceforge/pebble/domain/BlogEntry;)V
    //#output(net.sourceforge.pebble.decorator.EscapeMarkupDecorator__static_init): __Dispatch_Table.decorate(Lnet/sourceforge/pebble/api/decorator/ContentDecoratorContext;Lnet/sourceforge/pebble/domain/Comment;)V
    //#output(net.sourceforge.pebble.decorator.EscapeMarkupDecorator__static_init): __Dispatch_Table.decorate(Lnet/sourceforge/pebble/api/decorator/ContentDecoratorContext;Lnet/sourceforge/pebble/domain/StaticPage;)V
    //#output(net.sourceforge.pebble.decorator.EscapeMarkupDecorator__static_init): __Dispatch_Table.decorate(Lnet/sourceforge/pebble/api/decorator/ContentDecoratorContext;Lnet/sourceforge/pebble/domain/TrackBack;)V
    //#output(net.sourceforge.pebble.decorator.EscapeMarkupDecorator__static_init): __Dispatch_Table.escape(Ljava/lang/String;)Ljava/lang/String;
    //#output(net.sourceforge.pebble.decorator.EscapeMarkupDecorator__static_init): __Dispatch_Table.getBlog()Lnet/sourceforge/pebble/domain/Blog;
    //#output(net.sourceforge.pebble.decorator.EscapeMarkupDecorator__static_init): __Dispatch_Table.setBlog(Lnet/sourceforge/pebble/domain/Blog;)V
    //#output(net.sourceforge.pebble.decorator.EscapeMarkupDecorator__static_init): net/sourceforge/pebble/api/decorator/ContentDecorator.__Descendant_Table[net/sourceforge/pebble/decorator/EscapeMarkupDecorator]
    //#output(net.sourceforge.pebble.decorator.EscapeMarkupDecorator__static_init): net/sourceforge/pebble/decorator/ContentDecoratorSupport.__Descendant_Table[net/sourceforge/pebble/decorator/EscapeMarkupDecorator]
    //#post(net.sourceforge.pebble.decorator.EscapeMarkupDecorator__static_init): __Descendant_Table[net/sourceforge/pebble/decorator/EscapeMarkupDecorator] == &__Dispatch_Table
    //#post(net.sourceforge.pebble.decorator.EscapeMarkupDecorator__static_init): net/sourceforge/pebble/api/decorator/ContentDecorator.__Descendant_Table[net/sourceforge/pebble/decorator/EscapeMarkupDecorator] == &__Dispatch_Table
    //#post(net.sourceforge.pebble.decorator.EscapeMarkupDecorator__static_init): net/sourceforge/pebble/decorator/ContentDecoratorSupport.__Descendant_Table[net/sourceforge/pebble/decorator/EscapeMarkupDecorator] == &__Dispatch_Table
    //#post(net.sourceforge.pebble.decorator.EscapeMarkupDecorator__static_init): __Dispatch_Table.decorate(Lnet/sourceforge/pebble/api/decorator/ContentDecoratorContext;Lnet/sourceforge/pebble/domain/BlogEntry;)V == &decorate
    //#post(net.sourceforge.pebble.decorator.EscapeMarkupDecorator__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.EscapeMarkupDecorator__static_init): __Dispatch_Table.decorate(Lnet/sourceforge/pebble/api/decorator/ContentDecoratorContext;Lnet/sourceforge/pebble/domain/StaticPage;)V == &decorate
    //#post(net.sourceforge.pebble.decorator.EscapeMarkupDecorator__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.EscapeMarkupDecorator__static_init): __Dispatch_Table.escape(Ljava/lang/String;)Ljava/lang/String; == &escape
    //#post(net.sourceforge.pebble.decorator.EscapeMarkupDecorator__static_init): __Dispatch_Table.getBlog()Lnet/sourceforge/pebble/domain/Blog; == &net/sourceforge/pebble/decorator/ContentDecoratorSupport.getBlog
    //#post(net.sourceforge.pebble.decorator.EscapeMarkupDecorator__static_init): __Dispatch_Table.setBlog(Lnet/sourceforge/pebble/domain/Blog;)V == &net/sourceforge/pebble/decorator/ContentDecoratorSupport.setBlog
    //#escapemarkupdecorator.java:: end of method: net.sourceforge.pebble.decorator.EscapeMarkupDecorator.net.sourceforge.pebble.decorator.EscapeMarkupDecorator__static_init
    //#escapemarkupdecorator.java:: end of class: net.sourceforge.pebble.decorator.EscapeMarkupDecorator
