1 18 19 package sync4j.syncclient.blackberry.parser; 20 21 import java.util.Calendar ; 22 import java.util.Date ; 23 import java.util.Hashtable ; 24 import java.util.TimeZone ; 25 import java.util.Vector ; 26 27 import javax.microedition.pim.Event; 28 import javax.microedition.pim.EventList; 29 import net.rim.device.api.ui.component.Dialog; 30 import net.rim.device.api.i18n.SimpleDateFormat; 31 32 import sync4j.syncclient.common.StringTools; 33 34 import sync4j.syncclient.util.StaticDataHelper; 35 36 import sync4j.syncclient.util.StaticDataHelper; 37 38 45 46 public class XMLEventParser implements EventParser{ 47 48 50 private static final String SUMMARY = "Subject" ; 51 private static final String LOCATION = "Location" ; 52 private static final String NOTE = "Body" ; 53 private static final String START = "Start" ; 54 private static final String END = "End" ; 55 private static final String REVISION = "Revision" ; 56 private static final String ALARM = "ReminderMinutesBeforeStart" ; 57 private static final String CLASS = "Class" ; 58 59 private static final String START_MARKER = "<appointment>" ; 60 private static final String END_MARKER = "</appointment>" ; 61 62 private static final String DATETIME_FORMAT_UTC 63 = "yyyyMMdd'T'HHmmss'Z'" ; 64 65 private static final String UTC_TIMEZONE = "UTC" ; 66 67 69 private String [] tagArray = { 70 SUMMARY , 71 LOCATION , 72 NOTE , 73 START , 74 END , 75 REVISION , 76 ALARM , 77 CLASS 78 }; 79 80 private EventList list ; 81 private Event event ; 82 private boolean modify ; 83 84 92 public XMLEventParser(EventList list, Event event, boolean modify) { 93 94 this.list = list ; 95 this.event = event ; 96 this.modify = modify ; 97 } 98 99 107 public Event parseEvent(String eventString) { 108 109 if(modify) { 110 return modifyEvent (eventString); 111 } else { 112 return addEvent (eventString); 113 } 114 115 } 116 117 125 public Event addEvent(String eventString) { 126 127 Hashtable eventMap = buildMapFromXML(eventString); 128 if (eventMap != null) { 129 try { 130 131 String field = getValue(eventMap, SUMMARY); 132 if (isSupportedField(Event.SUMMARY, field)) { 133 event.addString(Event.SUMMARY, Event.ATTR_NONE, field); 134 } 135 136 field = getValue(eventMap, LOCATION); 137 if (isSupportedField(Event.LOCATION, field)) { 138 event.addString(Event.LOCATION, Event.ATTR_NONE, field); 139 } 140 141 field = getValue(eventMap, NOTE); 142 if (isSupportedField(Event.NOTE, field)) { 143 event.addString(Event.NOTE, Event.ATTR_NONE, field); 144 } 145 146 field = getValue(eventMap, START); 147 if (field != null && field.length() > 0) { 148 long dateStart = getDate(field); 149 if (isSupportedField(Event.START, field)) { 150 event.addDate(Event.START, Event.ATTR_NONE, dateStart); 151 } 152 } 153 154 field = getValue(eventMap, END); 155 if (field != null && field.length() > 0) { 156 long dateEnd = getDate(field); 157 if (isSupportedField(Event.END, field)) { 158 event.addDate(Event.END, Event.ATTR_NONE, dateEnd); 159 } 160 } 161 162 field = getValue(eventMap, REVISION); 163 if (field != null && field.length() > 0) { 164 long dateRevision = getDate(field); 165 if (isSupportedField(Event.REVISION, field)) { 166 event.addDate(Event.REVISION, Event.ATTR_NONE, dateRevision); 167 } 168 } 169 170 field = getValue(eventMap, ALARM); 171 if (field != null && field.length() > 0 && isSupportedField(Event.ALARM, field)) { 172 event.addInt(Event.ALARM, Event.ATTR_NONE, Integer.parseInt(field)); 173 } 174 175 field = getValue(eventMap, CLASS); 176 if (isSupportedField(Event.CLASS, field)) { 177 event.addInt(Event.CLASS, Event.ATTR_NONE, Integer.parseInt(field)); 178 } 179 180 return event; 181 182 } catch (Exception e) { 183 e.printStackTrace(); 184 return null; 185 } 186 } 187 188 return null; 189 } 190 191 199 public Event modifyEvent(String eventString) { 200 201 Hashtable eventMap = buildMapFromXML(eventString); 202 203 if (eventMap != null) { 204 205 try { 206 String field = getValue(eventMap, SUMMARY); 207 if (isSupportedField(Event.SUMMARY, field) && event.countValues(Event.SUMMARY) > 0) { 208 event.setString(Event.SUMMARY, 0, Event.ATTR_NONE, field); 209 } else { 210 event.removeValue(Event.SUMMARY, 0); 211 event.addString(Event.SUMMARY, Event.ATTR_NONE, field); 212 } 213 214 field = getValue(eventMap, LOCATION); 215 if (isSupportedField(Event.LOCATION, field) && event.countValues(Event.LOCATION) > 0) { 216 event.setString(Event.LOCATION, 0, Event.ATTR_NONE, field); 217 } else { 218 event.addString(Event.LOCATION, Event.ATTR_NONE, field); 219 } 220 221 field = getValue(eventMap, NOTE); 222 223 if (isSupportedField(Event.NOTE, field) && event.countValues(Event.NOTE) > 0) { 224 event.setString(Event.NOTE, 0, Event.ATTR_NONE, field); 225 } else { 226 event.addString(Event.NOTE, Event.ATTR_NONE, field); 227 } 228 229 field = getValue(eventMap, START); 230 if (field != null && field.length() > 0) { 231 long dateStart = getDate(field); 232 event.removeValue(Event.START, 0); 233 event.addDate(Event.START, Event.ATTR_NONE, dateStart); 234 } 235 236 field = getValue(eventMap, END); 237 if (field != null && field.length() > 0) { 238 long dateEnd = getDate(field); 239 event.removeValue(Event.END, 0); 240 event.addDate(Event.END, Event.ATTR_NONE, dateEnd); 241 } 242 243 field = getValue(eventMap, REVISION); 244 if (field != null && field.length() > 0) { 245 long dateRevision = getDate(field); 246 if (isSupportedAtrributedField(Event.END, Event.ATTR_NONE, field)) { 247 event.removeValue(Event.REVISION, 0); 248 event.addDate(Event.REVISION, Event.ATTR_NONE, dateRevision); 249 } 250 } 251 252 field = getValue(eventMap, ALARM); 253 254 if (field != null && field.length() > 0) { 255 256 int alarmSecondsBefore = getAlarmSecondsBefore(field); 257 if (isSupportedAtrributedField(Event.ALARM, Event.ATTR_NONE, field) && event.countValues(Event.ALARM) > 0) { 258 event.setInt(Event.ALARM, 0, Event.ATTR_NONE,alarmSecondsBefore); 259 } else { 260 event.addInt(Event.ALARM, Event.ATTR_NONE, alarmSecondsBefore); 261 } 262 263 } 264 265 field = getValue(eventMap, CLASS); 266 if (isSupportedAtrributedField(Event.CLASS, Event.ATTR_NONE, field)) { 267 event.removeValue(Event.ALARM, 0); 268 event.addInt(Event.CLASS, Event.ATTR_NONE, Integer.parseInt(field)); 269 } 270 271 return event; 272 } catch (Exception e) { 273 e.printStackTrace(); 274 return null; 275 } 276 } 277 return null; 278 } 279 280 287 public String toString(Event event) { 288 289 StringBuffer eventBuffer = new StringBuffer (); 290 291 eventBuffer.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); 292 293 eventBuffer.append("<appointment>\n"); 294 295 appendField (eventBuffer , 296 event , 297 Event.SUMMARY , 298 SUMMARY ); 299 300 appendField (eventBuffer , 301 event , 302 Event.LOCATION , 303 LOCATION ); 304 305 appendField (eventBuffer , 306 event , 307 Event.NOTE , 308 NOTE ); 309 310 appendFieldDate (eventBuffer , 311 event , 312 Event.START , 313 START ); 314 315 appendFieldDate (eventBuffer , 316 event , 317 Event.END , 318 END ); 319 320 appendFieldAlarmMB (eventBuffer , 321 event , 322 Event.ALARM , 323 ALARM ); 324 325 eventBuffer.append("</appointment>"); 326 327 return eventBuffer.toString(); 328 } 329 330 332 343 private void appendField(StringBuffer eventBuffer , 344 Event event , 345 int field , 346 String tag ) { 347 348 String value = null; 349 350 if (list.isSupportedField(field)) { 351 352 value = ""; 353 354 try { 355 value = event.getString(field, 0); 356 } catch (Exception e) { 357 StaticDataHelper.log("Not set field: " + tag); 358 } 359 360 appendToEvent(eventBuffer, tag, value); 361 } 362 } 363 364 375 private void appendFieldDate(StringBuffer eventBuffer , 376 Event event , 377 int field , 378 String tag) { 379 380 StaticDataHelper sdh = null ; 381 382 long value = 0 ; 383 Calendar rightNow = null ; 384 String formattedDate = null ; 385 SimpleDateFormat formatter = null ; 386 387 String format = null ; 388 389 long offset = 0 ; 390 391 sdh = new StaticDataHelper(); 392 393 if (list.isSupportedField(field)) { 394 395 try { 396 value = event.getDate(field, 0); 397 } catch (Exception e) { 398 StaticDataHelper.log("Not set field: " + tag); 399 } 400 401 format = DATETIME_FORMAT_UTC; 402 offset = getTimeZoneOffSet(); 403 404 rightNow = Calendar.getInstance(); 405 406 rightNow.setTime(new Date (value)); 407 408 formatter = new SimpleDateFormat (format); 409 formattedDate = formatter.format 410 (new Date (rightNow.getTime().getTime() - offset)); 411 412 appendToEvent(eventBuffer, tag, formattedDate); 413 } 414 } 415 416 427 private void appendFieldInt(StringBuffer eventBuffer , 428 Event event , 429 int field , 430 String tag ) { 431 432 String value = null ; 433 434 if (list.isSupportedField(field)) { 435 436 value = ""; 437 438 try { 439 value = String.valueOf(event.getInt(field, 0)); 440 } catch (Exception e) { 441 StaticDataHelper.log("Not set field: " + tag); 442 } 443 444 appendToEvent(eventBuffer, tag, value); 445 } 446 } 447 448 458 private void appendFieldAlarmMB(StringBuffer eventBuffer , 459 Event event , 460 int field , 461 String tag ) { 462 463 String value = null ; 464 465 if (list.isSupportedField(field)) { 466 467 value = ""; 468 469 try { 470 value = String.valueOf((event.getInt(field, 0))/60); 471 } catch (Exception e) { 472 StaticDataHelper.log("Not set field: " + tag); 473 } 474 475 appendToEvent(eventBuffer, tag, value); 476 } 477 } 478 479 488 private void appendToEvent(StringBuffer eventBuffer, String tag, String value) { 489 490 value = (value == null) ? "" : value; 491 492 if (value.length() > 0) { 493 value = StringTools.escapeXml(value); 494 } 495 496 eventBuffer.append("<").append(tag).append(">").append(value); 497 498 eventBuffer.append("</").append(tag).append(">\n"); 499 500 } 501 502 510 private String getValue(Hashtable eventMap, String key) { 511 Object val = eventMap.get(key); 512 String value = val == null ? "" : val.toString(); 513 return value.trim(); 514 } 515 516 526 private boolean isSupportedAtrributedField(int field, int attribute, String value) { 527 return isSupportedField(field, value) && list.isSupportedAttribute(field, attribute); 528 } 529 530 538 private boolean isSupportedField(int type, String value) { 539 return list.isSupportedField(type); 540 } 541 542 549 private Hashtable buildMapFromXML(String eventString) { 550 int startMarkerIndex = eventString.indexOf(START_MARKER); 551 int endMarkerIndex = eventString.indexOf(END_MARKER); 552 553 if(startMarkerIndex == -1 || endMarkerIndex == -1) { 554 Dialog.inform("Improper data from the server."); 555 return null; 556 } 557 558 Hashtable eventMap = new Hashtable (); 559 String startTag = ""; 560 String endTag = ""; 561 String degeneratedTag = ""; 562 String data = ""; 563 564 for (int i = 0; i < tagArray.length; i++) { 565 String tag = tagArray[i]; 566 567 startTag = "<"+tag+">"; 568 569 int startTagIndex = eventString.indexOf(startTag); 570 if(startTagIndex == -1) { 571 continue; 572 } 573 574 degeneratedTag = "<"+tag+"/>"; 575 int degeneratedTagIndex = eventString.indexOf(degeneratedTag); 576 if(degeneratedTagIndex != -1) { 577 continue; 578 } 579 580 endTag = "</"+tag+">"; 581 582 int endTagIndex = eventString.indexOf(endTag); 583 if(endTagIndex != -1) { 584 data = eventString.substring(startTagIndex+startTag.length(), endTagIndex); 585 } else { 586 data = ""; 587 } 588 589 if (data.length() > 0) { 590 data = StringTools.unescapeXml(data); 591 } 592 593 eventMap.put(tag, data); 594 } 595 return eventMap; 596 } 597 598 603 private long getDate(String field) { 604 605 int day = 0 ; 606 int mounth = 0 ; 607 int year = 0 ; 608 int hour = 0 ; 609 int minute = 0 ; 610 int second = 0 ; 611 612 long offset = 0 ; 613 614 Calendar date = null ; 615 616 offset = getTimeZoneOffSet(); 617 618 day = Integer.parseInt (field.substring( 6 , 8 )); 619 mounth = Integer.parseInt (field.substring( 4 , 6 )); 620 year = Integer.parseInt (field.substring( 0 , 4 )); 621 hour = Integer.parseInt (field.substring( 9 , 11 )); 622 minute = Integer.parseInt (field.substring( 11 , 13 )); 623 second = Integer.parseInt (field.substring( 13 , 15 )); 624 625 date = Calendar.getInstance(); 626 627 date.set(Calendar.DAY_OF_MONTH , day ) ; 628 date.set(Calendar.MONTH , mounth - 1 ) ; 629 date.set(Calendar.YEAR , year ) ; 630 date.set(Calendar.HOUR_OF_DAY , hour ) ; 631 date.set(Calendar.MINUTE , minute ) ; 632 date.set(Calendar.SECOND , second ) ; 633 634 return date.getTime().getTime() + offset; 635 636 } 637 638 643 private int getAlarmSecondsBefore(String field) 644 throws NumberFormatException { 645 int alarmMinutesBefore = Integer.parseInt(field) * 60; 646 return alarmMinutesBefore; 647 } 648 649 652 private long getTimeZoneOffSet() { 653 654 Calendar now = null; 655 TimeZone zn = null; 656 long offset = 0; 657 658 now = Calendar.getInstance(); 659 660 now.setTime(new Date ()); 661 662 zn = TimeZone.getDefault(); 663 664 offset = zn.getOffset(1 , 665 now.get(Calendar.YEAR) , 666 now.get(Calendar.MONTH) , 667 now.get(Calendar.DAY_OF_MONTH) , 668 now.get(Calendar.DAY_OF_WEEK) , 669 now.get(Calendar.HOUR_OF_DAY) * 60 * 60 * 1000 + 670 now.get(Calendar.MINUTE) * 60 * 1000 + 671 now.get(Calendar.SECOND) * 1000 ); 672 673 674 return offset; 675 676 } 677 678 679 } 680 | Popular Tags |