public void arcCreated(Object nodeId, Object targetNodeId, Object arcId) {
    ObjEntity entity = resolver.getObjEntity(((ObjectId) nodeId).getEntityName());
    ObjRelationship relationship = (ObjRelationship) entity.getRelationship(arcId.toString());

    if (relationship.isSourceIndependentFromTargetChange()) {

      if (!((ObjectId) nodeId).isTemporary()) {
        indirectModifications.add(nodeId);
      }

      if (relationship.isFlattened()) {
        if (relationship.isReadOnly()) {
          throw new CayenneRuntimeException(
              "Cannot set the read-only flattened relationship '"
                  + relationship.getName()
                  + "' in ObjEntity '"
                  + relationship.getSourceEntity().getName()
                  + "'.");
        }

        // Register this combination (so we can remove it later if an insert
        // occurs before commit)
        FlattenedArcKey key =
            new FlattenedArcKey((ObjectId) nodeId, (ObjectId) targetNodeId, relationship);

        // If this combination has already been deleted, simply undelete it.
        if (!flattenedDeletes.remove(key)) {
          flattenedInserts.add(key);
        }
      }
    }
  }
Example #2
0
  /**
   * If ObjEntity qualifier is set, asks it to inject initial value to an object. Also performs all
   * Persistent initialization operations
   */
  protected void injectInitialValue(Object obj) {
    // must follow this exact order of property initialization per CAY-653,
    // i.e. have
    // the id and the context in place BEFORE setPersistence is called

    Persistent object = (Persistent) obj;

    object.setObjectContext(this);
    object.setPersistenceState(PersistenceState.NEW);

    GraphManager graphManager = getGraphManager();
    synchronized (graphManager) {
      graphManager.registerNode(object.getObjectId(), object);
      graphManager.nodeCreated(object.getObjectId());
    }

    ObjEntity entity;
    try {
      entity = getEntityResolver().getObjEntity(object.getClass());
    } catch (CayenneRuntimeException ex) {
      // ObjEntity cannot be fetched, ignored
      entity = null;
    }

    if (entity != null) {
      if (entity.getDeclaredQualifier() instanceof ValueInjector) {
        ((ValueInjector) entity.getDeclaredQualifier()).injectValue(object);
      }
    }

    // invoke callbacks
    getEntityResolver().getCallbackRegistry().performCallbacks(LifecycleEvent.POST_ADD, object);
  }
  public void testPrefetch_ToManyNoReverseWithQualifier() throws Exception {
    createTwoArtistsAndTwoPaintingsDataSet();

    ObjEntity paintingEntity = context.getEntityResolver().lookupObjEntity(Painting.class);
    ObjRelationship relationship = (ObjRelationship) paintingEntity.getRelationship("toArtist");
    paintingEntity.removeRelationship("toArtist");

    try {

      SelectQuery q = new SelectQuery(Artist.class);
      q.setQualifier(ExpressionFactory.matchExp("artistName", "artist2"));
      q.addPrefetch(Artist.PAINTING_ARRAY_PROPERTY);

      final List<Artist> result = context.performQuery(q);

      queryInterceptor.runWithQueriesBlocked(
          new UnitTestClosure() {

            public void execute() {
              assertFalse(result.isEmpty());
              Artist a1 = result.get(0);
              List<?> toMany = (List<?>) a1.readPropertyDirectly("paintingArray");
              assertNotNull(toMany);
              assertFalse(((ValueHolder) toMany).isFault());
            }
          });

    } finally {
      paintingEntity.addRelationship(relationship);
    }
  }
Example #4
0
  /** Recursively appends all relationships in the entity inheritance hierarchy. */
  final void appendRelationships(Map<String, ObjRelationship> map) {
    map.putAll((Map<String, ObjRelationship>) super.getRelationshipMap());

    ObjEntity superEntity = getSuperEntity();
    if (superEntity != null) {
      superEntity.appendRelationships(map);
    }
  }
