Exemple #1
0
  public void delete(long id) {
    sharedLock();

    try {
      failIfReadonlyTx();
      validateId(id);

      Rec old = data.data.get(id);
      Object entity = obj(old);
      secureDelete(entity);

      boolean removed = data.data.remove(id, old);
      occErrorIf(
          !removed, "Concurrent modification occured while deleting the object with ID=%s!", id);

      if (data.insideTx.get()) {
        data.txChanges.putIfAbsent(id, old);
      }

      deleteRelsFor(entity);

      data.lastChangedOn.set(System.currentTimeMillis());

      Log.audit("Deleted DB record", "id", id);

    } finally {
      sharedUnlock();
    }
  }
Exemple #2
0
  private long _insert(Object record, boolean failOnReadOnlyTx) {
    U.notNull(record, "record");
    secureInsert(record);

    sharedLock();
    try {
      if (failOnReadOnlyTx) {
        failIfReadonlyTx();
      }

      long id = data.ids.incrementAndGet();
      Beany.setId(record, id);

      // Optimistic concurrency control through the "version" property
      if (Beany.hasProperty(record, VERSION)) {
        // FIXME rollback version in TX fails
        Beany.setPropValue(record, VERSION, 1);
      }

      Date now = new Date();

      if (Beany.hasProperty(record, CREATED_BY)) {
        Beany.setPropValue(record, CREATED_BY, username());
      }

      if (Beany.hasProperty(record, CREATED_ON)) {
        Beany.setPropValue(record, CREATED_ON, now);
      }

      if (Beany.hasProperty(record, LAST_UPDATED_BY)) {
        Beany.setPropValue(record, LAST_UPDATED_BY, username());
      }

      if (Beany.hasProperty(record, LAST_UPDATED_ON)) {
        Beany.setPropValue(record, LAST_UPDATED_ON, now);
      }

      if (data.insideTx.get()) {
        if (data.txInsertions.putIfAbsent(id, INSERTION) != null) {
          throw new IllegalStateException("Cannot insert changelog record with existing ID: " + id);
        }
      }

      if (data.data.putIfAbsent(id, rec(record)) != null) {
        throw new IllegalStateException("Cannot insert record with existing ID: " + id);
      }

      updateChangesFromRels(record);

      data.lastChangedOn.set(System.currentTimeMillis());

      Log.audit("Inserted DB record", "id", id);
      return id;
    } finally {
      sharedUnlock();
    }
  }
Exemple #3
0
  private void update_(long id, Object record, boolean reflectRelChanges, boolean checkSecurity) {

    failIfReadonlyTx();
    validateId(id);

    Rec old = data.data.get(id);
    Object entity = obj(old);

    if (checkSecurity) {
      secureUpdate(entity);
    }

    // Optimistic concurrency control through the "version" property
    Long oldVersion = U.or(Beany.getPropValueOfType(entity, VERSION, Long.class, null), 0L);
    Long recordVersion = U.or(Beany.getPropValueOfType(record, VERSION, Long.class, null), 0L);

    occErrorIf(
        !U.eq(oldVersion, recordVersion),
        "Concurrent modification occured while updating the object with ID=%s!",
        id);

    Beany.setId(record, id);

    if (!sudo && checkSecurity) {
      boolean canUpdate = false;
      for (Prop prop : Beany.propertiesOf(record)) {
        if (!Secure.getPropertyPermissions(username(), entity.getClass(), entity, prop.getName())
            .change) {
          prop.set(record, prop.get(entity));
        } else {
          canUpdate = true;
        }
      }
      U.secure(
          canUpdate,
          "Not enough privileges to update any column of %s!",
          entity.getClass().getSimpleName());
    }

    // Optimistic concurrency control through the "version" property
    if (Beany.hasProperty(record, VERSION)) {
      Beany.setPropValue(record, VERSION, oldVersion + 1);
    }

    if (checkSecurity) {
      secureUpdate(record);
    }

    if (Beany.hasProperty(record, LAST_UPDATED_BY)) {
      Beany.setPropValue(record, LAST_UPDATED_BY, username());
    }

    if (Beany.hasProperty(record, LAST_UPDATED_ON)) {
      Beany.setPropValue(record, LAST_UPDATED_ON, new Date());
    }

    boolean updated = data.data.replace(id, old, rec(record));

    occErrorIf(
        !updated, "Concurrent modification occured while updating the object with ID=%s!", id);

    if (data.insideTx.get()) {
      data.txChanges.putIfAbsent(id, old);
    }

    if (old == null) {
      throw new IllegalStateException("Cannot update non-existing record with ID=" + id);
    }

    if (reflectRelChanges) {
      updateChangesFromRels(record);
    }

    data.lastChangedOn.set(System.currentTimeMillis());

    Log.audit("Updated DB record", "id", id);
  }