Package er.extensions.eof

Source Code of er.extensions.eof.ERXDatabase$SnapshotUpdated

package er.extensions.eof;

import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

import com.webobjects.eoaccess.EOAdaptor;
import com.webobjects.eoaccess.EODatabase;
import com.webobjects.eoaccess.EODatabaseContext;
import com.webobjects.eoaccess.EOEntity;
import com.webobjects.eoaccess.EOModel;
import com.webobjects.eocontrol.EOEnterpriseObject;
import com.webobjects.eocontrol.EOGlobalID;
import com.webobjects.eocontrol.EOTemporaryGlobalID;
import com.webobjects.foundation.NSArray;
import com.webobjects.foundation.NSDictionary;
import com.webobjects.foundation.NSMutableDictionary;
import com.webobjects.foundation.NSNotification;
import com.webobjects.foundation.NSNotificationCenter;
import com.webobjects.foundation.NSSet;

import er.extensions.foundation.ERXArrayUtilities;
import er.extensions.foundation.ERXStringUtilities;

public class ERXDatabase extends EODatabase {
  public static final String SnapshotCacheChanged = "SnapshotCacheChanged";
  public static final String CacheChangeKey = "CacheChange";
 
  private boolean _globalIDChanged;
  private boolean _decrementSnapshot;

  public ERXDatabase(EOAdaptor adaptor) {
    super(adaptor);

    // AK: huge performance optimization when you use badly distributed LONG keys

    _snapshots = new NSMutableDictionary() {
      /**
       * Do I need to update serialVersionUID?
       * See section 5.6 <cite>Type Changes Affecting Serialization</cite> on page 51 of the
       * <a href="http://java.sun.com/j2se/1.4/pdf/serial-spec.pdf">Java Object Serialization Spec</a>
       */
      private static final long serialVersionUID = 1L;

      Map hashMap = new HashMap();

      @Override
      public Object objectForKey(Object key) {
        return hashMap.get(key);
      }

      @Override
      public void setObjectForKey(Object object, Object key) {
        hashMap.put(key, object);
      }

      @Override
      public Object removeObjectForKey(Object key) {
        return hashMap.remove(key);
      }

      @Override
      public NSDictionary immutableClone() {
        return new NSDictionary(hashMap);
      }

      @Override
      public NSArray allKeys() {
        return new NSArray(hashMap.keySet());
      }
    };
  }

  public ERXDatabase(EOModel model) {
    super(model);
  }

  public ERXDatabase(EODatabase _database) {
    this(_database.adaptor());
    Enumeration modelsEnum = _database.models().objectEnumerator();
    while (modelsEnum.hasMoreElements()) {
      EOModel model = (EOModel) modelsEnum.nextElement();
      addModel(model);
    }
    _database.dispose();
  }

  public synchronized void _notifyCacheChange(CacheChange cacheChange) {
    NSNotificationCenter.defaultCenter().postNotification(ERXDatabase.SnapshotCacheChanged, this, new NSDictionary(cacheChange, ERXDatabase.CacheChangeKey));
  }

  @Override
  protected NSSet _cachedFetchAttributesForEntityNamed(String name) {
    return super._cachedFetchAttributesForEntityNamed(name);
  }

  @Override
  protected void _clearLastRecords() {
    super._clearLastRecords();
  }

  @Override
  protected _DatabaseRecord _fastHashGet(EOGlobalID gid) {
    return super._fastHashGet(gid);
  }

  @Override
  protected void _fastHashInsert(_DatabaseRecord rec, EOGlobalID gid) {
    super._fastHashInsert(rec, gid);
    if (_globalIDChanged) {
      _notifyCacheChange(new SnapshotInserted(gid, snapshotForGlobalID(gid)));
    }
  }

  @Override
  protected void _fastHashRemove(EOGlobalID gid) {
    // if (_decrementSnapshot) {
    // System.out.println("ERXDatabase._fastHashRemove: remove " + gid);
    // NSLog.out.appendln(new RuntimeException());
    // }
    super._fastHashRemove(gid);
  }

  @Override
  public void _forgetSnapshotForGlobalID(EOGlobalID gid) {
    super._forgetSnapshotForGlobalID(gid);
  }

  @Override
  protected void _freeToManyMap(_DatabaseRecord rec) {
    super._freeToManyMap(rec);
  }