Example #5
0
 private boolean hasPeriode(DataObject object) {
   ObjEntity ent = entityFor(object);
   ObjAttribute attrDebut = (ObjAttribute) ent.getAttribute("debut");
   ObjAttribute attrFin = (ObjAttribute) ent.getAttribute("fin");
   return attrDebut != null
       && attrDebut.getJavaClass() == Date.class
       && attrFin != null
       && attrFin.getJavaClass() == Date.class;
 }
  public ClassDescriptor getDescriptor(String entityName) {
    ObjEntity entity = descriptorMap.getResolver().getObjEntity(entityName);
    if (entity == null) {
      throw new CayenneRuntimeException("Unmapped entity: " + entityName);
    }

    Class<?> entityClass = entity.getJavaClass();
    return getDescriptor(entity, entityClass);
  }
Example #7
0
  /**
   * Returns the type of lock used by this ObjEntity. If this entity is not locked, this method
   * would look in a super entity recursively, until it finds a lock somewhere in the inheritance
   * hierarchy.
   *
   * @since 1.1
   */
  public int getLockType() {
    // if this entity has an explicit lock,
    // no need to lookup inheritance hierarchy
    if (lockType != LOCK_TYPE_NONE) {
      return lockType;
    }

    ObjEntity superEntity = getSuperEntity();
    return (superEntity != null) ? superEntity.getLockType() : lockType;
  }
 private void applyChanges() {
   for (DuplicatedAttributeInfo attributeInfo : duplicatedAttributes) {
     if (attributeInfo.getAction().equals(DELETE_ACTION)) {
       entity.removeAttribute(attributeInfo.getName());
     }
     if (attributeInfo.getAction().equals(RENAME_ACTION)) {
       ProjectUtil.setAttributeName(
           entity.getAttribute(attributeInfo.getName()), attributeInfo.getNewName());
     }
   }
 }
  /**
   * Returns entity qualifier expressed as DB path qualifier or null if entity has no qualifier.
   *
   * @since 3.0
   */
  public Expression getDbQualifier() {
    if (entity.getDeclaredQualifier() == null) {
      return null;
    }

    if (normalizedQualifier == null) {
      normalizedQualifier = entity.translateToDbPath(entity.getDeclaredQualifier());
    }

    return normalizedQualifier;
  }
Example #10
0
  /**
   * Creates a DataObject from DataRow.
   *
   * @see DataRow
   * @since 3.1
   */
  public <T extends Persistent> T objectFromDataRow(Class<T> objectClass, DataRow dataRow) {
    ObjEntity entity = this.getEntityResolver().getObjEntity(objectClass);

    if (entity == null) {
      throw new CayenneRuntimeException("Unmapped Java class: " + objectClass);
    }

    ClassDescriptor descriptor = getEntityResolver().getClassDescriptor(entity.getName());
    List<T> list = objectsFromDataRows(descriptor, Collections.singletonList(dataRow));
    return list.get(0);
  }
