521052 - [REQU-76] (1) Classes
Signed-off-by: Martin Fleischer <m.fleischer@peak-solution.de>
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 16b6e17..14f2b6f 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
@@ -12,7 +12,9 @@
import java.util.HashMap;
import java.util.Map;
-import org.eclipse.mdm.api.base.model.Core;
+import org.eclipse.mdm.api.base.core.ChildrenStore;
+import org.eclipse.mdm.api.base.core.Core;
+import org.eclipse.mdm.api.base.core.EntityStore;
import org.eclipse.mdm.api.base.model.Entity;
import org.eclipse.mdm.api.base.model.Value;
import org.eclipse.mdm.api.base.query.Record;
diff --git a/src/main/java/org/eclipse/mdm/api/base/core/ChildrenStore.java b/src/main/java/org/eclipse/mdm/api/base/core/ChildrenStore.java
new file mode 100644
index 0000000..c24202d
--- /dev/null
+++ b/src/main/java/org/eclipse/mdm/api/base/core/ChildrenStore.java
@@ -0,0 +1,103 @@
+package org.eclipse.mdm.api.base.core;
+
+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 ChildrenStore {
+
+ private final Map<Class<? extends Deletable>, List<? extends Deletable>> current = new HashMap<>(0);
+ private final Map<Class<? extends Deletable>, List<? extends Deletable>> removed = new HashMap<>(0);
+
+ /**
+ * Returns current set of related children mapped by their type.
+ *
+ * @return Returned {@code Map} is unmodifiable.
+ */
+ public Map<Class<? extends Deletable>, List<? extends Deletable>> getCurrent() {
+ return Collections.unmodifiableMap(current);
+ }
+
+ /**
+ * Returns current set of removed related children mapped by their type.
+ *
+ * @return Returned {@code Map} is unmodifiable.
+ */
+ public Map<Class<? extends Deletable>, List<? extends Deletable>> getRemoved() {
+ return Collections.unmodifiableMap(removed);
+ }
+
+ /**
+ * Returns related child entities of given type.
+ *
+ * @param <T>
+ * Desired entity type.
+ * @param entityClass
+ * Used as identifier.
+ * @return Returned {@code List} is unmodifiable.
+ */
+ @SuppressWarnings("unchecked")
+ public <T extends Deletable> List<T> get(Class<T> entityClass) {
+ return Collections.unmodifiableList((List<T>) current.computeIfAbsent(entityClass, k -> new ArrayList<>()));
+ }
+
+ /**
+ * Sorts the child entities with given {@code Comparator}.
+ *
+ * @param <T>
+ * Desired entity type.
+ * @param entityClass
+ * Used as identifier.
+ * @param comparator
+ * Used for sorting.
+ */
+ @SuppressWarnings("unchecked")
+ public <T extends Deletable> void sort(Class<T> entityClass, Comparator<? super T> comparator) {
+ List<T> children = (List<T>) current.get(entityClass);
+ if (children != null) {
+ children.sort(comparator);
+ }
+ }
+
+ /**
+ * Adds given child entity.
+ *
+ * @param child
+ * The new child.
+ */
+ @SuppressWarnings("unchecked")
+ public void add(Deletable child) {
+ removed.getOrDefault(child.getClass(), new ArrayList<>()).remove(child);
+ ((List<Deletable>) current.computeIfAbsent(child.getClass(), k -> new ArrayList<>())).add(child);
+ }
+
+ /**
+ * Removes given child entity.
+ *
+ * @param child
+ * The child which will be removed.
+ */
+ @SuppressWarnings("unchecked")
+ public void remove(Deletable child) {
+ List<Deletable> children = (List<Deletable>) current.getOrDefault(child.getClass(), new ArrayList<>());
+ if (children.remove(child) && child.getID() != null && child.getID().length() > 0) {
+ ((List<Deletable>) removed.computeIfAbsent(child.getClass(), k -> new ArrayList<>())).add(child);
+ }
+ }
+
+ /**
+ * Clean up list of removed entities.
+ */
+ void apply() {
+ removed.clear();
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/org/eclipse/mdm/api/base/core/Core.java b/src/main/java/org/eclipse/mdm/api/base/core/Core.java
new file mode 100644
index 0000000..a8b33ae
--- /dev/null
+++ b/src/main/java/org/eclipse/mdm/api/base/core/Core.java
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2016 Gigatronik Ingolstadt GmbH
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.eclipse.mdm.api.base.core;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+import org.eclipse.mdm.api.base.model.FileLink;
+import org.eclipse.mdm.api.base.model.Value;
+
+/**
+ * Provides access to the internals of any entity:
+ *
+ * <ul>
+ * <li>name of the data source</li>
+ * <li>name of the type</li>
+ * <li>instance ID</li>
+ * <li>values</li>
+ * <li>added/removed file links</li>
+ * <li>related entities</li>
+ * <li>parent/child entities</li>
+ * </ul>
+ *
+ * @since 1.0.0
+ * @author Viktor Stoehr, Gigatronik Ingolstadt GmbH
+ */
+public interface Core {
+
+ // ======================================================================
+ // Public methods
+ // ======================================================================
+
+ /**
+ * Returns the name of the data source this entity was retrieved from.
+ *
+ * @return Name of the data source.
+ */
+ String getSourceName();
+
+ /**
+ * Returns the name of the entity type.
+ *
+ * @return Name of the entity type is returned.
+ */
+ String getTypeName();
+
+ /**
+ * Returns the instance ID or {@code 0} if this instance is not yet
+ * persisted.
+ *
+ * @return The instance ID is returned.
+ */
+ String getID();
+
+ /**
+ * Sets an instance ID.
+ *
+ * @param instanceID
+ * The new instance ID.
+ */
+ void setID(String instanceID);
+
+ /**
+ * Returns <i>all</i> {@link Value} containers of this entity.
+ *
+ * @return Values mapped by their name are returned.
+ */
+ Map<String, Value> getValues();
+
+ /**
+ * Hides {@link Value} containers whose name is contained in the given names
+ * {@code Collection}.
+ * E.g. hide attributes from a CatalogComponent when not used in a TemplateComponent.
+ *
+ * @param names
+ * Names of the {@code Value} which shall be hidden.
+ */
+ void hideValues(Collection<String> names);
+
+ /**
+ * Returns <i>all</i> {@link Value} containers, including the hidden ones.
+ *
+ * @return All {@code Value} containers are returned.
+ */
+ Map<String, Value> getAllValues();
+
+ /**
+ * Returns all newly added {@link FileLink}.
+ *
+ * @return New {@code FileLink}s are returned.
+ */
+ default List<FileLink> getAddedFileLinks() {
+ Predicate<FileLink> isRemote = FileLink::isRemote;
+
+ List<FileLink> fileLinks = getValues().values().stream().filter(v -> v.getValueType().isFileLink())
+ .filter(Value::isValid).map(v -> (FileLink) v.extract()).filter(isRemote.negate())
+ .collect(Collectors.toList());
+
+ List<Value> values = getValues().values().stream().filter(v -> v.getValueType().isFileLinkSequence())
+ .filter(Value::isValid).collect(Collectors.toList());
+
+ for (Value value : values) {
+ Arrays.stream((FileLink[]) value.extract()).filter(isRemote.negate()).forEach(fileLinks::add);
+ }
+
+ return fileLinks;
+ }
+
+ /**
+ * Returns all removed {@link FileLink}s.
+ *
+ * @return Removed {@code FileLink}s are returned.
+ */
+ default List<FileLink> getRemovedFileLinks() {
+ Predicate<FileLink> isRemote = FileLink::isRemote;
+
+ List<FileLink> fileLinks = getValues().values().stream().filter(v -> v.getValueType().isFileLink())
+ .filter(Value::isModified).map(v -> (FileLink) v.extractInitial()).filter(Objects::nonNull)
+ .filter(isRemote).collect(Collectors.toList());
+
+ List<Value> values = getValues().values().stream().filter(v -> v.getValueType().isFileLinkSequence())
+ .filter(Value::wasValid).filter(Value::isModified).collect(Collectors.toList());
+
+ for (Value value : values) {
+ List<FileLink> current = Arrays.asList((FileLink[]) value.extract());
+ Arrays.stream((FileLink[]) value.extractInitial()).filter(fl -> !current.contains(fl))
+ .forEach(fileLinks::add);
+ }
+
+ return fileLinks;
+ }
+
+ /**
+ * Applies modifications made to the entity stores and {@link Value}
+ * containers. This method is called when a transaction is finalized
+ * (all operations completed successfully) to reflect the new state in
+ * the core.
+ */
+ default void apply() {
+ // apply the removed state to mutable entities
+ getMutableStore().apply();
+
+ // apply the removed state to children
+ getChildrenStore().apply();
+
+ // apply modified values
+ getValues().values().stream().filter(Value::isModified).forEach(Value::apply);
+ }
+
+ /**
+ * Returns the mutable {@link EntityStore}.
+ * Holds entities with mutable (editable) relations to the entity
+ * bound to this core instance.
+ * This store only contains always only one relation for one entity.
+ * For child relations use {@link ChildrenStore}.
+ *
+ * @return The mutable {@code EntityStore} is returned.
+ */
+ EntityStore getMutableStore();
+
+ /**
+ * Returns the permanent {@link EntityStore}.
+ * Holds entities with immutable (non-editable) relations to the entity
+ * bound to this core instance.
+ * E.g. relations to the parent entity.
+ *
+ * @return The permanent {@code EntityStore} is returned.
+ */
+ EntityStore getPermanentStore();
+
+ /**
+ * Returns the {@link ChildrenStore}. This store holds child
+ * entities with relations to the entity bound to this core instance.
+ *
+ * @return The {@code ChildrenStore} is returned.
+ */
+ // 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();
+
+}
diff --git a/src/main/java/org/eclipse/mdm/api/base/core/EntityStore.java b/src/main/java/org/eclipse/mdm/api/base/core/EntityStore.java
new file mode 100644
index 0000000..74d88a2
--- /dev/null
+++ b/src/main/java/org/eclipse/mdm/api/base/core/EntityStore.java
@@ -0,0 +1,185 @@
+package org.eclipse.mdm.api.base.core;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.mdm.api.base.model.ContextType;
+import org.eclipse.mdm.api.base.model.Entity;
+
+/**
+ * Holds related entities of any kind and keeps track of modifications.
+ */
+public final class EntityStore {
+
+ private final Map<String, Entity> current = new HashMap<>(0);
+ private final Map<String, Entity> removed = new HashMap<>(0);
+
+ /**
+ * Returns current set of related entities.
+ *
+ * @return Returned {@code Collection} is unmodifiable.
+ */
+ public Collection<Entity> getCurrent() {
+ return Collections.unmodifiableCollection(current.values());
+ }
+
+ /**
+ * Returns current set of removed related entities.
+ *
+ * @return Returned {@code Collection} is unmodifiable.
+ */
+ public Collection<Entity> getRemoved() {
+ return Collections.unmodifiableCollection(removed.values());
+ }
+
+ /**
+ * Returns related entity identified by given entity class.
+ *
+ * @param <T>
+ * The desired entity type.
+ * @param entityClass
+ * Used as identifier.
+ * @return The related entity is returned or null of not defined.
+ */
+ public <T extends Entity> T get(Class<T> entityClass) {
+ return get(entityClass.getSimpleName(), entityClass);
+ }
+
+ /**
+ * Returns related entity identified by given entity class.
+ *
+ * @param <T>
+ * The desired entity type.
+ * @param relationName
+ * The relation name the entity is referenced by.
+ * @param entityClass
+ * Used as identifier.
+ * @return The related entity is returned or null of not defined.
+ */
+ public <T extends Entity> T get(String relationName, Class<T> entityClass) {
+ return entityClass.cast(current.get(relationName));
+ }
+
+ /**
+ * Replaces a related entity with the given one.
+ *
+ * @param entity
+ * The new related entity.
+ */
+ public void set(Entity entity) {
+ set(entity.getClass().getSimpleName(), entity);
+ }
+
+ /**
+ * Replaces a related entity with the given one.
+ *
+ * @param name
+ * The name of the relation the entity is referenced by.
+ * @param entity
+ * The new related entity.
+ */
+ public void set(String name, Entity entity) {
+ Entity old = current.put(name, entity);
+ if (old != null) {
+ removed.put(name, old);
+ }
+ }
+
+ /**
+ * Removes a related entity for given entity class.
+ *
+ * @param entityClass
+ * Used as identifier.
+ */
+ public void remove(Class<? extends Entity> entityClass) {
+ String key = entityClass.getSimpleName();
+ remove(key, entityClass);
+ }
+
+ /**
+ * Removes a related entity for given relation name and entity class.
+ *
+ * @param name
+ * The name of the relation the entity is referenced by.
+ * @param entityClass
+ * Used as identifier.
+ */
+ public void remove(String name, Class<? extends Entity> entityClass) {
+ Entity old = current.remove(name);
+ if (old != null) {
+ removed.put(name, old);
+ }
+ }
+
+ /**
+ * Returns related entity identified by given entity class and
+ * {@link ContextType}.
+ *
+ * @param <T>
+ * The desired entity type.
+ * @param entityClass
+ * Used as identifier.
+ * @param contextType
+ * Used as identifier.
+ * @return The related entity is returned or null of not defined.
+ */
+ public <T extends Entity> T get(Class<T> entityClass, ContextType contextType) {
+ return entityClass.cast(current.get(createContextTypeKey(entityClass, contextType)));
+ }
+
+ /**
+ * Replaces a related entity with the given one.
+ *
+ * @param entity
+ * The new related entity.
+ * @param contextType
+ * Used as identifier.
+ */
+ public void set(Entity entity, ContextType contextType) {
+ String key = createContextTypeKey(entity.getClass(), contextType);
+ Entity old = current.put(key, entity);
+ if (old != null) {
+ removed.put(key, old);
+ }
+ }
+
+ /**
+ * Removes a related entity for given entity class and
+ * {@link ContextType}.
+ *
+ * @param entityClass
+ * Used as identifier.
+ * @param contextType
+ * Used as identifier.
+ */
+ public void remove(Class<? extends Entity> entityClass, ContextType contextType) {
+ String key = createContextTypeKey(entityClass, contextType);
+ Entity old = current.remove(key);
+ if (old != null) {
+ removed.put(key, old);
+ }
+ }
+
+ /**
+ * Clean up list of removed entities.
+ */
+ void apply() {
+ removed.clear();
+ }
+
+ /**
+ * Generates a key from given entity class and {@link ContextType}.
+ *
+ * @param entityClass
+ * Identifier part 1.
+ * @param contextType
+ * Identifier part 2.
+ * @return A context type dependent key is returned.
+ */
+ private static String createContextTypeKey(Class<? extends Entity> entityClass, ContextType contextType) {
+ return entityClass.getSimpleName() + '_' + contextType;
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/org/eclipse/mdm/api/base/model/BaseEntity.java b/src/main/java/org/eclipse/mdm/api/base/model/BaseEntity.java
index 869be38..10884f2 100644
--- a/src/main/java/org/eclipse/mdm/api/base/model/BaseEntity.java
+++ b/src/main/java/org/eclipse/mdm/api/base/model/BaseEntity.java
@@ -12,6 +12,8 @@
import java.util.Map;
import java.util.stream.Collectors;
+import org.eclipse.mdm.api.base.core.Core;
+
/**
* This is a base implementation for modeled entities. API consumers should
* never use this class in any way, instead the most common interface should be
diff --git a/src/main/java/org/eclipse/mdm/api/base/model/BaseEntityFactory.java b/src/main/java/org/eclipse/mdm/api/base/model/BaseEntityFactory.java
index 6d8c36d..bf45157 100644
--- a/src/main/java/org/eclipse/mdm/api/base/model/BaseEntityFactory.java
+++ b/src/main/java/org/eclipse/mdm/api/base/model/BaseEntityFactory.java
@@ -14,8 +14,9 @@
import java.util.List;
import java.util.Optional;
-import org.eclipse.mdm.api.base.model.Core.ChildrenStore;
-import org.eclipse.mdm.api.base.model.Core.EntityStore;
+import org.eclipse.mdm.api.base.core.ChildrenStore;
+import org.eclipse.mdm.api.base.core.Core;
+import org.eclipse.mdm.api.base.core.EntityStore;
/**
* Implementation of an abstract entity factory which creates new entities.
diff --git a/src/main/java/org/eclipse/mdm/api/base/model/BaseParameter.java b/src/main/java/org/eclipse/mdm/api/base/model/BaseParameter.java
index 55c8b81..78b1dc0 100644
--- a/src/main/java/org/eclipse/mdm/api/base/model/BaseParameter.java
+++ b/src/main/java/org/eclipse/mdm/api/base/model/BaseParameter.java
@@ -14,6 +14,8 @@
import java.util.Optional;
import java.util.function.Function;
+import org.eclipse.mdm.api.base.core.Core;
+
/**
* Implementation of an abstract parameter which holds a value with one of the
* supported {@link ValueType}s listed below. The value is internally stored in
diff --git a/src/main/java/org/eclipse/mdm/api/base/model/Channel.java b/src/main/java/org/eclipse/mdm/api/base/model/Channel.java
index 15b121c..9f4f8ac 100644
--- a/src/main/java/org/eclipse/mdm/api/base/model/Channel.java
+++ b/src/main/java/org/eclipse/mdm/api/base/model/Channel.java
@@ -8,6 +8,8 @@
package org.eclipse.mdm.api.base.model;
+import org.eclipse.mdm.api.base.core.Core;
+
/**
* Implementation of the channel entity type. Entities of this type are based on
* {@link Quantity}s.
diff --git a/src/main/java/org/eclipse/mdm/api/base/model/ChannelGroup.java b/src/main/java/org/eclipse/mdm/api/base/model/ChannelGroup.java
index fbf5a8e..124d19d 100644
--- a/src/main/java/org/eclipse/mdm/api/base/model/ChannelGroup.java
+++ b/src/main/java/org/eclipse/mdm/api/base/model/ChannelGroup.java
@@ -8,6 +8,8 @@
package org.eclipse.mdm.api.base.model;
+import org.eclipse.mdm.api.base.core.Core;
+
/**
* Implementation of the channel group entity type. It belongs to exactly one
* {@link Measurement} and groups a set of its {@link Channel}s.
diff --git a/src/main/java/org/eclipse/mdm/api/base/model/ContextComponent.java b/src/main/java/org/eclipse/mdm/api/base/model/ContextComponent.java
index cbf8a81..58b6bbb 100644
--- a/src/main/java/org/eclipse/mdm/api/base/model/ContextComponent.java
+++ b/src/main/java/org/eclipse/mdm/api/base/model/ContextComponent.java
@@ -12,6 +12,8 @@
import java.util.Optional;
import java.util.stream.Collectors;
+import org.eclipse.mdm.api.base.core.Core;
+
/**
* Implementation of the context component entity types. Instances of this class
* are only provided / managed via the owning descriptive {@link ContextRoot}.
diff --git a/src/main/java/org/eclipse/mdm/api/base/model/ContextRoot.java b/src/main/java/org/eclipse/mdm/api/base/model/ContextRoot.java
index 4c7548f..8bc67f3 100644
--- a/src/main/java/org/eclipse/mdm/api/base/model/ContextRoot.java
+++ b/src/main/java/org/eclipse/mdm/api/base/model/ContextRoot.java
@@ -15,6 +15,8 @@
import java.util.Optional;
import java.util.stream.Collectors;
+import org.eclipse.mdm.api.base.core.Core;
+
/**
* Implementation of the context root entity types. This is the root node of the
* descriptive component structure for a {@link ContextType}. This element is
diff --git a/src/main/java/org/eclipse/mdm/api/base/model/ContextSensor.java b/src/main/java/org/eclipse/mdm/api/base/model/ContextSensor.java
index 1f3f909..b633002 100644
--- a/src/main/java/org/eclipse/mdm/api/base/model/ContextSensor.java
+++ b/src/main/java/org/eclipse/mdm/api/base/model/ContextSensor.java
@@ -8,6 +8,8 @@
package org.eclipse.mdm.api.base.model;
+import org.eclipse.mdm.api.base.core.Core;
+
/**
* Implementation of the context sensor entity types. Instances of this class
* are only provided / managed via the owning {@link ContextComponent}. A
diff --git a/src/main/java/org/eclipse/mdm/api/base/model/Core.java b/src/main/java/org/eclipse/mdm/api/base/model/Core.java
deleted file mode 100644
index b0132a3..0000000
--- a/src/main/java/org/eclipse/mdm/api/base/model/Core.java
+++ /dev/null
@@ -1,467 +0,0 @@
-/*
- * Copyright (c) 2016 Gigatronik Ingolstadt GmbH
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.eclipse.mdm.api.base.model;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.function.Predicate;
-import java.util.stream.Collectors;
-
-/**
- * Provides access to the internals of any entity:
- *
- * <ul>
- * <li>name of the data source</li>
- * <li>name of the type</li>
- * <li>instance ID</li>
- * <li>values</li>
- * <li>added/removed file links</li>
- * <li>related entities</li>
- * <li>parent/child entities</li>
- * </ul>
- *
- * @since 1.0.0
- * @author Viktor Stoehr, Gigatronik Ingolstadt GmbH
- */
-public interface Core {
-
- // ======================================================================
- // Public methods
- // ======================================================================
-
- /**
- * Returns the name of the data source this entity was retrieved from.
- *
- * @return Name of the data source.
- */
- String getSourceName();
-
- /**
- * Returns the name of the entity type.
- *
- * @return Name of the entity type is returned.
- */
- String getTypeName();
-
- /**
- * Returns the instance ID or {@code 0} if this instance is not yet
- * persisted.
- *
- * @return The instance ID is returned.
- */
- String getID();
-
- /**
- * Sets an instance ID.
- *
- * @param instanceID
- * The new instance ID.
- */
- void setID(String instanceID);
-
- /**
- * Returns <i>all</i> {@link Value} containers of this entity.
- *
- * @return Values mapped by their name are returned.
- */
- Map<String, Value> getValues();
-
- /**
- * Hides {@link Value} containers whose name is contained in the given names
- * {@code Collection}.
- * E.g. hide attributes from a CatalogComponent when not used in a TemplateComponent.
- *
- * @param names
- * Names of the {@code Value} which shall be hidden.
- */
- void hideValues(Collection<String> names);
-
- /**
- * Returns <i>all</i> {@link Value} containers, including the hidden ones.
- *
- * @return All {@code Value} containers are returned.
- */
- Map<String, Value> getAllValues();
-
- /**
- * Returns all newly added {@link FileLink}.
- *
- * @return New {@code FileLink}s are returned.
- */
- default List<FileLink> getAddedFileLinks() {
- Predicate<FileLink> isRemote = FileLink::isRemote;
-
- List<FileLink> fileLinks = getValues().values().stream().filter(v -> v.getValueType().isFileLink())
- .filter(Value::isValid).map(v -> (FileLink) v.extract()).filter(isRemote.negate())
- .collect(Collectors.toList());
-
- List<Value> values = getValues().values().stream().filter(v -> v.getValueType().isFileLinkSequence())
- .filter(Value::isValid).collect(Collectors.toList());
-
- for (Value value : values) {
- Arrays.stream((FileLink[]) value.extract()).filter(isRemote.negate()).forEach(fileLinks::add);
- }
-
- return fileLinks;
- }
-
- /**
- * Returns all removed {@link FileLink}s.
- *
- * @return Removed {@code FileLink}s are returned.
- */
- default List<FileLink> getRemovedFileLinks() {
- Predicate<FileLink> isRemote = FileLink::isRemote;
-
- List<FileLink> fileLinks = getValues().values().stream().filter(v -> v.getValueType().isFileLink())
- .filter(Value::isModified).map(v -> (FileLink) v.extractInitial()).filter(Objects::nonNull)
- .filter(isRemote).collect(Collectors.toList());
-
- List<Value> values = getValues().values().stream().filter(v -> v.getValueType().isFileLinkSequence())
- .filter(Value::wasValid).filter(Value::isModified).collect(Collectors.toList());
-
- for (Value value : values) {
- List<FileLink> current = Arrays.asList((FileLink[]) value.extract());
- Arrays.stream((FileLink[]) value.extractInitial()).filter(fl -> !current.contains(fl))
- .forEach(fileLinks::add);
- }
-
- return fileLinks;
- }
-
- /**
- * Applies modifications made to the entity stores and {@link Value}
- * containers. This method is called when a transaction is finalized
- * (all operations completed successfully) to reflect the new state in
- * the core.
- */
- default void apply() {
- // apply the removed state to mutable entities
- getMutableStore().apply();
-
- // apply the removed state to children
- getChildrenStore().apply();
-
- // apply modified values
- getValues().values().stream().filter(Value::isModified).forEach(Value::apply);
- }
-
- /**
- * Returns the mutable {@link EntityStore}.
- * Holds entities with mutable (editable) relations to the entity
- * bound to this core instance.
- * This store only contains always only one relation for one entity.
- * For child relations use {@link ChildrenStore}.
- *
- * @return The mutable {@code EntityStore} is returned.
- */
- EntityStore getMutableStore();
-
- /**
- * Returns the permanent {@link EntityStore}.
- * Holds entities with immutable (non-editable) relations to the entity
- * bound to this core instance.
- * E.g. relations to the parent entity.
- *
- * @return The permanent {@code EntityStore} is returned.
- */
- EntityStore getPermanentStore();
-
- /**
- * Returns the {@link ChildrenStore}. This store holds child
- * entities with relations to the entity bound to this core instance.
- *
- * @return The {@code ChildrenStore} is returned.
- */
- // 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();
-
- // ======================================================================
- // Inner classes
- // ======================================================================
-
- /**
- * Holds related entities of any kind and keeps track of modifications.
- */
- public static final class EntityStore {
-
- private final Map<String, Entity> current = new HashMap<>(0);
- private final Map<String, Entity> removed = new HashMap<>(0);
-
- /**
- * Returns current set of related entities.
- *
- * @return Returned {@code Collection} is unmodifiable.
- */
- public Collection<Entity> getCurrent() {
- return Collections.unmodifiableCollection(current.values());
- }
-
- /**
- * Returns current set of removed related entities.
- *
- * @return Returned {@code Collection} is unmodifiable.
- */
- public Collection<Entity> getRemoved() {
- return Collections.unmodifiableCollection(removed.values());
- }
-
- /**
- * Returns related entity identified by given entity class.
- *
- * @param <T>
- * The desired entity type.
- * @param entityClass
- * Used as identifier.
- * @return The related entity is returned or null of not defined.
- */
- public <T extends Entity> T get(Class<T> entityClass) {
- return get(entityClass.getSimpleName(), entityClass);
- }
-
- /**
- * Returns related entity identified by given entity class.
- *
- * @param <T>
- * The desired entity type.
- * @param relationName
- * The relation name the entity is referenced by.
- * @param entityClass
- * Used as identifier.
- * @return The related entity is returned or null of not defined.
- */
- public <T extends Entity> T get(String relationName, Class<T> entityClass) {
- return entityClass.cast(current.get(relationName));
- }
-
- /**
- * Replaces a related entity with the given one.
- *
- * @param entity
- * The new related entity.
- */
- public void set(Entity entity) {
- set(entity.getClass().getSimpleName(), entity);
- }
-
- /**
- * Replaces a related entity with the given one.
- *
- * @param name
- * The name of the relation the entity is referenced by.
- * @param entity
- * The new related entity.
- */
- public void set(String name, Entity entity) {
- Entity old = current.put(name, entity);
- if (old != null) {
- removed.put(name, old);
- }
- }
-
- /**
- * Removes a related entity for given entity class.
- *
- * @param entityClass
- * Used as identifier.
- */
- public void remove(Class<? extends Entity> entityClass) {
- String key = entityClass.getSimpleName();
- remove(key, entityClass);
- }
-
- /**
- * Removes a related entity for given relation name and entity class.
- *
- * @param name
- * The name of the relation the entity is referenced by.
- * @param entityClass
- * Used as identifier.
- */
- public void remove(String name, Class<? extends Entity> entityClass) {
- Entity old = current.remove(name);
- if (old != null) {
- removed.put(name, old);
- }
- }
-
- /**
- * Returns related entity identified by given entity class and
- * {@link ContextType}.
- *
- * @param <T>
- * The desired entity type.
- * @param entityClass
- * Used as identifier.
- * @param contextType
- * Used as identifier.
- * @return The related entity is returned or null of not defined.
- */
- public <T extends Entity> T get(Class<T> entityClass, ContextType contextType) {
- return entityClass.cast(current.get(createContextTypeKey(entityClass, contextType)));
- }
-
- /**
- * Replaces a related entity with the given one.
- *
- * @param entity
- * The new related entity.
- * @param contextType
- * Used as identifier.
- */
- public void set(Entity entity, ContextType contextType) {
- String key = createContextTypeKey(entity.getClass(), contextType);
- Entity old = current.put(key, entity);
- if (old != null) {
- removed.put(key, old);
- }
- }
-
- /**
- * Removes a related entity for given entity class and
- * {@link ContextType}.
- *
- * @param entityClass
- * Used as identifier.
- * @param contextType
- * Used as identifier.
- */
- public void remove(Class<? extends Entity> entityClass, ContextType contextType) {
- String key = createContextTypeKey(entityClass, contextType);
- Entity old = current.remove(key);
- if (old != null) {
- removed.put(key, old);
- }
- }
-
- /**
- * Clean up list of removed entities.
- */
- private void apply() {
- removed.clear();
- }
-
- /**
- * Generates a key from given entity class and {@link ContextType}.
- *
- * @param entityClass
- * Identifier part 1.
- * @param contextType
- * Identifier part 2.
- * @return A context type dependent key is returned.
- */
- private static String createContextTypeKey(Class<? extends Entity> entityClass, ContextType contextType) {
- return entityClass.getSimpleName() + '_' + contextType;
- }
-
- }
-
- /**
- * Holds related entities of any kind and keeps track of modifications.
- */
- public static final class ChildrenStore {
-
- private final Map<Class<? extends Deletable>, List<? extends Deletable>> current = new HashMap<>(0);
- private final Map<Class<? extends Deletable>, List<? extends Deletable>> removed = new HashMap<>(0);
-
- /**
- * Returns current set of related children mapped by their type.
- *
- * @return Returned {@code Map} is unmodifiable.
- */
- public Map<Class<? extends Deletable>, List<? extends Deletable>> getCurrent() {
- return Collections.unmodifiableMap(current);
- }
-
- /**
- * Returns current set of removed related children mapped by their type.
- *
- * @return Returned {@code Map} is unmodifiable.
- */
- public Map<Class<? extends Deletable>, List<? extends Deletable>> getRemoved() {
- return Collections.unmodifiableMap(removed);
- }
-
- /**
- * Returns related child entities of given type.
- *
- * @param <T>
- * Desired entity type.
- * @param entityClass
- * Used as identifier.
- * @return Returned {@code List} is unmodifiable.
- */
- @SuppressWarnings("unchecked")
- public <T extends Deletable> List<T> get(Class<T> entityClass) {
- return Collections.unmodifiableList((List<T>) current.computeIfAbsent(entityClass, k -> new ArrayList<>()));
- }
-
- /**
- * Sorts the child entities with given {@code Comparator}.
- *
- * @param <T>
- * Desired entity type.
- * @param entityClass
- * Used as identifier.
- * @param comparator
- * Used for sorting.
- */
- @SuppressWarnings("unchecked")
- public <T extends Deletable> void sort(Class<T> entityClass, Comparator<? super T> comparator) {
- List<T> children = (List<T>) current.get(entityClass);
- if (children != null) {
- children.sort(comparator);
- }
- }
-
- /**
- * Adds given child entity.
- *
- * @param child
- * The new child.
- */
- @SuppressWarnings("unchecked")
- public void add(Deletable child) {
- removed.getOrDefault(child.getClass(), new ArrayList<>()).remove(child);
- ((List<Deletable>) current.computeIfAbsent(child.getClass(), k -> new ArrayList<>())).add(child);
- }
-
- /**
- * Removes given child entity.
- *
- * @param child
- * The child which will be removed.
- */
- @SuppressWarnings("unchecked")
- public void remove(Deletable child) {
- List<Deletable> children = (List<Deletable>) current.getOrDefault(child.getClass(), new ArrayList<>());
- if (children.remove(child) && child.getID() != null && child.getID().length() > 0) {
- ((List<Deletable>) removed.computeIfAbsent(child.getClass(), k -> new ArrayList<>())).add(child);
- }
- }
-
- /**
- * Clean up list of removed entities.
- */
- private void apply() {
- removed.clear();
- }
-
- }
-
-}
diff --git a/src/main/java/org/eclipse/mdm/api/base/model/Environment.java b/src/main/java/org/eclipse/mdm/api/base/model/Environment.java
index 8220e4e..0d733f5 100644
--- a/src/main/java/org/eclipse/mdm/api/base/model/Environment.java
+++ b/src/main/java/org/eclipse/mdm/api/base/model/Environment.java
@@ -8,6 +8,8 @@
package org.eclipse.mdm.api.base.model;
+import org.eclipse.mdm.api.base.core.Core;
+
/**
* Implementation of the environment entity type. The {@link Environment} is a
* singleton within a connected data source.
diff --git a/src/main/java/org/eclipse/mdm/api/base/model/Measurement.java b/src/main/java/org/eclipse/mdm/api/base/model/Measurement.java
index 7e4d332..685cb7a 100644
--- a/src/main/java/org/eclipse/mdm/api/base/model/Measurement.java
+++ b/src/main/java/org/eclipse/mdm/api/base/model/Measurement.java
@@ -13,6 +13,7 @@
import java.util.Map;
import org.eclipse.mdm.api.base.BaseEntityManager;
+import org.eclipse.mdm.api.base.core.Core;
import org.eclipse.mdm.api.base.query.DataAccessException;
/**
diff --git a/src/main/java/org/eclipse/mdm/api/base/model/Parameter.java b/src/main/java/org/eclipse/mdm/api/base/model/Parameter.java
index 3845655..5e8038f 100644
--- a/src/main/java/org/eclipse/mdm/api/base/model/Parameter.java
+++ b/src/main/java/org/eclipse/mdm/api/base/model/Parameter.java
@@ -10,6 +10,8 @@
import java.time.LocalDateTime;
+import org.eclipse.mdm.api.base.core.Core;
+
/**
* Implementation of the parameter entity type. Instances of this class hold a
* value in its {@code String} representation, which is converted upon request
diff --git a/src/main/java/org/eclipse/mdm/api/base/model/ParameterSet.java b/src/main/java/org/eclipse/mdm/api/base/model/ParameterSet.java
index 178891d..fae8a2f 100644
--- a/src/main/java/org/eclipse/mdm/api/base/model/ParameterSet.java
+++ b/src/main/java/org/eclipse/mdm/api/base/model/ParameterSet.java
@@ -12,6 +12,8 @@
import java.util.Optional;
import java.util.stream.Collectors;
+import org.eclipse.mdm.api.base.core.Core;
+
/**
* Implementation of the parameter set entity type. Instances of this class
* group a set of further describing data stored in {@link Parameter}s.
diff --git a/src/main/java/org/eclipse/mdm/api/base/model/PhysicalDimension.java b/src/main/java/org/eclipse/mdm/api/base/model/PhysicalDimension.java
index c0068b3..aba5b12 100644
--- a/src/main/java/org/eclipse/mdm/api/base/model/PhysicalDimension.java
+++ b/src/main/java/org/eclipse/mdm/api/base/model/PhysicalDimension.java
@@ -8,6 +8,8 @@
package org.eclipse.mdm.api.base.model;
+import org.eclipse.mdm.api.base.core.Core;
+
/**
* Implementation of the physical dimension entity type. Each {@link Unit} must
* have a relation to an instance of this type. The attributes represent the
diff --git a/src/main/java/org/eclipse/mdm/api/base/model/Quantity.java b/src/main/java/org/eclipse/mdm/api/base/model/Quantity.java
index 4ed5d6e..1a1acd7 100644
--- a/src/main/java/org/eclipse/mdm/api/base/model/Quantity.java
+++ b/src/main/java/org/eclipse/mdm/api/base/model/Quantity.java
@@ -8,6 +8,8 @@
package org.eclipse.mdm.api.base.model;
+import org.eclipse.mdm.api.base.core.Core;
+
/**
* Implementation of the quantity entity type. {@link Channel}s are based on
* entities of this type. Each quantity has a relation to a default
diff --git a/src/main/java/org/eclipse/mdm/api/base/model/Test.java b/src/main/java/org/eclipse/mdm/api/base/model/Test.java
index 828a88c..21c1669 100644
--- a/src/main/java/org/eclipse/mdm/api/base/model/Test.java
+++ b/src/main/java/org/eclipse/mdm/api/base/model/Test.java
@@ -11,6 +11,8 @@
import java.util.List;
import java.util.Optional;
+import org.eclipse.mdm.api.base.core.Core;
+
/**
* Implementation of the test entity type. The test groups a number of single
* {@link TestStep}s. A measurement order always corresponds with exactly one
diff --git a/src/main/java/org/eclipse/mdm/api/base/model/TestStep.java b/src/main/java/org/eclipse/mdm/api/base/model/TestStep.java
index 126215d..6e542b3 100644
--- a/src/main/java/org/eclipse/mdm/api/base/model/TestStep.java
+++ b/src/main/java/org/eclipse/mdm/api/base/model/TestStep.java
@@ -12,6 +12,7 @@
import java.util.Map;
import org.eclipse.mdm.api.base.BaseEntityManager;
+import org.eclipse.mdm.api.base.core.Core;
import org.eclipse.mdm.api.base.query.DataAccessException;
/**
diff --git a/src/main/java/org/eclipse/mdm/api/base/model/Unit.java b/src/main/java/org/eclipse/mdm/api/base/model/Unit.java
index 1c6b49f..6c3bbfc 100644
--- a/src/main/java/org/eclipse/mdm/api/base/model/Unit.java
+++ b/src/main/java/org/eclipse/mdm/api/base/model/Unit.java
@@ -8,6 +8,8 @@
package org.eclipse.mdm.api.base.model;
+import org.eclipse.mdm.api.base.core.Core;
+
/**
* Implementation of the unit entity type. Units referring to the same
* {@link PhysicalDimension} can be converted to each other by means of their
diff --git a/src/main/java/org/eclipse/mdm/api/base/model/User.java b/src/main/java/org/eclipse/mdm/api/base/model/User.java
index 86cae4d..f7d745d 100644
--- a/src/main/java/org/eclipse/mdm/api/base/model/User.java
+++ b/src/main/java/org/eclipse/mdm/api/base/model/User.java
@@ -8,6 +8,8 @@
package org.eclipse.mdm.api.base.model;
+import org.eclipse.mdm.api.base.core.Core;
+
/**
* Implementation of the user entity type.
*
diff --git a/src/main/java/org/eclipse/mdm/api/base/model/Value.java b/src/main/java/org/eclipse/mdm/api/base/model/Value.java
index 2415137..87abf10 100644
--- a/src/main/java/org/eclipse/mdm/api/base/model/Value.java
+++ b/src/main/java/org/eclipse/mdm/api/base/model/Value.java
@@ -319,10 +319,6 @@
return sb.toString();
}
- // ======================================================================
- // Package methods
- // ======================================================================
-
/**
* Checks whether either the validity flag or the value have been modified
* since initialization.
@@ -330,7 +326,7 @@
* @return Returns {@code true} either if the flag or the value has been
* modified.
*/
- boolean isModified() {
+ public boolean isModified() {
return wasValid() != isValid() || !Objects.deepEquals(extractInitial(), extract());
}
@@ -339,7 +335,7 @@
*
* @return Returns {@code true} if the value was initially marked as valid.
*/
- boolean wasValid() {
+ public boolean wasValid() {
return initialValid;
}
@@ -348,17 +344,21 @@
*
* @return The initial value is returned.
*/
- Object extractInitial() {
+ public Object extractInitial() {
return initialValue;
}
/**
* Overwrites the initial validity flag and value with the current ones.
*/
- void apply() {
+ public void apply() {
initialValid = isValid();
initialValue = copy(extract());
}
+
+ // ======================================================================
+ // Package methods
+ // ======================================================================
/**
* Returns the {@code String} value from given array at given position.
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 19bbb5c..3e02c11 100755
--- a/src/test/java/org/eclipse/mdm/api/base/CoreImpl.java
+++ b/src/test/java/org/eclipse/mdm/api/base/CoreImpl.java
@@ -11,7 +11,9 @@
import java.util.Collection;
import java.util.Map;
-import org.eclipse.mdm.api.base.model.Core;
+import org.eclipse.mdm.api.base.core.ChildrenStore;
+import org.eclipse.mdm.api.base.core.Core;
+import org.eclipse.mdm.api.base.core.EntityStore;
import org.eclipse.mdm.api.base.model.Value;
/**
diff --git a/src/test/java/org/eclipse/mdm/api/base/EntityFactoryImpl.java b/src/test/java/org/eclipse/mdm/api/base/EntityFactoryImpl.java
index 798dfaf..b5b80e4 100755
--- a/src/test/java/org/eclipse/mdm/api/base/EntityFactoryImpl.java
+++ b/src/test/java/org/eclipse/mdm/api/base/EntityFactoryImpl.java
@@ -10,9 +10,9 @@
import java.util.Optional;
+import org.eclipse.mdm.api.base.core.Core;
import org.eclipse.mdm.api.base.model.BaseEntityFactory;
import org.eclipse.mdm.api.base.model.ContextType;
-import org.eclipse.mdm.api.base.model.Core;
import org.eclipse.mdm.api.base.model.Entity;
import org.eclipse.mdm.api.base.model.User;
diff --git a/src/test/java/org/eclipse/mdm/api/base/model/ModelTest.java b/src/test/java/org/eclipse/mdm/api/base/model/ModelTest.java
index f8e49a3..1394507 100755
--- a/src/test/java/org/eclipse/mdm/api/base/model/ModelTest.java
+++ b/src/test/java/org/eclipse/mdm/api/base/model/ModelTest.java
@@ -18,6 +18,7 @@
import org.eclipse.mdm.api.base.CoreImpl;
import org.eclipse.mdm.api.base.EntityFactoryImpl;
+import org.eclipse.mdm.api.base.core.Core;
import org.eclipse.mdm.api.base.massdata.UnitBuilder;
import org.eclipse.mdm.api.base.massdata.WriteRequest;
import org.eclipse.mdm.api.base.massdata.WriteRequestBuilder;