Search in sources :

Example 1 with ObservableCollection

use of io.requery.util.ObservableCollection in project requery by requery.

the class EntityWriter method updateAssociation.

@SuppressWarnings("unchecked")
private void updateAssociation(Cascade mode, E entity, EntityProxy<E> proxy, Attribute<E, ?> attribute) {
    switch(attribute.getCardinality()) {
        case ONE_TO_ONE:
            S value = (S) proxy.get(attribute, false);
            if (value != null) {
                Attribute<S, Object> mapped = Attributes.get(attribute.getMappedAttribute());
                EntityProxy<S> referred = context.proxyOf(value, true);
                referred.set(mapped, entity, PropertyState.MODIFIED);
                cascadeWrite(mode, value, referred);
            } else if (!stateless) {
                throw new PersistenceException("1-1 relationship can only be removed from the owning side");
            }
            break;
        case ONE_TO_MANY:
            Object relation = proxy.get(attribute, false);
            if (relation instanceof ObservableCollection) {
                ObservableCollection<S> collection = (ObservableCollection<S>) relation;
                CollectionChanges<?, S> changes = (CollectionChanges<?, S>) collection.observer();
                List<S> added = new ArrayList<>(changes.addedElements());
                List<S> removed = new ArrayList<>(changes.removedElements());
                changes.clear();
                for (S element : added) {
                    updateMappedAssociation(mode, element, attribute, entity);
                }
                for (S element : removed) {
                    updateMappedAssociation(Cascade.UPDATE, element, attribute, null);
                }
            } else if (relation instanceof Iterable) {
                Iterable<S> iterable = (Iterable<S>) relation;
                for (S added : iterable) {
                    updateMappedAssociation(mode, added, attribute, entity);
                }
            } else {
                throw new IllegalStateException("unsupported relation type " + relation);
            }
            break;
        case MANY_TO_MANY:
            final Class referencedClass = attribute.getReferencedClass();
            if (referencedClass == null) {
                throw new IllegalStateException("Invalid referenced class in " + attribute);
            }
            Type<?> referencedType = model.typeOf(referencedClass);
            QueryAttribute<S, Object> tKey = null;
            QueryAttribute<S, Object> uKey = null;
            for (Attribute a : referencedType.getAttributes()) {
                Class<?> referenced = a.getReferencedClass();
                if (referenced != null) {
                    if (tKey == null && entityClass.isAssignableFrom(referenced)) {
                        tKey = Attributes.query(a);
                    } else if (attribute.getElementClass() != null && attribute.getElementClass().isAssignableFrom(referenced)) {
                        uKey = Attributes.query(a);
                    }
                }
            }
            Objects.requireNotNull(tKey);
            Objects.requireNotNull(uKey);
            Attribute<E, Object> tRef = Attributes.get(tKey.getReferencedAttribute());
            Attribute<S, Object> uRef = Attributes.get(uKey.getReferencedAttribute());
            CollectionChanges<?, S> changes = null;
            relation = proxy.get(attribute, false);
            Iterable<S> addedElements = (Iterable<S>) relation;
            boolean isObservable = relation instanceof ObservableCollection;
            if (relation instanceof ObservableCollection) {
                ObservableCollection<S> collection = (ObservableCollection<S>) relation;
                changes = (CollectionChanges<?, S>) collection.observer();
                if (changes != null) {
                    addedElements = changes.addedElements();
                }
            }
            for (S added : addedElements) {
                S junction = (S) referencedType.getFactory().get();
                EntityProxy<S> junctionProxy = context.proxyOf(junction, false);
                EntityProxy<S> uProxy = context.proxyOf(added, false);
                if (attribute.getCascadeActions().contains(CascadeAction.SAVE)) {
                    cascadeWrite(mode, added, uProxy);
                }
                Object tValue = proxy.get(tRef, false);
                Object uValue = uProxy.get(uRef, false);
                junctionProxy.set(tKey, tValue, PropertyState.MODIFIED);
                junctionProxy.set(uKey, uValue, PropertyState.MODIFIED);
                Cascade cascade = isObservable && mode == Cascade.UPSERT ? Cascade.UPSERT : Cascade.INSERT;
                cascadeWrite(cascade, junction, null);
            }
            if (changes != null) {
                Object keyValue = proxy.get(tRef, false);
                for (S removed : changes.removedElements()) {
                    Object otherValue = context.proxyOf(removed, false).get(uRef);
                    Class<? extends S> removeType = (Class<? extends S>) referencedType.getClassType();
                    Supplier<? extends Scalar<Integer>> query = queryable.delete(removeType).where(tKey.equal(keyValue)).and(uKey.equal(otherValue));
                    int count = query.get().value();
                    if (count != 1) {
                        throw new RowCountException(1, count);
                    }
                }
                changes.clear();
            }
            break;
        case MANY_TO_ONE:
        default:
            break;
    }
    context.read(type.getClassType()).refresh(entity, proxy, attribute);
}
Also used : QueryAttribute(io.requery.meta.QueryAttribute) Attribute(io.requery.meta.Attribute) UPDATE(io.requery.query.element.QueryType.UPDATE) ArrayList(java.util.ArrayList) CollectionChanges(io.requery.proxy.CollectionChanges) ObservableCollection(io.requery.util.ObservableCollection) PersistenceException(io.requery.PersistenceException)

Aggregations

PersistenceException (io.requery.PersistenceException)1 Attribute (io.requery.meta.Attribute)1 QueryAttribute (io.requery.meta.QueryAttribute)1 CollectionChanges (io.requery.proxy.CollectionChanges)1 UPDATE (io.requery.query.element.QueryType.UPDATE)1 ObservableCollection (io.requery.util.ObservableCollection)1 ArrayList (java.util.ArrayList)1