Example #11
0
  /**
   * Returns an ObjEntity stripped of any server-side information, such as DbEntity mapping.
   * "clientClassName" property of this entity is used to initialize "className" property of
   * returned entity.
   *
   * @since 1.2
   */
  public ObjEntity getClientEntity() {

    ClientObjEntity entity = new ClientObjEntity(getName());
    entity.setClassName(getClientClassName());
    entity.setSuperClassName(getClientSuperClassName());
    entity.setSuperEntityName(getSuperEntityName());
    entity.setDeclaredQualifier(getDeclaredQualifier());

    // TODO: should we also copy lock type?

    Collection<ObjAttribute> primaryKeys = getMutablePrimaryKeys();
    Collection<ObjAttribute> clientPK = new ArrayList<ObjAttribute>(primaryKeys.size());

    for (ObjAttribute attribute : getDeclaredAttributes()) {
      ObjAttribute clientAttribute = attribute.getClientAttribute();
      entity.addAttribute(clientAttribute);

      if (primaryKeys.remove(attribute)) {
        clientPK.add(clientAttribute);
      }
    }

    // after all meaningful pks got removed, here we only have synthetic pks
    // left...
    for (ObjAttribute attribute : primaryKeys) {
      ObjAttribute clientAttribute = attribute.getClientAttribute();
      clientPK.add(clientAttribute);
    }

    entity.setPrimaryKeys(clientPK);

    // copy relationships; skip runtime generated relationships
    for (ObjRelationship relationship : getDeclaredRelationships()) {
      if (relationship.isRuntime()) {
        continue;
      }

      ObjEntity targetEntity = (ObjEntity) relationship.getTargetEntity();
      // note that 'isClientAllowed' also checks parent DataMap client
      // policy
      // that can be handy in case of cross-map relationships
      if (targetEntity == null || !targetEntity.isClientAllowed()) {
        continue;
      }

      entity.addRelationship(relationship.getClientRelationship());
    }

    // TODO: andrus 2/5/2007 - copy embeddables
    // TODO: andrus 2/5/2007 - copy callback methods

    return entity;
  }
  protected void indexSubclassDescriptors(
      PersistentDescriptor descriptor, EntityInheritanceTree inheritanceTree) {

    if (inheritanceTree != null) {

      for (EntityInheritanceTree child : inheritanceTree.getChildren()) {
        ObjEntity childEntity = child.getEntity();
        descriptor.addSubclassDescriptor(
            childEntity.getClassName(), descriptorMap.getDescriptor(childEntity.getName()));

        indexSubclassDescriptors(descriptor, child);
      }
    }
  }
Example #13
0
  /** Returns a DbEntity associated with this ObjEntity. */
  public DbEntity getDbEntity() {

    // since 1.2 - allow overriding DbEntity in the inheritance hierarchy...
    if (dbEntityName != null) {
      return getNonNullNamespace().getDbEntity(dbEntityName);
    }

    ObjEntity superEntity = getSuperEntity();
    if (superEntity != null) {
      return superEntity.getDbEntity();
    }

    return null;
  }
Example #14
0
  /**
   * Creates and registers a new persistent object.
   *
   * @since 1.2
   */
  @Override
  public <T> T newObject(Class<T> persistentClass) {
    if (persistentClass == null) {
      throw new NullPointerException("Null 'persistentClass'");
    }

    ObjEntity entity = getEntityResolver().getObjEntity(persistentClass);
    if (entity == null) {
      throw new IllegalArgumentException(
          "Class is not mapped with Cayenne: " + persistentClass.getName());
    }

    return (T) newObject(entity.getName());
  }
Example #15
0
  /**
   * Returns a named Relationship that either belongs to this ObjEntity or is inherited. Returns
   * null if no matching attribute is found.
   */
  @Override
  public ObjRelationship getRelationship(String name) {
    ObjRelationship relationship = (ObjRelationship) super.getRelationship(name);
    if (relationship != null) {
      return relationship;
    }

    if (superEntityName == null) {
      return null;
    }

    ObjEntity superEntity = getSuperEntity();
    return (superEntity != null) ? superEntity.getRelationship(name) : null;
  }
  public Collection<ObjAttribute> allAttributes() {
    if (subentities == null) {
      return entity.getAttributes();
    }

    Collection<ObjAttribute> c = new ArrayList<ObjAttribute>();
    appendDeclaredAttributes(c);

    // add base attributes if any
    ObjEntity superEntity = entity.getSuperEntity();
    if (superEntity != null) {
      c.addAll(superEntity.getAttributes());
    }

    return c;
  }
