//# 0 errors, 114 messages
//#
/*
    //#selecttag.java:1:1: class: net.sourceforge.pebble.web.tagext.SelectTag
    //#selecttag.java:1:1: method: net.sourceforge.pebble.web.tagext.SelectTag.net.sourceforge.pebble.web.tagext.SelectTag__static_init
 * 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.web.tagext;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspTagException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.TagSupport;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;

/**
 * Given a Collection or array, this tag produces a HTML select (dropdown) list
 * based upon the items contained within.
 *
 * @author    Simon Brown
 */
public class SelectTag extends TagSupport {
    //#selecttag.java:49: method: void net.sourceforge.pebble.web.tagext.SelectTag.net.sourceforge.pebble.web.tagext.SelectTag()
    //#input(void net.sourceforge.pebble.web.tagext.SelectTag()): this
    //#output(void net.sourceforge.pebble.web.tagext.SelectTag()): this.multiple
    //#output(void net.sourceforge.pebble.web.tagext.SelectTag()): this.size
    //#post(void net.sourceforge.pebble.web.tagext.SelectTag()): this.multiple == 0
    //#post(void net.sourceforge.pebble.web.tagext.SelectTag()): this.size == -1

  /** the items over which this tag should iterate */
  private Collection items;

  /** the name of the select control */
  private String name;

  /** the size of the select control */
  private int size = -1;

  /** the multiple attribute */
  private boolean multiple = false;
    //#selecttag.java:61: end of method: void net.sourceforge.pebble.web.tagext.SelectTag.net.sourceforge.pebble.web.tagext.SelectTag()

  /** the name of the property to be used as the displayed label */
  private String label;

  /** the name of the property to be used as the hidden value */
  private String value;

  /** the selected value */
  private Object selected;

  /**
   * Called when the starting tag is encountered.
   */
  public int doStartTag() throws JspException {
    // setup the iterator to be used
    Iterator iterator = items.iterator();
    //#selecttag.java:77: method: int net.sourceforge.pebble.web.tagext.SelectTag.doStartTag()
    //#input(int doStartTag()): this
    //#input(int doStartTag()): this.items
    //#input(int doStartTag()): this.label
    //#input(int doStartTag()): this.multiple
    //#input(int doStartTag()): this.name
    //#input(int doStartTag()): this.pageContext
    //#input(int doStartTag()): this.selected
    //#input(int doStartTag()): this.size
    //#input(int doStartTag()): this.value
    //#output(int doStartTag()): return_value
    //#pre[2] (int doStartTag()): this.items != null
    //#pre[4] (int doStartTag()): init'ed(this.multiple)
    //#pre[5] (int doStartTag()): init'ed(this.name)
    //#pre[6] (int doStartTag()): this.pageContext != null
    //#pre[8] (int doStartTag()): init'ed(this.size)
    //#pre[3] (int doStartTag()): (soft) init'ed(this.label)
    //#pre[7] (int doStartTag()): (soft) init'ed(this.selected)
    //#pre[9] (int doStartTag()): (soft) init'ed(this.value)
    //#presumption(int doStartTag()): java.lang.Class:getMethod(...)@106 != null
    //#presumption(int doStartTag()): java.lang.Class:getMethod(...)@137 != null
    //#presumption(int doStartTag()): java.lang.Object:getClass(...)@106 != null
    //#presumption(int doStartTag()): java.lang.Object:getClass(...)@137 != null
    //#presumption(int doStartTag()): java.lang.reflect.Method:invoke(...)@107 != null
    //#presumption(int doStartTag()): java.util.Iterator:next(...)@101 != null
    //#presumption(int doStartTag()): javax.servlet.jsp.PageContext:getOut(...)@80 != null
    //#post(int doStartTag()): return_value == 0
    //#test_vector(int doStartTag()): this.label: Addr_Set{null}, Inverse{null}
    //#test_vector(int doStartTag()): this.multiple: {0}, {1}
    //#test_vector(int doStartTag()): this.selected: Addr_Set{null}, Inverse{null}
    //#test_vector(int doStartTag()): this.size: {-2_147_483_648..0}, {1..4_294_967_295}
    //#test_vector(int doStartTag()): this.value: Addr_Set{null}, Inverse{null}
    //#test_vector(int doStartTag()): java.lang.String:equals(...)@127: {0}, {1}
    //#test_vector(int doStartTag()): java.util.Collection:contains(...)@124: {0}, {1}
    //#test_vector(int doStartTag()): java.util.Collection:instanceof(...)@122: {0}, {1}
    //#test_vector(int doStartTag()): java.util.Iterator:hasNext(...)@99: {1}, {0}

    try {
      JspWriter out = pageContext.getOut();

      // write the starting tag of the select control
      out.print("<select name=\"");
      out.print(name);
      out.print("\"");

      if (size > 0) {
        out.print(" size=\"");
        out.print(size);
        out.print("\"");
      }

      if (multiple) {
        out.print(" multiple=\"true\"");
      }

      out.print(">");

      while (iterator.hasNext()) {
        // get the next JavaBean from the items
        Object o = iterator.next();

        // and the property used to represent the hidden value
        String hiddenValue;
        if (value != null) {
          Method m = o.getClass().getMethod("get" + value.substring(0, 1).toUpperCase() + value.substring(1), new Class[] {});
          hiddenValue = m.invoke(o, new Object[]{}).toString();
        } else {
          hiddenValue = o.toString();
        }

        // and now generate the HTML
        out.print("<option value=\"");

        // call the accessor method for the value property
        // (this is the same as calling get<PropertyName>() on
        // the JavaBean instance)
        out.print(hiddenValue);
        out.print("\"");

        if (selected != null) {
          if (selected instanceof Collection) {
            Collection coll = (Collection)selected;
            if (coll.contains(hiddenValue)) {
              out.print(" selected=\"true\"");
            }
          } else if (selected.toString().equals(hiddenValue)) {
            out.print(" selected=\"true\"");
          }
        }
        out.print(">");

        if (label != null) {
          // and do the same for the label property
          // and use it to create a description of the property used
          // to represent the displayable label
          Method m = o.getClass().getMethod("get" + label.substring(0, 1).toUpperCase() + label.substring(1), new Class[] {});
          out.print(
              m.invoke(o, new Object[]{}));
        } else {
          out.print(o.toString());
        }
        out.print("</option>");
      }

      // write the ending tag of the select control
      out.print("</select>");
    } catch (Exception e) {
      e.printStackTrace();
      throw new JspTagException(e.getMessage());
    }

    // and skip the body
    return SKIP_BODY;
    //#selecttag.java:154: end of method: int net.sourceforge.pebble.web.tagext.SelectTag.doStartTag()
  }

