001: /*
002: * Version: MPL 1.1/GPL 2.0/LGPL 2.1
003: *
004: * "The contents of this file are subject to the Mozilla Public License
005: * Version 1.1 (the "License"); you may not use this file except in
006: * compliance with the License. You may obtain a copy of the License at
007: * http://www.mozilla.org/MPL/
008: *
009: * Software distributed under the License is distributed on an "AS IS"
010: * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
011: * License for the specific language governing rights and limitations under
012: * the License.
013: *
014: * The Original Code is ICEfaces 1.5 open source software code, released
015: * November 5, 2006. The Initial Developer of the Original Code is ICEsoft
016: * Technologies Canada, Corp. Portions created by ICEsoft are Copyright (C)
017: * 2004-2006 ICEsoft Technologies Canada, Corp. All Rights Reserved.
018: *
019: * Contributor(s): _____________________.
020: *
021: * Alternatively, the contents of this file may be used under the terms of
022: * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"
023: * License), in which case the provisions of the LGPL License are
024: * applicable instead of those above. If you wish to allow use of your
025: * version of this file only under the terms of the LGPL License and not to
026: * allow others to use your version of this file under the MPL, indicate
027: * your decision by deleting the provisions above and replace them with
028: * the notice and other provisions required by the LGPL License. If you do
029: * not delete the provisions above, a recipient may use your version of
030: * this file under either the MPL or the LGPL License."
031: *
032: */
033:
034: package com.icesoft.faces.component.selectinputdate;
035:
036: import com.icesoft.faces.component.CSS_DEFAULT;
037: import com.icesoft.faces.component.ext.HtmlInputText;
038: import com.icesoft.faces.component.ext.taglib.Util;
039: import com.icesoft.faces.context.DOMResponseWriter;
040: import com.icesoft.faces.util.CoreUtils;
041: import com.icesoft.faces.context.effects.JavascriptContext;
042: import com.icesoft.faces.context.BridgeFacesContext;
043:
044: import javax.faces.context.FacesContext;
045: import javax.faces.el.ValueBinding;
046: import java.io.IOException;
047: import java.text.DateFormat;
048: import java.text.SimpleDateFormat;
049: import java.util.ArrayList;
050: import java.util.Calendar;
051: import java.util.Date;
052: import java.util.HashMap;
053: import java.util.List;
054: import java.util.Map;
055:
056: /**
057: * SelectInputDate is a JSF component class that represents an ICEfaces input
058: * date selector.
059: * <p/>
060: * The component extends the ICEfaces extended HTMLPanelGroup.
061: * <p/>
062: * By default the component is rendered by the "com.icesoft.faces.Calendar"
063: * renderer type.
064: *
065: * @author Greg McCleary
066: * @version 1.1
067: */
068: public class SelectInputDate extends HtmlInputText {
069: /**
070: * The component type.
071: */
072: public static final String COMPONENT_TYPE = "com.icesoft.faces.SelectInputDate";
073: /**
074: * The component family.
075: */
076: public static final String COMPONENT_FAMILY = "javax.faces.Input";
077: /**
078: * The default renderer type.
079: */
080: private static final String DEFAULT_RENDERER_TYPE = "com.icesoft.faces.Calendar";
081: /**
082: * The default date format for the popup input text child component.
083: */
084: public static final String DEFAULT_POPUP_DATE_FORMAT = "MM/dd/yyyy";
085:
086: // style
087: private String style = null;
088:
089: private String styleClass = null;
090:
091: /**
092: * The current renderAsPopup state.
093: */
094: private Boolean _renderAsPopup = null;
095: /**
096: * The current directory path of the images used by the component.
097: */
098: private String _imageDir = null;
099: /**
100: * The current name of the move next image
101: */
102: private String _moveNextImage = null;
103: /**
104: * The current name of the move previous image.
105: */
106: private String _movePreviousImage = null;
107: /**
108: * The current name of the open popup image.
109: */
110: private String _openPopupImage = null;
111: /**
112: * The current name of the close popup image.
113: */
114: private String _closePopupImage = null;
115:
116: /**
117: * The current date format used for the input text child of the component.
118: * <p>Only applies when component is used in popup mode.
119: */
120: private String _popupDateFormat = null;
121:
122: /**
123: * The current popup state.
124: */
125: private List showPopup = new ArrayList();
126: /**
127: * The current navigation event state.
128: */
129: private boolean navEvent = false;
130: /**
131: * The current navigation date of the component.
132: */
133: private Date navDate = null;
134:
135: // declare default style classes
136: /**
137: * The default directory where the images used by this component can be
138: * found. This directory and its contents are included in the icefaces.jar
139: * file.
140: */
141: private final String DEFAULT_IMAGEDIR = "/xmlhttp/css/xp/css-images/";
142: /**
143: * The default move next image name.
144: */
145: private final String DEFAULT_MOVENEXT = "cal_arrow_right.gif";
146: /**
147: * The default move previous image name.
148: */
149: private final String DEFAULT_MOVEPREV = "cal_arrow_left.gif";
150: /**
151: * The default open popup image name.
152: */
153: private final String DEFAULT_OPENPOPUP = "cal_button.gif";
154: /**
155: * The default close popup image name.
156: */
157: private final String DEFAULT_CLOSEPOPUP = "cal_off.gif";
158: /**
159: * The default date format used by this component.
160: */
161: private DateFormat myDateFormat = new SimpleDateFormat(
162: DEFAULT_POPUP_DATE_FORMAT);
163:
164: public final static String CALENDAR_INPUTTEXT = "_calendarInputtext";
165:
166: /**
167: * Creates an instance and sets renderer type to "com.icesoft.faces.Calendar".
168: */
169: public SelectInputDate() {
170: setRendererType(DEFAULT_RENDERER_TYPE);
171: }
172:
173: public void encodeBegin(FacesContext context) throws IOException {
174: super .encodeBegin(context);
175: buildHeighLightMap();
176: }
177:
178: /**
179: * <p/>
180: * CSS style attribute. </p>
181: *
182: * @return style
183: */
184:
185: public String getStyle() {
186: if (this .style != null) {
187: return this .style;
188: }
189: ValueBinding _vb = getValueBinding("style");
190:
191: if (_vb != null) {
192: return (String) _vb.getValue(getFacesContext());
193: }
194: return null;
195: }
196:
197: /**
198: * <p/>
199: * CSS style attribute. </p>
200: *
201: * @param style
202: * @see #getStyle()
203: */
204: public void setStyle(String style) {
205: this .style = style;
206: }
207:
208: /**
209: * Formats the given date using the default date format MM/dd/yyyy.
210: *
211: * @param date
212: * @return the formatted date as a String.
213: */
214: public String formatDate(Date date) {
215: if (date != null) {
216: return myDateFormat.format(date);
217: } else {
218: return "";
219: }
220: }
221:
222: /**
223: * Sets the boolean navEvent attribute.
224: *
225: * @param navEvent a value of true indicates that a navigation event has
226: * occured.
227: */
228: public void setNavEvent(boolean navEvent) {
229: this .navEvent = navEvent;
230: }
231:
232: /**
233: * A navEvent value of true indicates that a navEvent has occured.
234: *
235: * @return a value of true if a navigation event caused that render.
236: */
237: public boolean isNavEvent() {
238: return this .navEvent;
239: }
240:
241: /**
242: * Set the date value of the navDate. The navDate is used to render a
243: * calendar when the user is navigating from month to month or year to
244: * year.
245: *
246: * @param navDate a Date assigned to the navDate.
247: */
248: public void setNavDate(Date navDate) {
249: this .navDate = navDate;
250: }
251:
252: /**
253: * Get the navDate to render a calendar on a navigation event.
254: *
255: * @return the navDate as a Date
256: */
257: public Date getNavDate() {
258: return this .navDate;
259: }
260:
261: /**
262: * Setting the showPopup attribute to true will render the SelectInputDate
263: * popup calendar.
264: *
265: * @param showPopup a value of true will cause the popup calendar to be
266: * rendered
267: */
268: public void setShowPopup(boolean showPopup) {
269: if (showPopup) {
270: this .showPopup.add(getClientId(FacesContext
271: .getCurrentInstance()));
272: } else {
273: this .showPopup.remove(getClientId(FacesContext
274: .getCurrentInstance()));
275: }
276: }
277:
278: /**
279: * A showPopup value of true indicates the SelectInputText popup be
280: * rendered.
281: *
282: * @return the current value showPopup
283: */
284: public boolean isShowPopup() {
285: if (showPopup.contains(getClientId(FacesContext
286: .getCurrentInstance()))) {
287: return true;
288: } else {
289: return false;
290: }
291: }
292:
293: /* (non-Javadoc)
294: * @see javax.faces.component.UIComponent#getFamily()
295: */
296: public String getFamily() {
297: return COMPONENT_FAMILY;
298: }
299:
300: /**
301: * Returns the style class name used for the row containing the month and
302: * Year. The style class is defined in an external style sheet.
303: *
304: * @return the style class name applied to the monthYearRow. If a
305: * monthYearRowClass attribute has not been set the default will be
306: * used.
307: */
308: public String getMonthYearRowClass() {
309: return Util
310: .getQualifiedStyleClass(this ,
311: CSS_DEFAULT.DEFAULT_YEARMONTHHEADER_CLASS,
312: isDisabled());
313: }
314:
315: /**
316: * Returns the style class name of the weekRowClass The style class is
317: * defined in an external style sheet.
318: *
319: * @return the style class name applied to the weekRow. If a weekRowClass
320: * attribute has not been set the default will be used.
321: */
322: public String getWeekRowClass() {
323: return Util.getQualifiedStyleClass(this ,
324: CSS_DEFAULT.DEFAULT_WEEKHEADER_CLASS, isDisabled());
325: }
326:
327: /**
328: * @return the style class name used for the input text of the calendar.
329: */
330: public String getCalendarInputClass() {
331: return Util.getQualifiedStyleClass(this ,
332: CSS_DEFAULT.DEFAULT_CALENDARINPUT_CLASS, isDisabled());
333: }
334:
335: /**
336: * Returns the style class name applied to the day cells in the
337: * SelectInputDate calendar.
338: *
339: * @return the style class name that is applied to the SelectInputDate day
340: * cells
341: */
342: public String getDayCellClass() {
343: return Util.getQualifiedStyleClass(this ,
344: CSS_DEFAULT.DEFAULT_DAYCELL_CLASS, isDisabled());
345: }
346:
347: /* (non-Javadoc)
348: * @see com.icesoft.faces.component.ext.HtmlInputText#setStyleClass(java.lang.String)
349: */
350: public void setStyleClass(String styleClass) {
351: this .styleClass = styleClass;
352: }
353:
354: /**
355: * <p>Return the value of the <code>styleClass</code> property.</p>
356: *
357: * @return styleClass
358: */
359: public String getStyleClass() {
360: return Util.getQualifiedStyleClass(this , styleClass,
361: CSS_DEFAULT.DEFAULT_CALENDAR, "styleClass",
362: isDisabled());
363: }
364:
365: /**
366: * Returns the currentDayCell style class name.
367: *
368: * @return style class name used for the current day cell
369: */
370: public String getCurrentDayCellClass() {
371: return Util.getQualifiedStyleClass(this ,
372: CSS_DEFAULT.DEFAULT_CURRENTDAYCELL_CLASS, isDisabled());
373: }
374:
375: /**
376: * @return the value of the renderAsPopup indicator.
377: */
378: public boolean isRenderAsPopup() {
379: if (_renderAsPopup != null) {
380: return _renderAsPopup.booleanValue();
381: }
382: ValueBinding vb = getValueBinding("renderAsPopup");
383: Boolean v = vb != null ? (Boolean) vb
384: .getValue(getFacesContext()) : null;
385: return v != null ? v.booleanValue() : false;
386: }
387:
388: /**
389: * @param b
390: */
391: public void setRenderAsPopup(boolean b) {
392: _renderAsPopup = new Boolean(b);
393: }
394:
395: /**
396: * Sets the directory where the images used by this component are located.
397: *
398: * @param imageDir the directory where the images used by this component are
399: * located
400: */
401: public void setImageDir(String imageDir) {
402: _imageDir = imageDir;
403: }
404:
405: /**
406: * @return the directory name where the images used by this component are
407: * located.
408: */
409: public String getImageDir() {
410: if (_imageDir != null) {
411: return _imageDir;
412: }
413:
414: ValueBinding vb = getValueBinding("imageDir");
415: if (vb != null) {
416: return (String) vb.getValue(getFacesContext());
417: } else {
418: return DEFAULT_IMAGEDIR;
419: }
420: }
421:
422: /**
423: * @return the name of the move next image.
424: */
425: public String getMoveNextImage() {
426: return this .DEFAULT_MOVENEXT;
427: }
428:
429: /**
430: * Returns the name of the move previous image.
431: *
432: * @return DEFAULT_MOVEPREV
433: */
434: public String getMovePreviousImage() {
435: return this .DEFAULT_MOVEPREV;
436: }
437:
438: /**
439: * returns the name of the open popup image.
440: *
441: * @return DEFAULT_OPENPOPUP
442: */
443: public String getOpenPopupImage() {
444: return this .DEFAULT_OPENPOPUP;
445: }
446:
447: /**
448: * Returns the name of the close popup image.
449: *
450: * @return DEFAULT_CLOSEPOPUP
451: */
452: public String getClosePopupImage() {
453: return this .DEFAULT_CLOSEPOPUP;
454: }
455:
456: /**
457: * Sets the date format of the input text child component when the component
458: * is in popup mode.
459: *
460: * @param popupDateFormat
461: */
462: public void setPopupDateFormat(String popupDateFormat) {
463: _popupDateFormat = popupDateFormat;
464: }
465:
466: /**
467: * Returns the date format string of the input text child componenet.
468: *
469: * @return _popupDateFormat
470: */
471: public String getPopupDateFormat() {
472: if (_popupDateFormat != null) {
473: myDateFormat = new SimpleDateFormat(_popupDateFormat);
474: return _popupDateFormat;
475: }
476: ValueBinding vb = getValueBinding("popupDateFormat");
477: if (vb != null) {
478: myDateFormat = new SimpleDateFormat((String) vb
479: .getValue(getFacesContext()));
480: return (String) vb.getValue(getFacesContext());
481: } else {
482: return DEFAULT_POPUP_DATE_FORMAT;
483: }
484: }
485:
486: /* (non-Javadoc)
487: * @see javax.faces.component.StateHolder#saveState(javax.faces.context.FacesContext)
488: */
489: public Object saveState(FacesContext context) {
490: Object values[] = new Object[10];
491: values[0] = super .saveState(context);
492: values[1] = _renderAsPopup;
493: values[2] = _popupDateFormat;
494: values[3] = _imageDir;
495: values[4] = _moveNextImage;
496: values[5] = _movePreviousImage;
497: values[6] = _openPopupImage;
498: values[7] = _closePopupImage;
499: values[8] = new Boolean(navEvent);
500: values[9] = navDate;
501: return ((Object) (values));
502: }
503:
504: /* (non-Javadoc)
505: * @see javax.faces.component.StateHolder#restoreState(javax.faces.context.FacesContext, java.lang.Object)
506: */
507: public void restoreState(FacesContext context, Object state) {
508: Object values[] = (Object[]) state;
509: super .restoreState(context, values[0]);
510: _renderAsPopup = (Boolean) values[1];
511: _popupDateFormat = (String) values[2];
512: _imageDir = (String) values[3];
513: _moveNextImage = (String) values[4];
514: _movePreviousImage = (String) values[5];
515: _openPopupImage = (String) values[6];
516: _closePopupImage = (String) values[7];
517: navEvent = ((Boolean) values[8]).booleanValue();
518: navDate = (Date) values[9];
519: }
520:
521: private Map linkMap = new HashMap();
522:
523: /**
524: * @return linkMap
525: */
526: public Map getLinkMap() {
527: return linkMap;
528: }
529:
530: /**
531: * @param linkMap
532: */
533: public void setLinkMap(Map linkMap) {
534: this .linkMap = linkMap;
535: }
536:
537: private String selectedDayLink;
538:
539: /**
540: * @return selectedDayLink
541: */
542: public String getSelectedDayLink() {
543: return selectedDayLink;
544: }
545:
546: /**
547: * @param selectedDayLink
548: */
549: public void setSelectedDayLink(String selectedDayLink) {
550: this .selectedDayLink = selectedDayLink;
551: }
552:
553: //this component was throwing an exception in popup mode, if the component has no binding for value attribute
554: //so here we returning current date in this case.
555: /* (non-Javadoc)
556: * @see javax.faces.component.ValueHolder#getValue()
557: */
558: public Object getValue() {
559: if (super .getValue() == null) {
560: if (DOMResponseWriter.isStreamWriting()) {
561: return new Date();
562: }
563: return null;
564: } else {
565: return super .getValue();
566: }
567: }
568:
569: private String highlightClass;
570:
571: /**
572: * <p>Set the value of the <code>highlightClass</code> property.</p>
573: *
574: * @param highlightClass
575: */
576: public void setHighlightClass(String highlightClass) {
577: this .highlightClass = highlightClass;
578: }
579:
580: /**
581: * <p>Return the value of the <code>highlightClass</code> property.</p>
582: *
583: * @return String highlightClass, if never set returns a blank string not
584: * null
585: */
586: public String getHighlightClass() {
587: if (highlightClass != null) {
588: return highlightClass;
589: }
590: ValueBinding vb = getValueBinding("highlightClass");
591: return vb != null ? (String) vb.getValue(getFacesContext())
592: : "";
593: }
594:
595: public void requestFocus() {
596: if (isRenderAsPopup()) {
597: ((BridgeFacesContext) FacesContext.getCurrentInstance())
598: .setFocusId("null");
599: JavascriptContext.focus(FacesContext.getCurrentInstance(),
600: this .getClientId(FacesContext.getCurrentInstance())
601: + CALENDAR_INPUTTEXT);
602: } else {
603: //log: focus can only be set in popup mode
604: }
605: }
606:
607: private String highlightUnit;
608:
609: /**
610: * <p>Set the value of the <code>highlightUnit</code> property.</p>
611: *
612: * @param highlightClass
613: */
614: public void setHighlightUnit(String highlightUnit) {
615: this .highlightUnit = highlightUnit;
616: }
617:
618: /**
619: * <p>Return the value of the <code>highlightUnit</code> property.</p>
620: *
621: * @return String highlightUnit, if never set returns a blank string not
622: * null
623: */
624: public String getHighlightUnit() {
625: if (highlightUnit != null) {
626: return highlightUnit;
627: }
628: ValueBinding vb = getValueBinding("highlightUnit");
629: return vb != null ? (String) vb.getValue(getFacesContext())
630: : "";
631: }
632:
633: private String highlightValue;
634:
635: /**
636: * <p>Set the value of the <code>highlightValue</code> property.</p>
637: *
638: * @param highlightValue
639: */
640: public void setHighlightValue(String highlightValue) {
641: this .highlightValue = highlightValue;
642: }
643:
644: /**
645: * <p>Return the value of the <code>highlightValue</code> property.</p>
646: *
647: * @return String highlightValue. if never set returns blank a string not
648: * null
649: */
650: public String getHighlightValue() {
651: if (highlightValue != null) {
652: return highlightValue;
653: }
654: ValueBinding vb = getValueBinding("highlightValue");
655: return vb != null ? (String) vb.getValue(getFacesContext())
656: : "";
657: }
658:
659: private Map hightlightRules = new HashMap();
660: private Map unitMap = new UnitMap();
661:
662: private void buildHeighLightMap() {
663: validateHighlight();
664: resetHighlightClasses(Calendar.YEAR);
665: }
666:
667: private boolean validateHighlight() {
668: hightlightRules.clear();
669: String highlightClassArray[] = getHighlightClass().split(":");
670: String highlightUnitArray[] = getHighlightUnit().split(":");
671: String highlightValueArray[] = getHighlightValue().split(":");
672: if ((highlightClassArray.length < 1)
673: || highlightClassArray[0].equals("")
674: || highlightUnitArray[0].equals("")
675: || highlightValueArray[0].equals("")) {
676: return false;
677: }
678: if (!(highlightClassArray.length == highlightUnitArray.length)
679: || !(highlightUnitArray.length == highlightValueArray.length)) {
680: System.out
681: .println("\n[SelectInputDate] The following attributes does not have corresponding values:"
682: + "\n-highlightClass \n-highlightUnit \n-highlightValue \n"
683: + "Note: When highlighting required, all above attributes "
684: + "need to be used together and should have corresponding values.\n"
685: + "Each entity can be separated using the : colon, e.g. \n"
686: + "highlightClass=\"weekend: newyear\" \n"
687: + "highlightUnit=\"DAY_OF_WEEK: DAY_OF_YEAR\" \n"
688: + "highlightValue=\"1, 7: 1\" ");
689: return false;
690: }
691:
692: for (int i = 0; i < highlightUnitArray.length; i++) {
693: try {
694: int option = Integer.parseInt(highlightUnitArray[i]
695: .trim());
696: if (option < 1 || option > 8) {
697: System.out
698: .println("[SelectInputDate:highlightUnit] \""
699: + highlightUnitArray[i].trim()
700: + "\" "
701: + "s not a valid unit value. Valid values are between 1 to 8");
702: return false;
703: }
704: } catch (NumberFormatException exception) {
705: if (unitMap.containsKey(highlightUnitArray[i].trim())) {
706: highlightUnitArray[i] = String.valueOf(unitMap
707: .get(highlightUnitArray[i].trim()));
708: } else {
709: System.out
710: .println("[SelectInputDate:highlightUnit] \""
711: + highlightUnitArray[i]
712: + "\" is "
713: + "not a valid unit value, String representation "
714: + "of unit must match with java.util.Calendar contants (e.g.)"
715: + "\nYEAR, MONTH, WEEK_OF_YEAR, WEEK_OF_MONTH, DATE, DAY_OF_YEAR, "
716: + "DAY_OF_WEEK and DAY_OF_WEEK_IN_MONTH");
717: return false;
718: }
719: }
720: String[] value = highlightValueArray[i].replaceAll(" ", "")
721: .trim().split(",");
722: for (int j = 0; j < value.length; j++) {
723: hightlightRules.put(highlightUnitArray[i].trim() + "$"
724: + value[j], highlightClassArray[i]);
725: }
726: }
727:
728: return true;
729: }
730:
731: Map getHightlightRules() {
732: return hightlightRules;
733: }
734:
735: void setHightlightRules(Map hightlightRules) {
736: this .hightlightRules = hightlightRules;
737: }
738:
739: private String highlightYearClass = "";
740: private String highlightMonthClass = "";
741: private String highlightWeekClass = "";
742: private String highlightDayClass = "";
743:
744: String getHighlightDayCellClass() {
745: return highlightYearClass + highlightMonthClass
746: + highlightWeekClass + highlightDayClass;
747: }
748:
749: String getHighlightMonthClass() {
750: return highlightMonthClass;
751: }
752:
753: void setHighlightMonthClass(String highlightMonthClass) {
754: this .highlightMonthClass = highlightMonthClass;
755: }
756:
757: String getHighlightYearClass() {
758: return highlightYearClass;
759: }
760:
761: void setHighlightYearClass(String highlightYearClass) {
762: this .highlightYearClass = highlightYearClass;
763: }
764:
765: String getHighlightWeekClass() {
766: return highlightWeekClass;
767: }
768:
769: void addHighlightWeekClass(String highlightWeekClass) {
770: if (this .highlightWeekClass.indexOf(highlightWeekClass) == -1) {
771: this .highlightWeekClass += (highlightWeekClass + " ");
772: }
773: }
774:
775: void addHighlightDayClass(String highlightDayClass) {
776: if (this .highlightDayClass.indexOf(highlightDayClass) == -1) {
777: this .highlightDayClass += (highlightDayClass + " ");
778: }
779: }
780:
781: void resetHighlightClasses(int level) {
782: if (level <= Calendar.MONTH) {
783: this .highlightMonthClass = "";
784: this .highlightYearClass = "";
785: this .highlightDayClass = "";
786: }
787: this .highlightDayClass = "";
788: this .highlightWeekClass = "";
789: }
790: }
791:
792: class UnitMap extends HashMap {
793: public UnitMap() {
794: this .put("YEAR", new Integer(Calendar.YEAR));
795: this .put("MONTH", new Integer(Calendar.MONTH));
796: this .put("WEEK_OF_YEAR", new Integer(Calendar.WEEK_OF_YEAR));
797: this .put("WEEK_OF_MONTH", new Integer(Calendar.WEEK_OF_MONTH));
798: this .put("DATE", new Integer(Calendar.DATE));
799: this .put("DAY_OF_YEAR", new Integer(Calendar.DAY_OF_YEAR));
800: this .put("DAY_OF_WEEK", new Integer(Calendar.DAY_OF_WEEK));
801: this .put("DAY_OF_WEEK_IN_MONTH", new Integer(
802: Calendar.DAY_OF_WEEK_IN_MONTH));
803: }
804:
805: public int getConstant(String key) {
806: if (!super .containsKey(key)) {
807: return 0;
808: }
809: return Integer.parseInt(super.get(key).toString());
810: }
811: }
|