Example #17
0
  /**
   * Returns true if this entity directly or indirectly inherits from a given entity, false
   * otherwise.
   *
   * @since 1.1
   */
  public boolean isSubentityOf(ObjEntity entity) {
    if (entity == null) {
      return false;
    }

    if (entity == this) {
      return false;
    }

    ObjEntity superEntity = getSuperEntity();
    if (superEntity == entity) {
      return true;
    }

    return (superEntity != null) ? superEntity.isSubentityOf(entity) : false;
  }
  public Collection<ObjRelationship> allRelationships() {
    if (subentities == null) {
      return entity.getRelationships();
    }

    Collection<ObjRelationship> c = new ArrayList<ObjRelationship>();
    appendDeclaredRelationships(c);

    // add base relationships if any
    ObjEntity superEntity = entity.getSuperEntity();
    if (superEntity != null) {
      c.addAll(superEntity.getRelationships());
    }

    return c;
  }
  protected void appendDeclaredRelationships(Collection<ObjRelationship> c) {
    c.addAll(entity.getDeclaredRelationships());

    if (subentities != null) {
      for (EntityInheritanceTree child : subentities) {
        child.appendDeclaredRelationships(c);
      }
    }
  }
  private void appendDeclaredRootDbEntity(PersistentDescriptor descriptor, ObjEntity entity) {

    DbEntity dbEntity = entity.getDbEntity();
    if (dbEntity != null) {
      // descriptor takes care of weeding off duplicates, which are likely
      // in cases
      // of non-horizontal inheritance
      descriptor.addRootDbEntity(dbEntity);
    }
  }
Example #21
0
  /**
   * Returns a named attribute that is either declared in this ObjEntity or is inherited. In any
   * case returned attribute 'getEntity' method will return this entity. Returns null if no matching
   * attribute is found.
   */
  @Override
  public ObjAttribute getAttribute(String name) {
    ObjAttribute attribute = (ObjAttribute) super.getAttribute(name);
    if (attribute != null) {
      return attribute;
    }

    // check embedded attribute
    int dot = name.indexOf('.');
    if (dot > 0 && dot < name.length() - 1) {
      ObjAttribute embedded = getAttribute(name.substring(0, dot));
      if (embedded instanceof EmbeddedAttribute) {
        return ((EmbeddedAttribute) embedded).getAttribute(name.substring(dot + 1));
      }
    }

    // check super attribute
    ObjEntity superEntity = getSuperEntity();
    if (superEntity != null) {

      ObjAttribute superAttribute = superEntity.getAttribute(name);
      if (superAttribute == null) {
        return null;
      }

      // decorate returned attribute to make it appear as if it belongs to
      // this
      // entity

      ObjAttribute decoratedAttribute = new ObjAttribute(superAttribute);
      decoratedAttribute.setEntity(this);

      String pathOverride = attributeOverrides.get(name);
      if (pathOverride != null) {
        decoratedAttribute.setDbAttributePath(pathOverride);
      }

      return decoratedAttribute;
    }

    return null;
  }
Example #22
0
  /** Recursively appends all attributes in the entity inheritance hierarchy. */
  final void appendAttributes(Map<String, ObjAttribute> map) {
    map.putAll((Map<String, ObjAttribute>) super.getAttributeMap());

    ObjEntity superEntity = getSuperEntity();
    if (superEntity != null) {
      SortedMap<String, ObjAttribute> attributeMap = new TreeMap<String, ObjAttribute>();
      superEntity.appendAttributes(attributeMap);
      for (String attributeName : attributeMap.keySet()) {

        String overridedDbPath = attributeOverrides.get(attributeName);

        ObjAttribute attribute = new ObjAttribute(attributeMap.get(attributeName));
        attribute.setEntity(this);
        if (overridedDbPath != null) {
          attribute.setDbAttributePath(overridedDbPath);
        }
        map.put(attributeName, attribute);
      }
    }
  }
