From 1f5574b1a23ee5722d1481f4901c94117bf48149 Mon Sep 17 00:00:00 2001 From: Matthias Koller Date: Thu, 15 Nov 2018 13:33:59 +0100 Subject: Added support for n-to-m relations Change-Id: I713855e85703f718066fd48c9052a97787eb88e2 Signed-off-by: Matthias Koller --- .../eclipse/mdm/api/base/BaseEntityManager.java | 8 ++ .../org/eclipse/mdm/api/base/adapter/Core.java | 10 +- .../eclipse/mdm/api/base/adapter/DefaultCore.java | 11 +- .../org/eclipse/mdm/api/base/adapter/Relation.java | 8 +- .../mdm/api/base/adapter/RelationStore.java | 115 +++++++++++++++++++++ .../java/org/eclipse/mdm/api/base/CoreImpl.java | 6 ++ .../org/eclipse/mdm/api/base/RelationImpl.java | 5 + 7 files changed, 160 insertions(+), 3 deletions(-) create mode 100644 src/main/java/org/eclipse/mdm/api/base/adapter/RelationStore.java diff --git a/src/main/java/org/eclipse/mdm/api/base/BaseEntityManager.java b/src/main/java/org/eclipse/mdm/api/base/BaseEntityManager.java index 9a24edb..989518b 100644 --- a/src/main/java/org/eclipse/mdm/api/base/BaseEntityManager.java +++ b/src/main/java/org/eclipse/mdm/api/base/BaseEntityManager.java @@ -270,6 +270,14 @@ public interface BaseEntityManager { */ Map loadContexts(ContextDescribable contextDescribable, ContextType... contextTypes) throws DataAccessException; + + /** + * @param entity The entity + * @param relationName The name of the relation, which entities should be loaded. + * @param relatedClass Class of the related entities. + * @return The related entities for the given {@link Entity} and relationName + */ + List loadRelatedEntities(Entity entity, String relationName, Class relatedClass); /** * Retrieves the {@link MeasuredValues} as specified by the given diff --git a/src/main/java/org/eclipse/mdm/api/base/adapter/Core.java b/src/main/java/org/eclipse/mdm/api/base/adapter/Core.java index 0726073..ac806d4 100644 --- a/src/main/java/org/eclipse/mdm/api/base/adapter/Core.java +++ b/src/main/java/org/eclipse/mdm/api/base/adapter/Core.java @@ -195,6 +195,14 @@ public interface Core { // TODO (8.11.2017; Florian Schmitt, Angelika Wittek) // Entities with more than one related entity that do not refer to children, have also to go here, // as it is not permitted to go to the other stores. Does this work at all? - ChildrenStore getChildrenStore(); + ChildrenStore getChildrenStore(); + + /** + * Returns the {@link RelationStore}. This store holds related + * entities for N to M relations. + * + * @return The {@link RelationStore} is returned + */ + RelationStore getNtoMStore(); } diff --git a/src/main/java/org/eclipse/mdm/api/base/adapter/DefaultCore.java b/src/main/java/org/eclipse/mdm/api/base/adapter/DefaultCore.java index 47958b6..ecdc6c1 100644 --- a/src/main/java/org/eclipse/mdm/api/base/adapter/DefaultCore.java +++ b/src/main/java/org/eclipse/mdm/api/base/adapter/DefaultCore.java @@ -47,7 +47,8 @@ public class DefaultCore implements Core { private final EntityStore permanentEntityStorage = new EntityStore(); private final EntityStore mutableEntityStorage = new EntityStore(); - private final ChildrenStore childrenStore = new ChildrenStore(); + private final ChildrenStore childrenStore = new ChildrenStore(); + private final RelationStore ntoMStore = new RelationStore(); private final Map values = new HashMap<>(); private final Map hiddenValues = new HashMap<>(); @@ -192,6 +193,14 @@ public class DefaultCore implements Core { @Override public ChildrenStore getChildrenStore() { return childrenStore; + } + + /** + * {@inheritDoc} + */ + @Override + public RelationStore getNtoMStore() { + return ntoMStore; } } diff --git a/src/main/java/org/eclipse/mdm/api/base/adapter/Relation.java b/src/main/java/org/eclipse/mdm/api/base/adapter/Relation.java index 5257061..0b4c7ab 100644 --- a/src/main/java/org/eclipse/mdm/api/base/adapter/Relation.java +++ b/src/main/java/org/eclipse/mdm/api/base/adapter/Relation.java @@ -110,5 +110,11 @@ public interface Relation { * equal with the given one and it is is an incoming relation. */ boolean isIncoming(RelationType relationType); - + + /** + * Checks whether this relation is a N to M relation. + * + * @return Returns {@code true} if this relation is N to M. + */ + boolean isNtoM(); } diff --git a/src/main/java/org/eclipse/mdm/api/base/adapter/RelationStore.java b/src/main/java/org/eclipse/mdm/api/base/adapter/RelationStore.java new file mode 100644 index 0000000..f7dacb9 --- /dev/null +++ b/src/main/java/org/eclipse/mdm/api/base/adapter/RelationStore.java @@ -0,0 +1,115 @@ +/******************************************************************************** + * Copyright (c) 2015-2018 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + * + ********************************************************************************/ + +package org.eclipse.mdm.api.base.adapter; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.mdm.api.base.model.Deletable; + +/** + * Holds related entities of any kind and keeps track of modifications. + */ +public final class RelationStore { + + private final Map> added = new HashMap<>(0); + private final Map> removed = new HashMap<>(0); + + /** + * Returns current set of related children mapped by their type. + * + * @return Returned {@code Map} is unmodifiable. + */ + public Map> getAdded() { + return Collections.unmodifiableMap(added); + } + + /** + * Returns current set of removed related children mapped by their type. + * + * @return Returned {@code Map} is unmodifiable. + */ + public Map> getRemoved() { + return Collections.unmodifiableMap(removed); + } + + /** + * Returns related child entities of given type. + * + * @param + * Desired entity type. + * @param entityClass + * Used as identifier. + * @return Returned {@code List} is unmodifiable. + */ + @SuppressWarnings("unchecked") + public List get(String relation) { + return Collections.unmodifiableList((List) added.computeIfAbsent(relation, k -> new ArrayList<>())); + } + + /** + * Sorts the child entities with given {@code Comparator}. + * + * @param + * Desired entity type. + * @param entityClass + * Used as identifier. + * @param comparator + * Used for sorting. + */ + @SuppressWarnings("unchecked") + public void sort(String relation, Comparator comparator) { + List children = (List) added.get(relation); + if (children != null) { + children.sort(comparator); + } + } + + /** + * Adds given child entity. + * + * @param child + * The new child. + */ + @SuppressWarnings("unchecked") + public void add(String relation, Deletable relatedEntity) { + removed.getOrDefault(relation, new ArrayList<>()).remove(relatedEntity); + ((List) added.computeIfAbsent(relation, k -> new ArrayList<>())).add(relatedEntity); + } + + /** + * Removes given child entity. + * + * @param relatedEntity + * The child which will be removed. + */ + @SuppressWarnings("unchecked") + public void remove(String relation, Deletable relatedEntity) { + added.getOrDefault(relation, new ArrayList<>()).remove(relatedEntity); + ((List) removed.computeIfAbsent(relation, k -> new ArrayList<>())).add(relatedEntity); + } + + /** + * Clean up list of removed entities. + */ + void apply() { + removed.clear(); + } + +} \ No newline at end of file diff --git a/src/test/java/org/eclipse/mdm/api/base/CoreImpl.java b/src/test/java/org/eclipse/mdm/api/base/CoreImpl.java index 82356db..9eb7f84 100755 --- a/src/test/java/org/eclipse/mdm/api/base/CoreImpl.java +++ b/src/test/java/org/eclipse/mdm/api/base/CoreImpl.java @@ -21,6 +21,7 @@ import java.util.Map; import org.eclipse.mdm.api.base.adapter.ChildrenStore; import org.eclipse.mdm.api.base.adapter.Core; import org.eclipse.mdm.api.base.adapter.EntityStore; +import org.eclipse.mdm.api.base.adapter.RelationStore; import org.eclipse.mdm.api.base.model.Value; /** @@ -91,4 +92,9 @@ public class CoreImpl implements Core { return new ChildrenStore(); } + @Override + public RelationStore getNtoMStore() { + return new RelationStore(); + } + } \ No newline at end of file diff --git a/src/test/java/org/eclipse/mdm/api/base/RelationImpl.java b/src/test/java/org/eclipse/mdm/api/base/RelationImpl.java index 576c8e9..fde52e5 100755 --- a/src/test/java/org/eclipse/mdm/api/base/RelationImpl.java +++ b/src/test/java/org/eclipse/mdm/api/base/RelationImpl.java @@ -71,4 +71,9 @@ public class RelationImpl implements Relation { public boolean isIncoming(RelationType relationType) { return false; } + + @Override + public boolean isNtoM() { + return false; + } } -- cgit v1.2.3