Search in sources :

Example 1 with AttributeChanges

use of com.haulmont.cuba.core.app.events.AttributeChanges in project cuba by cuba-platform.

the class EntityChangedEventManager method internalCollect.

public List<EntityChangedEventInfo> internalCollect(Collection<Entity> entities) {
    List<EntityChangedEventInfo> list = new ArrayList<>();
    for (Entity entity : entities) {
        PublishingInfo info = infoCache.computeIfAbsent(entity.getClass(), aClass -> {
            MetaClass metaClass = metadata.getClassNN(entity.getClass());
            Map attrMap = (Map) metaClass.getAnnotations().get(PublishEntityChangedEvents.class.getName());
            if (attrMap != null) {
                if (!(entity instanceof BaseGenericIdEntity)) {
                    log.warn("Cannot publish EntityChangedEvent for {} because it is not a BaseGenericIdEntity", entity);
                } else {
                    return new PublishingInfo(Boolean.TRUE.equals(attrMap.get("created")), Boolean.TRUE.equals(attrMap.get("updated")), Boolean.TRUE.equals(attrMap.get("deleted")));
                }
            }
            return new PublishingInfo();
        });
        if (info.publish) {
            EntityChangedEvent.Type type = null;
            AttributeChanges attributeChanges = null;
            if (info.onCreated && BaseEntityInternalAccess.isNew((BaseGenericIdEntity) entity)) {
                type = EntityChangedEvent.Type.CREATED;
                attributeChanges = getEntityAttributeChanges(entity, false);
            } else {
                if (info.onUpdated || info.onDeleted) {
                    AttributeChangeListener changeListener = (AttributeChangeListener) ((ChangeTracker) entity)._persistence_getPropertyChangeListener();
                    if (changeListener == null) {
                        log.trace("Cannot publish EntityChangedEvent for {} because its AttributeChangeListener is null", entity);
                        continue;
                    }
                    if (info.onDeleted && PersistenceImplSupport.isDeleted((BaseGenericIdEntity) entity, changeListener)) {
                        type = EntityChangedEvent.Type.DELETED;
                        attributeChanges = getEntityAttributeChanges(entity, true);
                    } else if (info.onUpdated && changeListener.hasChanges()) {
                        type = EntityChangedEvent.Type.UPDATED;
                        attributeChanges = getEntityAttributeChanges(entity, changeListener.getObjectChangeSet());
                    }
                }
            }
            if (type != null) {
                @SuppressWarnings("unchecked") EntityChangedEventInfo eventData = new EntityChangedEventInfo(this, entity, type, attributeChanges);
                list.add(eventData);
            }
        }
    }
    log.trace("collected {}", list);
    return list;
}
Also used : AttributeChanges(com.haulmont.cuba.core.app.events.AttributeChanges) EntityChangedEvent(com.haulmont.cuba.core.app.events.EntityChangedEvent) MetaClass(com.haulmont.chile.core.model.MetaClass) AttributeChangeListener(org.eclipse.persistence.internal.descriptors.changetracking.AttributeChangeListener) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap)

Example 2 with AttributeChanges

use of com.haulmont.cuba.core.app.events.AttributeChanges in project cuba by cuba-platform.

the class EntityChangedEventManager method getEntityAttributeChanges.

@SuppressWarnings("unchecked")
private AttributeChanges getEntityAttributeChanges(Entity entity, boolean deleted) {
    Set<AttributeChanges.Change> changes = new HashSet<>();
    Map<String, AttributeChanges> embeddedChanges = new HashMap<>();
    for (MetaProperty property : metadata.getClassNN(entity.getClass()).getProperties()) {
        Object value = entity.getValue(property.getName());
        if (deleted) {
            if (value instanceof EmbeddableEntity) {
                EmbeddableEntity embedded = (EmbeddableEntity) value;
                embeddedChanges.computeIfAbsent(property.getName(), s -> getEntityAttributeChanges(embedded, true));
            } else if (value instanceof Entity) {
                changes.add(new AttributeChanges.Change(property.getName(), Id.of((Entity) value)));
            } else if (value instanceof Collection) {
                Collection<Entity> coll = (Collection<Entity>) value;
                Collection<Id> idColl = value instanceof List ? new ArrayList<>() : new LinkedHashSet<>();
                for (Entity item : coll) {
                    idColl.add(Id.of(item));
                }
                changes.add(new AttributeChanges.Change(property.getName(), idColl));
            } else {
                changes.add(new AttributeChanges.Change(property.getName(), value));
            }
        } else {
            if (value != null) {
                changes.add(new AttributeChanges.Change(property.getName(), null));
            }
        }
    }
    if (deleted) {
        addDynamicAttributeChanges(entity, changes, true);
    }
    return new AttributeChanges(changes, embeddedChanges);
}
Also used : AttributeChanges(com.haulmont.cuba.core.app.events.AttributeChanges) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Id(com.haulmont.cuba.core.entity.contracts.Id) MetaProperty(com.haulmont.chile.core.model.MetaProperty)

Example 3 with AttributeChanges

use of com.haulmont.cuba.core.app.events.AttributeChanges in project jmix by jmix-framework.

the class CubaEntityChangedEventManager method handleEvent.