Example #23
0
  /**
   * ObjEntity property changed. May be name, attribute or relationship added or removed, etc.
   * Attribute and relationship property changes are handled in respective listeners.
   *
   * @since 1.2
   */
  public void objEntityChanged(EntityEvent e) {
    if ((e == null) || (e.getEntity() != this)) {
      // not our concern
      return;
    }

    // handle entity name changes
    if (e.getId() == EntityEvent.CHANGE && e.isNameChange()) {
      String oldName = e.getOldName();
      String newName = e.getNewName();

      DataMap map = getDataMap();
      if (map != null) {
        ObjEntity oe = (ObjEntity) e.getEntity();
        for (ObjRelationship relationship : oe.getRelationships()) {
          relationship = relationship.getReverseRelationship();
          if (null != relationship && relationship.targetEntityName.equals(oldName)) {
            relationship.targetEntityName = newName;
          }
        }
      }
    }
  }
  public void setDuplicatedAttributes(List<ObjAttribute> attributes) {
    if (duplicatedAttributes == null) {
      duplicatedAttributes = new LinkedList<DuplicatedAttributeInfo>();
    }

    duplicatedAttributes.clear();

    for (ObjAttribute attribute : attributes) {
      DuplicatedAttributeInfo attributeInfo =
          new DuplicatedAttributeInfo(
              attribute.getName(),
              attribute.getType(),
              superEntity.getAttribute(attribute.getName()).getType(),
              DELETE_ACTION);
      duplicatedAttributes.add(attributeInfo);
    }

    attributesTable.setModel(
        new DuplicatedAttributeTableModel(getMediator(), this, duplicatedAttributes));
  }
