1 18 19 package sync4j.exchange.items.calendar.dao; 20 21 import java.io.IOException ; 22 import java.text.MessageFormat ; 23 import java.util.ArrayList ; 24 import java.util.StringTokenizer ; 25 26 import sync4j.foundation.pdi.event.Reminder; 27 import sync4j.foundation.pdi.event.RecurrencePattern; 28 29 import sync4j.exchange.DataAccessException; 30 import sync4j.exchange.httptransport.WebDavHttpTransport; 31 import sync4j.exchange.items.calendar.model.Calendar; 32 import sync4j.exchange.items.common.dao.ItemDAO; 33 import sync4j.exchange.util.StringTools; 34 import sync4j.exchange.xml.XmlParseException; 35 import sync4j.exchange.xml.XmlParser; 36 37 38 46 public class CalendarDAO extends ItemDAO { 47 48 public static final String TAG_ALLDAYEVENT = "alldayevent" ; 50 public static final String TAG_BODY = 51 "textdescription" ; 52 public static final String TAG_BUSY_STATUS = "busystatus" ; 53 public static final String TAG_DATEEND = "dtend" ; 54 public static final String TAG_DATESTART = "dtstart" ; 55 56 public static final String TAG_LOCATION = "location" ; 57 public static final String TAG_RESPONSE = "a:response" ; 58 public static final String TAG_SUBJECT = "subject" ; 59 60 public static final String TAG_REMINDER_SET = "reminderset" ; 61 public static final String TAG_REMINDER_OFFSET = "reminderoffset" ; 62 63 public static final String TAG_REPLY_TIME = "replytime" ; 64 65 public static final String TAG_SENSITIVITY = "sensitivity" ; 66 67 public static final String TAG_RECURRENCE = "rrule" ; 68 69 public static final String TAG_SEQUENCE = "sequence" ; 70 71 public static final String TAG_MILEAGE = "mileage" ; 72 public static final String TAG_IMPORTANCE = "importance" ; 73 74 public static final String TAG_CATEGORIES = "categories" ; 75 76 public static final String TAG_REPLUID = "repluid" ; 77 public static final String TAG_LAST_MODIFIED = "getlastmodified" ; 78 79 private static final String WEBDAV_MSG_SELECT_CALENDARS = 80 "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n" + 81 "<D:searchrequest xmlns:D =\"DAV:\">\n" + 82 "<D:sql>\n" + 83 "Select " + 84 "\"http://schemas.microsoft.com/repl/repl-uid\" AS " + TAG_REPLUID + ", " + 85 "\"urn:schemas:calendar:location\" AS " + TAG_LOCATION + ", " + 86 "\"urn:schemas:httpmail:subject\" AS " + TAG_SUBJECT + ", " + 87 "\"urn:schemas:httpmail:textdescription\" AS " + TAG_BODY + ", " + 88 "\"urn:schemas:calendar:dtstart\" AS " + TAG_DATESTART + ", " + 89 "\"urn:schemas:calendar:dtend\" AS " + TAG_DATEEND + ", " + 90 "\"urn:schemas:calendar:alldayevent\" AS " + TAG_ALLDAYEVENT + ", " + 91 "\"urn:schemas:calendar:busystatus\" AS " + TAG_BUSY_STATUS + ", " + 92 "\"urn:schemas:calendar:sequence\" AS " + TAG_SEQUENCE + ", " + 93 "\"urn:schemas:calendar:rrule\" AS " + TAG_RECURRENCE + ", " + 94 "\"http://schemas.microsoft.com/mapi/reminderset\" AS " + TAG_REMINDER_SET + ", " + 95 "\"urn:schemas:calendar:reminderoffset\" AS " + TAG_REMINDER_OFFSET + ", " + 96 "\"urn:schemas:calendar:replytime\" AS " + TAG_REPLY_TIME + ", " + 97 "\"http://schemas.microsoft.com/mapi/sensitivity\" AS " + TAG_SENSITIVITY + ", " + 98 "\"http://schemas.microsoft.com/exchange/mileage\" AS " + TAG_MILEAGE + ", " + 99 "\"http://schemas.microsoft.com/exchange/keywords-utf8\" AS " + TAG_CATEGORIES + ", " + 100 "\"urn:schemas:httpmail:importance\" AS " + TAG_IMPORTANCE + ", " + 101 "\"DAV:getlastmodified\" AS " + TAG_LAST_MODIFIED + ", " + 102 "\"DAV:isfolder\" AS isfolder " + 103 "FROM \"/{0}/{1}/{2}\" " + 104 "{3}" + 105 "</D:sql>\n" + 106 "</D:searchrequest>" ; 107 108 private static final String FIELD_PREFIX = "urn:schemas:calendar:" ; 109 110 private static final String 111 WEBDAV_INIT_HM = "HM:" ; 112 private static final String 113 WEBDAV_INIT_HN = "HN:" ; 114 private static final String 115 WEBDAV_INIT_MAPI = "MAPI:" ; 116 private static final String 117 WEBDAV_INIT_EXCHANGE = "EX:" ; 118 119 private static final String 120 WEBDAV_TAG_ALLDAY = WEBDAV_INIT_HM + 121 TAG_ALLDAYEVENT ; 122 private static final String 123 WEBDAV_TAG_BODY = WEBDAV_INIT_HN + 124 TAG_BODY ; 125 private static final String 126 WEBDAV_TAG_BUSYSTATUS = WEBDAV_INIT_HM + 127 TAG_BUSY_STATUS ; 128 private static final String 129 WEBDAV_TAG_DATEEND = WEBDAV_INIT_HM + 130 TAG_DATEEND ; 131 private static final String 132 WEBDAV_TAG_DATESTART = WEBDAV_INIT_HM + 133 TAG_DATESTART ; 134 private static final String 135 WEBDAV_TAG_LOCATION = WEBDAV_INIT_HM + 136 TAG_LOCATION ; 137 private static final String 138 WEBDAV_TAG_SUBJECT = WEBDAV_INIT_HN + 139 TAG_SUBJECT ; 140 private static final String 141 WEBDAV_TAG_IMPORTANCE = WEBDAV_INIT_HN + 142 TAG_IMPORTANCE ; 143 private static final String 144 WEBDAV_TAG_REMINDER_SET = WEBDAV_INIT_MAPI + 145 TAG_REMINDER_SET ; 146 private static final String 147 WEBDAV_TAG_REMINDER_OFFSET = WEBDAV_INIT_HM + 148 TAG_REMINDER_OFFSET ; 149 private static final String 150 WEBDAV_TAG_REPLY_TIME = WEBDAV_INIT_HM + 151 TAG_REPLY_TIME ; 152 private static final String 153 WEBDAV_TAG_SENSITIVITY = WEBDAV_INIT_MAPI + 154 TAG_SENSITIVITY ; 155 private static final String 156 WEBDAV_TAG_RECURRENCE = WEBDAV_INIT_HM + 157 TAG_RECURRENCE ; 158 private static final String 159 WEBDAV_TAG_SEQUENCE = WEBDAV_INIT_HM + 160 TAG_SEQUENCE ; 161 private static final String 162 WEBDAV_TAG_MILEAGE = WEBDAV_INIT_EXCHANGE + 163 TAG_MILEAGE ; 164 private static final String 165 WEBDAV_TAG_CATEGORIES = WEBDAV_INIT_EXCHANGE + 166 TAG_CATEGORIES ; 167 private static final String 168 EVERY_WEEKDAY = "MO, TU, WE, TH, FR" ; 169 170 172 173 private WebDavHttpTransport webDavHttp = null ; 174 175 177 public CalendarDAO(String exchangeServerHost, 178 int exchangeServerPort) 179 throws DataAccessException { 180 181 this.webDavHttp = new WebDavHttpTransport(exchangeServerHost, 182 exchangeServerPort); 183 } 184 186 198 public Calendar setCalendar(Calendar c , 199 String username , 200 String credentials , 201 String exchangeFolder ) 202 throws DataAccessException { 203 204 String response = null ; 205 206 String id = null ; 207 208 StringBuffer webDavCalendarMsg = null ; 209 String webDavHeaderMsg = null ; 210 211 String startDate = null ; 212 String endDate = null ; 213 String subject = null ; 214 String body = null ; 215 String location = null ; 216 Boolean allDayB = null ; 217 String allDay = null ; 218 String busyStatus = null ; 219 220 String priority = null ; 221 Integer mileage = null ; 222 223 int reminderMinutesBeforeStart = 0 ; 224 boolean reminderSet = false ; 225 Integer replyTime = null ; 226 String sensitivity = null ; 227 String sequence = null ; 228 229 String categories = null ; 230 231 String server = null ; 232 String resource = null ; 233 234 String recurrence = null ; 235 236 String rrule = null ; 237 238 RecurrencePattern rp = c.getRecurrencePattern(); 239 240 server = getServerFromExchangeFolder (exchangeFolder ); 241 resource = getResourceFromExchangeFolder (exchangeFolder ); 242 243 rrule = c.getRrule().getPropertyValueAsString(); 244 245 if (rp != null){ 246 247 try { 248 recurrence = getExchangeRecurrence(rp); 249 } catch (Exception e) { 250 throw new DataAccessException(e.getMessage()); 251 } 252 253 } 254 255 try { 256 startDate = dateToWebDavTag (c.getDtStart ().getPropertyValueAsString()); 257 endDate = dateToWebDavTag (c.getDtEnd ().getPropertyValueAsString()); 258 } catch (Exception e) { 259 throw new DataAccessException(e.getMessage()); 260 } 261 262 if (c.getSummary() != null) { 263 subject = c.getSummary().getPropertyValueAsString(); 264 } 265 266 if (c.getDescription() != null) { 267 body = c.getDescription().getPropertyValueAsString(); 268 } 269 270 if (c.getLocation() != null) { 271 location = c.getLocation().getPropertyValueAsString(); 272 } 273 274 if (c.getCategories() != null) { 275 categories = c.getCategories().getPropertyValueAsString(); 276 } 277 278 allDayB = c.getAllDay(); 279 280 if (allDayB != null) { 281 282 if (allDayB.booleanValue()) { 283 allDay = "1"; 284 } else { 285 allDay = "0"; 286 } 287 } 288 289 if (c.getPriority() != null) { 290 priority = c.getPriority().getPropertyValueAsString(); 291 } 292 293 mileage = c.getMileage(); 294 295 Reminder reminder = c.getReminder(); 296 if (reminder != null) { 297 reminderMinutesBeforeStart = reminder.getMinutes(); 298 reminderSet = reminder.isActive(); 299 } 300 301 replyTime = c.getReplyTime(); 302 303 if (c.getClassEvent() != null) { 304 sensitivity = c.getClassEvent().getPropertyValueAsString(); 305 } 306 307 if (c.getSequence() != null) { 308 sequence = c.getSequence().getPropertyValueAsString(); 309 } 310 311 busyStatus = "0"; 315 316 webDavCalendarMsg = new StringBuffer (); 317 318 webDavCalendarMsg. 319 append 320 ("<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n" + 321 "<D:propertyupdate xmlns:D=\"DAV:\" " + 322 "xmlns:EX=\"http://schemas.microsoft.com/exchange/\" " + 323 "xmlns:HM=\"urn:schemas:calendar:\" " + 324 "xmlns:MAPI=\"http://schemas.microsoft.com/mapi/\" " + 325 "xmlns:X=\"xml:\" " + 326 "xmlns:HN=\"urn:schemas:httpmail:\" " + 327 "xmlns:dt=\"urn:uuid:c2f41010-65b3-11d1a29f-00aa00c14882/\" >\n" + 328 "<D:set>\n" + 329 " <D:prop>\n" + 330 " <D:contentclass>urn:content-classes:appointment</D:contentclass>\n" + 331 " <EX:outlookmessageclass>IPM.Appointment</EX:outlookmessageclass>\n" ); 332 333 if (subject != null) { 334 subject = StringTools.escapeXml(subject); 335 webDavCalendarMsg.append("<" + 336 WEBDAV_TAG_SUBJECT + 337 ">" + 338 subject + 339 "</" + 340 WEBDAV_TAG_SUBJECT + 341 ">\n" ); 342 } 343 344 if (body != null) { 345 body = StringTools.escapeXml(body); 346 webDavCalendarMsg.append("<" + 347 WEBDAV_TAG_BODY + 348 ">" + 349 body + 350 "</" + 351 WEBDAV_TAG_BODY + 352 ">\n" ); 353 } 354 355 if (location != null) { 356 location = StringTools.escapeXml(location); 357 webDavCalendarMsg.append("<" + 358 WEBDAV_TAG_LOCATION + 359 ">" + 360 location + 361 "</" + 362 WEBDAV_TAG_LOCATION + 363 ">\n" ); 364 } 365 366 webDavCalendarMsg.append("<" + 367 WEBDAV_TAG_DATESTART + 368 ">" + 369 startDate + 370 "</" + 371 WEBDAV_TAG_DATESTART + 372 ">\n" ); 373 374 webDavCalendarMsg.append("<" + 375 WEBDAV_TAG_DATEEND + 376 ">" + 377 endDate + 378 "</" + 379 WEBDAV_TAG_DATEEND + 380 ">\n" ); 381 382 if (allDay != null) { 383 webDavCalendarMsg.append("<" + 384 WEBDAV_TAG_ALLDAY + 385 ">" + 386 allDay + 387 "</" + 388 WEBDAV_TAG_ALLDAY + 389 ">\n" ); 390 } 391 392 if (busyStatus != null) { 393 webDavCalendarMsg.append("<" + 394 WEBDAV_TAG_BUSYSTATUS + 395 ">" + 396 busyStatus + 397 "</" + 398 WEBDAV_TAG_BUSYSTATUS + 399 ">\n" ); 400 } 401 402 webDavCalendarMsg.append("<" + 403 WEBDAV_TAG_IMPORTANCE + 404 ">" + 405 priority + 406 "</" + 407 WEBDAV_TAG_IMPORTANCE + 408 ">\n" ); 409 410 webDavCalendarMsg.append("<" + 411 WEBDAV_TAG_REMINDER_SET + 412 ">" + 413 (reminderSet ? "1" : "0") + 414 "</" + 415 WEBDAV_TAG_REMINDER_SET + 416 ">\n" ); 417 418 webDavCalendarMsg.append("<" + 419 WEBDAV_TAG_REMINDER_OFFSET + 420 ">" + 421 (reminderMinutesBeforeStart * 60) + 422 "</" + 423 WEBDAV_TAG_REMINDER_OFFSET + 424 ">\n" ); 425 426 if (replyTime != null) { 427 webDavCalendarMsg.append("<" + 428 WEBDAV_TAG_REPLY_TIME + 429 ">" + 430 replyTime.intValue() + 431 "</" + 432 WEBDAV_TAG_REPLY_TIME + 433 ">\n" ); 434 } 435 436 if (sensitivity != null) { 437 webDavCalendarMsg.append("<" + 438 WEBDAV_TAG_SENSITIVITY + 439 ">" + 440 sensitivity + 441 "</" + 442 WEBDAV_TAG_SENSITIVITY + 443 ">\n" ); 444 } 445 446 if (sequence != null) { 447 webDavCalendarMsg.append("<" + 448 WEBDAV_TAG_SEQUENCE + 449 ">" + 450 sequence + 451 "</" + 452 WEBDAV_TAG_SEQUENCE + 453 ">\n" ); 454 } 455 456 if (mileage != null) { 457 webDavCalendarMsg.append("<" + 458 WEBDAV_TAG_MILEAGE + 459 ">" + 460 mileage.intValue() + 461 "</" + 462 WEBDAV_TAG_MILEAGE + 463 ">\n" ); 464 } 465 466 if (categories != null) { 467 webDavCalendarMsg.append("<EX:keywords-utf8>"); 468 469 StringTokenizer st = new StringTokenizer (categories, ";"); 470 while (st.hasMoreTokens()) { 471 webDavCalendarMsg.append("<X:v>" + 472 st.nextToken().trim() + 473 "</X:v>\n" ); 474 } 475 476 webDavCalendarMsg.append("</EX:keywords-utf8>"); 477 478 } 479 480 if (recurrence != null && recurrence.length() > 0) { 481 482 webDavCalendarMsg.append("<" + 483 WEBDAV_TAG_RECURRENCE + 484 " dt:dt=\"mv.string\"" + 485 ">" ); 486 487 webDavCalendarMsg.append("<X:v>" + 488 recurrence + 489 "</X:v>\n" ); 490 491 webDavCalendarMsg.append("</" + 492 WEBDAV_TAG_RECURRENCE + 493 ">\n" ); 494 495 } 496 497 webDavCalendarMsg. 498 append("<HM:timezoneid dt:dt=\"int\"></HM:timezoneid>\n"); 499 500 webDavCalendarMsg. 501 append(" </D:prop>\n" + 502 "</D:set>\n" + 503 "</D:propertyupdate>" ); 504 505 webDavHeaderMsg 506 = MessageFormat.format(ItemDAO.WEBDAV_HEADER_PROPPATCH, 507 new Object [] { 508 "/" + 509 server + 510 "/" + 511 username + 512 "/" + 513 resource , 514 c.getHref() 515 } 516 ); 517 518 try { 519 response = this.webDavHttp.sendRequest(webDavHeaderMsg , 520 credentials , 521 webDavCalendarMsg.toString() , 522 FILE_ENCODING ); 523 } catch (Exception e) { 524 throw new DataAccessException("Error parsing calendar", e); 525 } 526 527 try { 528 int s = getStatusFromResponse(response); 529 checkResponseStatus(s); 530 } catch (Exception e) { 531 532 throw new DataAccessException("USER " + 533 username + 534 " URI " + 535 exchangeFolder + 536 " set Exchange calendar" , 537 e) ; 538 539 } 540 541 try { 542 id = XmlParser.getRuidFromResponse(response); 543 } catch (XmlParseException e) { 544 throw new DataAccessException("Error getting resource id", e); 545 } 546 547 c.setId(id); 548 549 return c; 550 551 } 552 553 564 public void removeCalendar(Calendar calendar , 565 String username , 566 String credentials , 567 String exchangeFolder ) 568 throws DataAccessException { 569 570 String webDavCalendarMsg = null ; 571 572 String webDavHeaderMsg = null ; 573 574 String response = null ; 575 576 String server = null ; 577 String resource = null ; 578 579 server = getServerFromExchangeFolder (exchangeFolder ); 580 resource = getResourceFromExchangeFolder (exchangeFolder ); 581 582 webDavCalendarMsg = "" ; 583 584 585 webDavHeaderMsg = 586 MessageFormat.format(ItemDAO.WEBDAV_HEADER_REMOVE, 587 new Object [] { 588 "/" + 589 server + 590 "/" + 591 username + 592 "/" + 593 resource , 594 calendar.getHref() 595 596 } 597 ); 598 599 600 try { 601 response = this.webDavHttp.sendRequest(webDavHeaderMsg, credentials, webDavCalendarMsg, FILE_ENCODING); 602 } catch (Exception e) { 603 throw new DataAccessException("Error parsing calendar", e); 604 } 605 606 try { 607 int s = getStatusFromResponse(response); 608 checkResponseStatus(s); 609 } catch (Exception e) { 610 611 throw new DataAccessException("USER " + 612 username + 613 " URI " + 614 exchangeFolder + 615 " removing Exchange calendar" , 616 e) ; 617 } 618 619 } 620 621 632 public Calendar[] getCalendars(String username , 633 String credentials , 634 String [] ids , 635 String exchangeFolder ) 636 throws DataAccessException { 637 638 String clause = null ; 639 640 clause = getClause(ids); 641 642 return getCalendars(username, credentials, clause, exchangeFolder); 643 } 644 645 657 public Calendar[] getCalendars(String username, 658 String credentials, 659 String fields[], 660 Object values[], 661 String exchangeFolder) throws DataAccessException { 662 663 String clause = null ; 664 665 clause = getClause(fields, values); 666 667 return getCalendars(username, credentials, clause, exchangeFolder); 668 } 669 670 680 private Calendar[] getCalendarsFromWebDavMsg(String webDavMsg) 681 throws DataAccessException { 682 683 ArrayList calendars = null ; 684 String [] resps = null ; 685 String [] msg = null ; 686 687 String response = null ; 688 String id = null ; 689 String replUid = null ; 690 691 String isFolder = null ; 692 693 int count = 0 ; 694 695 msg = new String [] {webDavMsg}; 696 697 calendars = new ArrayList (); 698 699 try { 700 701 resps = XmlParser.getXMLTag(msg, TAG_RESPONSE); 702 703 for (int i = 0, l = resps.length; i < l; i++) { 704 705 response = resps[i] ; 706 replUid = XmlParser.getXMLTagValue (response, TAG_REPLUID) ; 707 id = getIdFromReplUid (replUid) ; 708 709 isFolder = XmlParser.getXMLInitTagValue (response, 710 TAG_IS_FOLDER) ; 711 712 if(PROP_NO_FOLDER.equals(isFolder)) { 713 calendars.add(getCalendarFromResponseTag(id, response)); 714 count ++; 715 } 716 717 } 718 719 } catch (XmlParseException e) { 720 throw new DataAccessException("Error parsing calendar", 721 e); 722 } 723 724 return (Calendar[])calendars.toArray(new Calendar[count]); 725 726 } 727 728 738 private Calendar getCalendarFromResponseTag(String id, String msgResponse) 739 throws DataAccessException { 740 741 Calendar c = null ; 742 String lastUpdate = null ; 743 744 String dateStart = null ; 745 String dateEnd = null ; 746 String subject = null ; 747 String body = null ; 748 String location = null ; 749 Boolean allDayB = null ; 750 String allDay = null ; 751 String busyStatus = null ; 752 String importance = null ; 753 String mileage = null ; 754 String reminderOffset = null ; 755 String reminderSet = null ; 756 String replyTime = null ; 757 String sensitivity = null ; 758 String sequence = null ; 759 760 String [] categoriesList = null ; 761 String categories = null ; 762 String [] recurrenceList = null ; 763 String recurrence = null ; 764 String value = null ; 765 766 try { 767 768 body = XmlParser.getXMLTagValue 769 (msgResponse, TAG_BODY) ; 770 771 location = XmlParser.getXMLTagValue 772 (msgResponse, TAG_LOCATION) ; 773 774 subject = XmlParser.getXMLTagValue 775 (msgResponse, TAG_SUBJECT) ; 776 777 busyStatus = XmlParser.getXMLTagValue 778 (msgResponse, TAG_BUSY_STATUS) ; 779 780 dateStart = XmlParser.getXMLInitTagValue 781 (msgResponse, TAG_DATESTART) ; 782 783 dateEnd = XmlParser.getXMLInitTagValue 784 (msgResponse, TAG_DATEEND) ; 785 786 lastUpdate = XmlParser.getXMLInitTagValue 787 (msgResponse, TAG_LAST_MODIFIED) ; 788 789 allDay = XmlParser.getXMLInitTagValue 790 (msgResponse, TAG_ALLDAYEVENT) ; 791 792 importance = XmlParser.getXMLInitTagValue 793 (msgResponse, TAG_IMPORTANCE); 794 795 mileage = XmlParser.getXMLInitTagValue 796 (msgResponse, TAG_MILEAGE); 797 798 reminderOffset = XmlParser.getXMLInitTagValue 799 (msgResponse, TAG_REMINDER_OFFSET); 800 801 reminderSet = XmlParser.getXMLInitTagValue 802 (msgResponse, TAG_REMINDER_SET); 803 804 replyTime = XmlParser.getXMLInitTagValue 805 (msgResponse, TAG_REPLY_TIME); 806 807 sensitivity = XmlParser.getXMLInitTagValue 808 (msgResponse, TAG_SENSITIVITY); 809 810 sequence = XmlParser.getXMLInitTagValue 811 (msgResponse, TAG_SEQUENCE); 812 813 categories = 814 XmlParser.getXMLInitTagValue(msgResponse, TAG_CATEGORIES); 815 816 817 if (categories != null) { 818 categoriesList = 819 XmlParser.getXMLTag(new String [] {categories}, "c:v"); 820 } 821 if (categoriesList != null) { 822 StringBuffer sb = new StringBuffer (); 823 for (int i=0; i<categoriesList.length; i++) { 824 sb.append(categoriesList[i]).append("; "); 825 } 826 categories = sb.toString(); 827 } 828 829 830 recurrence = 831 XmlParser.getXMLInitTagValue(msgResponse, TAG_RECURRENCE); 832 833 834 if (recurrence != null) { 835 recurrence = recurrence.trim(); 836 recurrenceList = 837 XmlParser.getXMLTag(new String [] {recurrence}, "c:v"); 838 } 839 if (recurrenceList != null) { 840 841 StringBuffer sb = new StringBuffer (); 842 843 int l = recurrenceList.length; 844 845 if (l == 1) { 846 847 sb.append(recurrenceList[0]); 848 849 } else { 850 851 for (int i=0; i < l; i++) { 852 853 sb.append(recurrenceList[i]).append("; "); 854 } 855 856 } 857 858 recurrence = sb.toString(); 859 } 860 861 c = new Calendar(id, XmlParser.webDavTagToDate(lastUpdate)); 862 863 c.getDtStart ().setPropertyValue(XmlParser.webDavTagToPDIDate(dateStart )); 864 c.getDtEnd ().setPropertyValue(XmlParser.webDavTagToPDIDate(dateEnd )); 865 866 if (body != null) { 867 c.getDescription().setPropertyValue(body); 868 } 869 870 if (location != null) { 871 c.getLocation().setPropertyValue(location); 872 } 873 874 if (subject != null) { 875 c.getSummary().setPropertyValue(subject); 876 } 877 878 if (allDay != null) { 879 if("1".equals(allDay)) { 880 c.setAllDay(new Boolean (true)); 881 } else if("0".equals(allDay)) { 882 c.setAllDay(new Boolean (false)); 883 } 884 } 885 886 if (importance != null) { 887 c.getPriority().setPropertyValue(importance); 888 } 889 890 if (mileage != null) { 891 c.setMileage(new Integer (mileage)); 892 } 893 894 if (reminderOffset != null) { 895 Reminder reminder = c.getReminder(); 896 if (reminder == null) { 897 reminder = new Reminder(); 898 c.setReminder(reminder); 899 } 900 int minutes = ((new Integer (reminderOffset)).intValue()) / 60; 901 reminder.setMinutes(minutes); 902 } 903 904 if (reminderSet != null) { 905 Reminder reminder = c.getReminder(); 906 if (reminder == null) { 907 reminder = new Reminder(); 908 c.setReminder(reminder); 909 } 910 if (reminderSet.equals("1")) { 911 reminder.setActive(true); 912 } else { 913 reminder.setActive(false); 914 } 915 } 916 917 if (replyTime != null) { 918 c.setReplyTime(new Integer (replyTime)); 919 } 920 921 if (sensitivity != null) { 922 c.getClassEvent().setPropertyValue(sensitivity); 923 } 924 925 if (sequence != null) { 926 c.getSequence().setPropertyValue(sequence); 927 } 928 929 if (categories != null) { 930 c.getCategories().setPropertyValue(categories); 931 } 932 933 if (recurrence != null) { 934 c.setRecurrencePattern( 935 getRecurrencePattern(recurrence, 936 XmlParser.webDavTagToPDIDate(dateStart ))); 937 } 938 939 943 } catch (Exception e) { 944 throw new DataAccessException("Error parsing calendar item: ", e); 945 } 946 947 return c; 948 949 } 950 951 959 private static String getClause (String [] fields, Object [] values) { 960 961 StringBuffer clause = new StringBuffer (); 962 963 int l = fields.length; 964 965 if (l == 0) { 966 return ""; 967 } 968 969 clause.append("where ("); 970 971 StringBuffer tmp = null; 972 String valueTmp = null; 973 974 for (int i = 0; i < l; i++) { 975 tmp = new StringBuffer (); 976 977 valueTmp = ""; 978 979 if (TAG_DATESTART.equals(fields[i])) { 980 tmp.append("\"").append(FIELD_PREFIX).append("dtstart\"=CAST(\""); 981 982 if (values[i] != null) { 983 valueTmp = dateToWebDavTag((java.util.Date )values[i]); 984 } 985 tmp.append(valueTmp).append("\" as 'dateTime')"); 986 } 987 988 if (TAG_DATEEND.equals(fields[i])) { 989 tmp.append("\"").append(FIELD_PREFIX).append("dtend\"=CAST(\""); 990 991 if (values[i] != null) { 992 valueTmp = dateToWebDavTag((java.util.Date )values[i]); 993 } 994 995 tmp.append(valueTmp).append("\" as 'dateTime')"); 996 } 997 998 if (TAG_LOCATION.equals(fields[i])) { 999 tmp.append("\"").append(FIELD_PREFIX).append("location\""); 1000 1001 if (values[i] != null) { 1002 tmp.append("='"); 1003 valueTmp = String.valueOf(values[i]); 1004 valueTmp = valueTmp.replaceAll("'", "''"); 1005 valueTmp = StringTools.escapeXml(valueTmp); 1006 tmp.append(valueTmp).append("'"); 1007 } else { 1008 tmp.append(" is null "); 1009 } 1010 1011 } 1012 1013 if (i != 0 && tmp.length() != 0) { 1014 clause.append(" and ").append(tmp); 1015 } else if (tmp.length() != 0) { 1016 clause.append(tmp); 1017 } 1018 1019 } 1020 1021 clause.append(")\r\n"); 1022 1023 return clause.toString(); 1024 1025 } 1026 1027 1028 1039 private Calendar[] getCalendars(String username, 1040 String credentials, 1041 String clause, 1042 String exchangeFolder) throws DataAccessException { 1043 1044 Calendar[] exchangeCalendars = null; 1045 1046 String response = null; 1047 String webDavCalendarMsg = null; 1048 1049 String webDavHeaderMsg = null; 1050 1051 String server = null; 1052 String resource = null; 1053 1054 server = getServerFromExchangeFolder(exchangeFolder); 1055 resource = getResourceFromExchangeFolder(exchangeFolder); 1056 1057 if (clause == null || clause.length() == 0 ) { 1058 clause = " WHERE "; 1059 } else { 1060 clause = clause + " AND "; 1061 } 1062 1063 clause = clause + 1064 "not (\"http://schemas.microsoft.com/mapi/id/{00062002-0000-0000-C000-000000000046}/0x8231\" != cast(\"0\" as int) " + 1065 "and (\"urn:schemas:calendar:instancetype\" != 1 and \"urn:schemas:calendar:instancetype\" != 0))" ; 1066 1067 webDavCalendarMsg = 1068 MessageFormat.format(WEBDAV_MSG_SELECT_CALENDARS, 1069 new Object [] {server, username, resource, 1070 clause}); 1071 1072 webDavHeaderMsg = 1073 MessageFormat.format(ItemDAO.WEBDAV_HEADER_SELECT, 1074 new Object [] { 1075 "/" + 1076 server + 1077 "/" + 1078 username + 1079 "/" + 1080 resource 1081 } 1082 ); 1083 1084 try { 1085 response = this.webDavHttp.sendRequest(webDavHeaderMsg, credentials, 1086 webDavCalendarMsg, FILE_ENCODING); 1087 } catch (IOException e) { 1088 throw new DataAccessException( 1089 "Error getting Exchange server response", 1090 e); 1091 } 1092 1093 try { 1094 int s = getStatusFromResponse(response); 1095 checkResponseStatus(s); 1096 } catch (Exception e) { 1097 1098 throw new DataAccessException("USER " + 1099 username + 1100 " URI " + 1101 exchangeFolder + 1102 " getting exchange calendar", 1103 e); 1104 1105 } 1106 1107 exchangeCalendars = getCalendarsFromWebDavMsg(response); 1108 1109 return exchangeCalendars; 1110 1111 } 1112 1113 private RecurrencePattern getRecurrencePattern(String recurrence , 1114 String startDatePattern ) 1115 throws Exception { 1116 1117 RecurrencePattern rp = null; 1118 1119 short recurrenceType = 0 ; 1120 short dayOfWeekMask = 0 ; 1121 short dayOfMonth = 0 ; 1122 short monthOfYear = 0 ; 1123 short instance = 0 ; 1124 1125 int interval = 0 ; 1126 1127 String rt = null ; 1128 String value = null ; 1129 String days = null ; 1130 String endDatePattern = null ; 1131 1132 boolean noEndDate = true ; 1133 1134 rt = recurrence.substring(recurrence.indexOf("FREQ=") + "FREQ=".length(), 1135 recurrence.indexOf(";")).trim() ; 1136 1137 if (recurrence.indexOf("UNTIL") != -1) { 1141 noEndDate = false; 1142 int start = recurrence.indexOf("UNTIL=") + "UNTIL=".length(); 1143 int end = recurrence.indexOf(";", start); 1144 endDatePattern = recurrence.substring(start, end).trim(); 1145 1146 } 1147 1148 if (recurrence.indexOf("INTERVAL") != -1) { 1152 int start = recurrence.indexOf("INTERVAL=") + "INTERVAL=".length(); 1153 int end = recurrence.indexOf(";", start); 1154 value = recurrence.substring(start, end).trim(); 1155 interval = Integer.parseInt(value); 1156 1157 } 1158 1159 if ("DAILY".equals(rt)) { 1160 if (recurrence.indexOf(EVERY_WEEKDAY) != -1) { 1164 recurrenceType = RecurrencePattern.TYPE_WEEKLY; 1165 dayOfWeekMask = getDayOfWeekMask(EVERY_WEEKDAY); 1166 } else { 1167 recurrenceType = RecurrencePattern.TYPE_DAYLY; 1168 } 1169 } else if ("WEEKLY".equals(rt)){ 1170 int start = recurrence.indexOf("BYDAY=") + "BYDAY=".length(); 1174 int end = recurrence.indexOf(";", start); 1175 value = recurrence.substring(start, end).trim(); 1176 dayOfWeekMask = getDayOfWeekMask(value); 1177 recurrenceType = RecurrencePattern.TYPE_WEEKLY; 1178 } else if ("MONTHLY".equals(rt)){ 1179 if (recurrence.indexOf("BYDAY") != - 1) { 1180 int start = recurrence.indexOf("BYDAY=") + "BYDAY=".length(); 1184 int end = recurrence.indexOf(";", start); 1185 value = recurrence.substring(start, end).trim(); 1186 instance = Short.parseShort(value.substring(0,value.indexOf(" "))); 1187 if (instance == -1) { 1188 instance = 5; 1192 } 1193 dayOfWeekMask = getDayOfWeekMask(value.substring(value.indexOf(" ") + 1)); 1194 recurrenceType =RecurrencePattern.TYPE_MONTH_NTH; 1195 1196 } else { 1197 int start = recurrence.indexOf("BYMONTHDAY=") + "BYMONTHDAY=".length(); 1201 int end = recurrence.indexOf(";", start); 1202 value = recurrence.substring(start, end).trim(); 1203 dayOfMonth = Short.parseShort(value); 1204 recurrenceType =RecurrencePattern.TYPE_MONTHLY; 1205 } 1206 1207 } else if ("YEARLY".equals(rt)){ 1208 1209 int start = recurrence.indexOf("BYMONTH=") + "BYMONTH=".length(); 1210 int end = recurrence.indexOf(";", start); 1211 value = recurrence.substring(start, end).trim(); 1212 monthOfYear = Short.parseShort(value); 1213 1214 if (recurrence.indexOf("BYDAY") != - 1) { 1215 start = recurrence.indexOf("BYDAY=") + "BYDAY=".length(); 1219 end = recurrence.indexOf(";", start); 1220 value = recurrence.substring(start, end).trim(); 1221 instance = Short.parseShort(value.substring(0,value.indexOf(" "))); 1222 if (instance == -1) { 1223 instance = 5; 1227 } 1228 dayOfWeekMask = getDayOfWeekMask(value.substring(value.indexOf(" ") + 1)); 1229 1230 recurrenceType =RecurrencePattern.TYPE_YEAR_NTH; 1231 } else { 1232 start = recurrence.indexOf("BYMONTHDAY=") + "BYMONTHDAY=".length(); 1236 end = recurrence.indexOf(";", start); 1237 value = recurrence.substring(start, end).trim(); 1238 dayOfMonth = Short.parseShort(value); 1239 1240 recurrenceType =RecurrencePattern.TYPE_YEARLY; 1241 } 1242 1243 } 1244 1245 switch (recurrenceType) { 1246 case RecurrencePattern.TYPE_DAYLY: 1247 if(!noEndDate) { 1248 rp = RecurrencePattern.getDailyRecurrencePattern(interval , 1249 startDatePattern, 1250 endDatePattern , 1251 noEndDate); 1252 } else { 1253 rp = RecurrencePattern.getDailyRecurrencePattern(interval , 1254 startDatePattern, 1255 noEndDate); 1256 } 1257 break; 1258 case RecurrencePattern.TYPE_WEEKLY: 1259 if(!noEndDate) { 1260 rp = RecurrencePattern.getWeeklyRecurrencePattern(interval , 1261 dayOfWeekMask , 1262 startDatePattern , 1263 endDatePattern , 1264 noEndDate); 1265 } else { 1266 rp = RecurrencePattern.getWeeklyRecurrencePattern(interval , 1267 dayOfWeekMask , 1268 startDatePattern , 1269 noEndDate); 1270 } 1271 break; 1272 case RecurrencePattern.TYPE_MONTHLY: 1273 if(!noEndDate) { 1274 rp = RecurrencePattern.getMonthlyRecurrencePattern(interval , 1275 dayOfMonth , 1276 startDatePattern , 1277 endDatePattern , 1278 noEndDate); 1279 1280 } else { 1281 rp = RecurrencePattern.getMonthlyRecurrencePattern(interval , 1282 dayOfMonth , 1283 startDatePattern , 1284 noEndDate ); 1285 } 1286 break; 1287 case RecurrencePattern.TYPE_MONTH_NTH: 1288 if(!noEndDate) { 1289 rp = RecurrencePattern.getMonthNthRecurrencePattern(interval , 1290 dayOfWeekMask , 1291 instance , 1292 startDatePattern , 1293 endDatePattern , 1294 noEndDate); 1295 } else { 1296 rp = RecurrencePattern.getMonthNthRecurrencePattern(interval , 1297 dayOfWeekMask , 1298 instance , 1299 startDatePattern , 1300 noEndDate); 1301 } 1302 break; 1303 case RecurrencePattern.TYPE_YEARLY: 1304 if(!noEndDate) { 1305 rp = RecurrencePattern.getYearlyRecurrencePattern(dayOfMonth , 1306 monthOfYear , 1307 startDatePattern , 1308 endDatePattern , 1309 noEndDate); 1310 1311 } else { 1312 rp = RecurrencePattern.getYearlyRecurrencePattern(dayOfMonth , 1313 monthOfYear , 1314 startDatePattern , 1315 noEndDate); 1316 } 1317 break; 1318 case RecurrencePattern.TYPE_YEAR_NTH: 1319 if(!noEndDate) { 1320 rp = RecurrencePattern.getYearNthRecurrencePattern(dayOfWeekMask , 1321 monthOfYear , 1322 instance , 1323 startDatePattern , 1324 endDatePattern , 1325 noEndDate); 1326 } else { 1327 rp = RecurrencePattern.getYearNthRecurrencePattern(dayOfWeekMask , 1328 monthOfYear , 1329 instance , 1330 startDatePattern , 1331 noEndDate); 1332 } 1333 1334 } 1335 1336 return rp; 1337 1338 } 1339 1340 private String getExchangeRecurrence(RecurrencePattern rp) 1341 throws Exception { 1342 1343 String exr = null; 1344 1345 String type = null; 1346 String interval = null; 1347 String endPatternDate = null; 1348 1349 String dayOfMonth = null; 1350 String monthOfYear = null; 1351 1352 boolean noEndDate = false; 1353 1354 short instance = 0; 1355 1356 interval = ";INTERVAL=" + rp.getInterval(); 1357 1358 endPatternDate = rp.getEndDatePattern(); 1359 1360 1361 noEndDate = rp.isNoEndDate(); 1362 1363 if (!noEndDate) { 1364 endPatternDate = ";UNTIL=" + endPatternDate; 1365 } else { 1366 endPatternDate = "" ; 1367 } 1368 1369 switch (rp.getType()) { 1370 case RecurrencePattern.TYPE_DAYLY: 1371 exr = "FREQ=DAILY" + 1372 endPatternDate + 1373 interval + 1374 ";WKST=SU" ; 1375 break; 1376 case RecurrencePattern.TYPE_WEEKLY: 1377 1378 String dayOfWeekMask = null; 1379 1380 dayOfWeekMask = getDayOfWeekMask(rp.getDayOfWeekMask()); 1381 1382 if (dayOfWeekMask != null && dayOfWeekMask.length() > 0) { 1383 dayOfWeekMask = ";BYDAY=" + dayOfWeekMask; 1384 } else { 1385 dayOfWeekMask = ""; 1386 } 1387 1388 exr = "FREQ=WEEKLY" + 1389 endPatternDate + 1390 interval + 1391 dayOfWeekMask + 1392 ";WKST=SU" ; 1393 break ; 1394 case RecurrencePattern.TYPE_MONTHLY: 1395 1396 dayOfMonth = ";BYMONTHDAY=" + rp.getDayOfMonth(); 1397 1398 exr = "FREQ=MONTHLY" + 1399 endPatternDate + 1400 interval + 1401 dayOfMonth + 1402 ";WKST=SU" ; 1403 1404 break; 1405 case RecurrencePattern.TYPE_MONTH_NTH: 1406 1407 String instanceDayOfWeekMask = null; 1408 1409 instance = rp.getInstance(); 1410 1411 dayOfWeekMask = getDayOfWeekMask(rp.getDayOfWeekMask()); 1412 1413 if (dayOfWeekMask == null) { 1414 dayOfWeekMask = ""; 1415 } 1416 instanceDayOfWeekMask = ";BYDAY=" + instance + dayOfWeekMask; 1417 1418 exr = "FREQ=MONTHLY" + 1419 endPatternDate + 1420 interval + 1421 instanceDayOfWeekMask + 1422 ";WKST=SU" ; 1423 1424 break; 1425 case RecurrencePattern.TYPE_YEARLY: 1426 1427 dayOfMonth = ";BYMONTHDAY=" + rp.getDayOfMonth() ; 1428 monthOfYear = ";BYMONTH=" + rp.getMonthOfYear(); 1429 1430 exr = "FREQ=YEARLY" + 1431 endPatternDate + 1432 interval + 1433 dayOfMonth + 1434 ";WKST=SU" ; 1435 1436 break; 1437 1438 case RecurrencePattern.TYPE_YEAR_NTH: 1439 1440 instanceDayOfWeekMask = null; 1441 1442 instance = rp.getInstance(); 1443 1444 dayOfWeekMask = getDayOfWeekMask(rp.getDayOfWeekMask()); 1445 1446 if (dayOfWeekMask == null) { 1447 dayOfWeekMask = ""; 1448 } 1449 instanceDayOfWeekMask = ";BYDAY=" + instance + dayOfWeekMask; 1450 monthOfYear = ";BYMONTH=" + rp.getMonthOfYear(); 1451 1452 exr = "FREQ=YEARLY" + 1453 endPatternDate + 1454 interval + 1455 instanceDayOfWeekMask + 1456 monthOfYear + 1457 ";WKST=SU" ; 1458 1459 break; 1460 1461 1462 } 1463 1464 return exr; 1465 1466 1467 } 1468 1469 private short getDayOfWeekMask(String value) { 1470 1471 short dayOfWeekMask = 0; 1472 String day = null; 1473 1474 StringTokenizer st = new StringTokenizer (value, ","); 1475 1476 while (st.hasMoreTokens()) { 1477 1478 day = st.nextToken().trim(); 1479 1480 if ("SU".equals(day)) { 1481 dayOfWeekMask = (short) (dayOfWeekMask + RecurrencePattern.DAY_OF_WEEK_SUNDAY) ; 1482 } else if ("MO".equals(day)) { 1483 dayOfWeekMask = (short) (dayOfWeekMask + RecurrencePattern.DAY_OF_WEEK_MONDAY) ; 1484 } else if ("TU".equals(day)) { 1485 dayOfWeekMask = (short) (dayOfWeekMask + RecurrencePattern.DAY_OF_WEEK_TUESDAY) ; 1486 } else if ("WE".equals(day)) { 1487 dayOfWeekMask = (short) (dayOfWeekMask + RecurrencePattern.DAY_OF_WEEK_WEDNSDAY) ; 1488 } else if ("TH".equals(day)) { 1489 dayOfWeekMask = (short) (dayOfWeekMask + RecurrencePattern.DAY_OF_WEEK_THURSDAY) ; 1490 } else if ("FR".equals(day)) { 1491 dayOfWeekMask = (short) (dayOfWeekMask + RecurrencePattern.DAY_OF_WEEK_FRIDAY) ; 1492 } else if ("SA".equals(day)) { 1493 dayOfWeekMask = (short) (dayOfWeekMask + RecurrencePattern.DAY_OF_WEEK_SATURDAY) ; 1494 } 1495 1496 } 1497 1498 return dayOfWeekMask; 1499 1500 } 1501 1502 private String getDayOfWeekMask(short value) { 1503 1504 String dayOfWeekMask = ""; 1505 1506 if ((value & RecurrencePattern.DAY_OF_WEEK_SUNDAY) != 0 ) { 1507 dayOfWeekMask = "SU"; 1508 } 1509 1510 if ((value & RecurrencePattern.DAY_OF_WEEK_MONDAY) != 0 ) { 1511 1512 if (dayOfWeekMask.length() > 0) { 1513 dayOfWeekMask = dayOfWeekMask + ", "; 1514 } 1515 1516 dayOfWeekMask = dayOfWeekMask + "MO"; 1517 } 1518 1519 if ((value & RecurrencePattern.DAY_OF_WEEK_TUESDAY) != 0 ) { 1520 1521 if (dayOfWeekMask.length() > 0) { 1522 dayOfWeekMask = dayOfWeekMask + ", "; 1523 } 1524 1525 dayOfWeekMask = dayOfWeekMask + "TU"; 1526 } 1527 1528 if ((value & RecurrencePattern.DAY_OF_WEEK_WEDNSDAY) != 0 ) { 1529 1530 if (dayOfWeekMask.length() > 0) { 1531 dayOfWeekMask = dayOfWeekMask + ", "; 1532 } 1533 1534 dayOfWeekMask = dayOfWeekMask + "WE"; 1535 } 1536 1537 if ((value & RecurrencePattern.DAY_OF_WEEK_THURSDAY) != 0 ) { 1538 1539 if (dayOfWeekMask.length() > 0) { 1540 dayOfWeekMask = dayOfWeekMask + ", "; 1541 } 1542 1543 dayOfWeekMask = dayOfWeekMask + "TH"; 1544 } 1545 1546 if ((value & RecurrencePattern.DAY_OF_WEEK_FRIDAY) != 0 ) { 1547 1548 if (dayOfWeekMask.length() > 0) { 1549 dayOfWeekMask = dayOfWeekMask + ", "; 1550 } 1551 1552 dayOfWeekMask = dayOfWeekMask + "FR"; 1553 } 1554 1555 if ((value & RecurrencePattern.DAY_OF_WEEK_SATURDAY) != 0 ) { 1556 1557 if (dayOfWeekMask.length() > 0) { 1558 dayOfWeekMask = dayOfWeekMask + ", "; 1559 } 1560 1561 dayOfWeekMask = dayOfWeekMask + "SA"; 1562 } 1563 1564 return dayOfWeekMask; 1565 1566 1567 } 1568 1569} 1570 | Popular Tags |