1 18 package sync4j.syncclient.test; 19 20 import java.io.*; 21 import java.security.Principal ; 22 import java.util.HashMap ; 23 import java.util.Date ; 24 import java.util.Vector ; 25 import java.util.Enumeration ; 26 import java.util.Properties ; 27 28 import sync4j.syncclient.common.logging.Logger; 29 import sync4j.syncclient.common.SourceUtils; 30 import sync4j.syncclient.test.FileSystemSyncSource; 31 import sync4j.syncclient.spds.engine.*; 32 import sync4j.syncclient.spds.SyncException; 33 34 import sync4j.framework.tools.Base64; 35 36 import sync4j.foundation.pdi.contact.*; 37 import sync4j.foundation.pdi.event.*; 38 import sync4j.foundation.pdi.converter.*; 39 import sync4j.foundation.pdi.parser.*; 40 41 60 public class SIFFileSystemSyncSource extends FileSystemSyncSource 61 implements SyncSource { 62 63 private static final String DATABASE_HEADER 65 = "SIFFileSystemSyncSource file database"; 66 67 private static final String CONTENT_TYPE_VCARD = "vCard" ; 71 private static final String CONTENT_TYPE_ICAL = "iCalendar"; 72 private static final String CONTENT_TYPE_TEXT = "text" ; 73 private static final String CONTENT_TYPE_SIFC = "SIF-C" ; 74 private static final String CONTENT_TYPE_SIFE = "SIF-E" ; 75 76 private static final int TYPE_VCARD = 0; 80 private static final int TYPE_ICAL = 1; 81 private static final int TYPE_TEXT = 2; 82 private static final int TYPE_SIFC = 3; 83 private static final int TYPE_SIFE = 4; 84 85 89 private String sourceDrive; 90 public void setSourceDrive(String sourceDrive) { 91 this.sourceDrive = sourceDrive; 92 if (getSourceDirectory() != null) { 93 super.setSourceDirectory(sourceDrive + getSourceDirectory()); 94 } 95 } 96 public String getSourceDrive() { 97 return this.sourceDrive; 98 } 99 100 public void setSourceDirectory(String sourceDirectory) { 101 if (sourceDrive != null) { 102 sourceDirectory = sourceDrive + sourceDirectory; 103 } 104 super.setSourceDirectory(sourceDirectory); 105 } 106 107 108 111 private String charset = "PLAIN"; 112 public void setCharset(String charset) { 113 this.charset = charset; 114 } 115 public String getCharset() { 116 return this.charset; 117 } 118 119 120 123 private String clientContentType; 124 public String getClientContentType() { 125 return this.clientContentType; 126 } 127 public void setClientContentType(String clientContentType) { 128 this.clientContentType = clientContentType; 129 setClientItemType(); 130 } 131 132 135 private int CLIENT_TYPE = TYPE_TEXT; 136 private void setClientItemType() { 137 if (this.clientContentType.equals(CONTENT_TYPE_VCARD)) { 138 CLIENT_TYPE = TYPE_VCARD; 139 } else if (this.clientContentType.equals(CONTENT_TYPE_ICAL)) { 140 CLIENT_TYPE = TYPE_ICAL; 141 } else if (this.clientContentType.equals(CONTENT_TYPE_TEXT)) { 142 CLIENT_TYPE = TYPE_TEXT; 143 } else if (this.clientContentType.equals(CONTENT_TYPE_SIFC)) { 144 CLIENT_TYPE = TYPE_SIFC; 145 } else if (this.clientContentType.equals(CONTENT_TYPE_SIFE)) { 146 CLIENT_TYPE = TYPE_SIFE; 147 } 148 } 149 150 153 private String serverContentType; 154 public String getServerContentType() { 155 return this.serverContentType; 156 } 157 public void setServerContentType(String serverContentType) { 158 this.serverContentType = serverContentType; 159 setServerItemType(); 160 } 161 162 165 private int SERVER_TYPE = TYPE_TEXT; 166 private void setServerItemType() { 167 if (this.serverContentType.equals(CONTENT_TYPE_VCARD)) { 168 SERVER_TYPE = TYPE_VCARD; 169 } else if (this.serverContentType.equals(CONTENT_TYPE_ICAL)) { 170 SERVER_TYPE = TYPE_ICAL; 171 } else if (this.serverContentType.equals(CONTENT_TYPE_TEXT)) { 172 SERVER_TYPE = TYPE_TEXT; 173 } else if (this.serverContentType.equals(CONTENT_TYPE_SIFC)) { 174 SERVER_TYPE = TYPE_SIFC; 175 } else if (this.serverContentType.equals(CONTENT_TYPE_SIFE)) { 176 SERVER_TYPE = TYPE_SIFE; 177 } 178 } 179 180 182 public SIFFileSystemSyncSource() { 183 } 184 185 public SyncItem setSyncItem(Principal principal, SyncItem syncItem) 187 throws SyncException { 188 try { 189 String fileName = syncItem.getKey().getKeyAsString(); 190 byte[] fileContent = 191 (byte[])syncItem.getPropertyValue(SyncItem.PROPERTY_BINARY_CONTENT); 192 193 if (fileContent == null) { 194 fileContent = new byte[0]; 195 } 196 197 if (isEncode()) { 198 fileContent = Base64.decode(fileContent); 199 } 200 201 switch (CLIENT_TYPE) { 205 case TYPE_VCARD: 207 switch (SERVER_TYPE) { 211 case TYPE_SIFC: 213 fileContent = handleSIFCAsVCard(fileContent, fileName, syncItem); 214 break; 215 case TYPE_VCARD: 217 case TYPE_TEXT: 218 break; 222 default: 223 String msg = "Content types not compatible: " 224 + " Client content type = " 225 + clientContentType 226 + " Server content type = " 227 + serverContentType 228 ; 229 throw new SyncException(msg); 230 } 231 break; 232 case TYPE_ICAL: 234 switch (SERVER_TYPE) { 238 case TYPE_SIFE: 240 fileContent = handleSIFEAsICal(fileContent, fileName, syncItem); 241 break; 242 case TYPE_ICAL: 244 case TYPE_TEXT: 245 break; 249 default: 250 String msg = "Content types not compatible: " 251 + " Client content type = " 252 + clientContentType 253 + " Server content type = " 254 + serverContentType 255 ; 256 throw new SyncException(msg); 257 } 258 break; 259 case TYPE_TEXT: 261 break; 266 case TYPE_SIFC: 268 switch (SERVER_TYPE) { 272 case TYPE_VCARD: 274 fileContent = handleVCardAsSIFC(fileContent, fileName, syncItem); 275 fileContent = handleSIFContent(fileContent, fileName, syncItem); 276 break; 277 case TYPE_SIFC: 279 fileContent = handleSIFContent(fileContent, fileName, syncItem); 280 break; 281 case TYPE_TEXT: 283 break; 287 default: 288 String msg = "Content types not compatible: " 289 + " Client content type = " 290 + clientContentType 291 + " Server content type = " 292 + serverContentType 293 ; 294 throw new SyncException(msg); 295 } 296 break; 297 case TYPE_SIFE: 299 switch (SERVER_TYPE) { 303 case TYPE_ICAL: 305 fileContent = handleICalAsSIFE(fileContent, fileName, syncItem); 306 fileContent = handleSIFContent(fileContent, fileName, syncItem); 307 break; 308 case TYPE_SIFE: 310 fileContent = handleSIFContent(fileContent, fileName, syncItem); 311 break; 312 case TYPE_TEXT: 314 break; 318 default: 319 String msg = "Content types not compatible: " 320 + " Client content type = " 321 + clientContentType 322 + " Server content type = " 323 + serverContentType 324 ; 325 throw new SyncException(msg); 326 } 327 break; 328 } 329 330 FileOutputStream fos = new FileOutputStream( 331 new File(getSourceDirectory(), fileName) 332 ); 333 fos.write(fileContent); 334 fos.close(); 335 336 setState(principal, fileName, SyncItemState.SYNCHRONIZED); 337 338 SyncItem newSyncItem = 339 new SyncItemImpl(this, fileName, SyncItemState.NEW); 340 341 newSyncItem.setProperties(syncItem.getProperties()); 342 343 return newSyncItem; 344 } catch (Exception e) { 345 throw new SyncException( "Error setting the item " 346 + syncItem.getKey().getKeyAsString() 347 , e 348 ); 349 } 350 } 351 352 364 private byte[] handleSIFCAsVCard(byte[] fileContent, String fileName, SyncItem syncItem) 365 throws SyncException { 366 367 try { 368 369 ByteArrayInputStream xmlStream = new ByteArrayInputStream(fileContent); 373 XMLContactParser parser = new XMLContactParser(xmlStream); 374 Contact contact = (Contact)parser.parse(); 375 Converter converter = new Converter((String )null, charset); 379 String vcard = converter.contactToVcard(contact); 380 381 return vcard.getBytes(); 382 383 } catch (Exception e) { 384 String msg = "Error converting item " 385 + syncItem.getKey().getKeyAsString() 386 + " from SIF-C to VCard format" 387 ; 388 throw new SyncException(msg, e); 389 } 390 391 } 392 393 403 private byte[] handleSIFEAsICal(byte[] fileContent, String fileName, SyncItem syncItem) 404 throws SyncException { 405 406 try { 407 408 ByteArrayInputStream xmlStream = new ByteArrayInputStream(fileContent); 412 XMLEventParser parser = new XMLEventParser(xmlStream); 413 Calendar calendar = (Calendar)parser.parse(); 414 Converter converter = new Converter((String )null, charset); 418 String ical = converter.calendarToIcalendar(calendar); 419 420 return ical.getBytes(); 421 422 } catch (Exception e) { 423 String msg = "Error converting item " 424 + syncItem.getKey().getKeyAsString() 425 + " from SIF-E to ICal format" 426 ; 427 throw new SyncException(msg, e); 428 } 429 430 } 431 432 443 private byte[] handleVCardAsSIFC(byte[] fileContent, String fileName, SyncItem syncItem) 444 throws SyncException { 445 446 try { 447 448 String fc = SourceUtils.handleLineDelimiting(new String (fileContent)); 452 453 ByteArrayInputStream buffer = new ByteArrayInputStream(fc.getBytes()); 454 VcardParser parser = new VcardParser(buffer); 458 Contact contact = (Contact)parser.vCard(); 459 460 Converter converter = new Converter((String )null, charset); 464 String xmlStream = converter.contactToXML(contact); 465 466 return xmlStream.getBytes(); 467 468 } catch(TokenMgrError e) { 469 throw new SyncException("Lexical error to parse item " + 470 syncItem.getKey().getKeyAsString(), e); 471 } catch (ParseException e) { 472 throw new SyncException("Error parsing the item " + 473 syncItem.getKey().getKeyAsString() 474 + " from vCard to SIF-C", e); 475 } catch (Exception e) { 476 throw new SyncException( "Error to handle convert from vCard to SIF-C" 477 + " of the item " 478 + syncItem.getKey().getKeyAsString(), e); 479 } 480 } 481 482 493 private byte[] handleICalAsSIFE(byte[] fileContent, String fileName, SyncItem syncItem) 494 throws SyncException { 495 496 try { 497 498 String fc = SourceUtils.handleLineDelimiting(new String (fileContent)); 502 503 ByteArrayInputStream buffer = new ByteArrayInputStream(fc.getBytes()); 504 ICalendarParser parser = new ICalendarParser(buffer); 508 Calendar calendar = (Calendar)parser.iCalendar(); 509 510 Converter converter = new Converter((String )null, charset); 514 String xmlStream = converter.calendarToXML(calendar); 515 516 return xmlStream.getBytes(); 517 518 } catch(TokenMgrError e) { 519 throw new SyncException("Lexical error to parse item " + 520 syncItem.getKey().getKeyAsString(), e); 521 } catch (ParseException e) { 522 throw new SyncException("Error parsing the item " + 523 syncItem.getKey().getKeyAsString() 524 + " from iCal to SIF-E", e); 525 } catch (Exception e) { 526 throw new SyncException( "Error to handle convert from iCal to SIF-E" 527 + " of the item " 528 + syncItem.getKey().getKeyAsString(), e); 529 } 530 } 531 532 544 private byte[] handleSIFContent(byte[] fileContent, String fileName, SyncItem syncItem) 545 throws SyncException { 546 547 try { 548 549 HashMap hashMap = null; 550 HashMap hashMapFromFile = null; 551 String xmlStream = new String (fileContent); 552 553 File f = new File(getSourceDirectory(), fileName); 554 if (f.exists()) { 555 hashMapFromFile = SourceUtils.xmlToHashMap(readFileString(f)); 556 hashMap = SourceUtils.xmlToHashMap(xmlStream); 557 hashMapFromFile.putAll(hashMap); 558 fileContent = SourceUtils.hashMapToXml(hashMapFromFile).getBytes(); 559 } 560 else { 561 fileContent = xmlStream.getBytes(); 562 } 563 564 return fileContent; 565 566 } catch (IOException e) { 567 throw new SyncException("Error setting the item " + 568 syncItem.getKey().getKeyAsString(), e); 569 } catch (ParseException e) { 570 throw new SyncException("Error parsing the item " + 571 syncItem.getKey().getKeyAsString(), e); 572 } catch (Exception e) { 573 throw new SyncException("Error setting the hashmap in item " + 574 syncItem.getKey().getKeyAsString(), e); 575 } 576 } 577 578 587 private String readFileString(File file) throws IOException { 588 FileInputStream fis = null; 589 590 byte[] buf = new byte[(int)file.length()]; 591 try { 592 fis = new FileInputStream(file); 593 fis.read(buf); 594 fis.close(); 595 } finally { 596 if (fis != null) { 597 fis.close(); 598 } 599 } 600 return new String (buf); 601 } 602 603 617 protected SyncItem[] filterSyncItems(Principal principal, Date since, char state) 618 throws SyncException { 619 Properties syncDatabase = updateSyncDatabase(principal); 620 621 Vector syncItems = new Vector (); 622 623 long fileTimestamp, 624 sinceTimestamp = (since == null) ? -1 : since.getTime(); 625 626 SyncItem syncItem = null; 627 String fileName = null; 628 String stateString = null; 629 char fileState ; 630 byte[] fileContent = new byte[0]; 631 632 for (Enumeration en = syncDatabase.keys(); en.hasMoreElements(); ) { 633 fileName = (String )en.nextElement(); 634 stateString = (String )syncDatabase.get(fileName); 635 fileState = stateFromStateString(stateString); 636 if ((state == SyncItemState.UNKNOWN) || (fileState == state)) { 637 fileTimestamp = lastModifiedFromStateString(stateString); 638 if (fileTimestamp > sinceTimestamp ) { 639 syncItem = new SyncItemImpl(this, fileName, fileState); 640 fileContent = readFileContent(fileName); 641 642 if (fileContent.length != 0) { 643 try { 649 fileContent = handleItemContentType(fileContent, fileName, syncItem); 650 } catch(Exception e) { 651 e.printStackTrace(); 652 if(Logger.isLoggable(Logger.INFO)) { 653 Logger.info("Error handle item content type " + e); 654 } 655 throw new SyncException("Error handle item content type ", e); 656 } 657 } 658 659 if (isEncode()){ 660 syncItem.setProperty( 661 new SyncItemProperty( 662 SyncItem.PROPERTY_BINARY_CONTENT, 663 Base64.encode(fileContent) 664 ) 665 ); 666 } else { 667 syncItem.setProperty( 668 new SyncItemProperty( 669 SyncItem.PROPERTY_BINARY_CONTENT, 670 fileContent 671 ) 672 ); 673 } 674 syncItems.addElement(syncItem); 675 } 676 } 677 } 679 SyncItem[] ret = new SyncItem[syncItems.size()]; 680 for (int i=0; i<ret.length; ++i) { 681 ret[i] = (SyncItem)syncItems.elementAt(i); 682 } 683 684 return ret; 685 } 686 687 700 private byte[] handleItemContentType(byte[] fileContent, 701 String fileName , 702 SyncItem syncItem ) 703 throws SyncException { 704 705 switch (SERVER_TYPE) { 709 case TYPE_VCARD: 711 switch (CLIENT_TYPE) { 715 case TYPE_SIFC: 717 fileContent = handleSIFCAsVCard(fileContent, fileName, syncItem); 718 break; 719 case TYPE_VCARD: 721 case TYPE_TEXT: 722 break; 726 default: 727 String msg = "Content types not compatible: " 728 + " Client content type = " 729 + clientContentType 730 + " Server content type = " 731 + serverContentType 732 ; 733 throw new SyncException(msg); 734 } 735 break; 736 case TYPE_ICAL: 738 switch (CLIENT_TYPE) { 742 case TYPE_SIFE: 744 fileContent = handleSIFEAsICal(fileContent, fileName, syncItem); 745 break; 746 case TYPE_ICAL: 748 case TYPE_TEXT: 749 break; 753 default: 754 String msg = "Content types not compatible: " 755 + " Client content type = " 756 + clientContentType 757 + " Server content type = " 758 + serverContentType 759 ; 760 throw new SyncException(msg); 761 } 762 break; 763 case TYPE_TEXT: 765 break; 770 case TYPE_SIFC: 772 switch (CLIENT_TYPE) { 776 case TYPE_VCARD: 778 fileContent = handleVCardAsSIFC(fileContent, fileName, syncItem); 779 break; 780 case TYPE_SIFC: 782 fileContent = handleSIFContent(fileContent, fileName, syncItem); 783 break; 784 case TYPE_TEXT: 786 break; 790 default: 791 String msg = "Content types not compatible: " 792 + " Client content type = " 793 + clientContentType 794 + " Server content type = " 795 + serverContentType 796 ; 797 throw new SyncException(msg); 798 } 799 break; 800 case TYPE_SIFE: 802 switch (CLIENT_TYPE) { 806 case TYPE_ICAL: 808 fileContent = handleICalAsSIFE(fileContent, fileName, syncItem); 809 break; 810 case TYPE_SIFE: 812 fileContent = handleSIFContent(fileContent, fileName, syncItem); 813 break; 814 case TYPE_TEXT: 816 break; 820 default: 821 String msg = "Content types not compatible: " 822 + " Client content type = " 823 + clientContentType 824 + " Server content type = " 825 + serverContentType 826 ; 827 throw new SyncException(msg); 828 } 829 break; 830 } return fileContent; 832 } 833 } 834 | Popular Tags |