Example #25
0
 /**
  * Simule la présence d'une valeur.
  *
  * <p>Seules les relations toOne sont supportées.
  *
  * @param property La propriété à simuler.
  */
 public void fake(String property) {
   // Test de la propriété
   ObjEntity ent = objEntity();
   ObjRelationship rel = (ObjRelationship) ent.getRelationship(property);
   if (rel == null) {
     throw new IllegalArgumentException("Pas de relation " + ent.getName() + "." + property);
   }
   if (rel.isToMany()) {
     throw new IllegalArgumentException(
         "La relation " + ent.getName() + "." + property + " n'est pas un toOne");
   }
   ObjEntity targetEntity = (ObjEntity) rel.getTargetEntity();
   // Ok, ajout.
   fakes.put(property, targetEntity.getJavaClass());
 }
  /**
   * Returns a qualifier Expression that matches root entity of this tree and all its subentities.
   */
  public Expression qualifierForEntityAndSubclasses() {
    Expression qualifier = entity.getDeclaredQualifier();

    if (qualifier == null) {
      // match all
      return null;
    }

    if (subentities != null) {
      for (EntityInheritanceTree child : subentities) {
        Expression childQualifier = child.qualifierForEntityAndSubclasses();

        // if any child qualifier is null, just return null, since no filtering is
        // possible
        if (childQualifier == null) {
          return null;
        }

        qualifier = qualifier.orExp(childQualifier);
      }
    }

    return qualifier;
  }
  public void testForeignKey() throws Exception {
    dropTableIfPresent("NEW_TABLE");
    dropTableIfPresent("NEW_TABLE2");

    assertTokensAndExecute(0, 0);

    DbEntity dbEntity1 = new DbEntity("NEW_TABLE");

    DbAttribute e1col1 = new DbAttribute("ID", Types.INTEGER, dbEntity1);
    e1col1.setMandatory(true);
    e1col1.setPrimaryKey(true);
    dbEntity1.addAttribute(e1col1);

    DbAttribute e1col2 = new DbAttribute("NAME", Types.VARCHAR, dbEntity1);
    e1col2.setMaxLength(10);
    e1col2.setMandatory(false);
    dbEntity1.addAttribute(e1col2);

    map.addDbEntity(dbEntity1);

    DbEntity dbEntity2 = new DbEntity("NEW_TABLE2");
    DbAttribute e2col1 = new DbAttribute("ID", Types.INTEGER, dbEntity2);
    e2col1.setMandatory(true);
    e2col1.setPrimaryKey(true);
    dbEntity2.addAttribute(e2col1);
    DbAttribute e2col2 = new DbAttribute("FK", Types.INTEGER, dbEntity2);
    dbEntity2.addAttribute(e2col2);
    DbAttribute e2col3 = new DbAttribute("NAME", Types.VARCHAR, dbEntity2);
    e2col3.setMaxLength(10);
    dbEntity2.addAttribute(e2col3);

    map.addDbEntity(dbEntity2);

    // create db relationships
    DbRelationship rel1To2 = new DbRelationship("rel1To2");
    rel1To2.setSourceEntity(dbEntity1);
    rel1To2.setTargetEntity(dbEntity2);
    rel1To2.setToMany(true);
    rel1To2.addJoin(new DbJoin(rel1To2, e1col1.getName(), e2col2.getName()));
    dbEntity1.addRelationship(rel1To2);
    DbRelationship rel2To1 = new DbRelationship("rel2To1");
    rel2To1.setSourceEntity(dbEntity2);
    rel2To1.setTargetEntity(dbEntity1);
    rel2To1.setToMany(false);
    rel2To1.addJoin(new DbJoin(rel2To1, e2col2.getName(), e1col1.getName()));
    dbEntity2.addRelationship(rel2To1);
    assertSame(rel1To2, rel2To1.getReverseRelationship());
    assertSame(rel2To1, rel1To2.getReverseRelationship());

    assertTokensAndExecute(4, 0);
    assertTokensAndExecute(0, 0);

    // create ObjEntities
    ObjEntity objEntity1 = new ObjEntity("NewTable");
    objEntity1.setDbEntity(dbEntity1);
    ObjAttribute oatr1 = new ObjAttribute("name");
    oatr1.setDbAttributePath(e1col2.getName());
    oatr1.setType("java.lang.String");
    objEntity1.addAttribute(oatr1);
    map.addObjEntity(objEntity1);
    ObjEntity objEntity2 = new ObjEntity("NewTable2");
    objEntity2.setDbEntity(dbEntity2);
    ObjAttribute o2a1 = new ObjAttribute("name");
    o2a1.setDbAttributePath(e2col3.getName());
    o2a1.setType("java.lang.String");
    objEntity2.addAttribute(o2a1);
    map.addObjEntity(objEntity2);

    // create ObjRelationships
    assertEquals(0, objEntity1.getRelationships().size());
    assertEquals(0, objEntity2.getRelationships().size());
    ObjRelationship objRel1To2 = new ObjRelationship("objRel1To2");
    objRel1To2.addDbRelationship(rel1To2);
    objRel1To2.setSourceEntity(objEntity1);
    objRel1To2.setTargetEntity(objEntity2);
    objEntity1.addRelationship(objRel1To2);
    ObjRelationship objRel2To1 = new ObjRelationship("objRel2To1");
    objRel2To1.addDbRelationship(rel2To1);
    objRel2To1.setSourceEntity(objEntity2);
    objRel2To1.setTargetEntity(objEntity1);
    objEntity2.addRelationship(objRel2To1);
    assertEquals(1, objEntity1.getRelationships().size());
    assertEquals(1, objEntity2.getRelationships().size());
    assertSame(objRel1To2, objRel2To1.getReverseRelationship());
    assertSame(objRel2To1, objRel1To2.getReverseRelationship());

    // remove relationship and fk from model, merge to db and read to model
    dbEntity2.removeRelationship(rel2To1.getName());
    dbEntity1.removeRelationship(rel1To2.getName());
    dbEntity2.removeAttribute(e2col2.getName());
    List<MergerToken> tokens = createMergeTokens();
    assertTokens(tokens, 2, 1);
    for (MergerToken token : tokens) {
      if (token.getDirection().isToDb()) {
        execute(token);
      }
    }
    assertTokensAndExecute(0, 0);
    dbEntity2.addRelationship(rel2To1);
    dbEntity1.addRelationship(rel1To2);
    dbEntity2.addAttribute(e2col2);

    // try do use the merger to remove the relationship in the model
    tokens = createMergeTokens();
    assertTokens(tokens, 2, 0);
    // TODO: reversing the following two tokens should also reverse the order
    MergerToken token0 = tokens.get(0).createReverse(mergerFactory());
    MergerToken token1 = tokens.get(1).createReverse(mergerFactory());
    if (!(token0 instanceof DropRelationshipToModel && token1 instanceof DropColumnToModel
        || token1 instanceof DropRelationshipToModel && token0 instanceof DropColumnToModel)) {
      fail();
    }
    execute(token0);
    execute(token1);

    // check after merging
    assertNull(dbEntity2.getAttribute(e2col2.getName()));
    assertEquals(0, dbEntity1.getRelationships().size());
    assertEquals(0, dbEntity2.getRelationships().size());
    assertEquals(0, objEntity1.getRelationships().size());
    assertEquals(0, objEntity2.getRelationships().size());

    // clear up
    dbEntity1.removeRelationship(rel1To2.getName());
    dbEntity2.removeRelationship(rel2To1.getName());
    map.removeObjEntity(objEntity1.getName(), true);
    map.removeDbEntity(dbEntity1.getName(), true);
    map.removeObjEntity(objEntity2.getName(), true);
    map.removeDbEntity(dbEntity2.getName(), true);
    resolver.refreshMappingCache();
    assertNull(map.getObjEntity(objEntity1.getName()));
    assertNull(map.getDbEntity(dbEntity1.getName()));
    assertNull(map.getObjEntity(objEntity2.getName()));
    assertNull(map.getDbEntity(dbEntity2.getName()));
    assertFalse(map.getDbEntities().contains(dbEntity1));
    assertFalse(map.getDbEntities().contains(dbEntity2));

    assertTokensAndExecute(2, 0);
    assertTokensAndExecute(0, 0);
  }
