1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.custom.calendar;
20
21 import java.io.IOException;
22 import java.text.DateFormat;
23 import java.text.DateFormatSymbols;
24 import java.text.ParseException;
25 import java.text.SimpleDateFormat;
26 import java.util.Calendar;
27 import java.util.Date;
28 import java.util.List;
29 import java.util.Locale;
30 import java.util.Map;
31
32 import javax.faces.application.Application;
33 import javax.faces.application.FacesMessage;
34 import javax.faces.application.Resource;
35 import javax.faces.component.EditableValueHolder;
36 import javax.faces.component.UIComponent;
37 import javax.faces.component.UIInput;
38 import javax.faces.component.UIParameter;
39 import javax.faces.component.behavior.ClientBehavior;
40 import javax.faces.component.html.HtmlCommandLink;
41 import javax.faces.component.html.HtmlOutputText;
42 import javax.faces.context.FacesContext;
43 import javax.faces.context.ResponseWriter;
44 import javax.faces.convert.Converter;
45 import javax.faces.convert.ConverterException;
46 import javax.faces.convert.DateTimeConverter;
47 import javax.faces.event.ComponentSystemEvent;
48 import javax.faces.event.ComponentSystemEventListener;
49 import javax.faces.event.ListenerFor;
50
51 import org.apache.commons.lang.StringEscapeUtils;
52 import org.apache.commons.logging.Log;
53 import org.apache.commons.logging.LogFactory;
54 import org.apache.myfaces.component.LibraryLocationAware;
55 import org.apache.myfaces.component.UserRoleUtils;
56 import org.apache.myfaces.custom.inputTextHelp.HtmlInputTextHelp;
57 import org.apache.myfaces.dateformat.SimpleDateFormatter;
58 import org.apache.myfaces.renderkit.html.util.AddResource;
59 import org.apache.myfaces.renderkit.html.util.AddResourceFactory;
60 import org.apache.myfaces.shared_tomahawk.renderkit.JSFAttr;
61 import org.apache.myfaces.shared_tomahawk.renderkit.RendererUtils;
62 import org.apache.myfaces.shared_tomahawk.renderkit.html.HTML;
63 import org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlRenderer;
64 import org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlRendererUtils;
65 import org.apache.myfaces.shared_tomahawk.renderkit.html.util.JavascriptUtils;
66 import org.apache.myfaces.shared_tomahawk.renderkit.html.util.ResourceUtils;
67 import org.apache.myfaces.shared_tomahawk.util.MessageUtils;
68 import org.apache.myfaces.tomahawk.application.PreRenderViewAddResourceEvent;
69 import org.apache.myfaces.tomahawk.util.Constants;
70 import org.apache.myfaces.tomahawk.util.TomahawkResourceUtils;
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115 @ListenerFor(systemEventClass=PreRenderViewAddResourceEvent.class)
116 public class HtmlCalendarRenderer
117 extends HtmlRenderer implements ComponentSystemEventListener
118 {
119 private final Log log = LogFactory.getLog(HtmlCalendarRenderer.class);
120
121 private static final String JAVASCRIPT_ENCODED = "org.apache.myfaces.calendar.JAVASCRIPT_ENCODED";
122 private static final String JAVASCRIPT_ENCODED_JSF2 = "org.apache.myfaces.calendar.JAVASCRIPT_ENCODED_JSF2";
123
124
125 private static final String RESOURCE_NONE = "none";
126
127 public void processEvent(ComponentSystemEvent event)
128 {
129 HtmlInputCalendar inputCalendar = (HtmlInputCalendar) event.getComponent();
130
131 if (inputCalendar.isRenderAsPopup() && inputCalendar.isAddResources())
132 {
133 FacesContext facesContext = FacesContext.getCurrentInstance();
134 if (!facesContext.getAttributes().containsKey(JAVASCRIPT_ENCODED_JSF2))
135 {
136 TomahawkResourceUtils.addOutputScriptResource(facesContext, "oam.custom.inputTextHelp", "inputTextHelp.js");
137 }
138 addScriptAndCSSResourcesWithJSF2ResourceAPI(facesContext, inputCalendar);
139 }
140 }
141
142 public void encodeEnd(FacesContext facesContext, UIComponent component)
143 throws IOException
144 {
145 RendererUtils.checkParamValidity(facesContext, component, HtmlInputCalendar.class);
146
147 HtmlInputCalendar inputCalendar = (HtmlInputCalendar) component;
148
149 Locale currentLocale = facesContext.getViewRoot().getLocale();
150 Map<String, List<ClientBehavior>> behaviors = inputCalendar.getClientBehaviors();
151 if (!behaviors.isEmpty())
152 {
153 ResourceUtils.renderDefaultJsfJsInlineIfNecessary(facesContext, facesContext.getResponseWriter());
154 }
155
156 log.debug("current locale:" + currentLocale.toString());
157
158 String textValue;
159
160 Converter converter = inputCalendar.getConverter();
161 Object submittedValue = inputCalendar.getSubmittedValue();
162
163 Date value;
164
165 if (submittedValue != null)
166 {
167
168 textValue = (String) submittedValue;
169
170 if(textValue ==null || textValue.trim().length()==0 || textValue.equals(getHelperString(inputCalendar)))
171 {
172 value = null;
173 }
174 else
175 {
176 try
177 {
178 String formatStr = CalendarDateTimeConverter.createJSPopupFormat(facesContext, inputCalendar.getPopupDateFormat());
179 Calendar timeKeeper = Calendar.getInstance(currentLocale);
180 int firstDayOfWeek = timeKeeper.getFirstDayOfWeek() - 1;
181 org.apache.myfaces.dateformat.DateFormatSymbols symbols = new org.apache.myfaces.dateformat.DateFormatSymbols(currentLocale);
182
183 SimpleDateFormatter dateFormat = new SimpleDateFormatter(formatStr, symbols, firstDayOfWeek);
184 value = dateFormat.parse(textValue);
185 }
186 catch (IllegalArgumentException illegalArgumentException)
187 {
188 value = null;
189 }
190 }
191 }
192 else
193 {
194 if (converter == null)
195 {
196 CalendarDateTimeConverter defaultConverter = new CalendarDateTimeConverter();
197
198 value = (Date) getDateBusinessConverter(inputCalendar).getDateValue(facesContext, component, inputCalendar.getValue());
199
200 textValue = defaultConverter.getAsString(facesContext, inputCalendar, value);
201 }
202 else
203 {
204 Object componentValue = null;
205 boolean usedComponentValue = false;
206
207 if(converter instanceof DateConverter)
208 {
209 value = ((DateConverter) converter).getAsDate(facesContext, inputCalendar);
210 }
211 else
212 {
213 componentValue = inputCalendar.getValue();
214 if (componentValue instanceof Date)
215 {
216 value = (Date) componentValue;
217 }
218 else
219 {
220 usedComponentValue = true;
221 value = null;
222 }
223 }
224 textValue = converter.getAsString(facesContext, inputCalendar, usedComponentValue ? componentValue : value);
225 }
226 }
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273 Calendar timeKeeper = Calendar.getInstance(currentLocale);
274 timeKeeper.setTime(value!=null?value:new Date());
275
276 DateFormatSymbols symbols = new DateFormatSymbols(currentLocale);
277
278 if(inputCalendar.isRenderAsPopup())
279 {
280 renderPopup(facesContext, inputCalendar, textValue, timeKeeper, symbols);
281 }
282 else
283 {
284 renderInline(facesContext, inputCalendar, timeKeeper, symbols);
285 }
286
287 component.getChildren().removeAll(component.getChildren());
288 }
289
290 private void renderPopup(
291 FacesContext facesContext,
292 HtmlInputCalendar inputCalendar,
293 String value,
294 Calendar timeKeeper,
295 DateFormatSymbols symbols) throws IOException
296 {
297 if(inputCalendar.isAddResources())
298 addScriptAndCSSResources(facesContext, inputCalendar);
299
300
301 UIInput uiInput = (UIInput) inputCalendar;
302 Converter converter = uiInput.getConverter();
303 String dateFormat = null;
304 if (converter != null && converter instanceof DateTimeConverter) {
305 dateFormat = ((DateTimeConverter) converter).getPattern();
306 }
307 if (dateFormat == null) {
308 dateFormat = CalendarDateTimeConverter.createJSPopupFormat(facesContext,
309 inputCalendar.getPopupDateFormat());
310 }
311
312 Application application = facesContext.getApplication();
313
314 HtmlInputTextHelp inputText = getOrCreateInputTextChild(inputCalendar, application);
315
316 RendererUtils.copyHtmlInputTextAttributes(inputCalendar, inputText);
317
318 inputText.setId(inputCalendar.getId()+"_input");
319
320 boolean forceId = RendererUtils.getBooleanValue(
321 JSFAttr.FORCE_ID_ATTR,
322 inputCalendar.getAttributes().get(JSFAttr.FORCE_ID_ATTR),
323 false);
324 if (forceId) {
325 inputText.getAttributes().put(JSFAttr.FORCE_ID_ATTR, Boolean.TRUE);
326 }
327
328 inputText.setConverter(null);
329 inputText.setTransient(true);
330 inputText.setHelpText(inputCalendar.getHelpText());
331 inputText.setSelectText(true);
332
333 inputText.setValue(value);
334
335
336
337
338
339
340
341
342
343
344 inputText.setDisabled(inputCalendar.isDisabled());
345 inputText.setReadonly(inputCalendar.isReadonly());
346 inputText.setEnabledOnUserRole(inputCalendar.getEnabledOnUserRole());
347 inputText.setVisibleOnUserRole(inputCalendar.getVisibleOnUserRole());
348
349
350
351
352
353
354 inputCalendar.getChildren().add(inputText);
355
356
357 inputText.setId(inputText.getId());
358
359 inputText.setName(inputCalendar.getClientId(facesContext));
360
361 inputText.setTargetClientId(inputCalendar.getClientId(facesContext));
362
363 ResponseWriter writer = facesContext.getResponseWriter();
364
365 writer.startElement(HTML.SPAN_ELEM, inputCalendar);
366
367 writer.writeAttribute(HTML.ID_ATTR, inputCalendar.getClientId(facesContext), null);
368
369 RendererUtils.renderChild(facesContext, inputText);
370
371
372
373
374
375
376
377 writer.startElement(HTML.SPAN_ELEM,inputCalendar);
378 writer.writeAttribute(HTML.ID_ATTR,inputCalendar.getClientId(facesContext)+"Span",
379 JSFAttr.ID_ATTR);
380 writer.endElement(HTML.SPAN_ELEM);
381
382 if (!isDisabled(facesContext, inputCalendar) && !inputCalendar.isReadonly())
383 {
384 writer.startElement(HTML.SCRIPT_ELEM, inputCalendar);
385 writer.writeAttribute(HTML.SCRIPT_TYPE_ATTR,HTML.SCRIPT_TYPE_TEXT_JAVASCRIPT,null);
386
387 String calendarVar = JavascriptUtils.getValidJavascriptName(
388 inputCalendar.getClientId(facesContext)+"CalendarVar",false);
389
390 writer.writeText(calendarVar+"=new org_apache_myfaces_PopupCalendar();\n",null);
391 writer.writeText(getLocalizedLanguageScript(facesContext,symbols,
392 timeKeeper.getFirstDayOfWeek(),inputCalendar,calendarVar)+"\n",null);
393
394 StringBuffer script = new StringBuffer();
395 setStringVariable(script, calendarVar +".initData.selectMode",inputCalendar.getPopupSelectMode());
396 writer.writeText(script.toString(), null);
397
398 writer.writeText(calendarVar+".init(document.getElementById('"+
399 inputCalendar.getClientId(facesContext)+"Span"+"'));\n",null);
400 writer.endElement(HTML.SCRIPT_ELEM);
401 if(!inputCalendar.isDisplayValueOnly())
402 {
403 getScriptBtn(writer, facesContext, inputCalendar,
404 dateFormat,inputCalendar.getPopupButtonString(), new FunctionCallProvider(){
405 public String getFunctionCall(FacesContext facesContext, UIComponent uiComponent, String dateFormat)
406 {
407 String clientId = uiComponent.getClientId(facesContext);
408 String inputClientId = null;
409 if (Boolean.TRUE.equals(uiComponent.getAttributes().get(JSFAttr.FORCE_ID_ATTR)))
410 {
411 if (uiComponent.getChildCount() > 0)
412 {
413 for (int i = 0, size = uiComponent.getChildCount(); i < size ; i++)
414 {
415 UIComponent child = uiComponent.getChildren().get(i);
416 if (child instanceof HtmlInputTextHelp && child.getId() != null && child.getId().endsWith("_input"))
417 {
418 inputClientId = child.getClientId();
419 }
420 }
421 }
422 if (inputClientId == null)
423 {
424 String oldId = uiComponent.getId();
425 uiComponent.setId(uiComponent.getId()+"_input");
426 inputClientId = uiComponent.getClientId();
427 uiComponent.setId(oldId);
428 }
429 }
430 else
431 {
432 inputClientId = clientId;
433 }
434
435 String clientVar = JavascriptUtils.getValidJavascriptName(clientId+"CalendarVar",true);
436
437 return clientVar+"._popUpCalendar(this,document.getElementById('"+inputClientId+"'),'"+dateFormat+"')";
438 }
439 });
440 }
441 }
442
443 writer.endElement(HTML.SPAN_ELEM);
444
445 inputCalendar.getChildren().remove(inputText);
446 }
447
448 private void renderInline(
449 FacesContext facesContext,
450 HtmlInputCalendar inputCalendar,
451 Calendar timeKeeper,
452 DateFormatSymbols symbols) throws IOException
453 {
454 String[] weekdays = mapShortWeekdays(symbols);
455 String[] months = mapMonths(symbols);
456
457 int lastDayInMonth = timeKeeper.getActualMaximum(Calendar.DAY_OF_MONTH);
458
459 int currentDay = timeKeeper.get(Calendar.DAY_OF_MONTH);
460
461 if (currentDay > lastDayInMonth)
462 currentDay = lastDayInMonth;
463
464 timeKeeper.set(Calendar.DAY_OF_MONTH, 1);
465
466 int weekDayOfFirstDayOfMonth = mapCalendarDayToCommonDay(timeKeeper.get(Calendar.DAY_OF_WEEK));
467
468 int weekStartsAtDayIndex = mapCalendarDayToCommonDay(timeKeeper.getFirstDayOfWeek());
469
470 ResponseWriter writer = facesContext.getResponseWriter();
471
472 HtmlRendererUtils.writePrettyLineSeparator(facesContext);
473 HtmlRendererUtils.writePrettyLineSeparator(facesContext);
474
475 writer.startElement(HTML.TABLE_ELEM, inputCalendar);
476 HtmlRendererUtils.renderHTMLAttributes(writer, inputCalendar, HTML.UNIVERSAL_ATTRIBUTES);
477
478 Map<String, List<ClientBehavior>> behaviors = inputCalendar.getClientBehaviors();
479
480 if (behaviors != null && !behaviors.isEmpty())
481 {
482 writer.writeAttribute(HTML.ID_ATTR, inputCalendar.getClientId(facesContext),null);
483 HtmlRendererUtils.renderBehaviorizedEventHandlers(facesContext, writer, inputCalendar, behaviors);
484 HtmlRendererUtils.renderBehaviorizedFieldEventHandlersWithoutOnchangeAndOnselect(facesContext, writer, inputCalendar, behaviors);
485 }
486 else
487 {
488 HtmlRendererUtils.writeIdIfNecessary(writer, inputCalendar, facesContext);
489 HtmlRendererUtils.renderHTMLAttributes(writer, inputCalendar, HTML.EVENT_HANDLER_ATTRIBUTES);
490 HtmlRendererUtils.renderHTMLAttributes(writer, inputCalendar, HTML.COMMON_FIELD_EVENT_ATTRIBUTES_WITHOUT_ONSELECT_AND_ONCHANGE);
491 }
492 writer.flush();
493
494 HtmlRendererUtils.writePrettyLineSeparator(facesContext);
495
496 writer.startElement(HTML.TR_ELEM, inputCalendar);
497
498 if(inputCalendar.getMonthYearRowClass() != null)
499 writer.writeAttribute(HTML.CLASS_ATTR, inputCalendar.getMonthYearRowClass(), null);
500
501 writeMonthYearHeader(facesContext, writer, inputCalendar, timeKeeper,
502 currentDay, weekdays, months);
503
504 writer.endElement(HTML.TR_ELEM);
505
506 HtmlRendererUtils.writePrettyLineSeparator(facesContext);
507
508 writer.startElement(HTML.TR_ELEM, inputCalendar);
509
510 if(inputCalendar.getWeekRowClass() != null)
511 writer.writeAttribute(HTML.CLASS_ATTR, inputCalendar.getWeekRowClass(), null);
512
513 writeWeekDayNameHeader(weekStartsAtDayIndex, weekdays,
514 facesContext, writer, inputCalendar);
515
516 writer.endElement(HTML.TR_ELEM);
517
518 HtmlRendererUtils.writePrettyLineSeparator(facesContext);
519
520 writeDays(facesContext, writer, inputCalendar, timeKeeper,
521 currentDay, weekStartsAtDayIndex, weekDayOfFirstDayOfMonth,
522 lastDayInMonth, weekdays);
523
524 writer.endElement(HTML.TABLE_ELEM);
525 }
526
527 private HtmlInputTextHelp getOrCreateInputTextChild(HtmlInputCalendar inputCalendar, Application application)
528 {
529 HtmlInputTextHelp inputText = null;
530
531 List li = inputCalendar.getChildren();
532
533 for (int i = 0; i < li.size(); i++)
534 {
535 UIComponent uiComponent = (UIComponent) li.get(i);
536
537 if(uiComponent instanceof HtmlInputTextHelp)
538 {
539 inputText = (HtmlInputTextHelp) uiComponent;
540 break;
541 }
542 }
543
544 if(inputText == null)
545 {
546 inputText = (HtmlInputTextHelp) application.createComponent(HtmlInputTextHelp.COMPONENT_TYPE);
547
548
549 for (Map.Entry<String,List<ClientBehavior>> entry : inputCalendar.getClientBehaviors().entrySet())
550 {
551 List<ClientBehavior> list = entry.getValue();
552 if (list != null && !list.isEmpty())
553 {
554 for (ClientBehavior cb : list)
555 {
556 inputText.addClientBehavior(entry.getKey(), cb);
557 }
558 }
559 }
560 }
561 return inputText;
562 }
563
564
565
566
567 static public void addScriptAndCSSResources(FacesContext facesContext, UIComponent component){
568
569
570
571
572
573 if (facesContext.getAttributes().containsKey(JAVASCRIPT_ENCODED) ||
574 facesContext.getAttributes().containsKey(JAVASCRIPT_ENCODED_JSF2))
575 {
576 return;
577 }
578
579 AddResource addresource = AddResourceFactory.getInstance(facesContext);
580
581
582 String styleLocation = HtmlRendererUtils.getStyleLocation(component);
583
584 if(styleLocation==null)
585 {
586
587
588
589
590
591
592
593
594
595
596
597
598
599 }
600 else if (!RESOURCE_NONE.equals(styleLocation))
601 {
602 addresource.addStyleSheet(facesContext, AddResource.HEADER_BEGIN, styleLocation+"/theme.css");
603 }
604 else
605 {
606
607 }
608
609 String javascriptLocation = HtmlRendererUtils.getJavascriptLocation(component);
610
611 if(javascriptLocation==null)
612 {
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631 }
632 else if (!RESOURCE_NONE.equals(javascriptLocation))
633 {
634 addresource.addJavaScriptAtPosition(facesContext, AddResource.HEADER_BEGIN, javascriptLocation+ "/prototype.js");
635 addresource.addJavaScriptAtPosition(facesContext, AddResource.HEADER_BEGIN, javascriptLocation+ "/date.js");
636 addresource.addJavaScriptAtPosition(facesContext, AddResource.HEADER_BEGIN, javascriptLocation+ "/popcalendar.js");
637 }
638 else
639 {
640
641 }
642
643 facesContext.getAttributes().put(JAVASCRIPT_ENCODED, Boolean.TRUE);
644 }
645
646 static public void addScriptAndCSSResourcesWithJSF2ResourceAPI(FacesContext facesContext, UIComponent component){
647
648
649
650
651
652 if (facesContext.getAttributes().containsKey(JAVASCRIPT_ENCODED_JSF2))
653 {
654 return;
655 }
656
657
658
659 String styleLocation = HtmlRendererUtils.getStyleLocation(component);
660
661 if(styleLocation==null)
662 {
663 String styleLibrary = (String) component.getAttributes().get(LibraryLocationAware.STYLE_LIBRARY_ATTR);
664 if (styleLibrary == null)
665 {
666
667 TomahawkResourceUtils.addOutputStylesheetResource(facesContext, "oam.custom.calendar.WH", "theme.css");
668
669 TomahawkResourceUtils.addOutputStylesheetResource(facesContext, "oam.custom.calendar.DB", "theme.css");
670 }
671 else
672 {
673 TomahawkResourceUtils.addOutputStylesheetResource(facesContext, styleLocation, "theme.css");
674 }
675 }
676
677 String javascriptLocation = HtmlRendererUtils.getJavascriptLocation(component);
678
679 if(javascriptLocation==null)
680 {
681 String javascriptLibrary = (String) component.getAttributes().get(LibraryLocationAware.JAVASCRIPT_LIBRARY_ATTR);
682 if (javascriptLibrary == null)
683 {
684
685 TomahawkResourceUtils.addOutputScriptResource(facesContext, "oam.custom.prototype", "prototype.js");
686
687 TomahawkResourceUtils.addOutputScriptResource(facesContext, "oam.custom.calendar", "date.js");
688
689 TomahawkResourceUtils.addOutputScriptResource(facesContext, "oam.custom.calendar", "popcalendar.js");
690 }
691 else
692 {
693 TomahawkResourceUtils.addOutputScriptResource(facesContext, javascriptLibrary, "prototype.js");
694 TomahawkResourceUtils.addOutputScriptResource(facesContext, javascriptLibrary, "date.js");
695 TomahawkResourceUtils.addOutputScriptResource(facesContext, javascriptLibrary, "popcalendar.js");
696
697 }
698 }
699
700 facesContext.getAttributes().put(JAVASCRIPT_ENCODED_JSF2, Boolean.TRUE);
701 }
702
703
704
705
706
707
708
709
710
711
712
713 public static String getLocalizedLanguageScript(FacesContext facesContext,
714 DateFormatSymbols symbols, int firstDayOfWeek, UIComponent uiComponent,
715 String popupCalendarVariable)
716 {
717
718
719
720 int realFirstDayOfWeek = firstDayOfWeek - 1;
721
722 String[] weekDays;
723
724 if (realFirstDayOfWeek == 0)
725 {
726
727 weekDays = mapShortWeekdaysStartingWithSunday(symbols);
728 }
729 else if (realFirstDayOfWeek == 1)
730 {
731
732 weekDays = mapShortWeekdays(symbols);
733 }
734 else if (realFirstDayOfWeek == 6)
735 {
736
737 weekDays = mapShortWeekdaysStartingWithSaturday(symbols);
738 }
739 else
740 {
741 throw new IllegalStateException("Week may only start with saturday, sunday or monday.");
742 }
743
744 StringBuffer script = new StringBuffer();
745 AddResource ar = AddResourceFactory.getInstance(facesContext);
746
747 if (uiComponent instanceof HtmlInputCalendar)
748 {
749 HtmlInputCalendar calendar = (HtmlInputCalendar) uiComponent;
750
751 String popupTheme = calendar.getPopupTheme();
752 if (popupTheme == null)
753 {
754 popupTheme = "DB";
755 }
756 setStringVariable(script, popupCalendarVariable + ".initData.themePrefix",
757 "jscalendar-" + popupTheme);
758
759
760
761 String imageLocation = HtmlRendererUtils.getImageLocation(uiComponent);
762 if (imageLocation == null)
763 {
764 String imageLibrary = (String) uiComponent.getAttributes().get(LibraryLocationAware.IMAGE_LIBRARY_ATTR);
765 if (imageLibrary == null)
766 {
767
768
769
770
771 Resource resource = facesContext.getApplication().getResourceHandler().createResource(
772 ";j", "oam.custom.calendar"+((popupTheme!=null&&popupTheme.length()>0)?"."+popupTheme:""));
773 String path = resource.getRequestPath();
774 int index = path.indexOf("/;j");
775 String prefix = path.substring(0, index+1);
776 String suffix = path.substring(index+3);
777 setStringVariable(script, popupCalendarVariable + ".initData.imgDir",prefix);
778 setStringVariable(script, popupCalendarVariable + ".initData.imgDirSuffix",suffix);
779 }
780 else
781 {
782 Resource resource = facesContext.getApplication().getResourceHandler().createResource(
783 ";j", imageLibrary);
784 String path = resource.getRequestPath();
785 int index = path.indexOf("/;j");
786 String prefix = path.substring(0, index+1);
787 String suffix = path.substring(index+3);
788 setStringVariable(script, popupCalendarVariable + ".initData.imgDir",prefix);
789 setStringVariable(script, popupCalendarVariable + ".initData.imgDirSuffix",suffix);
790 }
791 }
792 else
793 {
794 setStringVariable(script, popupCalendarVariable + ".initData.imgDir",
795 (JavascriptUtils.encodeString(AddResourceFactory.getInstance(facesContext)
796 .getResourceUri(facesContext, imageLocation + "/"))));
797 setStringVariable(script, popupCalendarVariable + ".initData.imgDirSuffix","");
798 }
799 }
800 else
801 {
802 String imageLocation = HtmlRendererUtils.getImageLocation(uiComponent);
803 if (imageLocation == null)
804 {
805 String imageLibrary = (String) uiComponent.getAttributes().get(LibraryLocationAware.IMAGE_LIBRARY_ATTR);
806 if (imageLibrary == null)
807 {
808
809
810
811
812 Resource resource = facesContext.getApplication().getResourceHandler().createResource(
813 ";j", "oam.custom.calendar.images");
814 String path = resource.getRequestPath();
815 int index = path.indexOf("/;j");
816 String prefix = path.substring(0, index+1);
817 String suffix = path.substring(index+3);
818 setStringVariable(script, popupCalendarVariable + ".initData.imgDir",prefix);
819 setStringVariable(script, popupCalendarVariable + ".initData.imgDirSuffix",suffix);
820 }
821 else
822 {
823 Resource resource = facesContext.getApplication().getResourceHandler().createResource(
824 ";j", imageLibrary);
825 String path = resource.getRequestPath();
826 int index = path.indexOf("/;j");
827 String prefix = path.substring(0, index+1);
828 String suffix = path.substring(index+3);
829 setStringVariable(script, popupCalendarVariable + ".initData.imgDir",prefix);
830 setStringVariable(script, popupCalendarVariable + ".initData.imgDirSuffix",suffix);
831 }
832 }
833 else
834 {
835 setStringVariable(script, popupCalendarVariable + ".initData.imgDir",
836 (JavascriptUtils.encodeString(AddResourceFactory.getInstance(facesContext)
837 .getResourceUri(facesContext, imageLocation + "/"))));
838 setStringVariable(script, popupCalendarVariable + ".initData.imgDirSuffix","");
839 }
840 }
841 defineStringArray(script, popupCalendarVariable + ".initData.monthName", mapMonths(symbols));
842 defineStringArray(script, popupCalendarVariable + ".initData.dayName", weekDays);
843 setIntegerVariable(script, popupCalendarVariable + ".initData.startAt", realFirstDayOfWeek);
844
845 defineStringArray(script, popupCalendarVariable + ".dateFormatSymbols.weekdays",
846 mapWeekdaysStartingWithSunday(symbols));
847 defineStringArray(script, popupCalendarVariable + ".dateFormatSymbols.shortWeekdays",
848 mapShortWeekdaysStartingWithSunday(symbols));
849 defineStringArray(script, popupCalendarVariable + ".dateFormatSymbols.shortMonths",
850 mapShortMonths(symbols));
851 defineStringArray(script, popupCalendarVariable + ".dateFormatSymbols.months",
852 mapMonths(symbols));
853 defineStringArray(script, popupCalendarVariable + ".dateFormatSymbols.eras", symbols
854 .getEras());
855 defineStringArray(script, popupCalendarVariable + ".dateFormatSymbols.ampms", symbols
856 .getAmPmStrings());
857
858 if (uiComponent instanceof HtmlInputCalendar)
859 {
860
861 HtmlInputCalendar inputCalendar = (HtmlInputCalendar) uiComponent;
862
863 if (inputCalendar.getPopupGotoString() != null)
864 setStringVariable(script, popupCalendarVariable + ".initData.gotoString",
865 inputCalendar.getPopupGotoString());
866 if (inputCalendar.getPopupTodayString() != null)
867 setStringVariable(script, popupCalendarVariable + ".initData.todayString",
868 inputCalendar.getPopupTodayString());
869 if (inputCalendar.getPopupTodayDateFormat() != null)
870 setStringVariable(script, popupCalendarVariable + ".initData.todayDateFormat",
871 inputCalendar.getPopupTodayDateFormat());
872 else if (inputCalendar.getPopupDateFormat() != null)
873 setStringVariable(script, popupCalendarVariable + ".initData.todayDateFormat",
874 inputCalendar.getPopupDateFormat());
875 if (inputCalendar.getPopupWeekString() != null)
876 setStringVariable(script, popupCalendarVariable + ".initData.weekString",
877 inputCalendar.getPopupWeekString());
878 if (inputCalendar.getPopupScrollLeftMessage() != null)
879 setStringVariable(script, popupCalendarVariable + ".initData.scrollLeftMessage",
880 inputCalendar.getPopupScrollLeftMessage());
881 if (inputCalendar.getPopupScrollRightMessage() != null)
882 setStringVariable(script, popupCalendarVariable + ".initData.scrollRightMessage",
883 inputCalendar.getPopupScrollRightMessage());
884 if (inputCalendar.getPopupSelectMonthMessage() != null)
885 setStringVariable(script, popupCalendarVariable + ".initData.selectMonthMessage",
886 inputCalendar.getPopupSelectMonthMessage());
887 if (inputCalendar.getPopupSelectYearMessage() != null)
888 setStringVariable(script, popupCalendarVariable + ".initData.selectYearMessage",
889 inputCalendar.getPopupSelectYearMessage());
890 if (inputCalendar.getPopupSelectDateMessage() != null)
891 setStringVariable(script, popupCalendarVariable + ".initData.selectDateMessage",
892 inputCalendar.getPopupSelectDateMessage());
893 setBooleanVariable(script, popupCalendarVariable + ".initData.popupLeft", inputCalendar
894 .isPopupLeft());
895
896 }
897
898 return script.toString();
899 }
900
901 private static void setBooleanVariable(StringBuffer script, String name, boolean value)
902 {
903 script.append(name);
904 script.append(" = ");
905 script.append(value);
906 script.append(";\n");
907 }
908
909 private static void setIntegerVariable(StringBuffer script, String name, int value)
910 {
911 script.append(name);
912 script.append(" = ");
913 script.append(value);
914 script.append(";\n");
915 }
916
917 private static void setStringVariable(StringBuffer script, String name, String value)
918 {
919 script.append(name);
920 script.append(" = \"");
921 script.append(StringEscapeUtils.escapeJavaScript(value));
922 script.append("\";\n");
923 }
924
925 private static void defineStringArray(StringBuffer script, String arrayName, String[] array)
926 {
927 script.append(arrayName);
928 script.append(" = new Array(");
929
930 for(int i=0;i<array.length;i++)
931 {
932 if(i!=0)
933 script.append(",");
934
935 script.append("\"");
936 script.append(StringEscapeUtils.escapeJavaScript(array[i]));
937 script.append("\"");
938 }
939
940 script.append(");\n");
941 }
942
943 public static void getScriptBtn(ResponseWriter writer, FacesContext facesContext, UIComponent uiComponent,
944 String dateFormat, String popupButtonString, FunctionCallProvider prov)
945 throws IOException
946 {
947 boolean renderButtonAsImage = false;
948 String popupButtonStyle = null;
949 String popupButtonStyleClass = null;
950
951 if(uiComponent instanceof HtmlInputCalendar)
952 {
953 HtmlInputCalendar calendar = (HtmlInputCalendar)uiComponent;
954 renderButtonAsImage = calendar.isRenderPopupButtonAsImage();
955 popupButtonStyle = calendar.getPopupButtonStyle();
956 popupButtonStyleClass = calendar.getPopupButtonStyleClass();
957 }
958
959 if (!renderButtonAsImage) {
960
961 writer.startElement(HTML.INPUT_ELEM, uiComponent);
962 writer.writeAttribute(HTML.TYPE_ATTR, HTML.INPUT_TYPE_BUTTON, null);
963
964 writer.writeAttribute(HTML.ONCLICK_ATTR,
965 prov.getFunctionCall(facesContext,uiComponent,dateFormat),
966 null);
967
968 if(popupButtonString==null)
969 popupButtonString="...";
970 writer.writeAttribute(HTML.VALUE_ATTR, StringEscapeUtils.escapeJavaScript(popupButtonString), null);
971
972 if(popupButtonStyle != null)
973 {
974 writer.writeAttribute(HTML.STYLE_ATTR, popupButtonStyle, null);
975 }
976
977 if(popupButtonStyleClass != null)
978 {
979 writer.writeAttribute(HTML.CLASS_ATTR, popupButtonStyleClass, null);
980 }
981
982 writer.endElement(HTML.INPUT_ELEM);
983 } else {
984
985 writer.startElement(HTML.IMG_ELEM, uiComponent);
986 AddResource addResource = AddResourceFactory.getInstance(facesContext);
987
988 String imgUrl = (String) uiComponent.getAttributes().get("popupButtonImageUrl");
989
990 if(imgUrl!=null)
991 {
992 writer.writeAttribute(HTML.SRC_ATTR, addResource.getResourceUri(facesContext, imgUrl), null);
993 }
994 else
995 {
996
997 Resource res = facesContext.getApplication().getResourceHandler().createResource("calendar.gif", "oam.custom.calendar.images");
998 writer.writeAttribute(HTML.SRC_ATTR, res.getRequestPath(), null);
999 }
1000
1001 if(popupButtonStyle != null)
1002 {
1003 writer.writeAttribute(HTML.STYLE_ATTR, popupButtonStyle, null);
1004 }
1005 else
1006 {
1007 writer.writeAttribute(HTML.STYLE_ATTR, "vertical-align:bottom;", null);
1008 }
1009
1010 if(popupButtonStyleClass != null)
1011 {
1012 writer.writeAttribute(HTML.CLASS_ATTR, popupButtonStyleClass, null);
1013 }
1014
1015 writer.writeAttribute(HTML.ONCLICK_ATTR, prov.getFunctionCall(facesContext, uiComponent, dateFormat),
1016 null);
1017
1018 writer.endElement(HTML.IMG_ELEM);
1019 }
1020 }
1021
1022
1023 private void writeMonthYearHeader(FacesContext facesContext, ResponseWriter writer, UIInput inputComponent, Calendar timeKeeper,
1024 int currentDay, String[] weekdays,
1025 String[] months)
1026 throws IOException
1027 {
1028 Calendar cal = shiftMonth(facesContext, timeKeeper, currentDay, -1);
1029
1030 writeCell(facesContext, writer, inputComponent, "<", cal.getTime(), null);
1031
1032 writer.startElement(HTML.TD_ELEM, inputComponent);
1033 writer.writeAttribute(HTML.COLSPAN_ATTR, new Integer(weekdays.length - 2), null);
1034 writer.writeText(months[timeKeeper.get(Calendar.MONTH)] + " " + timeKeeper.get(Calendar.YEAR), null);
1035 writer.endElement(HTML.TD_ELEM);
1036
1037 cal = shiftMonth(facesContext, timeKeeper, currentDay, 1);
1038
1039 writeCell(facesContext, writer, inputComponent, ">", cal.getTime(), null);
1040 }
1041
1042 private Calendar shiftMonth(FacesContext facesContext,
1043 Calendar timeKeeper, int currentDay, int shift)
1044 {
1045 Calendar cal = copyCalendar(facesContext, timeKeeper);
1046
1047 cal.set(Calendar.DAY_OF_MONTH, 1);
1048 cal.set(Calendar.MONTH, cal.get(Calendar.MONTH) + shift);
1049
1050 if(currentDay > cal.getActualMaximum(Calendar.DAY_OF_MONTH))
1051 currentDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
1052
1053 cal.set(Calendar.DAY_OF_MONTH, currentDay);
1054 return cal;
1055 }
1056
1057 private Calendar copyCalendar(FacesContext facesContext, Calendar timeKeeper)
1058 {
1059 Calendar cal = Calendar.getInstance(facesContext.getViewRoot().getLocale());
1060 cal.setTime(timeKeeper.getTime());
1061 return cal;
1062 }
1063
1064 private void writeWeekDayNameHeader(int weekStartsAtDayIndex, String[] weekdays, FacesContext facesContext, ResponseWriter writer, UIInput inputComponent)
1065 throws IOException
1066 {
1067 for (int i = weekStartsAtDayIndex; i < weekdays.length; i++)
1068 writeCell(facesContext,
1069 writer, inputComponent, weekdays[i], null, null);
1070
1071 for (int i = 0; i < weekStartsAtDayIndex; i++)
1072 writeCell(facesContext, writer,
1073 inputComponent, weekdays[i], null, null);
1074 }
1075
1076 private void writeDays(FacesContext facesContext, ResponseWriter writer,
1077 HtmlInputCalendar inputComponent, Calendar timeKeeper, int currentDay, int weekStartsAtDayIndex,
1078 int weekDayOfFirstDayOfMonth, int lastDayInMonth, String[] weekdays)
1079 throws IOException
1080 {
1081 Calendar cal;
1082
1083 int space = (weekStartsAtDayIndex < weekDayOfFirstDayOfMonth) ? (weekDayOfFirstDayOfMonth - weekStartsAtDayIndex)
1084 : (weekdays.length - weekStartsAtDayIndex + weekDayOfFirstDayOfMonth);
1085
1086 if (space == weekdays.length)
1087 space = 0;
1088
1089 int columnIndexCounter = 0;
1090
1091 for (int i = 0; i < space; i++)
1092 {
1093 if (columnIndexCounter == 0)
1094 {
1095 writer.startElement(HTML.TR_ELEM, inputComponent);
1096 }
1097
1098 writeCell(facesContext, writer, inputComponent, "",
1099 null, inputComponent.getDayCellClass());
1100 columnIndexCounter++;
1101 }
1102
1103 for (int i = 0; i < lastDayInMonth; i++)
1104 {
1105 if (columnIndexCounter == 0)
1106 {
1107 writer.startElement(HTML.TR_ELEM, inputComponent);
1108 }
1109
1110 cal = copyCalendar(facesContext, timeKeeper);
1111 cal.set(Calendar.DAY_OF_MONTH, i + 1);
1112
1113 String cellStyle = inputComponent.getDayCellClass();
1114
1115 if((currentDay - 1) == i)
1116 cellStyle = inputComponent.getCurrentDayCellClass();
1117
1118 writeCell(facesContext, writer,
1119 inputComponent, String.valueOf(i + 1), cal.getTime(),
1120 cellStyle);
1121
1122 columnIndexCounter++;
1123
1124 if (columnIndexCounter == weekdays.length)
1125 {
1126 writer.endElement(HTML.TR_ELEM);
1127 HtmlRendererUtils.writePrettyLineSeparator(facesContext);
1128 columnIndexCounter = 0;
1129 }
1130 }
1131
1132 if (columnIndexCounter != 0)
1133 {
1134 for (int i = columnIndexCounter; i < weekdays.length; i++)
1135 {
1136 writeCell(facesContext, writer,
1137 inputComponent, "", null, inputComponent.getDayCellClass());
1138 }
1139
1140 writer.endElement(HTML.TR_ELEM);
1141 HtmlRendererUtils.writePrettyLineSeparator(facesContext);
1142 }
1143 }
1144
1145
1146
1147
1148 private void writeCell(FacesContext facesContext,
1149 ResponseWriter writer, UIInput component, String content,
1150 Date valueForLink, String styleClass)
1151 throws IOException
1152 {
1153 writer.startElement(HTML.TD_ELEM, component);
1154
1155 if (styleClass != null)
1156 writer.writeAttribute(HTML.CLASS_ATTR, styleClass, null);
1157
1158 if (valueForLink == null)
1159 writer.writeText(content, JSFAttr.VALUE_ATTR);
1160 else
1161 {
1162 writeLink(content, component, facesContext, valueForLink);
1163 }
1164
1165 writer.endElement(HTML.TD_ELEM);
1166 }
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178 private void writeLink(String content,
1179 UIInput component,
1180 FacesContext facesContext,
1181 Date valueForLink)
1182 throws IOException
1183 {
1184 Converter converter = getConverter(component);
1185 Application application = facesContext.getApplication();
1186
1187 HtmlOutputText text
1188 = (HtmlOutputText)application.createComponent(HtmlOutputText.COMPONENT_TYPE);
1189 text.setValue(content);
1190 text.setId(component.getId() + "_" + valueForLink.getTime() + "_text");
1191 text.setTransient(true);
1192
1193 HtmlInputCalendar calendar = (HtmlInputCalendar)component;
1194 if (isDisabled(facesContext, component) || calendar.isReadonly())
1195 {
1196 component.getChildren().add(text);
1197
1198 RendererUtils.renderChild(facesContext, text);
1199 return;
1200 }
1201
1202 HtmlCommandLink link
1203 = (HtmlCommandLink)application.createComponent(HtmlCommandLink.COMPONENT_TYPE);
1204 link.setId(component.getId() + "_" + valueForLink.getTime() + "_link");
1205 link.setTransient(true);
1206 link.setImmediate(component.isImmediate());
1207
1208 UIParameter parameter
1209 = (UIParameter)application.createComponent(UIParameter.COMPONENT_TYPE);
1210 parameter.setId(component.getId() + "_" + valueForLink.getTime() + "_param");
1211 parameter.setTransient(true);
1212 parameter.setName(component.getClientId(facesContext));
1213 parameter.setValue(converter.getAsString(facesContext, component, valueForLink));
1214
1215 RendererUtils.addOrReplaceChild(component,link);
1216 link.getChildren().add(parameter);
1217 link.getChildren().add(text);
1218
1219 RendererUtils.renderChild(facesContext, link);
1220 }
1221
1222 private Converter getConverter(UIInput component)
1223 {
1224 Converter converter = component.getConverter();
1225
1226 if (converter == null)
1227 {
1228 converter = new CalendarDateTimeConverter();
1229 }
1230 return converter;
1231 }
1232
1233 private DateBusinessConverter getDateBusinessConverter(AbstractHtmlInputCalendar component)
1234 {
1235 DateBusinessConverter dateBusinessConverter = component.getDateBusinessConverter();
1236 if (dateBusinessConverter == null)
1237 {
1238 dateBusinessConverter = new DefaultDateBusinessConverter();
1239 }
1240 return dateBusinessConverter;
1241 }
1242
1243 private int mapCalendarDayToCommonDay(int day)
1244 {
1245 switch (day)
1246 {
1247 case Calendar.TUESDAY:
1248 return 1;
1249 case Calendar.WEDNESDAY:
1250 return 2;
1251 case Calendar.THURSDAY:
1252 return 3;
1253 case Calendar.FRIDAY:
1254 return 4;
1255 case Calendar.SATURDAY:
1256 return 5;
1257 case Calendar.SUNDAY:
1258 return 6;
1259 default:
1260 return 0;
1261 }
1262 }
1263
1264 private static String[] mapShortWeekdays(DateFormatSymbols symbols)
1265 {
1266 String[] weekdays = new String[7];
1267
1268 String[] localeWeekdays = symbols.getShortWeekdays();
1269
1270 weekdays[0] = localeWeekdays[Calendar.MONDAY];
1271 weekdays[1] = localeWeekdays[Calendar.TUESDAY];
1272 weekdays[2] = localeWeekdays[Calendar.WEDNESDAY];
1273 weekdays[3] = localeWeekdays[Calendar.THURSDAY];
1274 weekdays[4] = localeWeekdays[Calendar.FRIDAY];
1275 weekdays[5] = localeWeekdays[Calendar.SATURDAY];
1276 weekdays[6] = localeWeekdays[Calendar.SUNDAY];
1277
1278 return weekdays;
1279 }
1280
1281 private static String[] mapShortWeekdaysStartingWithSunday(DateFormatSymbols symbols)
1282 {
1283 String[] weekdays = new String[7];
1284
1285 String[] localeWeekdays = symbols.getShortWeekdays();
1286
1287 weekdays[0] = localeWeekdays[Calendar.SUNDAY];
1288 weekdays[1] = localeWeekdays[Calendar.MONDAY];
1289 weekdays[2] = localeWeekdays[Calendar.TUESDAY];
1290 weekdays[3] = localeWeekdays[Calendar.WEDNESDAY];
1291 weekdays[4] = localeWeekdays[Calendar.THURSDAY];
1292 weekdays[5] = localeWeekdays[Calendar.FRIDAY];
1293 weekdays[6] = localeWeekdays[Calendar.SATURDAY];
1294
1295 return weekdays;
1296 }
1297
1298
1299 private static String[] mapShortWeekdaysStartingWithSaturday(DateFormatSymbols symbols)
1300 {
1301 String[] weekdays = new String[7];
1302
1303 String[] localeWeekdays = symbols.getShortWeekdays();
1304
1305 weekdays[0] = localeWeekdays[Calendar.SATURDAY];
1306 weekdays[1] = localeWeekdays[Calendar.SUNDAY];
1307 weekdays[2] = localeWeekdays[Calendar.MONDAY];
1308 weekdays[3] = localeWeekdays[Calendar.TUESDAY];
1309 weekdays[4] = localeWeekdays[Calendar.WEDNESDAY];
1310 weekdays[5] = localeWeekdays[Calendar.THURSDAY];
1311 weekdays[6] = localeWeekdays[Calendar.FRIDAY];
1312
1313 return weekdays;
1314 }
1315
1316 private static String[] mapWeekdaysStartingWithSunday(DateFormatSymbols symbols)
1317 {
1318 String[] weekdays = new String[7];
1319
1320 String[] localeWeekdays = symbols.getWeekdays();
1321
1322 weekdays[0] = localeWeekdays[Calendar.SUNDAY];
1323 weekdays[1] = localeWeekdays[Calendar.MONDAY];
1324 weekdays[2] = localeWeekdays[Calendar.TUESDAY];
1325 weekdays[3] = localeWeekdays[Calendar.WEDNESDAY];
1326 weekdays[4] = localeWeekdays[Calendar.THURSDAY];
1327 weekdays[5] = localeWeekdays[Calendar.FRIDAY];
1328 weekdays[6] = localeWeekdays[Calendar.SATURDAY];
1329
1330 return weekdays;
1331 }
1332
1333 public static String[] mapMonths(DateFormatSymbols symbols)
1334 {
1335 String[] months = new String[12];
1336
1337 String[] localeMonths = symbols.getMonths();
1338
1339 months[0] = localeMonths[Calendar.JANUARY];
1340 months[1] = localeMonths[Calendar.FEBRUARY];
1341 months[2] = localeMonths[Calendar.MARCH];
1342 months[3] = localeMonths[Calendar.APRIL];
1343 months[4] = localeMonths[Calendar.MAY];
1344 months[5] = localeMonths[Calendar.JUNE];
1345 months[6] = localeMonths[Calendar.JULY];
1346 months[7] = localeMonths[Calendar.AUGUST];
1347 months[8] = localeMonths[Calendar.SEPTEMBER];
1348 months[9] = localeMonths[Calendar.OCTOBER];
1349 months[10] = localeMonths[Calendar.NOVEMBER];
1350 months[11] = localeMonths[Calendar.DECEMBER];
1351
1352 return months;
1353 }
1354
1355 public static String[] mapShortMonths(DateFormatSymbols symbols)
1356 {
1357 String[] months = new String[12];
1358
1359 String[] localeMonths = symbols.getShortMonths();
1360
1361 months[0] = localeMonths[Calendar.JANUARY];
1362 months[1] = localeMonths[Calendar.FEBRUARY];
1363 months[2] = localeMonths[Calendar.MARCH];
1364 months[3] = localeMonths[Calendar.APRIL];
1365 months[4] = localeMonths[Calendar.MAY];
1366 months[5] = localeMonths[Calendar.JUNE];
1367 months[6] = localeMonths[Calendar.JULY];
1368 months[7] = localeMonths[Calendar.AUGUST];
1369 months[8] = localeMonths[Calendar.SEPTEMBER];
1370 months[9] = localeMonths[Calendar.OCTOBER];
1371 months[10] = localeMonths[Calendar.NOVEMBER];
1372 months[11] = localeMonths[Calendar.DECEMBER];
1373
1374 return months;
1375 }
1376
1377
1378 public void decode(FacesContext facesContext, UIComponent component)
1379 {
1380 if(HtmlRendererUtils.isDisabledOrReadOnly(component))
1381 {
1382
1383 return;
1384 }
1385
1386 RendererUtils.checkParamValidity(facesContext, component, HtmlInputCalendar.class);
1387
1388
1389
1390 if (!(component instanceof EditableValueHolder)) {
1391 throw new IllegalArgumentException("Component "
1392 + component.getClientId(facesContext)
1393 + " is not an EditableValueHolder");
1394 }
1395 Map paramMap = facesContext.getExternalContext()
1396 .getRequestParameterMap();
1397 String clientId = component.getClientId(facesContext);
1398
1399 if(paramMap.containsKey(clientId))
1400 {
1401 String value = (String) paramMap.get(clientId);
1402
1403
1404
1405 ((EditableValueHolder) component).setSubmittedValue(value);
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417 }
1418 else
1419 {
1420 log.warn(HtmlRendererUtils.NON_SUBMITTED_VALUE_WARNING +
1421 " Component : "+
1422 RendererUtils.getPathToComponent(component));
1423 }
1424
1425 HtmlRendererUtils.decodeClientBehaviors(facesContext, component);
1426 }
1427
1428 protected static boolean isDisabled(FacesContext facesContext, UIComponent uiComponent)
1429 {
1430 if (!UserRoleUtils.isEnabledOnUserRole(uiComponent))
1431 {
1432 return true;
1433 }
1434 else
1435 {
1436 if (uiComponent instanceof HtmlInputCalendar)
1437 {
1438 return ((HtmlInputCalendar)uiComponent).isDisabled();
1439 }
1440 else
1441 {
1442 return org.apache.myfaces.shared_tomahawk.renderkit.RendererUtils.getBooleanAttribute(uiComponent, HTML.DISABLED_ATTR, false);
1443 }
1444 }
1445 }
1446
1447 public Object getConvertedValue(FacesContext facesContext, UIComponent uiComponent, Object submittedValue) throws ConverterException
1448 {
1449 RendererUtils.checkParamValidity(facesContext, uiComponent, HtmlInputCalendar.class);
1450
1451 AbstractHtmlInputCalendar uiInput = (AbstractHtmlInputCalendar) uiComponent;
1452
1453 Converter converter = uiInput.getConverter();
1454
1455 if (submittedValue != null && !(submittedValue instanceof String))
1456 {
1457 throw new IllegalArgumentException("Submitted value of type String expected");
1458 }
1459
1460
1461 if(submittedValue != null && submittedValue.equals(getHelperString(uiComponent)))
1462 return null;
1463
1464 if(converter==null)
1465 {
1466 converter = new CalendarDateTimeConverter();
1467
1468 Date date = (Date) converter.getAsObject(facesContext, uiComponent, (String) submittedValue);
1469
1470 return getDateBusinessConverter(uiInput).getBusinessValue(facesContext, uiComponent, date);
1471 }
1472 else
1473 {
1474 return converter.getAsObject(facesContext, uiComponent, (String) submittedValue);
1475 }
1476 }
1477
1478 public interface DateConverter extends Converter
1479 {
1480 public Date getAsDate(FacesContext facesContext, UIComponent uiComponent);
1481 }
1482
1483 private static String getHelperString(UIComponent uiComponent)
1484 {
1485 return uiComponent instanceof HtmlInputCalendar?((HtmlInputCalendar) uiComponent).getHelpText():null;
1486 }
1487
1488 public static class CalendarDateTimeConverter implements DateConverter
1489 {
1490 private static final String CONVERSION_MESSAGE_ID = "org.apache.myfaces.calendar.CONVERSION";
1491
1492 public Object getAsObject(FacesContext facesContext, UIComponent uiComponent, String s)
1493 {
1494 if(s==null || s.trim().length()==0 || s.equals(getHelperString(uiComponent)))
1495 return null;
1496
1497 if(uiComponent instanceof HtmlInputCalendar && ((HtmlInputCalendar) uiComponent).isRenderAsPopup())
1498 {
1499 HtmlInputCalendar calendar = (HtmlInputCalendar) uiComponent;
1500 String popupDateFormat = calendar.getPopupDateFormat();
1501 String formatStr = createJSPopupFormat(facesContext, popupDateFormat);
1502 Locale locale = facesContext.getViewRoot().getLocale();
1503 Calendar timeKeeper = Calendar.getInstance(locale);
1504 int firstDayOfWeek = timeKeeper.getFirstDayOfWeek() - 1;
1505 org.apache.myfaces.dateformat.DateFormatSymbols symbols = new org.apache.myfaces.dateformat.DateFormatSymbols(locale);
1506 SimpleDateFormatter dateFormat = new SimpleDateFormatter(formatStr, symbols, firstDayOfWeek);
1507
1508 Date date = dateFormat.parse(s);
1509 if (date != null) {
1510 return date;
1511 }
1512 FacesMessage msg = MessageUtils.getMessage(Constants.TOMAHAWK_DEFAULT_BUNDLE,FacesMessage.SEVERITY_ERROR,CONVERSION_MESSAGE_ID,new Object[]{
1513 uiComponent.getId(),s},facesContext);
1514 throw new ConverterException(msg);
1515 }
1516 else
1517 {
1518 DateFormat dateFormat = createStandardDateFormat(facesContext);
1519 dateFormat.setLenient(false);
1520 try
1521 {
1522 Date date = dateFormat.parse(s);
1523 return date;
1524 }
1525 catch (ParseException e)
1526 {
1527 FacesMessage msg = MessageUtils.getMessage(Constants.TOMAHAWK_DEFAULT_BUNDLE,FacesMessage.SEVERITY_ERROR,CONVERSION_MESSAGE_ID,new Object[]{
1528 uiComponent.getId(),s},facesContext);
1529 throw new ConverterException(msg,e);
1530 }
1531 }
1532 }
1533
1534 public Date getAsDate(FacesContext facesContext, UIComponent uiComponent)
1535 {
1536 return RendererUtils.getDateValue(uiComponent);
1537 }
1538
1539 public static String createJSPopupFormat(FacesContext facesContext, String popupDateFormat)
1540 {
1541
1542 if(popupDateFormat == null)
1543 {
1544 SimpleDateFormat defaultDateFormat = createStandardDateFormat(facesContext);
1545 popupDateFormat = defaultDateFormat.toPattern();
1546 }
1547
1548 return popupDateFormat;
1549 }
1550
1551 public String getAsString(FacesContext facesContext, UIComponent uiComponent, Object o)
1552 {
1553 Date date = (Date) o;
1554
1555 if(date==null)
1556 return getHelperString(uiComponent);
1557
1558 if(uiComponent instanceof HtmlInputCalendar && ((HtmlInputCalendar) uiComponent).isRenderAsPopup())
1559 {
1560 HtmlInputCalendar calendar = (HtmlInputCalendar) uiComponent;
1561 String popupDateFormat = calendar.getPopupDateFormat();
1562 String formatStr = createJSPopupFormat(facesContext, popupDateFormat);
1563 Locale locale = facesContext.getViewRoot().getLocale();
1564 Calendar timeKeeper = Calendar.getInstance(locale);
1565 int firstDayOfWeek = timeKeeper.getFirstDayOfWeek() - 1;
1566 org.apache.myfaces.dateformat.DateFormatSymbols symbols = new org.apache.myfaces.dateformat.DateFormatSymbols(locale);
1567
1568 SimpleDateFormatter dateFormat = new SimpleDateFormatter(formatStr, symbols, firstDayOfWeek);
1569 return dateFormat.format(date);
1570 }
1571 else
1572 {
1573 DateFormat dateFormat = createStandardDateFormat(facesContext);
1574 dateFormat.setLenient(false);
1575 return dateFormat.format(date);
1576 }
1577 }
1578
1579 private static SimpleDateFormat createStandardDateFormat(FacesContext facesContext)
1580 {
1581 DateFormat dateFormat;
1582 dateFormat = DateFormat.getDateInstance(DateFormat.SHORT,
1583 facesContext.getViewRoot().getLocale());
1584
1585 if(dateFormat instanceof SimpleDateFormat)
1586 return (SimpleDateFormat) dateFormat;
1587 else
1588 return new SimpleDateFormat("dd.MM.yyyy", facesContext.getViewRoot().getLocale());
1589 }
1590 }
1591 }