michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: package org.mozilla.gecko.sync.repositories; michael@0: michael@0: import java.util.Collection; michael@0: import java.util.Iterator; michael@0: michael@0: import org.mozilla.gecko.background.common.log.Logger; michael@0: import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionBeginDelegate; michael@0: import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionFinishDelegate; michael@0: import org.mozilla.gecko.sync.repositories.domain.Record; michael@0: michael@0: public abstract class StoreTrackingRepositorySession extends RepositorySession { michael@0: private static final String LOG_TAG = "StoreTrackSession"; michael@0: protected StoreTracker storeTracker; michael@0: michael@0: protected static StoreTracker createStoreTracker() { michael@0: return new HashSetStoreTracker(); michael@0: } michael@0: michael@0: public StoreTrackingRepositorySession(Repository repository) { michael@0: super(repository); michael@0: } michael@0: michael@0: @Override michael@0: public void begin(RepositorySessionBeginDelegate delegate) throws InvalidSessionTransitionException { michael@0: RepositorySessionBeginDelegate deferredDelegate = delegate.deferredBeginDelegate(delegateQueue); michael@0: try { michael@0: super.sharedBegin(); michael@0: } catch (InvalidSessionTransitionException e) { michael@0: deferredDelegate.onBeginFailed(e); michael@0: return; michael@0: } michael@0: // Or do this in your own subclass. michael@0: storeTracker = createStoreTracker(); michael@0: deferredDelegate.onBeginSucceeded(this); michael@0: } michael@0: michael@0: @Override michael@0: protected synchronized void trackGUID(String guid) { michael@0: if (this.storeTracker == null) { michael@0: throw new IllegalStateException("Store tracker not yet initialized!"); michael@0: } michael@0: this.storeTracker.trackRecordForExclusion(guid); michael@0: } michael@0: michael@0: @Override michael@0: protected synchronized void untrackGUID(String guid) { michael@0: if (this.storeTracker == null) { michael@0: throw new IllegalStateException("Store tracker not yet initialized!"); michael@0: } michael@0: this.storeTracker.untrackStoredForExclusion(guid); michael@0: } michael@0: michael@0: @Override michael@0: protected synchronized void untrackGUIDs(Collection guids) { michael@0: if (this.storeTracker == null) { michael@0: throw new IllegalStateException("Store tracker not yet initialized!"); michael@0: } michael@0: if (guids == null) { michael@0: return; michael@0: } michael@0: for (String guid : guids) { michael@0: this.storeTracker.untrackStoredForExclusion(guid); michael@0: } michael@0: } michael@0: michael@0: protected void trackRecord(Record record) { michael@0: michael@0: Logger.debug(LOG_TAG, "Tracking record " + record.guid + michael@0: " (" + record.lastModified + ") to avoid re-upload."); michael@0: // Future: we care about the timestamp… michael@0: trackGUID(record.guid); michael@0: } michael@0: michael@0: protected void untrackRecord(Record record) { michael@0: Logger.debug(LOG_TAG, "Un-tracking record " + record.guid + "."); michael@0: untrackGUID(record.guid); michael@0: } michael@0: michael@0: @Override michael@0: public Iterator getTrackedRecordIDs() { michael@0: if (this.storeTracker == null) { michael@0: throw new IllegalStateException("Store tracker not yet initialized!"); michael@0: } michael@0: return this.storeTracker.recordsTrackedForExclusion(); michael@0: } michael@0: michael@0: @Override michael@0: public void abort(RepositorySessionFinishDelegate delegate) { michael@0: this.storeTracker = null; michael@0: super.abort(delegate); michael@0: } michael@0: michael@0: @Override michael@0: public void finish(RepositorySessionFinishDelegate delegate) throws InactiveSessionException { michael@0: super.finish(delegate); michael@0: this.storeTracker = null; michael@0: } michael@0: }