Example #28
0
  /**
   * Returns a DataRow reflecting current, possibly uncommitted, object state.
   *
   * <p><strong>Warning:</strong> This method will return a partial snapshot if an object or one of
   * its related objects that propagate their keys to this object have temporary ids. DO NOT USE
   * this method if you expect a DataRow to represent a complete object state.
   *
   * @since 1.1
   */
  public DataRow currentSnapshot(final Persistent object) {

    // for a HOLLOW object return snapshot from cache
    if (object.getPersistenceState() == PersistenceState.HOLLOW
        && object.getObjectContext() != null) {

      return getObjectStore().getSnapshot(object.getObjectId());
    }

    ObjEntity entity = getEntityResolver().getObjEntity(object);
    final ClassDescriptor descriptor = getEntityResolver().getClassDescriptor(entity.getName());
    final DataRow snapshot = new DataRow(10);
    snapshot.setEntityName(entity.getName());

    descriptor.visitProperties(
        new PropertyVisitor() {

          public boolean visitAttribute(AttributeProperty property) {
            ObjAttribute objAttr = property.getAttribute();

            // processing compound attributes correctly
            snapshot.put(objAttr.getDbAttributePath(), property.readPropertyDirectly(object));
            return true;
          }

          public boolean visitToMany(ToManyProperty property) {
            // do nothing
            return true;
          }

          public boolean visitToOne(ToOneProperty property) {
            ObjRelationship rel = property.getRelationship();

            // if target doesn't propagates its key value, skip it
            if (rel.isSourceIndependentFromTargetChange()) {
              return true;
            }

            Object targetObject = property.readPropertyDirectly(object);
            if (targetObject == null) {
              return true;
            }

            // if target is Fault, get id attributes from stored snapshot
            // to avoid unneeded fault triggering
            if (targetObject instanceof Fault) {
              DataRow storedSnapshot = getObjectStore().getSnapshot(object.getObjectId());
              if (storedSnapshot == null) {
                throw new CayenneRuntimeException(
                    "No matching objects found for ObjectId "
                        + object.getObjectId()
                        + ". Object may have been deleted externally.");
              }

              DbRelationship dbRel = rel.getDbRelationships().get(0);
              for (DbJoin join : dbRel.getJoins()) {
                String key = join.getSourceName();
                snapshot.put(key, storedSnapshot.get(key));
              }

              return true;
            }

            // target is resolved and we have an FK->PK to it,
            // so extract it from target...
            Persistent target = (Persistent) targetObject;
            Map<String, Object> idParts = target.getObjectId().getIdSnapshot();

            // this may happen in uncommitted objects - see the warning in
            // the JavaDoc
            // of
            // this method.
            if (idParts.isEmpty()) {
              return true;
            }

            DbRelationship dbRel = rel.getDbRelationships().get(0);
            Map<String, Object> fk = dbRel.srcFkSnapshotWithTargetSnapshot(idParts);
            snapshot.putAll(fk);
            return true;
          }
        });

    // process object id map
    // we should ignore any object id values if a corresponding attribute
    // is a part of relationship "toMasterPK", since those values have been
    // set above when db relationships where processed.
    Map<String, Object> thisIdParts = object.getObjectId().getIdSnapshot();
    if (thisIdParts != null) {

      // put only those that do not exist in the map
      for (Map.Entry<String, Object> entry : thisIdParts.entrySet()) {
        String nextKey = entry.getKey();
        if (!snapshot.containsKey(nextKey)) {
          snapshot.put(nextKey, entry.getValue());
        }
      }
    }

    return snapshot;
  }
