001 package edu.nrao.sss.webapp.faces.component; 002 003 import javax.faces.component.UIInput; 004 import javax.faces.context.FacesContext; 005 import javax.faces.context.ResponseWriter; 006 import javax.faces.el.ValueBinding; 007 008 import java.io.IOException; 009 import java.util.Map; 010 import java.util.Date; 011 import java.text.SimpleDateFormat; 012 013 import edu.nrao.sss.util.DateUtility; 014 import edu.nrao.sss.webapp.faces.converter.DateConverter; 015 016 import org.apache.log4j.Logger; 017 018 public class DateTimeUIComponent extends UIInput 019 { 020 private static final Logger log = Logger.getLogger(DateTimeUIComponent.class); 021 022 private Boolean enabled = null; 023 private Boolean showTime = null; 024 private String dateSeparator = null; 025 private String timeSeparator = null; 026 027 protected static final SimpleDateFormat getYear = new SimpleDateFormat("yyyy"); 028 protected static final SimpleDateFormat getMonth = new SimpleDateFormat("MM"); 029 protected static final SimpleDateFormat getDay = new SimpleDateFormat("dd"); 030 protected static final SimpleDateFormat getHour = new SimpleDateFormat("HH"); 031 protected static final SimpleDateFormat getMinute = new SimpleDateFormat("mm"); 032 protected static final SimpleDateFormat getSecond = new SimpleDateFormat("ss"); 033 034 public void encodeBegin(FacesContext context) 035 throws IOException 036 { 037 boolean enabled = isEnabled(); 038 039 Map attrs = getAttributes(); 040 String disabledDateStyleClass = (String)attrs.get("disabledDateStyleClass"); 041 String disabledTimeStyleClass = (String)attrs.get("disabledTimeStyleClass"); 042 043 String dateStyleClass = (String)attrs.get("dateStyleClass"); 044 String timeStyleClass = (String)attrs.get("timeStyleClass"); 045 String dateFieldStyleClass = (String)attrs.get("dateFieldStyleClass"); 046 String timeFieldStyleClass = (String)attrs.get("timeFieldStyleClass"); 047 048 ResponseWriter writer = context.getResponseWriter(); 049 050 String id = getClientId(context); 051 String yearId = id + ":year"; 052 String monthId = id + ":month"; 053 String dayId = id + ":day"; 054 String hourId = id + ":hour"; 055 String minuteId = id + ":minute"; 056 String secondId = id + ":second"; 057 058 String year = "yyyy"; 059 String month = "MM"; 060 String day = "dd"; 061 String hour = "HH"; 062 String minute = "mm"; 063 String second = "ss"; 064 065 Date date = (Date)getValue(); 066 067 if (date != null && !DateUtility.earlyDateEquals(date) && !DateUtility.lateDateEquals(date)) 068 { 069 year = getYear.format(date); 070 month = getMonth.format(date); 071 day = getDay.format(date); 072 hour = getHour.format(date); 073 minute = getMinute.format(date); 074 second = getSecond.format(date); 075 } 076 077 // wrapper span with our component id on it 078 writer.startElement("span", this); 079 080 //We render two wrapper spans, one for the date input and one for the time input. 081 writer.startElement("span", this); 082 writer.writeAttribute("id", id, null); 083 084 //Now 3 input fields with 2 spans for separators. 085 if (enabled) 086 { 087 if (dateStyleClass != null && dateStyleClass.length() > 0) 088 writer.writeAttribute("class", dateStyleClass, null); 089 writer.startElement("input", this); 090 writer.writeAttribute("type", "text", null); 091 writer.writeAttribute("id", yearId, null); 092 writer.writeAttribute("name", yearId, null); 093 writer.writeAttribute("value", year, null); 094 writer.writeAttribute("size", 4, null); 095 writer.writeAttribute("maxlength", 4, null); 096 writer.writeAttribute("onfocus", "if(this.value == 'yyyy'){this.value='';}", null); 097 writer.writeAttribute("onblur", "iceSubmitPartial(form, this, event); return false;", null); 098 099 if (dateFieldStyleClass != null && dateFieldStyleClass.length() > 0) 100 writer.writeAttribute("class", dateFieldStyleClass, null); 101 writer.endElement("input"); 102 103 encodeDateSeparator(writer); 104 105 writer.startElement("input", this); 106 writer.writeAttribute("type", "text", null); 107 writer.writeAttribute("id", monthId, null); 108 writer.writeAttribute("name", monthId, null); 109 writer.writeAttribute("value", month, null); 110 writer.writeAttribute("size", 2, null); 111 writer.writeAttribute("maxlength", 2, null); 112 writer.writeAttribute("onfocus", "if(this.value == 'MM'){this.value='';}", null); 113 writer.writeAttribute("onblur", "iceSubmitPartial(form, this, event); return false;", null); 114 115 if (dateFieldStyleClass != null && dateFieldStyleClass.length() > 0) 116 writer.writeAttribute("class", dateFieldStyleClass, null); 117 118 writer.endElement("input"); 119 120 encodeDateSeparator(writer); 121 122 writer.startElement("input", this); 123 writer.writeAttribute("type", "text", null); 124 writer.writeAttribute("id", dayId, null); 125 writer.writeAttribute("name", dayId, null); 126 writer.writeAttribute("value", day, null); 127 writer.writeAttribute("size", 2, null); 128 writer.writeAttribute("maxlength", 2, null); 129 writer.writeAttribute("onfocus", "if(this.value == 'dd'){this.value='';}", null); 130 writer.writeAttribute("onblur", "iceSubmitPartial(form, this, event); return false;", null); 131 132 if (dateFieldStyleClass != null && dateFieldStyleClass.length() > 0) 133 writer.writeAttribute("class", dateFieldStyleClass, null); 134 writer.endElement("input"); 135 } 136 137 else 138 { 139 if (disabledDateStyleClass != null && disabledDateStyleClass.length() > 0) 140 writer.writeAttribute("class", disabledDateStyleClass, null); 141 writer.startElement("span", this); 142 if (dateFieldStyleClass != null && dateFieldStyleClass.length() > 0) 143 writer.writeAttribute("class", dateFieldStyleClass, null); 144 writer.write(year); 145 writer.endElement("span"); 146 147 encodeDateSeparator(writer); 148 149 writer.startElement("span", this); 150 if (dateFieldStyleClass != null && dateFieldStyleClass.length() > 0) 151 writer.writeAttribute("class", dateFieldStyleClass, null); 152 writer.write(month); 153 writer.endElement("span"); 154 155 encodeDateSeparator(writer); 156 157 writer.startElement("span", this); 158 if (dateFieldStyleClass != null && dateFieldStyleClass.length() > 0) 159 writer.writeAttribute("class", dateFieldStyleClass, null); 160 writer.write(day); 161 writer.endElement("span"); 162 } 163 164 165 //End the date input element 166 writer.endElement("span"); 167 168 if (getShowTime()) 169 { 170 writer.startElement("span", this); 171 172 //Now 3 input fields with 2 spans for separators. 173 if (enabled) 174 { 175 if (timeStyleClass != null && timeStyleClass.length() > 0) 176 writer.writeAttribute("class", timeStyleClass, null); 177 writer.startElement("input", this); 178 writer.writeAttribute("type", "text", null); 179 writer.writeAttribute("id", hourId, null); 180 writer.writeAttribute("name", hourId, null); 181 writer.writeAttribute("value", hour, null); 182 writer.writeAttribute("size", 2, null); 183 writer.writeAttribute("maxlength", 2, null); 184 writer.writeAttribute("onfocus", "if(this.value == 'HH'){this.value='';}", null); 185 writer.writeAttribute("onblur", "iceSubmitPartial(form, this, event); return false;", null); 186 187 if (timeFieldStyleClass != null && timeFieldStyleClass.length() > 0) 188 writer.writeAttribute("class", timeFieldStyleClass, null); 189 writer.endElement("input"); 190 191 encodeTimeSeparator(writer); 192 193 writer.startElement("input", this); 194 writer.writeAttribute("type", "text", null); 195 writer.writeAttribute("id", minuteId, null); 196 writer.writeAttribute("name", minuteId, null); 197 writer.writeAttribute("value", minute, null); 198 writer.writeAttribute("size", 2, null); 199 writer.writeAttribute("maxlength", 2, null); 200 writer.writeAttribute("onfocus", "if(this.value == 'mm'){this.value='';}", null); 201 writer.writeAttribute("onblur", "iceSubmitPartial(form, this, event); return false;", null); 202 203 if (timeFieldStyleClass != null && timeFieldStyleClass.length() > 0) 204 writer.writeAttribute("class", timeFieldStyleClass, null); 205 206 writer.endElement("input"); 207 208 encodeTimeSeparator(writer); 209 210 writer.startElement("input", this); 211 writer.writeAttribute("type", "text", null); 212 writer.writeAttribute("id", secondId, null); 213 writer.writeAttribute("name", secondId, null); 214 writer.writeAttribute("value", second, null); 215 writer.writeAttribute("size", 2, null); 216 writer.writeAttribute("maxlength", 2, null); 217 writer.writeAttribute("onfocus", "if(this.value == 'ss'){this.value='';}", null); 218 writer.writeAttribute("onblur", "iceSubmitPartial(form, this, event); return false;", null); 219 220 if (timeFieldStyleClass != null && timeFieldStyleClass.length() > 0) 221 writer.writeAttribute("class", timeFieldStyleClass, null); 222 223 writer.endElement("input"); 224 } 225 226 else 227 { 228 if (disabledTimeStyleClass != null && disabledTimeStyleClass.length() > 0) 229 writer.writeAttribute("class", disabledTimeStyleClass, null); 230 writer.startElement("span", this); 231 if (timeFieldStyleClass != null && timeFieldStyleClass.length() > 0) 232 writer.writeAttribute("class", timeFieldStyleClass, null); 233 writer.write(hour); 234 writer.endElement("span"); 235 236 encodeTimeSeparator(writer); 237 238 writer.startElement("span", this); 239 if (timeFieldStyleClass != null && timeFieldStyleClass.length() > 0) 240 writer.writeAttribute("class", timeFieldStyleClass, null); 241 writer.write(minute); 242 writer.endElement("span"); 243 244 encodeTimeSeparator(writer); 245 246 writer.startElement("span", this); 247 if (timeFieldStyleClass != null && timeFieldStyleClass.length() > 0) 248 writer.writeAttribute("class", timeFieldStyleClass, null); 249 writer.write(second); 250 writer.endElement("span"); 251 } 252 253 //End the time input element 254 writer.endElement("span"); 255 } 256 257 // end main wrapper 258 writer.endElement("span"); 259 } 260 261 private void encodeDateSeparator(ResponseWriter writer) 262 throws IOException 263 { 264 writer.write(getDateSeparator()); 265 } 266 267 private void encodeTimeSeparator(ResponseWriter writer) 268 throws IOException 269 { 270 writer.write(getTimeSeparator()); 271 } 272 273 public void decode(FacesContext context) 274 { 275 String id = getClientId(context); 276 String yearId = id + ":year"; 277 String monthId = id + ":month"; 278 String dayId = id + ":day"; 279 String hourId = id + ":hour"; 280 String minuteId = id + ":minute"; 281 String secondId = id + ":second"; 282 283 Map parms = context.getExternalContext().getRequestParameterMap(); 284 285 String year = (String)parms.get(yearId); 286 String month = (String)parms.get(monthId); 287 String day = (String)parms.get(dayId); 288 String hour = (String)parms.get(hourId); 289 String minute = (String)parms.get(minuteId); 290 String second = (String)parms.get(secondId); 291 292 293 boolean showTime = getShowTime(); 294 295 if (year == null || month == null || day == null) 296 setSubmittedValue(null); 297 298 else if (showTime && (hour == null || minute == null || second == null)) 299 setSubmittedValue(null); 300 301 else 302 { 303 boolean atLeastOneSet = false; 304 if (year.equals("yyyy")) 305 year = "2000"; 306 else 307 atLeastOneSet = true; 308 309 if (month.equals("MM")) 310 month = "01"; 311 else 312 atLeastOneSet = true; 313 314 if (day.equals("dd")) 315 day = "01"; 316 else 317 atLeastOneSet = true; 318 319 if (showTime) 320 { 321 if (hour.equals("HH")) 322 hour = "00"; 323 else 324 atLeastOneSet = true; 325 326 if (minute.equals("mm")) 327 minute = "00"; 328 else 329 atLeastOneSet = true; 330 331 if (second.equals("ss")) 332 second = "00"; 333 else 334 atLeastOneSet = true; 335 } 336 337 if (!atLeastOneSet) 338 setSubmittedValue(null); 339 340 else 341 { 342 //Regardless of the separators the user sees, here we need to use the 343 //separators that the DateConverter is expecting. 344 345 StringBuilder date = new StringBuilder(year); 346 date.append(DateConverter.dateFieldSeparator); 347 date.append(month); 348 date.append(DateConverter.dateFieldSeparator); 349 date.append(day); 350 351 date.append(DateConverter.dateTimeSeparator); 352 353 if (showTime) 354 { 355 date.append(hour); 356 date.append(DateConverter.timeFieldSeparator); 357 date.append(minute); 358 date.append(DateConverter.timeFieldSeparator); 359 date.append(second); 360 } 361 362 else 363 { 364 date.append("00"); 365 date.append(DateConverter.timeFieldSeparator); 366 date.append("00"); 367 date.append(DateConverter.timeFieldSeparator); 368 date.append("00"); 369 } 370 371 setValid(true); 372 373 setSubmittedValue(date.toString()); 374 } 375 } 376 } 377 378 public Object saveState(FacesContext context) 379 { 380 Object[] state = new Object[4]; 381 state[0] = super.saveState(context); 382 state[1] = this.enabled; 383 state[2] = this.dateSeparator; 384 state[3] = this.timeSeparator; 385 state[4] = this.showTime; 386 387 return state; 388 } 389 390 public void restoreState(FacesContext context, Object state) 391 { 392 Object[] myState = (Object[])state; 393 super.restoreState(context, myState[0]); 394 setEnabled((Boolean)myState[1]); 395 setDateSeparator((String)myState[2]); 396 setTimeSeparator((String)myState[3]); 397 setShowTime((Boolean)myState[4]); 398 } 399 400 public String getDateSeparator() 401 { 402 if (this.dateSeparator != null) 403 return this.dateSeparator; 404 405 ValueBinding vb = getValueBinding("dateSeparator"); 406 if (vb != null) 407 { 408 Object val = vb.getValue(getFacesContext()); 409 410 if (val instanceof String && val != null) 411 return (String)val; 412 } 413 414 //else 415 return "-"; 416 } 417 418 public void setDateSeparator(String s) 419 { 420 this.dateSeparator = s; 421 } 422 423 public String getTimeSeparator() 424 { 425 if (this.timeSeparator != null) 426 return this.timeSeparator; 427 428 ValueBinding vb = getValueBinding("timeSeparator"); 429 if (vb != null) 430 { 431 Object val = vb.getValue(getFacesContext()); 432 433 if (val instanceof String && val != null) 434 return (String)val; 435 } 436 437 //else 438 return ":"; 439 } 440 441 public void setTimeSeparator(String s) 442 { 443 this.timeSeparator = s; 444 } 445 446 public Boolean isEnabled() 447 { 448 if (this.enabled != null) 449 return this.enabled; 450 451 ValueBinding vb = getValueBinding("enabled"); 452 if (vb != null) 453 { 454 Object val = vb.getValue(getFacesContext()); 455 456 if (val instanceof Boolean && val != null) 457 return (Boolean)val; 458 } 459 460 //else 461 return Boolean.TRUE; 462 } 463 464 public void setEnabled(Boolean e) 465 { 466 this.enabled = e; 467 } 468 469 public Boolean getShowTime() 470 { 471 if (this.showTime != null) 472 return this.showTime; 473 474 ValueBinding vb = getValueBinding("showTime"); 475 if (vb != null) 476 { 477 Object val = vb.getValue(getFacesContext()); 478 479 if (val instanceof Boolean && val != null) 480 return (Boolean)val; 481 } 482 483 //else 484 return Boolean.TRUE; 485 } 486 487 public void setShowTime(Boolean s) 488 { 489 this.showTime = s; 490 } 491 492 493 /** Overridden to be empty. */ 494 public void encodeEnd(FacesContext context) throws IOException {} 495 496 /** Overridden to be empty. */ 497 public void encodeChildren(FacesContext context) throws IOException {} 498 }