@EventListener
public void handleEvent(io.jmix.core.event.EntityChangedEvent<? extends Entity> event) {
    PublishingInfo info = infoCache.computeIfAbsent(event.getEntityId().getEntityClass(), aClass -> {
        MetaClass metaClass = metadata.getClass(event.getEntityId().getEntityClass());
        MetaClass originalMetaClass = extendedEntities.getOriginalOrThisMetaClass(metaClass);
        Map attrMap = (Map) metaClass.getAnnotations().get(PublishEntityChangedEvents.class.getName());
        if (attrMap != null) {
            return new PublishingInfo(Boolean.TRUE.equals(attrMap.get("created")), Boolean.TRUE.equals(attrMap.get("updated")), Boolean.TRUE.equals(attrMap.get("deleted")), originalMetaClass);
        }
        return new PublishingInfo();
    });
    EntityChangedEvent.Type type = resolveType(event.getType());
    if (!info.publish || (!info.onCreated && type == EntityChangedEvent.Type.CREATED) || (!info.onUpdated && type == EntityChangedEvent.Type.UPDATED) || (!info.onDeleted && type == EntityChangedEvent.Type.DELETED)) {
        return;
    }
    io.jmix.core.Id<? extends Entity> entityId = event.getEntityId();
    eventPublisher.publish(new EntityChangedEvent<>(event.getSource(), Id.of(entityId.getValue(), entityId.getEntityClass()), type, new AttributeChanges(event.getChanges())));
}
Also used : AttributeChanges(com.haulmont.cuba.core.app.events.AttributeChanges) MetaClass(io.jmix.core.metamodel.model.MetaClass) EntityChangedEvent(com.haulmont.cuba.core.app.events.EntityChangedEvent) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Map(java.util.Map) EventListener(org.springframework.context.event.EventListener)

Example 4 with AttributeChanges

use of com.haulmont.cuba.core.app.events.AttributeChanges in project cuba by cuba-platform.

the class EntityChangedEventManager method getEntityAttributeChanges.

@SuppressWarnings("unchecked")
private AttributeChanges getEntityAttributeChanges(@Nullable Entity entity, ObjectChangeSet changeSet) {
    if (changeSet == null)
        return null;
    Set<AttributeChanges.Change> changes = new HashSet<>();
    Map<String, AttributeChanges> embeddedChanges = new HashMap<>();
    for (ChangeRecord changeRecord : changeSet.getChanges()) {
        if (changeRecord instanceof AggregateChangeRecord) {
            embeddedChanges.computeIfAbsent(changeRecord.getAttribute(), s -> getEntityAttributeChanges(null, ((AggregateChangeRecord) changeRecord).getChangedObject()));
        } else {
            Object oldValue = changeRecord.getOldValue();
            if (oldValue instanceof Entity) {
                changes.add(new AttributeChanges.Change(changeRecord.getAttribute(), Id.of((Entity) oldValue)));
            } else if (oldValue instanceof Collection) {
                Collection<Entity> coll = (Collection<Entity>) oldValue;
                Collection<Id> idColl = oldValue instanceof List ? new ArrayList<>() : new LinkedHashSet<>();
                for (Entity item : coll) {
                    idColl.add(Id.of(item));
                }
                changes.add(new AttributeChanges.Change(changeRecord.getAttribute(), idColl));
            } else {
                changes.add(new AttributeChanges.Change(changeRecord.getAttribute(), oldValue));
            }
        }
    }
    addDynamicAttributeChanges(entity, changes, false);
    return new AttributeChanges(changes, embeddedChanges);
}
Also used : AttributeChanges(com.haulmont.cuba.core.app.events.AttributeChanges) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) AggregateChangeRecord(org.eclipse.persistence.sessions.changesets.AggregateChangeRecord) AggregateChangeRecord(org.eclipse.persistence.sessions.changesets.AggregateChangeRecord) ChangeRecord(org.eclipse.persistence.sessions.changesets.ChangeRecord)

Example 5 with AttributeChanges

use of com.haulmont.cuba.core.app.events.AttributeChanges in project documentation by cuba-platform.

the class CustomerChangedListener method beforeCommit.

// <1>
@EventListener
public void beforeCommit(EntityChangedEvent<Customer, UUID> event) {
    // <2>
    Id<Customer, UUID> entityId = event.getEntityId();
    // <3>
    EntityChangedEvent.Type changeType = event.getType();
    AttributeChanges changes = event.getChanges();
    if (changes.isChanged("name")) {
        // <4>
        // <5>
        String oldName = changes.getOldValue("name");
    // ...
    }
}
Also used : AttributeChanges(com.haulmont.cuba.core.app.events.AttributeChanges) Customer(com.company.demo.entity.Customer) EntityChangedEvent(com.haulmont.cuba.core.app.events.EntityChangedEvent) UUID(java.util.UUID) TransactionalEventListener(org.springframework.transaction.event.TransactionalEventListener) EventListener(org.springframework.context.event.EventListener)

Aggregations

AttributeChanges (com.haulmont.cuba.core.app.events.AttributeChanges)5 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)4 EntityChangedEvent (com.haulmont.cuba.core.app.events.EntityChangedEvent)3 EventListener (org.springframework.context.event.EventListener)2 Customer (com.company.demo.entity.Customer)1 MetaClass (com.haulmont.chile.core.model.MetaClass)1 MetaProperty (com.haulmont.chile.core.model.MetaProperty)1 Id (com.haulmont.cuba.core.entity.contracts.Id)1 MetaClass (io.jmix.core.metamodel.model.MetaClass)1 Map (java.util.Map)1 UUID (java.util.UUID)1 AttributeChangeListener (org.eclipse.persistence.internal.descriptors.changetracking.AttributeChangeListener)1 AggregateChangeRecord (org.eclipse.persistence.sessions.changesets.AggregateChangeRecord)1 ChangeRecord (org.eclipse.persistence.sessions.changesets.ChangeRecord)1 TransactionalEventListener (org.springframework.transaction.event.TransactionalEventListener)1