Example #29
0
 /**
  * Returns a fully-qualified name of the client-side super class of the DataObject class. This
  * value is used as a hint for class generation. If the entity inherits from another entity, a
  * superclass is the class of that entity.
  *
  * @since 1.2
  */
 public String getClientSuperClassName() {
   ObjEntity superEntity = getSuperEntity();
   return (superEntity != null) ? superEntity.getClientClassName() : clientSuperClassName;
 }
Example #30
0
  /**
   * Registers a transient object with the context, recursively registering all transient persistent
   * objects attached to this object via relationships.
   *
   * <p><i>Note that since 3.0 this method takes Object as an argument instead of a {@link
   * DataObject}.</i>
   *
   * @param object new object that needs to be made persistent.
   */
  @Override
  public void registerNewObject(Object object) {
    if (object == null) {
      throw new NullPointerException("Can't register null object.");
    }

    ObjEntity entity = getEntityResolver().getObjEntity((Persistent) object);
    if (entity == null) {
      throw new IllegalArgumentException(
          "Can't find ObjEntity for Persistent class: "
              + object.getClass().getName()
              + ", class is likely not mapped.");
    }

    final Persistent persistent = (Persistent) object;

    // sanity check - maybe already registered
    if (persistent.getObjectId() != null) {
      if (persistent.getObjectContext() == this) {
        // already registered, just ignore
        return;
      } else if (persistent.getObjectContext() != null) {
        throw new IllegalStateException(
            "Persistent is already registered with another DataContext. "
                + "Try using 'localObjects()' instead.");
      }
    } else {
      persistent.setObjectId(new ObjectId(entity.getName()));
    }

    ClassDescriptor descriptor = getEntityResolver().getClassDescriptor(entity.getName());
    if (descriptor == null) {
      throw new IllegalArgumentException("Invalid entity name: " + entity.getName());
    }

    injectInitialValue(object);

    // now we need to find all arc changes, inject missing value holders and
    // pull in
    // all transient connected objects

    descriptor.visitProperties(
        new PropertyVisitor() {

          public boolean visitToMany(ToManyProperty property) {
            property.injectValueHolder(persistent);

            if (!property.isFault(persistent)) {

              Object value = property.readProperty(persistent);
              Collection<Map.Entry> collection =
                  (value instanceof Map) ? ((Map) value).entrySet() : (Collection) value;

              Iterator<Map.Entry> it = collection.iterator();
              while (it.hasNext()) {
                Object target = it.next();

                if (target instanceof Persistent) {
                  Persistent targetDO = (Persistent) target;

                  // make sure it is registered
                  registerNewObject(targetDO);
                  getObjectStore()
                      .arcCreated(
                          persistent.getObjectId(), targetDO.getObjectId(), property.getName());
                }
              }
            }
            return true;
          }

          public boolean visitToOne(ToOneProperty property) {
            Object target = property.readPropertyDirectly(persistent);

            if (target instanceof Persistent) {

              Persistent targetDO = (Persistent) target;

              // make sure it is registered
              registerNewObject(targetDO);
              getObjectStore()
                  .arcCreated(persistent.getObjectId(), targetDO.getObjectId(), property.getName());
            }
            return true;
          }

          public boolean visitAttribute(AttributeProperty property) {
            return true;
          }
        });
  }