001: package org.apache.turbine.util;
002:
003: /*
004: * Licensed to the Apache Software Foundation (ASF) under one
005: * or more contributor license agreements. See the NOTICE file
006: * distributed with this work for additional information
007: * regarding copyright ownership. The ASF licenses this file
008: * to you under the Apache License, Version 2.0 (the
009: * "License"); you may not use this file except in compliance
010: * with the License. You may obtain a copy of the License at
011: *
012: * http://www.apache.org/licenses/LICENSE-2.0
013: *
014: * Unless required by applicable law or agreed to in writing,
015: * software distributed under the License is distributed on an
016: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017: * KIND, either express or implied. See the License for the
018: * specific language governing permissions and limitations
019: * under the License.
020: */
021:
022: import java.text.NumberFormat;
023: import java.util.Calendar;
024: import java.util.Date;
025:
026: import org.apache.ecs.ConcreteElement;
027: import org.apache.ecs.ElementContainer;
028: import org.apache.ecs.html.Comment;
029: import org.apache.ecs.html.Input;
030: import org.apache.ecs.html.Option;
031: import org.apache.ecs.html.Select;
032:
033: /**
034: * TimeSelector is a utility class to handle the creation of a set of
035: * time drop-down menus. The code is broken into a set of static methods
036: * for quick and easy access to the individual select objects:
037: *
038: * <pre>
039: * ElementContainer ec timeSelect = new ElementContainer();
040: * String myName = "mytime";
041: * ec.addElement(TimeSelector.getHourSelector(myName));
042: * ec.addElement(TimeSelector.getMinuteSelector(myName));
043: * ec.addElement(TimeSelector.getAMPMSelector(myName));
044: * </pre>
045: *
046: * There are also methods which will use attributes to build a
047: * complete time selector in the default 12hr format (eg HH:MM am/pm):
048: *
049: * <pre>
050: * TimeSelector ts = new TimeSelector(myName);
051: * timeSelect = ts.ecsOutput();
052: * </pre>
053: *
054: * Minutes/Seconds are by default rounded to the nearest 5 units
055: * although this can be easily changed.
056: *
057: * 24hr TimeSelectors can also be produced. The following example
058: * creates a full precision TimeSelector (eg HH:MM:SS):
059: *
060: * <pre>
061: * TimeSelector ts = new TimeSelector(myName);
062: * ts.setTimeFormat(TimeSelector.TWENTY_FOUR_HOUR);
063: * ts.setMinuteInterval(1);
064: * ts.setSecondInterval(1);
065: * ts.setShowSeconds(true);
066: * timeSelect = ts.toString();
067: * </pre>
068: *
069: * @author <a href="mailto:ekkerbj@netscape.net">Jeffrey D. Brekke</a>
070: * @author <a href="mailto:rich@thenetrevolution.com">Rich Aston</a>
071: * @version $Id: TimeSelector.java 534527 2007-05-02 16:10:59Z tv $
072: */
073: public class TimeSelector {
074: /** Prefix for time names. */
075: public static final String DEFAULT_PREFIX = "TimeSelector";
076:
077: /** Suffix for hour parameter. */
078: public static final String HOUR_SUFFIX = "_hour";
079:
080: /** Suffix for minute parameter. */
081: public static final String MINUTE_SUFFIX = "_minute";
082:
083: /** Suffix for second parameter. */
084: public static final String SECOND_SUFFIX = "_second";
085:
086: /** Suffix for am/pm parameter. */
087: public static final String AMPM_SUFFIX = "_ampm";
088:
089: /** Constant for 12hr format */
090: public static final int TWELVE_HOUR = 0;
091:
092: /** Constant for 24hr format */
093: public static final int TWENTY_FOUR_HOUR = 1;
094:
095: /** TODO: Add ability to specify Locale. */
096: private static final NumberFormat nbrFmt;
097:
098: private static final int DEFAULT_MINUTE_INTERVAL = 5;
099: private static final int DEFAULT_SECOND_INTERVAL = 5;
100: private static final int DEFAULT_TIME_FORMAT = TWELVE_HOUR;
101:
102: private int timeFormat = DEFAULT_TIME_FORMAT;
103: private int minuteInterval = DEFAULT_MINUTE_INTERVAL;
104: private int secondInterval = DEFAULT_SECOND_INTERVAL;
105:
106: private Calendar useDate = null;
107: private String selName = null;
108: private String onChange = null;
109: private boolean onChangeSet = false;
110: private boolean showSeconds = false;
111: private int setSeconds = 0;
112:
113: static {
114: nbrFmt = NumberFormat.getInstance();
115: nbrFmt.setMinimumIntegerDigits(2);
116: nbrFmt.setMaximumIntegerDigits(2);
117: }
118:
119: /**
120: * Constructor defaults to current date/time and uses the default
121: * prefix: <pre>TimeSelector.DEFAULT</pre>
122: */
123: public TimeSelector() {
124: this .selName = DEFAULT_PREFIX;
125: this .useDate = Calendar.getInstance();
126: this .useDate.setTime(new Date());
127: }
128:
129: /**
130: * Constructor, uses the date/time set in the calendar
131: * passed in (with the date/time set correctly).
132: *
133: * @param selName A String with the selector name.
134: * @param useDate A Calendar with a date/time.
135: */
136: public TimeSelector(String selName, Calendar useDate) {
137: this .useDate = useDate;
138: this .selName = selName;
139: }
140:
141: /**
142: * Constructor defaults to current date/time.
143: *
144: * @param selName A String with the selector name.
145: */
146: public TimeSelector(String selName) {
147: this .selName = selName;
148: this .useDate = Calendar.getInstance();
149: this .useDate.setTime(new Date());
150: }
151:
152: /**
153: * Adds the onChange to all of <code><SELECT></code> tags.
154: * This is limited to one function for all three popups and is only
155: * used when the output() methods are used. Individual getHour,
156: * getMinute, getSecond, getAMPM static methods will not use this
157: * setting.
158: *
159: * @param onChange A String to use for onChange attribute. If null,
160: * then nothing will be set.
161: * @return A TimeSelector (self).
162: */
163: public TimeSelector setOnChange(String onChange) {
164: if (onChange != null) {
165: this .onChange = onChange;
166: this .onChangeSet = true;
167: } else {
168: this .onChange = null;
169: this .onChangeSet = false;
170: }
171: return this ;
172: }
173:
174: /**
175: * Select the second to be selected if the showSeconds(false) behavior
176: * is used. Individual getHour, getMinute, getSecond, getAMPM
177: * static methods will not use this setting.
178: *
179: * @param seconds The second.
180: * @return A TimeSelector (self).
181: */
182: public TimeSelector setSeconds(int seconds) {
183: this .setSeconds = seconds;
184: this .showSeconds = false;
185: return this ;
186: }
187:
188: /**
189: * Set the interval between options in the minute select box.
190: * Individual getHour, getMinute, getSecond, getAMPM static methods
191: * will not use this setting.
192: *
193: * @param minutes Interval in minutes.
194: * @return A TimeSelector (self).
195: */
196: public TimeSelector setMinuteInterval(int minutes) {
197: this .minuteInterval = minutes;
198: return this ;
199: }
200:
201: /**
202: * Set the interval between options in the second select box.
203: * Individual getHour, getMinute, getSecond, getAMPM static methods
204: * will not use this setting.
205: *
206: * @param seconds Interval in seconds.
207: * @return A TimeSelector (self).
208: */
209: public TimeSelector setSecondInterval(int seconds) {
210: this .secondInterval = seconds;
211: return this ;
212: }
213:
214: /**
215: * Set the time format to 12 or 24 hour. Individual getHour,
216: * getMinute, getSecond, getAMPM static methods
217: * will not use this setting.
218: *
219: * @param format Time format.
220: * @return A TimeSelector (self).
221: */
222: public TimeSelector setTimeFormat(int format) {
223: this .timeFormat = format;
224: return this ;
225: }
226:
227: /**
228: * Whether or not to show the seconds as a popup menu. The seconds will
229: * be a hidden parameter and the value set with setSeconds is used.
230: * Individual getHour, getMinute, getSecond, getAMPM static methods
231: * will not use this setting.
232: *
233: * @param show True if the second should be shown.
234: * @return A TimeSelector (self).
235: */
236: public TimeSelector setShowSeconds(boolean show) {
237: this .showSeconds = show;
238: return this ;
239: }
240:
241: /**
242: * Set the selector name prefix. Individual getHour, getMinute,
243: * getSeconds, getAMPM static methods will not use this setting.
244: *
245: * @param selname A String with the select name prefix.
246: */
247: public void setSelName(String selName) {
248: this .selName = selName;
249: }
250:
251: /**
252: * Get the selector name prefix.
253: *
254: * @return A String with the select name prefix.
255: */
256: public String getSelName() {
257: return selName;
258: }
259:
260: /**
261: * Return a second selector.
262: *
263: * @param name The name to use for the selected second.
264: * @return A select object with second options.
265: */
266: public static Select getSecondSelector(String name) {
267: return (getSecondSelector(name, Calendar.getInstance()));
268: }
269:
270: /**
271: * Return a second selector.
272: *
273: * @param name The name to use for the selected second.
274: * @param now Calendar to start with.
275: * @return A select object with second options.
276: */
277: public static Select getSecondSelector(String name, Calendar now) {
278: return (getSecondSelector(name, Calendar.getInstance(),
279: DEFAULT_SECOND_INTERVAL));
280: }
281:
282: /**
283: * Return a second selector.
284: *
285: * @param name The name to use for the selected second.
286: * @param now Calendar to start with.
287: * @param interval Interval between options.
288: * @return A select object with second options.
289: */
290: public static Select getSecondSelector(String name, Calendar now,
291: int interval) {
292: Select secondSelect = new Select().setName(name);
293:
294: for (int currentSecond = 0; currentSecond <= 59; currentSecond += interval) {
295: Option o = new Option();
296: o.addElement(nbrFmt.format(currentSecond));
297: o.setValue(currentSecond);
298: int nearestSecond = ((now.get(Calendar.SECOND) / interval) * interval);
299:
300: if (nearestSecond == currentSecond) {
301: o.setSelected(true);
302: }
303: secondSelect.addElement(o);
304: }
305: return (secondSelect);
306: }
307:
308: /**
309: * Return a minute selector.
310: *
311: * @param name The name to use for the selected minute.
312: * @return A select object with minute options.
313: */
314: public static Select getMinuteSelector(String name) {
315: return (getMinuteSelector(name, Calendar.getInstance()));
316: }
317:
318: /**
319: * Return a minute selector.
320: *
321: * @param name The name to use for the selected minute.
322: * @return A select object with minute options.
323: */
324: public static Select getMinuteSelector(String name, Calendar now) {
325: return (getMinuteSelector(name, now, DEFAULT_MINUTE_INTERVAL));
326: }
327:
328: /**
329: * Return a minute selector.
330: *
331: * @param name The name to use for the selected minute.
332: * @param now Calendar to start with.
333: * @param interval Interval between options.
334: * @return A select object with minute options.
335: */
336: public static Select getMinuteSelector(String name, Calendar now,
337: int interval) {
338: Select minuteSelect = new Select().setName(name);
339:
340: for (int curMinute = 0; curMinute <= 59; curMinute += interval) {
341: Option o = new Option();
342: o.addElement(nbrFmt.format(curMinute));
343: o.setValue(curMinute);
344: int nearestMinute = ((now.get(Calendar.MINUTE)) / interval)
345: * interval;
346:
347: if (nearestMinute == curMinute) {
348: o.setSelected(true);
349: }
350: minuteSelect.addElement(o);
351: }
352: return (minuteSelect);
353: }
354:
355: /**
356: * Return an 12 hour selector.
357: *
358: * @param name The name to use for the selected hour.
359: * @return A select object with all the hours.
360: */
361: public static Select getHourSelector(String name) {
362: return (getHourSelector(name, Calendar.getInstance()));
363: }
364:
365: /**
366: * Return an 12 hour selector.
367: *
368: * @param name The name to use for the selected hour.
369: * @param now Calendar to start with.
370: * @return A select object with all the hours.
371: */
372: public static Select getHourSelector(String name, Calendar now) {
373: return (getHourSelector(name, Calendar.getInstance(),
374: TWELVE_HOUR));
375: }
376:
377: /**
378: * Return an hour selector (either 12hr or 24hr depending on
379: * <code>format</code>.
380: *
381: * @param name The name to use for the selected hour.
382: * @param now Calendar to start with.
383: * @param format Time format.
384: * @return A select object with all the hours.
385: */
386: public static Select getHourSelector(String name, Calendar now,
387: int format) {
388: Select hourSelect = new Select().setName(name);
389:
390: if (format == TWENTY_FOUR_HOUR) {
391: for (int currentHour = 0; currentHour <= 23; currentHour++) {
392: Option o = new Option();
393: o.addElement(nbrFmt.format(currentHour));
394: o.setValue(currentHour);
395: if (now.get(Calendar.HOUR_OF_DAY) == currentHour) {
396: o.setSelected(true);
397: }
398: hourSelect.addElement(o);
399: }
400: } else {
401: for (int curHour = 1; curHour <= 12; curHour++) {
402: Option o = new Option();
403:
404: o.addElement(nbrFmt.format((long) curHour));
405: o.setValue(curHour);
406: if (now.get(Calendar.AM_PM) == Calendar.AM) {
407: if (((now.get(Calendar.HOUR_OF_DAY)) == 0)
408: && (curHour == 12)) {
409: o.setSelected(true);
410: } else {
411: if (now.get(Calendar.HOUR_OF_DAY) == curHour) {
412: o.setSelected(true);
413: }
414: }
415: } else {
416: if (((now.get(Calendar.HOUR_OF_DAY)) == 12)
417: && (curHour == 12)) {
418: o.setSelected(true);
419: } else {
420: if (now.get(Calendar.HOUR_OF_DAY) == curHour + 12) {
421: o.setSelected(true);
422: }
423: }
424: }
425: hourSelect.addElement(o);
426: }
427: }
428: return (hourSelect);
429: }
430:
431: /**
432: * Return an am/pm selector.
433: *
434: * @param name The name to use for the selected am/pm.
435: * @return A select object with am/pm
436: */
437: public static Select getAMPMSelector(String name) {
438: Calendar c = Calendar.getInstance();
439: c.setTime(new Date());
440: return (getAMPMSelector(name, c));
441: }
442:
443: /**
444: * Return an am/pm selector.
445: *
446: * @param name The name to use for the selected am/pm.
447: * @param now Calendar to start with.
448: * @return A select object with am/pm.
449: */
450: public static Select getAMPMSelector(String name, Calendar now) {
451: Select ampmSelect = new Select().setName(name);
452:
453: Option o = new Option();
454: o.addElement("am");
455: o.setValue(Calendar.AM);
456: if (now.get(Calendar.AM_PM) == Calendar.AM) {
457: o.setSelected(true);
458: }
459: ampmSelect.addElement(o);
460:
461: o = new Option();
462: o.addElement("pm");
463: o.setValue(Calendar.PM);
464: if (now.get(Calendar.AM_PM) == Calendar.PM) {
465: o.setSelected(true);
466: }
467: ampmSelect.addElement(o);
468:
469: return (ampmSelect);
470: }
471:
472: /**
473: * Used to build the popupmenu in HTML. The properties set in the
474: * object are used to generate the correct HTML. The selName
475: * attribute is used to seed the names of the select lists. The
476: * names will be generated as follows:
477: *
478: * <ul>
479: * <li>selName + "_hour"</li>
480: * <li>selName + "_minute"</li>
481: * <li>selName + "_ampm"</li>
482: * </ul>
483: *
484: * If onChange was set it is also used in the generation of the
485: * output. The output HTML will list the select lists in the
486: * following order: hour minute ampm.
487: *
488: * If setShowSeconds(true) is used then an addition second select box
489: * is produced after the minute select box.
490: *
491: * If setTimeFormat(TimeSelector.TWENTY_FOUR_HOUR) is used then
492: * the ampm select box is omitted.
493: *
494: * @return A String with the correct HTML for the date selector.
495: */
496: public String output() {
497: return (ecsOutput().toString());
498: }
499:
500: /**
501: * Used to build the popupmenu in HTML. The properties set in the
502: * object are used to generate the correct HTML. The selName
503: * attribute is used to seed the names of the select lists. The
504: * names will be generated as follows:
505: *
506: * <ul>
507: * <li>selName + "_hour"</li>
508: * <li>selName + "_minute"</li>
509: * <li>selName + "_ampm"</li>
510: * </ul>
511: *
512: * If onChange was set it is also used in the generation of the
513: * output. The output HTML will list the select lists in the
514: * following order: hour minute ampm.
515: *
516: * If setShowSeconds(true) is used then an addition second select box
517: * is produced after the minute select box.
518: *
519: * If setTimeFormat(TimeSelector.TWENTY_FOUR_HOUR) is used then
520: * the ampm select box is omitted.
521: *
522: * @return A String with the correct HTML for the date selector.
523: */
524: public String toString() {
525: return (ecsOutput().toString());
526: }
527:
528: /**
529: * Return an ECS container with the select objects inside.
530: *
531: * @return An ECS container.
532: */
533: public ElementContainer ecsOutput() {
534: if (this .useDate == null) {
535: this .useDate = Calendar.getInstance();
536: this .useDate.setTime(new Date());
537: }
538:
539: ConcreteElement secondSelect = null;
540:
541: Select ampmSelect = getAMPMSelector(selName + AMPM_SUFFIX,
542: useDate);
543:
544: Select hourSelect = getHourSelector(selName + HOUR_SUFFIX,
545: useDate, this .timeFormat);
546:
547: Select minuteSelect = getMinuteSelector(
548: selName + MINUTE_SUFFIX, useDate, this .minuteInterval);
549:
550: if (this .showSeconds) {
551: Select tmp = getSecondSelector(selName + SECOND_SUFFIX,
552: useDate, this .secondInterval);
553: if (onChangeSet)
554: tmp.setOnChange(onChange);
555: secondSelect = tmp;
556: } else {
557: secondSelect = new Input(Input.hidden, selName
558: + SECOND_SUFFIX, setSeconds);
559: }
560:
561: if (onChangeSet) {
562: hourSelect.setOnChange(onChange);
563: minuteSelect.setOnChange(onChange);
564: ampmSelect.setOnChange(onChange);
565: }
566:
567: ElementContainer ec = new ElementContainer();
568: ec
569: .addElement(new Comment(
570: "== BEGIN org.apache.turbine.util.TimeSelector.ecsOutput() =="));
571: ec.addElement(hourSelect);
572: ec.addElement(":");
573: ec.addElement(minuteSelect);
574: if (this .showSeconds == true)
575: ec.addElement(":");
576: ec.addElement(secondSelect);
577: if (this .timeFormat == TimeSelector.TWELVE_HOUR) {
578: ec.addElement(ampmSelect);
579: }
580: ec
581: .addElement(new Comment(
582: "== END org.apache.turbine.util.TimeSelector.ecsOutput() =="));
583: return (ec);
584: }
585: }
|