    001    package org.apache.turbine.util;
    002
    003
    004    /*
    005     * Licensed to the Apache Software Foundation (ASF) under one
    006     * or more contributor license agreements.  See the NOTICE file
    007     * distributed with this work for additional information
    008     * regarding copyright ownership.  The ASF licenses this file
    009     * to you under the Apache License, Version 2.0 (the
    010     * "License"); you may not use this file except in compliance
    011     * with the License.  You may obtain a copy of the License at
    012     *
    013     *   http://www.apache.org/licenses/LICENSE-2.0
    014     *
    015     * Unless required by applicable law or agreed to in writing,
    016     * software distributed under the License is distributed on an
    017     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    018     * KIND, either express or implied.  See the License for the
    019     * specific language governing permissions and limitations
    020     * under the License.
    021     */
    022
    023
    024    import java.text.DateFormatSymbols;
    025    import java.util.Calendar;
    026    import java.util.Date;
    027
    028    import org.apache.ecs.ConcreteElement;
    029    import org.apache.ecs.ElementContainer;
    030    import org.apache.ecs.html.Input;
    031    import org.apache.ecs.html.Option;
    032    import org.apache.ecs.html.Select;
    033
    034    /**
    035     * DateSelector is a utility class to handle the creation of a set of
    036     * date popup menus.  The code is broken into a set of static methods
    037     * for quick and easy access to the individual select objects:
    038     *
    039     *  <pre>
    040     *  ElementContainer ec dateSelect = new ElementContainer();
    041     *  String myName = "mydate";
    042     *  ec.addElement(DateSelector.getMonthSelector(myName));
    043     *  ec.addElement(DateSelector.getDaySelector(myName));
    044     *  ec.addElement(DateSelector.getYearSelector(myName));
    045     *  </pre>
    046     *
    047     * There are also methods which will use attributes to build a
    048     * complete month,day,year selector:
    049     *
    050     *  <pre>
    051     *  DateSelector ds = new DateSelector(myName);
    052     *  dateSelect = ds.ecsOutput();
    053     *  </pre>
    054     *
    055     * The above element container would use the onChange setting and may
    056     * hide the selected day if set via showDays().<br>
    057     *
    058     * @author <a href="mailto:ekkerbj@netscape.net">Jeffrey D. Brekke</a>
    059     * @author <a href="mailto:jon@clearink.com">Jon S. Stevens</a>
    060     * @author <a href="mailto:leon@clearink.com">Leon Atkinson</a>
    061     * @version $Id: DateSelector.java 615328 2008-01-25 20:25:05Z tv $
    062     */
    063    public class DateSelector
    064    {
    065        /** Prefix for date names. */
    066        public static final String DEFAULT_PREFIX = "DateSelector";
    067
    068        /** Suffix for day parameter. */
    069        public static final String DAY_SUFFIX = "_day";
    070
    071        /** Suffix for month parameter. */
    072        public static final String MONTH_SUFFIX = "_month";
    073
    074        /** Suffix for year parameter. */
    075        public static final String YEAR_SUFFIX = "_year";
    076
    077        private Calendar useDate = null;
    078        private String selName = null;
    079        private static final String[] monthName =
    080                new DateFormatSymbols().getMonths();
    081        private String onChange = null;
    082        private boolean onChangeSet = false;
    083        private boolean showDays = true;
    084        private int setDay = 0;
    085        private boolean useYears = false;
    086        private int firstYear = 0;
    087        private int lastYear = 0;
    088        private int selectedYear = 0;
    089
    090        /**
    091         * Constructor defaults to current date and uses the default
    092         * prefix: <pre>DateSelector.DEFAULT</pre>
    093         */
    094        public DateSelector()
    095        {
    096            this.selName = DEFAULT_PREFIX;
    097            this.useDate = Calendar.getInstance();
    098            this.useDate.setTime(new Date());
    099        }
    100
    101        /**
    102         * Constructor, uses the date set in a calendar that has been
    103         * already passed in (with the date set correctly).
    104         *
    105         * @param selName A String with the selector name.
    106         * @param useDate A Calendar with a date.
    107         */
    108        public DateSelector(String selName, Calendar useDate)
    109        {
    110            this.useDate = useDate;
    111            this.selName = selName;
    112        }
    113
    114        /**
    115         * Constructor defaults to current date.
    116         *
    117         * @param selName A String with the selector name.
    118         */
    119        public DateSelector(String selName)
    120        {
    121            this.selName = selName;
    122            this.useDate = Calendar.getInstance();
    123            this.useDate.setTime(new Date());
    124        }
    125
    126        /**
    127         * Adds the onChange to all of &lt;SELECT&gt; tags.  This is limited to
    128         * one function for all three popups and is only used when the
    129         * output() methods are used.  Individual getMonth, getDay,
    130         * getYear static methods will not use this setting.
    131         *
    132         * @param string A String to use for onChange attribute.  If null,
    133         * then nothing will be set.
    134         * @return A DateSelector (self).
    135         */
    136        public DateSelector setOnChange(String onChange)
    137        {
    138            if (onChange != null)
    139            {
    140                this.onChange = onChange;
    141                this.onChangeSet = true;
    142            }
    143            else
    144            {
    145                this.onChange = null;
    146                this.onChangeSet = false;
    147            }
    148            return this;
    149        }
    150
    151        /**
    152         * Select the day to be selected if the showDays(false) behavior
    153         * is used.  Individual getMonth, getDay, getYear static methods
    154         * will not use this setting.
    155         *
    156         * @param day The day.
    157         * @return A DateSelector (self).
    158         */
    159        public DateSelector setDay(int day)
    160        {
    161            this.setDay = day;
    162            this.showDays = false;
    163            return this;
    164        }
    165
    166        /**
    167         * Whether or not to show the days as a popup menu.  The days will
    168         * be a hidden parameter and the value set with setDay is used.
    169         * Individual getMonth, getDay, getYear static methods will not
    170         * use this setting.
    171         *
    172         * @param show True if the day should be shown.
    173         * @return A DateSelector (self).
    174         */
    175        public DateSelector setShowDay(boolean show)
    176        {
    177            this.showDays = false;
    178            return this;
    179        }
    180
    181        /**
    182         * Set the selector name prefix.  Individual getMonth, getDay,
    183         * getYear static methods will not use this setting.
    184         *
    185         * @param selname A String with the select name prefix.
    186         */
    187        public void setSelName(String selName)
    188        {
    189            this.selName = selName;
    190        }
    191
    192        /**
    193         * Get the selector name prefix.
    194         *
    195         * @return A String with the select name prefix.
    196         */
    197        public String getSelName()
    198        {
    199            return selName;
    200        }
    201
    202        /**
    203         * Return a month selector.
    204         *
    205         * @param name The name to use for the selected month.
    206         * @return A select object with all the months.
    207         */
    208        public static Select getMonthSelector(String name)
    209        {
    210            return (getMonthSelector(name, Calendar.getInstance()));
    211        }
    212
    213        /**
    214         * Return a month selector.
    215         *
    216         * Note: The values of the month placed into the select list are
    217         * the month integers starting at 0 (ie: if the user selects
    218         * February, the selected value will be 1).
    219         *
    220         * @param name The name to use for the selected month.
    221         * @param now Calendar to start with.
    222         * @return A select object with all the months.
    223         */
    224        public static Select getMonthSelector(String name, Calendar now)
    225        {
    226            Select monthSelect = new Select().setName(name);
    227
    228            for (int curMonth = 0; curMonth <= 11; curMonth++)
    229            {
    230                Option o = new Option();
    231                o.addElement(monthName[curMonth]);
    232                o.setValue(curMonth);
    233                if ((now.get(Calendar.MONTH)) == curMonth)
    234                {
    235                    o.setSelected(true);
    236                }
    237                monthSelect.addElement(o);
    238            }
    239            return (monthSelect);
    240        }
    241
    242        /**
    243         * Return a day selector.
    244         *
    245         * @param name The name to use for the selected day.
    246         * @return A select object with all the days in a month.
    247         */
    248        public static Select getDaySelector(String name)
    249        {
    250            return (getDaySelector(name, Calendar.getInstance()));
    251        }
    252
    253        /**
    254         * Return a day selector.
    255         *
    256         * @param name The name to use for the selected day.
    257         * @param now Calendar to start with.
    258         * @return A select object with all the days in a month.
    259         */
    260        public static Select getDaySelector(String name, Calendar now)
    261        {
    262            Select daySelect = new Select().setName(name);
    263
    264            for (int currentDay = 1; currentDay <= 31; currentDay++)
    265            {
    266                Option o = new Option();
    267                o.addElement(Integer.toString(currentDay));
    268                o.setValue(currentDay);
    269                if (now.get(Calendar.DAY_OF_MONTH) == currentDay)
    270                {
    271                    o.setSelected(true);
    272                }
    273                daySelect.addElement(o);
    274            }
    275            return (daySelect);
    276        }
    277
    278        /**
    279         * Return a year selector.
    280         *
    281         * @param name The name to use for the selected year.
    282         * @return A select object with all the years starting five years
    283         * from now and five years before this year.
    284         */
    285        public static Select getYearSelector(String name)
    286        {
    287            return (getYearSelector(name, Calendar.getInstance()));
    288        }
    289
    290        /**
    291         * Return a year selector.
    292         *
    293         * @param name The name to use for the selected year.
    294         * @param now Calendar to start with.
    295         * @return A select object with all the years starting five years
    296         * from now and five years before this year.
    297         */
    298        public static Select getYearSelector(String name, Calendar now)
    299        {
    300            int startYear = now.get(Calendar.YEAR);
    301            return (getYearSelector(name, startYear - 5, startYear + 5, startYear));
    302        }
    303
    304        /**
    305         * Return a year selector.
    306         *
    307         * @param name The name to use for the selected year.
    308         * @param firstYear the first (earliest) year in the selector.
    309         * @param lastYear the last (latest) year in the selector.
    310         * @param selectedYear the year initially selected in the Select html.
    311         * @return A select object with all the years from firstyear
    312         * to lastyear..
    313         */
    314        public static Select getYearSelector(String name,
    315                                             int firstYear, int lastYear,
    316                                             int selectedYear)
    317        {
    318            Select yearSelect = new Select().setName(name);
    319
    320            for (int currentYear = firstYear;
    321                 currentYear <= lastYear;
    322
    323                 currentYear++)
    324            {
    325                Option o = new Option();
    326                o.addElement(Integer.toString(currentYear));
    327                o.setValue(currentYear);
    328                if (currentYear == selectedYear)
    329                {
    330                    o.setSelected(true);
    331                }
    332                yearSelect.addElement(o);
    333            }
    334            return (yearSelect);
    335        }
    336
    337        /**
    338         * Select the day to be selected if the showDays(false) behavior
    339         * is used.  Individual getMonth, getDay, getYear static methods
    340         * will not use this setting.
    341         *
    342         * @param day The day.
    343         * @return A DateSelector (self).
    344         */
    345        public boolean setYear(int firstYear, int lastYear, int selectedYear)
    346        {
    347            if (firstYear <= lastYear && firstYear <= selectedYear
    348                    && selectedYear <= lastYear)
    349            {
    350                this.useYears = true;
    351                this.firstYear = firstYear;
    352                this.lastYear = lastYear;
    353                this.selectedYear = selectedYear;
    354                return true;
    355            }
    356            else
    357            {
    358                return false;
    359            }
    360        }
    361
    362        /**
    363         * Used to build the popupmenu in HTML.  The properties set in the
    364         * object are used to generate the correct HTML.  The selName
    365         * attribute is used to seed the names of the select lists.  The
    366         * names will be generated as follows:
    367         *
    368         * <ul>
    369         *  <li>selName + "_month"</li>
    370         *  <li>selName + "_day"</li>
    371         *  <li>selName + "_year"</li>
    372         * </ul>
    373         *
    374         * If onChange was set it is also used in the generation of the
    375         * output.  The output HTML will list the select lists in the
    376         * following order: month day year.
    377         *
    378         * @return A String with the correct HTML for the date selector.
    379         */
    380        public String output()
    381        {
    382            return (ecsOutput().toString());
    383        }
    384
    385        /**
    386         * Used to build the popupmenu in HTML.  The properties set in the
    387         * object are used to generate the correct HTML.  The selName
    388         * attribute is used to seed the names of the select lists.  The
    389         * names will be generated as follows:
    390         *
    391         * <ul>
    392         *  <li>selName + "_month"</li>
    393         *  <li>selName + "_day"</li>
    394         *  <li>selName + "_year"</li>
    395         * </ul>
    396         *
    397         * The output HTML will list the select lists in the following
    398         * order: month day year.
    399         *
    400         * @return A String with the correct HTML for the date selector.
    401         */
    402        public String toString()
    403        {
    404            return (ecsOutput().toString());
    405        }
    406
    407        /*
    408         * Return an ECS container with the month, day, and year select
    409         * objects inside.
    410         *
    411         * @return An ECS container.
    412         */
    413        public ElementContainer ecsOutput()
    414        {
    415            if (this.useDate == null)
    416            {
    417                this.useDate.setTime(new Date());
    418            }
    419
    420            Select monthSelect = getMonthSelector(selName + MONTH_SUFFIX, useDate);
    421            ConcreteElement daySelect = null;
    422            if (!showDays)
    423            {
    424                daySelect = new Input(Input.hidden, selName + DAY_SUFFIX, setDay);
    425            }
    426            else
    427            {
    428                Select tmp = getDaySelector(selName + DAY_SUFFIX, useDate);
    429                if (onChangeSet)
    430                {
    431                    tmp.setOnChange(onChange);
    432                }
    433                daySelect = tmp;
    434            }
    435            Select yearSelect = null;
    436            if (useYears)
    437            {
    438                yearSelect = getYearSelector(selName + YEAR_SUFFIX,
    439                        firstYear, lastYear, selectedYear);
    440            }
    441            else
    442            {
    443                yearSelect = getYearSelector(selName + YEAR_SUFFIX, useDate);
    444            }
    445            if (onChangeSet)
    446            {
    447                monthSelect.setOnChange(onChange);
    448                yearSelect.setOnChange(onChange);
    449            }
    450            ElementContainer ec = new ElementContainer();
    451            // ec.addElement(new Comment("== BEGIN org.apache.turbine.util.DateSelector.ecsOutput() =="));
    452            ec.addElement(monthSelect);
    453            ec.addElement(daySelect);
    454            ec.addElement(yearSelect);
    455            // ec.addElement(new Comment("== END org.apache.turbine.util.DateSelector.ecsOutput() =="));
    456            return (ec);
    457        }
    458    }