  /**
   * Sets the items over which this tag should iterate.
   *
   * @param items   a Collection or array
   */
  public void setItems(Object items) {
    if (items instanceof Collection) {
    //#selecttag.java:163: method: void net.sourceforge.pebble.web.tagext.SelectTag.setItems(Object)
    //#input(void setItems(Object)): items
    //#input(void setItems(Object)): this
    //#output(void setItems(Object)): this.items
    //#post(void setItems(Object)): possibly_updated(this.items)
      this.items = (Collection)items;
    } else if (items instanceof Object[]) {
      this.items = Arrays.asList((Object[])items);
    }
  }
    //#selecttag.java:168: end of method: void net.sourceforge.pebble.web.tagext.SelectTag.setItems(Object)

  /**
   * Sets the name for the generated select control.
   *
   * @param name    the name as a String
   */
  public void setName(String name) {
    this.name = name;
    //#selecttag.java:176: method: void net.sourceforge.pebble.web.tagext.SelectTag.setName(String)
    //#input(void setName(String)): name
    //#input(void setName(String)): this
    //#output(void setName(String)): this.name
    //#post(void setName(String)): this.name == name
    //#post(void setName(String)): init'ed(this.name)
  }
    //#selecttag.java:177: end of method: void net.sourceforge.pebble.web.tagext.SelectTag.setName(String)

  /**
   * Sets the size of the generated select control.
   *
   * @param size    the size
   */
  public void setSize(int size) {
    this.size = size;
    //#selecttag.java:185: method: void net.sourceforge.pebble.web.tagext.SelectTag.setSize(int)
    //#input(void setSize(int)): size
    //#input(void setSize(int)): this
    //#output(void setSize(int)): this.size
    //#post(void setSize(int)): this.size == size
    //#post(void setSize(int)): init'ed(this.size)
  }
    //#selecttag.java:186: end of method: void net.sourceforge.pebble.web.tagext.SelectTag.setSize(int)

  /**
   * Sets the multiple attribute on the underlying select control.
   *
   * @param   multiple    a boolean
   */
  public void setMultiple(boolean multiple) {
    this.multiple = multiple;
    //#selecttag.java:194: method: void net.sourceforge.pebble.web.tagext.SelectTag.setMultiple(bool)
    //#input(void setMultiple(bool)): multiple
    //#input(void setMultiple(bool)): this
    //#output(void setMultiple(bool)): this.multiple
    //#post(void setMultiple(bool)): this.multiple == multiple
    //#post(void setMultiple(bool)): init'ed(this.multiple)
  }
    //#selecttag.java:195: end of method: void net.sourceforge.pebble.web.tagext.SelectTag.setMultiple(bool)

