Package er.extensions.eof

Source Code of er.extensions.eof.ERXDatabaseContext

package er.extensions.eof;

import org.apache.log4j.Logger;

import com.webobjects.eoaccess.EOAttribute;
import com.webobjects.eoaccess.EODatabase;
import com.webobjects.eoaccess.EODatabaseContext;
import com.webobjects.eoaccess.EODatabaseOperation;
import com.webobjects.eoaccess.EOEntity;
import com.webobjects.eoaccess.ERXEOAccessHelper;
import com.webobjects.eocontrol.EOEditingContext;
import com.webobjects.eocontrol.EOFetchSpecification;
import com.webobjects.eocontrol.EOGlobalID;
import com.webobjects.foundation.NSArray;
import com.webobjects.foundation.NSDictionary;
import com.webobjects.foundation.NSKeyValueCoding;

public class ERXDatabaseContext extends EODatabaseContext {

  /** general logging */
  public static final Logger log = Logger.getLogger(ERXDatabaseContext.class);

  private static ThreadLocal _fetching = new ThreadLocal();

  public ERXDatabaseContext(EODatabase database) {
    super(new ERXDatabase(database));
  }

  public static boolean isFetching() {
    Boolean fetching = (Boolean) _fetching.get();
    // System.out.println("ERXDatabaseContext.isFetching: " +
    // Thread.currentThread() + ", " + fetching);
    return fetching != null && fetching.booleanValue();
  }

  public static void setFetching(boolean fetching) {
    // System.out.println("ERXDatabaseContext.setFetching: " +
    // Thread.currentThread() + ", " + fetching);
    _fetching.set(Boolean.valueOf(fetching));
  }

  @Override
  public NSArray objectsForSourceGlobalID(EOGlobalID gid, String name, EOEditingContext context) {
    NSArray results;
    boolean fetching = isFetching();
    if (!fetching) {
      setFetching(true);
    }
    try {
      results = super.objectsForSourceGlobalID(gid, name, context);
    }
    finally {
      if (!fetching) {
        setFetching(false);
      }
    }
    return results;
  }

  @Override
  public NSArray _objectsWithFetchSpecificationEditingContext(EOFetchSpecification fetchSpec, EOEditingContext context) {
    NSArray results;
    boolean fetching = isFetching();
    if (!fetching) {
      setFetching(!fetchSpec.refreshesRefetchedObjects());
    }
    try {
      results = super._objectsWithFetchSpecificationEditingContext(fetchSpec, context);
    }
    finally {
      if (!fetching) {
        setFetching(false);
      }
    }
    return results;
  }
 
  @Override
  public void _followFetchSpecification(EOFetchSpecification fetchSpec, String relationshipName, NSArray sourceObjects, EOEditingContext context) {
    fetchSpec = ERXEOAccessHelper.adjustPrefetching(this, fetchSpec, relationshipName, sourceObjects, context);
    super._followFetchSpecification(fetchSpec, relationshipName, sourceObjects, context);
  }

  @Override
  public void _verifyNoChangesToReadonlyEntity(EODatabaseOperation dbOp) {
    EOEntity entity = dbOp.entity();
    if (entity.isReadOnly()) {
      switch (dbOp.databaseOperator()) {
      case 0: // '\0'
        return;

      case 1: // '\001'
        throw new IllegalStateException("cannot insert object:" + dbOp.object() + " that corresponds to read-only entity: " + entity.name() + " in databaseContext " + this);

      case 3: // '\003'
        throw new IllegalStateException("cannot delete object:" + dbOp.object() + " that corresponds to read-only entity:" + entity.name() + " in databaseContext " + this);

      case 2: // '\002'
        if (!dbOp.dbSnapshot().equals(dbOp.newRow())) {
          throw new IllegalStateException("cannot update '" + dbOp.rowDiffsForAttributes(entity.attributes()).allKeys() + "' keys on object:" + dbOp.object() + " that corresponds to read-only entity: " + entity.name() + " in databaseContext " + this);
        }
        return;
      }
    }
    // HACK: ak these methods are protected, so we call them via KVC
    if (dbOp.databaseOperator() == 2 && ((Boolean) NSKeyValueCoding.Utility.valueForKey(entity, "_hasNonUpdateableAttributes")).booleanValue()) {
      NSArray keys = (NSArray) NSKeyValueCoding.Utility.valueForKey(entity, "dbSnapshotKeys");
      NSDictionary dbSnapshot = dbOp.dbSnapshot();
      NSDictionary newRow = dbOp.newRow();
      for (int i = keys.count() - 1; i >= 0; i--) {
        String key = (String) keys.objectAtIndex(i);
        EOAttribute att = entity.attributeNamed(key);
        // FIX: ak when you have single-table inheritance and in the
        // child there are foreign keys that are not in the parent
        // THEN, if the entity _hasNonUpdateableAttributes (public PK or
        // read only props) the DB op is checked
        // against the attributes. BUT this dictionary has all entries,
        // even from the child (most likely NULL values)
        // and the current implementation doesn't check against the case
        // when the attribute isn't present in the first place.
        // SO we add this check and live happily ever after
        if (att != null && att._isNonUpdateable() && !dbSnapshot.objectForKey(key).equals(newRow.objectForKey(key))) {
          if (att.isReadOnly()) {
            throw new IllegalStateException("cannot update read-only key '" + key + "' on object:" + dbOp.object() + " of entity: " + entity.name() + " in databaseContext " + this);
          }
          throw new IllegalStateException("cannot update primary-key '" + key + "' from '" + dbSnapshot.objectForKey(key) + "' to '" + newRow.objectForKey(key) + "' on object:" + dbOp.object() + " of entity: " + entity.name() + " in databaseContext " + this);
        }
      }

    }
  }
}
TOP

Related Classes of er.extensions.eof.ERXDatabaseContext

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.