  @Override
  public void _globalIDChanged(NSNotification notification) {
    boolean oldGlobalIDChanged = _globalIDChanged;
    _globalIDChanged = true;
    try {
      super._globalIDChanged(notification);
    }
    finally {
      _globalIDChanged = oldGlobalIDChanged;
    }
  }

  @Override
  public void recordSnapshotForGlobalID(NSDictionary snapshot, EOGlobalID gid) {
    if (!ERXDatabaseContext.isFetching() && !(gid instanceof EOTemporaryGlobalID)) {
      _notifyCacheChange(new SnapshotUpdated(gid, snapshot));
    }
    super.recordSnapshotForGlobalID(snapshot, gid);
  }

  @Override
  public void recordSnapshotForSourceGlobalID(NSArray gids, EOGlobalID gid, String name) {
    if (!ERXDatabaseContext.isFetching()) {
      NSArray originalToManyGIDs = snapshotForSourceGlobalID(gid, name);
      _notifyCacheChange(new ToManySnapshotUpdated(gid, name, originalToManyGIDs, gids));
    }
    super.recordSnapshotForSourceGlobalID(gids, gid, name);
  }

  @Override
  public int _indexOfRegisteredContext(EODatabaseContext context) {
    return super._indexOfRegisteredContext(context);
  }

  @Override
  protected EOGlobalID _recordedGIDForSnapshotWithGid(EOGlobalID gid) {
    return super._recordedGIDForSnapshotWithGid(gid);
  }

  @Override
  protected void _setTimestampForCachedGlobalID(EOGlobalID gid) {
    super._setTimestampForCachedGlobalID(gid);
  }

  @Override
  public int _snapshotCountForGlobalID(EOGlobalID gid) {
    return super._snapshotCountForGlobalID(gid);
  }

  @Override
  public EOAdaptor adaptor() {
    return super.adaptor();
  }

  @Override
  public void addModel(EOModel model) {
    super.addModel(model);
  }

  @Override
  public boolean addModelIfCompatible(EOModel model) {
    return super.addModelIfCompatible(model);
  }

  @Override
  public void decrementSnapshotCountForGlobalID(EOGlobalID gid) {
    boolean oldDecrementSnapshot = _decrementSnapshot;
    _decrementSnapshot = true;
    try {
      super.decrementSnapshotCountForGlobalID(gid);
    }
    finally {
      _decrementSnapshot = oldDecrementSnapshot;
    }
  }

  @Override
  public void dispose() {
    super.dispose();
  }

  @Override
  public EOEntity entityForObject(EOEnterpriseObject object) {
    return super.entityForObject(object);
  }

  @Override
  public EOEntity entityNamed(String entityName) {
    return super.entityNamed(entityName);
  }

  @Override
  public void forgetAllSnapshots() {
    super.forgetAllSnapshots();
  }

  @Override
  public void forgetSnapshotForGlobalID(EOGlobalID gid) {
    super.forgetSnapshotForGlobalID(gid);
  }

  @Override
  public void forgetSnapshotsForGlobalIDs(NSArray array) {
    super.forgetSnapshotsForGlobalIDs(array);
  }

  @Override
  public void handleDroppedConnection() {
    super.handleDroppedConnection();
  }

  @Override
  public void incrementSnapshotCountForGlobalID(EOGlobalID gid) {
    super.incrementSnapshotCountForGlobalID(gid);
  }

  @Override
  public void invalidateResultCache() {
    super.invalidateResultCache();
  }

  @Override
  public void invalidateResultCacheForEntityNamed(String name) {
    super.invalidateResultCacheForEntityNamed(name);
  }

  @Override
  public NSArray models() {
    return super.models();
  }

  @Override
  public void recordSnapshots(NSDictionary snapshots) {
    super.recordSnapshots(snapshots);
  }

  @Override
  public void recordToManySnapshots(NSDictionary snapshots) {
    super.recordToManySnapshots(snapshots);
  }

  @Override
  public void registerContext(EODatabaseContext context) {
    super.registerContext(context);
  }

  @Override
  public NSArray registeredContexts() {
    return super.registeredContexts();
  }

  @Override
  public void removeModel(EOModel model) {
    super.removeModel(model);
  }

  @Override
  public NSArray resultCacheForEntityNamed(String name) {
    return super.resultCacheForEntityNamed(name);
  }

  @Override
  public void setResultCache(NSArray cache, String name) {
    super.setResultCache(cache, name);
  }

  @Override
  public void setTimestampToNow() {
    super.setTimestampToNow();
  }

