View Javadoc

    1   package org.apache.turbine.util;
    2
    3   /*
    4    * Licensed to the Apache Software Foundation (ASF) under one
    5    * or more contributor license agreements.  See the NOTICE file
    6    * distributed with this work for additional information
    7    * regarding copyright ownership.  The ASF licenses this file
    8    * to you under the Apache License, Version 2.0 (the
    9    * "License"); you may not use this file except in compliance
    10   * with the License.  You may obtain a copy of the License at
    11   *
    12   *   http://www.apache.org/licenses/LICENSE-2.0
    13   *
    14   * Unless required by applicable law or agreed to in writing,
    15   * software distributed under the License is distributed on an
    16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    17   * KIND, either express or implied.  See the License for the
    18   * specific language governing permissions and limitations
    19   * under the License.
    20   */
    21
    22  import java.text.NumberFormat;
    23  import java.util.Calendar;
    24  import java.util.Date;
    25
    26  import org.apache.ecs.ConcreteElement;
    27  import org.apache.ecs.ElementContainer;
    28  import org.apache.ecs.html.Comment;
    29  import org.apache.ecs.html.Input;
    30  import org.apache.ecs.html.Option;
    31  import org.apache.ecs.html.Select;
    32
    33  /**
    34   * TimeSelector is a utility class to handle the creation of a set of
    35   * time drop-down menus.  The code is broken into a set of static methods
    36   * for quick and easy access to the individual select objects:
    37   *
    38   *  <pre>
    39   *  ElementContainer ec timeSelect = new ElementContainer();
    40   *  String myName = "mytime";
    41   *  ec.addElement(TimeSelector.getHourSelector(myName));
    42   *  ec.addElement(TimeSelector.getMinuteSelector(myName));
    43   *  ec.addElement(TimeSelector.getAMPMSelector(myName));
    44   *  </pre>
    45   *
    46   * There are also methods which will use attributes to build a
    47   * complete time selector in the default 12hr format (eg HH:MM am/pm):
    48   *
    49   *  <pre>
    50   *  TimeSelector ts = new TimeSelector(myName);
    51   *  timeSelect = ts.ecsOutput();
    52   *  </pre>
    53   *
    54   * Minutes/Seconds are by default rounded to the nearest 5 units
    55   * although this can be easily changed.
    56   *
    57   * 24hr TimeSelectors can also be produced. The following example
    58   * creates a full precision TimeSelector (eg HH:MM:SS):
    59   *
    60   *  <pre>
    61   *  TimeSelector ts = new TimeSelector(myName);
    62   *  ts.setTimeFormat(TimeSelector.TWENTY_FOUR_HOUR);
    63   *  ts.setMinuteInterval(1);
    64   *  ts.setSecondInterval(1);
    65   *  ts.setShowSeconds(true);
    66   *  timeSelect = ts.toString();
    67   *  </pre>
    68   *
    69   * @author <a href="mailto:ekkerbj@netscape.net">Jeffrey D. Brekke</a>
    70   * @author <a href="mailto:rich@thenetrevolution.com">Rich Aston</a>
    71   * @version $Id: TimeSelector.java 1078552 2011-03-06 19:58:46Z tv $
    72   */
    73  public class TimeSelector
    74  {
    75      /** Prefix for time names. */
    76      public static final String DEFAULT_PREFIX = "TimeSelector";
    77
    78      /** Suffix for hour parameter. */
    79      public static final String HOUR_SUFFIX = "_hour";
    80
    81      /** Suffix for minute parameter. */
    82      public static final String MINUTE_SUFFIX = "_minute";
    83
    84      /** Suffix for second parameter. */
    85      public static final String SECOND_SUFFIX = "_second";
    86
    87      /** Suffix for am/pm parameter. */
    88      public static final String AMPM_SUFFIX = "_ampm";
    89
    90      /** Constant for 12hr format */
    91      public static final int TWELVE_HOUR = 0;
    92
    93      /** Constant for 24hr format */
    94      public static final int TWENTY_FOUR_HOUR = 1;
    95
    96      /** TODO: Add ability to specify Locale. */
    97      private static final NumberFormat nbrFmt;
    98
    99      private static final int DEFAULT_MINUTE_INTERVAL = 5;
    100     private static final int DEFAULT_SECOND_INTERVAL = 5;
    101     private static final int DEFAULT_TIME_FORMAT = TWELVE_HOUR;
    102
    103     private int timeFormat = DEFAULT_TIME_FORMAT;
    104     private int minuteInterval = DEFAULT_MINUTE_INTERVAL;
    105     private int secondInterval = DEFAULT_SECOND_INTERVAL;
    106
    107     private Calendar useDate = null;
    108     private String selName = null;
    109     private String onChange = null;
    110     private boolean onChangeSet = false;
    111     private boolean showSeconds = false;
    112     private int setSeconds = 0;
    113
    114     static
    115     {
    116         nbrFmt = NumberFormat.getInstance();
    117         nbrFmt.setMinimumIntegerDigits(2);
    118         nbrFmt.setMaximumIntegerDigits(2);
    119     }
    120
    121     /**
    122      * Constructor defaults to current date/time and uses the default
    123      * prefix: <pre>TimeSelector.DEFAULT</pre>
    124      */
    125     public TimeSelector()
    126     {
    127         this.selName = DEFAULT_PREFIX;
    128         this.useDate = Calendar.getInstance();
    129         this.useDate.setTime(new Date());
    130     }
    131
    132     /**
    133      * Constructor, uses the date/time set in the calendar
    134      * passed in (with the date/time set correctly).
    135      *
    136      * @param selName A String with the selector name.
    137      * @param useDate A Calendar with a date/time.
    138      */
    139     public TimeSelector(String selName, Calendar useDate)
    140     {
    141         this.useDate = useDate;
    142         this.selName = selName;
    143     }
    144
    145     /**
    146      * Constructor defaults to current date/time.
    147      *
    148      * @param selName A String with the selector name.
    149      */
    150     public TimeSelector(String selName)
    151     {
    152         this.selName = selName;
    153         this.useDate = Calendar.getInstance();
    154         this.useDate.setTime(new Date());
    155     }
    156
    157     /**
    158      * Adds the onChange to all of <code>&lt;SELECT&gt;</code> tags.
    159      * This is limited to one function for all three popups and is only
    160      * used when the output() methods are used.  Individual getHour,
    161      * getMinute, getSecond, getAMPM static methods will not use this
    162      * setting.
    163      *
    164      * @param onChange A String to use for onChange attribute.  If null,
    165      * then nothing will be set.
    166      * @return A TimeSelector (self).
    167      */
    168     public TimeSelector setOnChange(String onChange)
    169     {
    170         if (onChange != null)
    171         {
    172             this.onChange = onChange;
    173             this.onChangeSet = true;
    174         }
    175         else
    176         {
    177             this.onChange = null;
    178             this.onChangeSet = false;
    179         }
    180         return this;
    181     }
    182
    183     /**
    184      * Select the second to be selected if the showSeconds(false) behavior
    185      * is used.  Individual getHour, getMinute, getSecond, getAMPM
    186      * static methods will not use this setting.
    187      *
    188      * @param seconds The second.
    189      * @return A TimeSelector (self).
    190      */
    191     public TimeSelector setSeconds(int seconds)
    192     {
    193         this.setSeconds = seconds;
    194         this.showSeconds = false;
    195         return this;
    196     }
    197
    198     /**
    199      * Set the interval between options in the minute select box.
    200      * Individual getHour, getMinute, getSecond, getAMPM static methods
    201      * will not use this setting.
    202      *
    203      * @param minutes Interval in minutes.
    204      * @return A TimeSelector (self).
    205      */
    206     public TimeSelector setMinuteInterval(int minutes)
    207     {
    208         this.minuteInterval = minutes;
    209         return this;
    210     }
    211
    212     /**
    213      * Set the interval between options in the second select box.
    214      * Individual getHour, getMinute, getSecond, getAMPM static methods
    215      * will not use this setting.
    216      *
    217      * @param seconds Interval in seconds.
    218      * @return A TimeSelector (self).
    219      */
    220     public TimeSelector setSecondInterval(int seconds)
    221     {
    222         this.secondInterval = seconds;
    223         return this;
    224     }
    225
    226     /**
    227      * Set the time format to 12 or 24 hour. Individual getHour,
    228      * getMinute, getSecond, getAMPM static methods
    229      * will not use this setting.
    230      *
    231      * @param format Time format.
    232      * @return A TimeSelector (self).
    233      */
    234     public TimeSelector setTimeFormat(int format)
    235     {
    236         this.timeFormat = format;
    237         return this;
    238     }
    239
    240     /**
    241      * Whether or not to show the seconds as a popup menu.  The seconds will
    242      * be a hidden parameter and the value set with setSeconds is used.
    243      * Individual getHour, getMinute, getSecond, getAMPM static methods
    244      * will not use this setting.
    245      *
    246      * @param show True if the second should be shown.
    247      * @return A TimeSelector (self).
    248      */
    249     public TimeSelector setShowSeconds(boolean show)
    250     {
    251         this.showSeconds = show;
    252         return this;
    253     }
    254
    255     /**
    256      * Set the selector name prefix.  Individual getHour, getMinute,
    257      * getSeconds, getAMPM static methods will not use this setting.
    258      *
    259      * @param selname A String with the select name prefix.
    260      */
    261     public void setSelName(String selName)
    262     {
    263         this.selName = selName;
    264     }
    265
    266     /**
    267      * Get the selector name prefix.
    268      *
    269      * @return A String with the select name prefix.
    270      */
    271     public String getSelName()
    272     {
    273         return selName;
    274     }
    275
    276     /**
    277      * Return a second selector.
    278      *
    279      * @param name The name to use for the selected second.
    280      * @return A select object with second options.
    281      */
    282     public static Select getSecondSelector(String name)
    283     {
    284         return (getSecondSelector(name, Calendar.getInstance()));
    285     }
    286
    287     /**
    288      * Return a second selector.
    289      *
    290      * @param name The name to use for the selected second.
    291      * @param now Calendar to start with.
    292      * @return A select object with second options.
    293      */
    294     public static Select getSecondSelector(String name, Calendar now)
    295     {
    296         return (getSecondSelector(name, Calendar.getInstance(),
    297                 DEFAULT_SECOND_INTERVAL));
    298     }
    299
    300     /**
    301      * Return a second selector.
    302      *
    303      * @param name The name to use for the selected second.
    304      * @param now Calendar to start with.
    305      * @param interval Interval between options.
    306      * @return A select object with second options.
    307      */
    308     public static Select getSecondSelector(String name, Calendar now,
    309                                            int interval)
    310     {
    311         Select secondSelect = new Select().setName(name);
    312
    313         for (int currentSecond = 0; currentSecond <= 59; currentSecond += interval)
    314         {
    315             Option o = new Option();
    316             o.addElement(nbrFmt.format(currentSecond));
    317             o.setValue(currentSecond);
    318             int nearestSecond =
    319                     ((now.get(Calendar.SECOND) / interval) * interval);
    320
    321             if (nearestSecond == currentSecond)
    322             {
    323                 o.setSelected(true);
    324             }
    325             secondSelect.addElement(o);
    326         }
    327         return (secondSelect);
    328     }
    329
    330     /**
    331      * Return a minute selector.
    332      *
    333      * @param name The name to use for the selected minute.
    334      * @return A select object with minute options.
    335      */
    336     public static Select getMinuteSelector(String name)
    337     {
    338         return (getMinuteSelector(name, Calendar.getInstance()));
    339     }
    340
    341     /**
    342      * Return a minute selector.
    343      *
    344      * @param name The name to use for the selected minute.
    345      * @return A select object with minute options.
    346      */
    347     public static Select getMinuteSelector(String name, Calendar now)
    348     {
    349         return (getMinuteSelector(name, now, DEFAULT_MINUTE_INTERVAL));
    350     }
    351
    352     /**
    353      * Return a minute selector.
    354      *
    355      * @param name The name to use for the selected minute.
    356      * @param now Calendar to start with.
    357      * @param interval Interval between options.
    358      * @return A select object with minute options.
    359      */
    360     public static Select getMinuteSelector(String name, Calendar now,
    361                                            int interval)
    362     {
    363         Select minuteSelect = new Select().setName(name);
    364
    365         for (int curMinute = 0; curMinute <= 59; curMinute += interval)
    366         {
    367             Option o = new Option();
    368             o.addElement(nbrFmt.format(curMinute));
    369             o.setValue(curMinute);
    370             int nearestMinute =
    371                     ((now.get(Calendar.MINUTE)) / interval) * interval;
    372
    373             if (nearestMinute == curMinute)
    374             {
    375                 o.setSelected(true);
    376             }
    377             minuteSelect.addElement(o);
    378         }
    379         return (minuteSelect);
    380     }
    381
    382     /**
    383      * Return an 12 hour selector.
    384      *
    385      * @param name The name to use for the selected hour.
    386      * @return A select object with all the hours.
    387      */
    388     public static Select getHourSelector(String name)
    389     {
    390         return (getHourSelector(name, Calendar.getInstance()));
    391     }
    392
    393     /**
    394      * Return an 12 hour selector.
    395      *
    396      * @param name The name to use for the selected hour.
    397      * @param now Calendar to start with.
    398      * @return A select object with all the hours.
    399      */
    400     public static Select getHourSelector(String name, Calendar now)
    401     {
    402         return (getHourSelector(name, Calendar.getInstance(), TWELVE_HOUR));
    403     }
    404
    405     /**
    406      * Return an hour selector (either 12hr or 24hr depending on
    407      * <code>format</code>.
    408      *
    409      * @param name The name to use for the selected hour.
    410      * @param now Calendar to start with.
    411      * @param format Time format.
    412      * @return A select object with all the hours.
    413      */
    414     @SuppressWarnings("cast")
    415     public static Select getHourSelector(String name, Calendar now, int format)
    416     {
    417         Select hourSelect = new Select().setName(name);
    418
    419         if (format == TWENTY_FOUR_HOUR)
    420         {
    421             for (int currentHour = 0; currentHour <= 23; currentHour++)
    422             {
    423                 Option o = new Option();
    424                 o.addElement(nbrFmt.format(currentHour));
    425                 o.setValue(currentHour);
    426                 if (now.get(Calendar.HOUR_OF_DAY) == currentHour)
    427                 {
    428                     o.setSelected(true);
    429                 }
    430                 hourSelect.addElement(o);
    431             }
    432         }
    433         else
    434         {
    435             for (int curHour = 1; curHour <= 12; curHour++)
    436             {
    437                 Option o = new Option();
    438
    439                 o.addElement(nbrFmt.format((long) curHour));
    440                 o.setValue(curHour);
    441                 if (now.get(Calendar.AM_PM) == Calendar.AM)
    442                 {
    443                     if (((now.get(Calendar.HOUR_OF_DAY)) == 0) &&
    444                             (curHour == 12))
    445                     {
    446                         o.setSelected(true);
    447                     }
    448                     else
    449                     {
    450                         if (now.get(Calendar.HOUR_OF_DAY) == curHour)
    451                         {
    452                             o.setSelected(true);
    453                         }
    454                     }
    455                 }
    456                 else
    457                 {
    458                     if (((now.get(Calendar.HOUR_OF_DAY)) == 12) &&
    459                             (curHour == 12))
    460                     {
    461                         o.setSelected(true);
    462                     }
    463                     else
    464                     {
    465                         if (now.get(Calendar.HOUR_OF_DAY) == curHour + 12)
    466                         {
    467                             o.setSelected(true);
    468                         }
    469                     }
    470                 }
    471                 hourSelect.addElement(o);
    472             }
    473         }
    474         return (hourSelect);
    475     }
    476
    477     /**
    478      * Return an am/pm selector.
    479      *
    480      * @param name The name to use for the selected am/pm.
    481      * @return A select object with am/pm
    482      */
    483     public static Select getAMPMSelector(String name)
    484     {
    485         Calendar c = Calendar.getInstance();
    486         c.setTime(new Date());
    487         return (getAMPMSelector(name, c));
    488     }
    489
    490     /**
    491      * Return an am/pm selector.
    492      *
    493      * @param name The name to use for the selected am/pm.
    494      * @param now Calendar to start with.
    495      * @return A select object with am/pm.
    496      */
    497     public static Select getAMPMSelector(String name,
    498                                          Calendar now)
    499     {
    500         Select ampmSelect = new Select().setName(name);
    501
    502         Option o = new Option();
    503         o.addElement("am");
    504         o.setValue(Calendar.AM);
    505         if (now.get(Calendar.AM_PM) == Calendar.AM)
    506         {
    507             o.setSelected(true);
    508         }
    509         ampmSelect.addElement(o);
    510
    511         o = new Option();
    512         o.addElement("pm");
    513         o.setValue(Calendar.PM);
    514         if (now.get(Calendar.AM_PM) == Calendar.PM)
    515         {
    516             o.setSelected(true);
    517         }
    518         ampmSelect.addElement(o);
    519
    520         return (ampmSelect);
    521     }
    522
    523     /**
    524      * Used to build the popupmenu in HTML.  The properties set in the
    525      * object are used to generate the correct HTML.  The selName
    526      * attribute is used to seed the names of the select lists.  The
    527      * names will be generated as follows:
    528      *
    529      * <ul>
    530      *  <li>selName + "_hour"</li>
    531      *  <li>selName + "_minute"</li>
    532      *  <li>selName + "_ampm"</li>
    533      * </ul>
    534      *
    535      * If onChange was set it is also used in the generation of the
    536      * output.  The output HTML will list the select lists in the
    537      * following order: hour minute ampm.
    538      *
    539      * If setShowSeconds(true) is used then an addition second select box
    540      * is produced after the minute select box.
    541      *
    542      * If setTimeFormat(TimeSelector.TWENTY_FOUR_HOUR) is used then
    543      * the ampm select box is omitted.
    544      *
    545      * @return A String with the correct HTML for the date selector.
    546      */
    547     public String output()
    548     {
    549         return (ecsOutput().toString());
    550     }
    551
    552     /**
    553      * Used to build the popupmenu in HTML.  The properties set in the
    554      * object are used to generate the correct HTML.  The selName
    555      * attribute is used to seed the names of the select lists.  The
    556      * names will be generated as follows:
    557      *
    558      * <ul>
    559      *  <li>selName + "_hour"</li>
    560      *  <li>selName + "_minute"</li>
    561      *  <li>selName + "_ampm"</li>
    562      * </ul>
    563      *
    564      * If onChange was set it is also used in the generation of the
    565      * output.  The output HTML will list the select lists in the
    566      * following order: hour minute ampm.
    567      *
    568      * If setShowSeconds(true) is used then an addition second select box
    569      * is produced after the minute select box.
    570      *
    571      * If setTimeFormat(TimeSelector.TWENTY_FOUR_HOUR) is used then
    572      * the ampm select box is omitted.
    573      *
    574      * @return A String with the correct HTML for the date selector.
    575      */
    576     @Override
    577     public String toString()
    578     {
    579         return (ecsOutput().toString());
    580     }
    581
    582     /**
    583      * Return an ECS container with the select objects inside.
    584      *
    585      * @return An ECS container.
    586      */
    587     public ElementContainer ecsOutput()
    588     {
    589         if (this.useDate == null)
    590         {
    591             this.useDate = Calendar.getInstance();
    592             this.useDate.setTime(new Date());
    593         }
    594
    595         ConcreteElement secondSelect = null;
    596
    597         Select ampmSelect = getAMPMSelector(selName + AMPM_SUFFIX, useDate);
    598
    599         Select hourSelect = getHourSelector(selName + HOUR_SUFFIX,
    600                 useDate, this.timeFormat);
    601
    602         Select minuteSelect = getMinuteSelector(selName + MINUTE_SUFFIX,
    603                 useDate, this.minuteInterval);
    604
    605         if (this.showSeconds)
    606         {
    607             Select tmp = getSecondSelector(selName + SECOND_SUFFIX, useDate,
    608                     this.secondInterval);
    609             if (onChangeSet)
    610                 tmp.setOnChange(onChange);
    611             secondSelect = tmp;
    612         }
    613         else
    614         {
    615             secondSelect = new Input(Input.hidden,
    616                     selName + SECOND_SUFFIX,
    617                     setSeconds);
    618         }
    619
    620         if (onChangeSet)
    621         {
    622             hourSelect.setOnChange(onChange);
    623             minuteSelect.setOnChange(onChange);
    624             ampmSelect.setOnChange(onChange);
    625         }
    626
    627         ElementContainer ec = new ElementContainer();
    628         ec.addElement(new Comment(
    629                 "== BEGIN org.apache.turbine.util.TimeSelector.ecsOutput() =="));
    630         ec.addElement(hourSelect);
    631         ec.addElement(":");
    632         ec.addElement(minuteSelect);
    633         if (this.showSeconds == true)
    634             ec.addElement(":");
    635         ec.addElement(secondSelect);
    636         if (this.timeFormat == TimeSelector.TWELVE_HOUR)
    637         {
    638             ec.addElement(ampmSelect);
    639         }
    640         ec.addElement(new Comment(
    641                 "== END org.apache.turbine.util.TimeSelector.ecsOutput() =="));
    642         return (ec);
    643     }
    644 }