1 18 package sync4j.framework.engine.source; 19 20 import java.util.Collection ; 21 import java.util.ArrayList ; 22 import java.util.Iterator ; 23 import java.util.List ; 24 25 import java.security.Principal ; 26 import java.sql.Timestamp ; 27 28 import sync4j.framework.engine.SyncProperty; 29 import sync4j.framework.engine.SyncItemKey; 30 import sync4j.framework.engine.SyncItem; 31 import sync4j.framework.engine.SyncItemImpl; 32 import sync4j.framework.engine.SyncItemState; 33 import sync4j.framework.engine.source.SyncSourceException; 34 import sync4j.framework.engine.source.SyncSource; 35 36 52 public class MemorySyncSource 53 extends AbstractSyncSource 54 implements SyncSource, CommittableSyncSource, java.io.Serializable { 55 56 58 public static final String NAME = "MemorySyncSource"; 59 60 62 private List existingSyncItems; 64 private List newSyncItems ; 65 private List updatedSyncItems ; 66 private List deletedSyncItems ; 67 68 private List allNewSyncItems ; 69 private List allUpdatedSyncItems ; 70 private List allDeletedSyncItems ; 71 72 75 private SyncItem lo; 76 77 79 public MemorySyncSource() { 80 lo = null; 81 } 82 83 public MemorySyncSource(String name, String type, String sourceURI) { 84 super(name, type, sourceURI); 85 lo = null; 86 initialize(new ArrayList (), new ArrayList (), new ArrayList ()); 87 88 allNewSyncItems = new ArrayList (); 89 allUpdatedSyncItems = new ArrayList (); 90 allDeletedSyncItems = new ArrayList (); 91 92 setExistingItems(new ArrayList ()); 93 } 94 95 public MemorySyncSource(String name , 96 List unchangedSyncItems, 97 List deletedSyncItems , 98 List newSyncItems ) { 99 super(name); 103 lo = null; 104 initialize(deletedSyncItems, newSyncItems, updatedSyncItems); 105 setExistingItems(new ArrayList ()); 106 } 107 108 110 115 public void setName(String name) { 116 this.name = name; 117 } 118 119 122 123 public SyncItem setSyncItem(Principal principal, SyncItem syncItem) 124 throws SyncSourceException { 125 newSyncItems.remove (syncItem); 126 deletedSyncItems.add(syncItem); 127 128 updatedSyncItems.add(syncItem); 129 130 SyncItemKey mappedKey = syncItem.getMappedKey(); 131 String mappedKeyValue = (mappedKey == null) ? null 132 : mappedKey.getKeyAsString(); 133 134 SyncItem newSyncItem = new SyncItemImpl( 135 this, 136 syncItem.getKey().getKeyAsString(), 137 mappedKeyValue, 138 SyncItemState.NEW 139 ); 140 141 newSyncItem.setProperties(syncItem.getProperties()); 142 143 return newSyncItem; 144 } 145 146 149 150 public SyncItem[] setSyncItems(Principal principal, SyncItem[] syncItems) 151 throws SyncSourceException { 152 SyncItem[] ret = new SyncItem[syncItems.length]; 153 for (int i=0; (i<syncItems.length); ++i) { 154 ret[i] = setSyncItem(principal, syncItems[i]); 155 } 157 return ret; 158 } 159 160 166 public SyncItem getSyncItemFromId(Principal principal, SyncItemKey syncItemKey) 167 throws SyncSourceException { 168 SyncItem[] all = this.getAllSyncItems(principal); 169 170 for (int i=0; ((all != null) && (i<all.length)); ++i) { 171 if (syncItemKey.equals(all[i].getKey())) { 172 return all[i]; 173 } 174 } 175 176 return null; 177 } 178 179 183 public SyncItem[] getSyncItemsFromIds(Principal principal, SyncItemKey[] syncItemKeys) 184 throws SyncSourceException { 185 ArrayList ret = new ArrayList (); 186 SyncItem syncItem = null; 187 188 for (int i=0; ((syncItemKeys != null) && (i<syncItemKeys.length)); ++i) { 189 syncItem = getSyncItemFromId(principal, syncItemKeys[i]); 190 191 if (syncItem != null) { 192 ret.add(syncItem); 193 } 194 } 195 196 return (SyncItem[])ret.toArray(new SyncItem[ret.size()]); 197 } 198 199 202 public SyncItemKey[] getNewSyncItemKeys(Principal principal, 203 Timestamp since ) 204 throws SyncSourceException { 205 return extractKeys(newSyncItems); 206 } 207 208 211 public SyncItem[] getNewSyncItems(Principal principal, 212 Timestamp since ) 213 throws SyncSourceException { 214 return (SyncItem[])newSyncItems.toArray(new SyncItem[0]); 215 } 216 217 220 public SyncItemKey[] getDeletedSyncItemKeys(Principal principal, 221 Timestamp since ) 222 throws SyncSourceException { 223 return extractKeys(deletedSyncItems); 224 } 225 226 229 public SyncItem[] getDeletedSyncItems(Principal principal, 230 Timestamp since ) 231 throws SyncSourceException { 232 return (SyncItem[])deletedSyncItems.toArray(new SyncItem[0]); 233 } 234 235 239 public SyncItemKey[] getUpdatedSyncItemKeys(Principal principal, 240 Timestamp since ) 241 throws SyncSourceException { 242 return extractKeys(updatedSyncItems); 243 } 244 245 248 public SyncItem[] getUpdatedSyncItems(Principal principal, 249 Timestamp since ) 250 throws SyncSourceException { 251 return (SyncItem[])updatedSyncItems.toArray(new SyncItem[0]); 252 } 253 254 257 public void removeSyncItem(Principal principal, SyncItem syncItem) 258 throws SyncSourceException { 259 newSyncItems.remove (syncItem); 260 updatedSyncItems.remove (syncItem); 261 262 deletedSyncItems.add(syncItem); 263 } 264 265 268 public void removeSyncItems(Principal principal, SyncItem[] syncItems) 269 throws SyncSourceException { 270 for (int i=0; i<syncItems.length; ++i) { 271 removeSyncItem(principal, syncItems[i]); 272 } } 274 275 278 public SyncItem[] getAllSyncItems(Principal principal) 279 throws SyncSourceException { 280 return (SyncItem[])existingSyncItems.toArray(new SyncItemImpl[0]); 281 } 282 283 286 public boolean isModified(Principal principal, Timestamp since) { 287 try { 288 return (getDeletedSyncItems(principal, since).length > 0) 289 || (getNewSyncItems(principal, since).length > 0) 290 || (getUpdatedSyncItems(principal, since).length > 0); 291 } catch (Exception e) { 292 e.printStackTrace(); 293 return false; 294 } 295 } 296 297 304 public void initialize(List deletedItems , 305 List newItems , 306 List updatedItems ) { 307 308 if (deletedSyncItems == null) { 320 deletedSyncItems = new ArrayList (); 321 } else { 322 deletedSyncItems.clear(); 323 } 324 325 if (newSyncItems == null) { 326 newSyncItems = new ArrayList (); 327 } else { 328 newSyncItems.clear(); 329 } 330 331 if (updatedSyncItems == null) { 332 updatedSyncItems = new ArrayList (); 333 } else { 334 updatedSyncItems.clear(); 335 } 336 337 deletedSyncItems.addAll(deletedItems) ; 338 newSyncItems.addAll(newItems) ; 339 updatedSyncItems.addAll(updatedItems ) ; 340 341 boolean cont = false; 342 do { 343 cont = handleLOs(); 344 } while (cont); 345 346 SyncItem syncItem = null; 352 Iterator i = deletedSyncItems.iterator(); 353 while (i.hasNext()) { 354 syncItem = (SyncItem)i.next(); 355 newSyncItems.remove(syncItem) ; 356 updatedSyncItems.remove(syncItem) ; 357 } 358 359 i = updatedSyncItems.iterator(); 360 while (i.hasNext()) { 361 syncItem = (SyncItem)i.next(); 362 newSyncItems.remove(syncItem) ; 363 deletedSyncItems.remove(syncItem); 364 } 365 366 i = newSyncItems.iterator(); 367 while (i.hasNext()) { 368 syncItem = (SyncItem)i.next(); 369 updatedSyncItems.remove(syncItem); 370 deletedSyncItems.remove(syncItem); 371 } 372 } 373 374 375 381 public void setExistingItems(List items) { 382 existingSyncItems = items; 383 } 384 385 386 399 public SyncItem getSyncItemFromTwin(Principal principal, SyncItem syncItemTwin) 400 throws SyncSourceException { 401 SyncItem[] syncItems = 402 getSyncItemsFromTwins(principal, new SyncItem[] {syncItemTwin}); 403 404 if ((syncItems == null) || (syncItems.length == 0)) { 405 return null; } 407 408 return syncItems[0]; 409 } 410 411 424 public SyncItem[] getSyncItemsFromTwins(Principal principal, SyncItem[] syncItemTwins) 425 throws SyncSourceException { 426 ArrayList ret = new ArrayList (); 427 428 String [] contents = new String [syncItemTwins.length]; 429 430 for (int i=0; i<syncItemTwins.length; ++i) { 431 contents[i] = new String ((byte[])syncItemTwins[i].getProperty(SyncItem.PROPERTY_BINARY_CONTENT).getValue()); 432 } 433 434 SyncItem[] all = getAllSyncItems(principal); 435 436 String content = null; 437 SyncProperty prop = null; 438 for (int i=0; i<all.length; ++i) { 439 prop = all[i].getProperty(SyncItem.PROPERTY_BINARY_CONTENT); 440 if (prop != null) { 441 content = new String ((byte[])prop.getValue()); 442 } 443 444 for (int j=0; ((content != null) && (j<contents.length)); ++j) { 445 if (content.equals(contents[j])) { 446 ret.add(all[i]); 447 break; 448 } 449 } 450 } 451 452 return (SyncItem[])ret.toArray(new SyncItem[ret.size()]); 453 } 454 455 457 private SyncItemKey[] extractKeys(Collection syncItems) { 458 SyncItemKey[] keys = new SyncItemKey[syncItems.size()]; 459 460 SyncItem syncItem = null; 461 int j = 0; 462 for(Iterator i = syncItems.iterator(); i.hasNext(); ++j) { 463 syncItem = (SyncItem)i.next(); 464 465 keys[j] = syncItem.getKey(); 466 } 468 return keys; 469 } 470 471 private SyncItemKey[] extractKeys(SyncItem[] syncItems) { 472 SyncItemKey[] keys = new SyncItemKey[syncItems.length]; 473 474 for(int j = 0; j<syncItems.length; ++j) { 475 keys[j] = syncItems[j].getKey(); 476 } 478 return keys; 479 } 480 481 486 private boolean handleLOs() { 487 boolean ret = false; 488 489 SyncItem chunk = null; 490 int p = -1; 491 492 if (lo != null) { 493 p = newSyncItems.indexOf(lo); 495 if (p >= 0) { 496 chunk = (SyncItem)newSyncItems.get(p); 497 } else { 498 p = updatedSyncItems.indexOf(lo); 499 if (p >= 0) { 500 chunk = (SyncItem)updatedSyncItems.get(p); 501 } 502 } 503 504 if (chunk != null) { 505 mergeLOChunk(chunk); 506 507 if (chunk.getState() != SyncItemState.PARTIAL) { 513 switch (lo.getState()) { 514 case SyncItemState.PARTIAL: 515 break; 519 520 case SyncItemState.NEW: 521 newSyncItems.remove(chunk); 525 newSyncItems.add(lo); 526 lo = null; ret = true; 527 break; 528 529 case SyncItemState.UPDATED: 530 case SyncItemState.SYNCHRONIZED: 531 updatedSyncItems.remove(chunk); 535 updatedSyncItems.add(lo); 536 lo = null; ret = true; 537 break; 538 } 539 } } } else { 542 546 Iterator i = newSyncItems.iterator(); 547 while(i.hasNext()) { 548 chunk = (SyncItem)i.next(); 549 550 if (chunk.getState() == SyncItemState.PARTIAL) { 551 lo = newSyncItem(chunk); 552 lo.setState(SyncItemState.NEW); 553 break; 554 } 555 } 556 557 i = updatedSyncItems.iterator(); 558 while(i.hasNext()) { 559 chunk = (SyncItem)i.next(); 560 561 if (chunk.getState() == SyncItemState.PARTIAL) { 562 lo = newSyncItem(chunk); 563 lo.setState(SyncItemState.UPDATED); 564 break; 565 } 566 } 567 } 568 569 return ret; 570 } 571 572 579 private void mergeLOChunk(SyncItem chunk) { 580 if (lo == null) { 581 return; 585 } 586 587 byte[] loData = (byte[])lo.getPropertyValue(lo.PROPERTY_BINARY_CONTENT); 588 byte[] chunkData = (byte[])chunk.getPropertyValue(lo.PROPERTY_BINARY_CONTENT); 589 590 byte[] allData = new byte[loData.length + chunkData.length]; 591 592 System.arraycopy(loData, 0, allData, 0, loData.length); 593 System.arraycopy(chunkData, 0, allData, loData.length, chunkData.length); 594 595 SyncProperty size = lo.getProperty(lo.PROPERTY_SIZE); 596 lo.setProperties(chunk.getProperties()); 597 lo.setPropertyValue(lo.PROPERTY_BINARY_CONTENT, allData); 598 lo.setProperty(size); 599 } 600 601 607 private SyncItem newSyncItem(SyncItem fromSyncItem) { 608 SyncItemKey mappedKey = fromSyncItem.getMappedKey(); 609 610 String mappedKeyValue = (mappedKey == null) 611 ? null 612 : mappedKey.getKeyAsString() 613 ; 614 SyncItemImpl syncItem 615 = new SyncItemImpl(fromSyncItem.getSyncSource() , 616 fromSyncItem.getKey().getKeyAsString(), 617 mappedKeyValue , 618 fromSyncItem.getState() ); 619 620 syncItem.setProperties(fromSyncItem.getProperties()); 621 622 return syncItem; 623 } 624 625 public void commitSync() throws SyncSourceException { 626 allNewSyncItems.addAll(newSyncItems); 627 allUpdatedSyncItems.addAll(updatedSyncItems); 628 allDeletedSyncItems.addAll(deletedSyncItems); 629 } 630 631 public SyncItem[] getAllNewSyncItems(Principal principal, Timestamp since) 632 throws SyncSourceException { 633 return (SyncItem[])allNewSyncItems.toArray(new SyncItem[0]); 634 } 635 636 public SyncItem[] getAllUpdatedSyncItems(Principal principal,Timestamp since) 637 throws SyncSourceException { 638 return (SyncItem[])allUpdatedSyncItems.toArray(new SyncItem[0]); 639 } 640 641 public SyncItem[] getAllDeletedSyncItems(Principal principal, Timestamp since) 642 throws SyncSourceException { 643 return (SyncItem[])allDeletedSyncItems.toArray(new SyncItem[0]); 644 } 645 646 } | Popular Tags |