  @Override
  public NSDictionary snapshotForGlobalID(EOGlobalID gid, long timestamp) {
    return super.snapshotForGlobalID(gid, timestamp);
  }

  @Override
  public NSDictionary snapshotForGlobalID(EOGlobalID gid) {
    return super.snapshotForGlobalID(gid);
  }

  @Override
  public NSArray snapshotForSourceGlobalID(EOGlobalID gid, String name, long timestamp) {
    return super.snapshotForSourceGlobalID(gid, name, timestamp);
  }

  @Override
  public NSArray snapshotForSourceGlobalID(EOGlobalID gid, String name) {
    return super.snapshotForSourceGlobalID(gid, name);
  }

  @Override
  public NSDictionary snapshots() {
    return super.snapshots();
  }

  @Override
  public long timestampForGlobalID(EOGlobalID gid) {
    return super.timestampForGlobalID(gid);
  }

  @Override
  public long timestampForSourceGlobalID(EOGlobalID gid, String name) {
    return super.timestampForSourceGlobalID(gid, name);
  }

  @Override
  public void unregisterContext(EODatabaseContext context) {
    super.unregisterContext(context);
  }

  public static abstract class CacheChange {
    private EOGlobalID _gid;

    public CacheChange(EOGlobalID gid) {
      _gid = gid;
    }

    public EOGlobalID gid() {
      return _gid;
    }

    @Override
    public String toString() {
      return "[" + ERXStringUtilities.getSimpleClassName(getClass()) + ": " + _gid + "]";
    }
  }

  public static abstract class SnapshotCacheChange extends CacheChange {
    private NSDictionary _snapshot;

    public SnapshotCacheChange(EOGlobalID gid, NSDictionary snapshot) {
      super(gid);
      _snapshot = snapshot;
    }

    public NSDictionary snapshot() {
      return _snapshot;
    }
  }

  public static class SnapshotInserted extends SnapshotCacheChange {
    public SnapshotInserted(EOGlobalID gid, NSDictionary snapshot) {
      super(gid, snapshot);
    }
  }

  public static class SnapshotUpdated extends SnapshotCacheChange {
    public SnapshotUpdated(EOGlobalID gid, NSDictionary snapshot) {
      super(gid, snapshot);
    }
  }

  public static class SnapshotDeleted extends SnapshotCacheChange {
    public SnapshotDeleted(EOGlobalID gid, NSDictionary snapshot) {
      super(gid, snapshot);
    }
  }

  public static class ToManySnapshotUpdated extends CacheChange {
    private String _name;
    private NSArray _addedGIDs;
    private NSArray _removedGIDs;
    private boolean _removeAll;

    public ToManySnapshotUpdated(EOGlobalID sourceGID, String name, NSArray addedGIDs, NSArray removedGIDs, boolean removeAll) {
      super(sourceGID);
      _name = name;
      _addedGIDs = addedGIDs;
      _removedGIDs = removedGIDs;
      _removeAll = removeAll;
    }
   
    public ToManySnapshotUpdated(EOGlobalID sourceGID, String name, NSArray originalToManyGIDs, NSArray newToManyGIDs) {
      super(sourceGID);
      _name = name;
      if (originalToManyGIDs == null || originalToManyGIDs.count() == 0) {
        _addedGIDs = newToManyGIDs;
      }
      else if (newToManyGIDs == null || newToManyGIDs.count() == 0) {
        _removeAll = true;
        _removedGIDs = originalToManyGIDs;
      }
      else {
        _addedGIDs = ERXArrayUtilities.arrayMinusArray(newToManyGIDs, originalToManyGIDs);
        _removedGIDs = ERXArrayUtilities.arrayMinusArray(originalToManyGIDs, newToManyGIDs);
      }
    }

    public String name() {
      return _name;
    }

    public NSArray removedGIDs() {
      return _removedGIDs;
    }

    public boolean removeAll() {
      return _removeAll;
    }

    public NSArray addedGIDs() {
      return _addedGIDs;
    }

    @Override
    public String toString() {
      return "[ToManySnapshotChanged: sourceGID = " + gid() + "; name = " + _name + "; added = " + ((_addedGIDs == null) ? 0 : _addedGIDs.count()) + "; removed = " + ((_removedGIDs == null) ? 0 : _removedGIDs.count()) + "; removeAll = " + _removeAll + "]";
    }
  }
}
TOP

Related Classes of er.extensions.eof.ERXDatabase$SnapshotUpdated

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.