  /**
   * Sets the name of the property to display.
   *
   * @param label   the name of the label property
   */
  public void setLabel(String label) {
    this.label = label;
    //#selecttag.java:203: method: void net.sourceforge.pebble.web.tagext.SelectTag.setLabel(String)
    //#input(void setLabel(String)): label
    //#input(void setLabel(String)): this
    //#output(void setLabel(String)): this.label
    //#post(void setLabel(String)): this.label == label
    //#post(void setLabel(String)): init'ed(this.label)
  }
    //#selecttag.java:204: end of method: void net.sourceforge.pebble.web.tagext.SelectTag.setLabel(String)

  /**
   * Sets the name of the property to use as the hidden value.
   *
   * @param value   the name of the value property
   */
  public void setValue(String value) {
    this.value = value;
    //#selecttag.java:212: method: void net.sourceforge.pebble.web.tagext.SelectTag.setValue(String)
    //#input(void setValue(String)): this
    //#input(void setValue(String)): value
    //#output(void setValue(String)): this.value
    //#post(void setValue(String)): this.value == value
    //#post(void setValue(String)): init'ed(this.value)
  }
    //#selecttag.java:213: end of method: void net.sourceforge.pebble.web.tagext.SelectTag.setValue(String)

  /**
   * Sets the selected value.
   *
   * @param selected    the selected value
   */
  public void setSelected(Object selected) {
    this.selected = selected;
    //#selecttag.java:221: method: void net.sourceforge.pebble.web.tagext.SelectTag.setSelected(Object)
    //#input(void setSelected(Object)): selected
    //#input(void setSelected(Object)): this
    //#output(void setSelected(Object)): this.selected
    //#post(void setSelected(Object)): this.selected == selected
    //#post(void setSelected(Object)): init'ed(this.selected)
  }
    //#selecttag.java:222: end of method: void net.sourceforge.pebble.web.tagext.SelectTag.setSelected(Object)

}    //#output(net.sourceforge.pebble.web.tagext.SelectTag__static_init): __Descendant_Table[net/sourceforge/pebble/web/tagext/SelectTag]
    //#output(net.sourceforge.pebble.web.tagext.SelectTag__static_init): __Dispatch_Table.doStartTag()I
    //#output(net.sourceforge.pebble.web.tagext.SelectTag__static_init): __Dispatch_Table.setItems(Ljava/lang/Object;)V
    //#output(net.sourceforge.pebble.web.tagext.SelectTag__static_init): __Dispatch_Table.setLabel(Ljava/lang/String;)V
    //#output(net.sourceforge.pebble.web.tagext.SelectTag__static_init): __Dispatch_Table.setMultiple(Z)V
    //#output(net.sourceforge.pebble.web.tagext.SelectTag__static_init): __Dispatch_Table.setName(Ljava/lang/String;)V
    //#output(net.sourceforge.pebble.web.tagext.SelectTag__static_init): __Dispatch_Table.setSelected(Ljava/lang/Object;)V
    //#output(net.sourceforge.pebble.web.tagext.SelectTag__static_init): __Dispatch_Table.setSize(I)V
    //#output(net.sourceforge.pebble.web.tagext.SelectTag__static_init): __Dispatch_Table.setValue(Ljava/lang/String;)V
    //#post(net.sourceforge.pebble.web.tagext.SelectTag__static_init): __Descendant_Table[net/sourceforge/pebble/web/tagext/SelectTag] == &__Dispatch_Table
    //#post(net.sourceforge.pebble.web.tagext.SelectTag__static_init): __Dispatch_Table.doStartTag()I == &doStartTag
    //#post(net.sourceforge.pebble.web.tagext.SelectTag__static_init): __Dispatch_Table.setItems(Ljava/lang/Object;)V == &setItems
    //#post(net.sourceforge.pebble.web.tagext.SelectTag__static_init): __Dispatch_Table.setLabel(Ljava/lang/String;)V == &setLabel
    //#post(net.sourceforge.pebble.web.tagext.SelectTag__static_init): __Dispatch_Table.setMultiple(Z)V == &setMultiple
    //#post(net.sourceforge.pebble.web.tagext.SelectTag__static_init): __Dispatch_Table.setName(Ljava/lang/String;)V == &setName
    //#post(net.sourceforge.pebble.web.tagext.SelectTag__static_init): __Dispatch_Table.setSelected(Ljava/lang/Object;)V == &setSelected
    //#post(net.sourceforge.pebble.web.tagext.SelectTag__static_init): __Dispatch_Table.setSize(I)V == &setSize
    //#post(net.sourceforge.pebble.web.tagext.SelectTag__static_init): __Dispatch_Table.setValue(Ljava/lang/String;)V == &setValue
    //#selecttag.java:: end of method: net.sourceforge.pebble.web.tagext.SelectTag.net.sourceforge.pebble.web.tagext.SelectTag__static_init
    //#selecttag.java:: end of class: net.sourceforge.pebble.web.tagext.SelectTag
