elements) throws StrolchPersistenceException;
+ /**
+ *
+ * Removes all elements regardless of type from the underlying persistence layer
+ *
+ *
+ *
+ * Note: This method does not support versioning. This method completely removes all objects regardless of
+ * type and their versions!
+ *
+ *
+ * @return the number of elements removed
+ *
+ * @throws StrolchPersistenceException
+ */
public long removeAll();
+ /**
+ *
+ * Removes all elements of the given type from the underlying persistence layer
+ *
+ *
+ *
+ * Note: This method does not support versioning. This method completely removes all objects of the given
+ * type and their versions!
+ *
+ *
+ * @param type
+ * the type of element to remove
+ *
+ * @return the number of elements removed
+ */
public long removeAllBy(String type);
+
+ /**
+ *
+ * Removes the given version of the given element from the underlying persistence layer. The version must be the
+ * latest version and thus always deletes the newest version. To delete multiple versions call this method multiple
+ * times. To remove it completely, call the {@link #remove(StrolchRootElement)} method.
+ *
+ *
+ *
+ * Note: This element given must be the current latest version!
+ *
+ *
+ * @param element
+ * the latest version of the element to be removed
+ *
+ * @throws StrolchPersistenceException
+ * if the element/version does not exist
+ */
+ public void removeVersion(T element) throws StrolchPersistenceException;
+
}
diff --git a/li.strolch.agent/src/main/java/li/strolch/persistence/api/StrolchTransaction.java b/li.strolch.agent/src/main/java/li/strolch/persistence/api/StrolchTransaction.java
index 87a085499..255faddb8 100644
--- a/li.strolch.agent/src/main/java/li/strolch/persistence/api/StrolchTransaction.java
+++ b/li.strolch.agent/src/main/java/li/strolch/persistence/api/StrolchTransaction.java
@@ -279,19 +279,6 @@ public interface StrolchTransaction extends AutoCloseable {
*/
public boolean isSuppressAudits();
- /**
- *
- * @param versioningEnabled
- */
- public void setVersioningEnabled(boolean versioningEnabled);
-
- /**
- * Returns true if versioning of objects is enabled
- *
- * @return true if versioning of objects is enabled
- */
- public boolean isVersioningEnabled();
-
/**
* If the given argument is true, then logging of a {@link TransactionCloseStrategy#DO_NOTHING} will be suppressed
*
@@ -307,6 +294,13 @@ public interface StrolchTransaction extends AutoCloseable {
*/
boolean isSuppressDoNothingLogging();
+ /**
+ * Returns true if versioning is enabled on the {@link StrolchRealm} for which this transaction has been opened
+ *
+ * @return true if versioning is enabled
+ */
+ boolean isVersioningEnabled();
+
/**
* Locks the given element and registers it on the transaction so the lock is released when the transaction is
* closed
@@ -376,21 +370,6 @@ public interface StrolchTransaction extends AutoCloseable {
*/
public Audit auditFrom(AccessType accessType, StrolchRootElement element);
- /**
- * Creates a new version for the given element. If the element has no version yet, then the result will be version
- * 0, otherwise the version will be an increment to the current version
- *
- * @param element
- * the element for which to create a new version
- * @param deleted
- * if true, then the version will be marked as deleted, i.e. this object was removed from the element
- * maps
- *
- * @return the new version, which is either an increment of the existing version on the element, or it will be
- * version 0
- */
- public void updateVersionFor(StrolchRootElement element, boolean deleted);
-
/**
*
* Performs the given {@link OrderQuery} and each returned {@link Order} is passed through the {@link OrderVisitor}
diff --git a/li.strolch.agent/src/main/java/li/strolch/persistence/inmemory/InMemoryActivityDao.java b/li.strolch.agent/src/main/java/li/strolch/persistence/inmemory/InMemoryActivityDao.java
index 24cc74856..501ba4f10 100644
--- a/li.strolch.agent/src/main/java/li/strolch/persistence/inmemory/InMemoryActivityDao.java
+++ b/li.strolch.agent/src/main/java/li/strolch/persistence/inmemory/InMemoryActivityDao.java
@@ -25,6 +25,10 @@ import li.strolch.runtime.query.inmemory.InMemoryQuery;
public class InMemoryActivityDao extends InMemoryDao implements ActivityDao {
+ public InMemoryActivityDao(boolean versioningEnabled) {
+ super(versioningEnabled);
+ }
+
@Override
public List doQuery(ActivityQuery activityQuery) {
InMemoryActivityQueryVisitor visitor = new InMemoryActivityQueryVisitor();
diff --git a/li.strolch.agent/src/main/java/li/strolch/persistence/inmemory/InMemoryDao.java b/li.strolch.agent/src/main/java/li/strolch/persistence/inmemory/InMemoryDao.java
index c220d619a..9ad89ce78 100644
--- a/li.strolch.agent/src/main/java/li/strolch/persistence/inmemory/InMemoryDao.java
+++ b/li.strolch.agent/src/main/java/li/strolch/persistence/inmemory/InMemoryDao.java
@@ -16,6 +16,7 @@
package li.strolch.persistence.inmemory;
import java.text.MessageFormat;
+import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
@@ -29,25 +30,32 @@ import li.strolch.persistence.api.StrolchPersistenceException;
public class InMemoryDao implements StrolchDao {
- private Map> elementMap;
+ private Map>> elementMap;
+ private boolean versioningEnabled;
- public InMemoryDao() {
+ public InMemoryDao(boolean versioningEnabled) {
+ this.versioningEnabled = versioningEnabled;
this.elementMap = new HashMap<>();
}
@Override
public synchronized boolean hasElement(String type, String id) {
- Map byType = this.elementMap.get(type);
+ Map> byType = this.elementMap.get(type);
if (byType == null)
return false;
- return byType.containsKey(id);
+
+ ArrayDeque list = byType.get(id);
+ if (list == null)
+ return false;
+
+ return !list.getLast().getVersion().isDeleted();
}
@Override
public synchronized long querySize() {
long size = 0;
for (String type : this.elementMap.keySet()) {
- Map byType = this.elementMap.get(type);
+ Map> byType = this.elementMap.get(type);
size += byType.size();
}
return size;
@@ -55,7 +63,7 @@ public class InMemoryDao implements StrolchDao
@Override
public synchronized long querySize(String type) {
- Map byType = this.elementMap.get(type);
+ Map> byType = this.elementMap.get(type);
if (byType == null)
return 0;
return byType.size();
@@ -63,21 +71,19 @@ public class InMemoryDao implements StrolchDao
@Override
public synchronized Set queryKeySet() {
-
Set keySet = new HashSet<>();
for (String type : this.elementMap.keySet()) {
- Map byType = this.elementMap.get(type);
+ Map> byType = this.elementMap.get(type);
for (String id : byType.keySet()) {
keySet.add(id);
}
}
-
return keySet;
}
@Override
public synchronized Set queryKeySet(String type) {
- Map byType = this.elementMap.get(type);
+ Map> byType = this.elementMap.get(type);
if (byType == null)
return new HashSet<>(0);
return new HashSet<>(byType.keySet());
@@ -90,19 +96,58 @@ public class InMemoryDao implements StrolchDao
@Override
public synchronized T queryBy(String type, String id) {
- Map byType = this.elementMap.get(type);
+ Map> byType = this.elementMap.get(type);
if (byType == null)
return null;
- return byType.get(id);
+ ArrayDeque list = byType.get(id);
+ if (list == null)
+ return null;
+
+ T t = list.getLast();
+ if (t.getVersion() != null && t.getVersion().isDeleted())
+ return null;
+
+ return t;
+ }
+
+ @Override
+ public synchronized T queryBy(String type, String id, int version) {
+ Map> byType = this.elementMap.get(type);
+ if (byType == null)
+ return null;
+ ArrayDeque list = byType.get(id);
+ if (list == null)
+ return null;
+
+ for (T t : list) {
+ if (t.getVersion().getVersion() == version)
+ return t;
+ }
+
+ return null;
+ }
+
+ @Override
+ public synchronized List queryVersionsFor(String type, String id) {
+ Map> byType = this.elementMap.get(type);
+ if (byType == null)
+ return null;
+ ArrayDeque list = byType.get(id);
+ if (list == null)
+ return new ArrayList<>();
+ return new ArrayList<>(list);
}
@Override
public synchronized List queryAll() {
List elements = new ArrayList<>();
for (String type : this.elementMap.keySet()) {
- Map byType = this.elementMap.get(type);
+ Map> byType = this.elementMap.get(type);
for (String id : byType.keySet()) {
- elements.add(byType.get(id));
+ ArrayDeque list = byType.get(id);
+ T last = list.getLast();
+ if (last.getVersion() == null || !last.getVersion().isDeleted())
+ elements.add(last);
}
}
@@ -111,27 +156,43 @@ public class InMemoryDao implements StrolchDao
@Override
public synchronized List queryAll(String type) {
- Map byType = this.elementMap.get(type);
+ Map> byType = this.elementMap.get(type);
if (byType == null)
return new ArrayList<>(0);
- return new ArrayList<>(byType.values());
+
+ List elements = new ArrayList<>();
+ for (ArrayDeque list : byType.values()) {
+ T last = list.getLast();
+ if (last.getVersion() == null || !last.getVersion().isDeleted())
+ elements.add(last);
+ }
+
+ return elements;
}
@Override
public synchronized void save(T element) {
- Map byType = this.elementMap.get(element.getType());
+ Map> byType = this.elementMap.get(element.getType());
if (byType == null) {
byType = new HashMap<>();
this.elementMap.put(element.getType(), byType);
}
- if (byType.containsKey(element.getId())) {
+ ArrayDeque list = byType.get(element.getId());
+
+ // only allow add for existing id, if the existing one is "deleted"
+ if (list != null && !list.getLast().getVersion().isDeleted()) {
String msg = "An element already exists with the id {0}. Elements of the same class must always have a unique id, regardless of their type!"; //$NON-NLS-1$
msg = MessageFormat.format(msg, element.getId());
throw new StrolchPersistenceException(msg);
}
- byType.put(element.getId(), element);
+ if (list == null) {
+ list = new ArrayDeque<>();
+ byType.put(element.getId(), list);
+ }
+
+ list.addLast(element);
}
@Override
@@ -143,13 +204,24 @@ public class InMemoryDao implements StrolchDao
@Override
public synchronized void update(T element) {
- Map byType = this.elementMap.get(element.getType());
+ Map> byType = this.elementMap.get(element.getType());
if (byType == null) {
- byType = new HashMap<>();
- this.elementMap.put(element.getType(), byType);
+ String msg = "The element does not yet exist with the type {0} and id {1}. Use add() for new objects!"; //$NON-NLS-1$
+ msg = MessageFormat.format(msg, element.getType(), element.getId());
+ throw new StrolchPersistenceException(msg);
}
- byType.put(element.getId(), element);
+ ArrayDeque list = byType.get(element.getId());
+ if (list == null) {
+ String msg = "The element does not yet exist with the type {0} and id {1}. Use add() for new objects!"; //$NON-NLS-1$
+ msg = MessageFormat.format(msg, element.getType(), element.getId());
+ throw new StrolchPersistenceException(msg);
+ }
+
+ if (!this.versioningEnabled)
+ list.clear();
+
+ list.addLast(element);
}
@Override
@@ -161,7 +233,7 @@ public class InMemoryDao implements StrolchDao
@Override
public synchronized void remove(T element) {
- Map byType = this.elementMap.get(element.getType());
+ Map> byType = this.elementMap.get(element.getType());
if (byType != null) {
byType.remove(element.getId());
@@ -184,7 +256,7 @@ public class InMemoryDao implements StrolchDao
Set keySet = new HashSet<>(this.elementMap.keySet());
for (String type : keySet) {
- Map byType = this.elementMap.remove(type);
+ Map> byType = this.elementMap.remove(type);
removed += byType.size();
byType.clear();
}
@@ -194,11 +266,42 @@ public class InMemoryDao implements StrolchDao
@Override
public synchronized long removeAllBy(String type) {
- Map byType = this.elementMap.remove(type);
+ Map> byType = this.elementMap.remove(type);
if (byType == null)
return 0;
long removed = byType.size();
byType.clear();
return removed;
}
+
+ @Override
+ public synchronized void removeVersion(T element) throws StrolchPersistenceException {
+
+ Map> byType = this.elementMap.get(element.getType());
+ if (byType == null) {
+ String msg = "The element does not yet exist with the type {0}!"; //$NON-NLS-1$
+ msg = MessageFormat.format(msg, element.getType());
+ throw new StrolchPersistenceException(msg);
+ }
+
+ ArrayDeque list = byType.get(element.getId());
+ if (list == null) {
+ String msg = "The element does not yet exist with the type {0} and id {1}!"; //$NON-NLS-1$
+ msg = MessageFormat.format(msg, element.getType(), element.getId());
+ throw new StrolchPersistenceException(msg);
+ }
+
+ T last = list.getLast();
+ if (!last.getVersion().equals(element.getVersion())) {
+ String msg = "The current version {0} is not the same as the version to remove {1}!"; //$NON-NLS-1$
+ msg = MessageFormat.format(msg, last.getVersion(), element.getVersion());
+ throw new StrolchPersistenceException(msg);
+ }
+
+ list.removeLast();
+
+ if (list.isEmpty()) {
+ byType.remove(element.getId());
+ }
+ }
}
diff --git a/li.strolch.agent/src/main/java/li/strolch/persistence/inmemory/InMemoryOrderDao.java b/li.strolch.agent/src/main/java/li/strolch/persistence/inmemory/InMemoryOrderDao.java
index af629543c..0c9990db2 100644
--- a/li.strolch.agent/src/main/java/li/strolch/persistence/inmemory/InMemoryOrderDao.java
+++ b/li.strolch.agent/src/main/java/li/strolch/persistence/inmemory/InMemoryOrderDao.java
@@ -25,6 +25,10 @@ import li.strolch.runtime.query.inmemory.InMemoryQuery;
public class InMemoryOrderDao extends InMemoryDao implements OrderDao {
+ public InMemoryOrderDao(boolean versioningEnabled) {
+ super(versioningEnabled);
+ }
+
@Override
public List doQuery(OrderQuery orderQuery) {
InMemoryOrderQueryVisitor visitor = new InMemoryOrderQueryVisitor();
diff --git a/li.strolch.agent/src/main/java/li/strolch/persistence/inmemory/InMemoryPersistence.java b/li.strolch.agent/src/main/java/li/strolch/persistence/inmemory/InMemoryPersistence.java
index d5a5fe089..be5aec095 100644
--- a/li.strolch.agent/src/main/java/li/strolch/persistence/inmemory/InMemoryPersistence.java
+++ b/li.strolch.agent/src/main/java/li/strolch/persistence/inmemory/InMemoryPersistence.java
@@ -30,11 +30,13 @@ import li.strolch.runtime.privilege.PrivilegeHandler;
public class InMemoryPersistence implements PersistenceHandler {
+ private boolean versioningEnabled;
private Map daoCache;
private PrivilegeHandler privilegeHandler;
- public InMemoryPersistence(PrivilegeHandler privilegeHandler) {
+ public InMemoryPersistence(PrivilegeHandler privilegeHandler, boolean versioningEnabled) {
this.privilegeHandler = privilegeHandler;
+ this.versioningEnabled = versioningEnabled;
this.daoCache = new HashMap<>();
}
@@ -75,7 +77,8 @@ public class InMemoryPersistence implements PersistenceHandler {
private synchronized DaoCache getDaoCache(StrolchTransaction tx) {
DaoCache daoCache = this.daoCache.get(tx.getRealmName());
if (daoCache == null) {
- daoCache = new DaoCache(new InMemoryOrderDao(), new InMemoryResourceDao(), new InMemoryActivityDao(),
+ daoCache = new DaoCache(new InMemoryOrderDao(this.versioningEnabled),
+ new InMemoryResourceDao(this.versioningEnabled), new InMemoryActivityDao(this.versioningEnabled),
new InMemoryAuditDao());
this.daoCache.put(tx.getRealmName(), daoCache);
}
diff --git a/li.strolch.agent/src/main/java/li/strolch/persistence/inmemory/InMemoryResourceDao.java b/li.strolch.agent/src/main/java/li/strolch/persistence/inmemory/InMemoryResourceDao.java
index 3dd198682..966694cbc 100644
--- a/li.strolch.agent/src/main/java/li/strolch/persistence/inmemory/InMemoryResourceDao.java
+++ b/li.strolch.agent/src/main/java/li/strolch/persistence/inmemory/InMemoryResourceDao.java
@@ -25,6 +25,10 @@ import li.strolch.runtime.query.inmemory.InMemoryResourceQueryVisitor;
public class InMemoryResourceDao extends InMemoryDao implements ResourceDao {
+ public InMemoryResourceDao(boolean versioningEnabled) {
+ super(versioningEnabled);
+ }
+
@Override
public List doQuery(ResourceQuery resourceQuery) {
InMemoryResourceQueryVisitor visitor = new InMemoryResourceQueryVisitor();
diff --git a/li.strolch.agent/src/test/java/li/strolch/agent/ComponentContainerTest.java b/li.strolch.agent/src/test/java/li/strolch/agent/ComponentContainerTest.java
index 810838da8..f799c76aa 100644
--- a/li.strolch.agent/src/test/java/li/strolch/agent/ComponentContainerTest.java
+++ b/li.strolch.agent/src/test/java/li/strolch/agent/ComponentContainerTest.java
@@ -50,6 +50,7 @@ public class ComponentContainerTest {
public static final String PATH_CACHED_CONTAINER = "src/test/resources/cachedtest";
public static final String PATH_EMPTY_CONTAINER = "src/test/resources/emptytest";
public static final String PATH_MINIMAL_CONTAINER = "src/test/resources/minimaltest";
+ public static final String PATH_VERSIONING_CONTAINER = "src/test/resources/versioningtest";
public static final String PATH_REALM_RUNTIME = "target/realmtest/";
public static final String PATH_TRANSIENT_RUNTIME = "target/transienttest/";
diff --git a/li.strolch.agent/src/test/java/li/strolch/runtime/query/inmemory/InMemoryOrderQueryTest.java b/li.strolch.agent/src/test/java/li/strolch/runtime/query/inmemory/InMemoryOrderQueryTest.java
new file mode 100644
index 000000000..ba0bda78e
--- /dev/null
+++ b/li.strolch.agent/src/test/java/li/strolch/runtime/query/inmemory/InMemoryOrderQueryTest.java
@@ -0,0 +1,319 @@
+/*
+ * Copyright 2013 Robert von Burg
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package li.strolch.runtime.query.inmemory;
+
+import static li.strolch.model.query.ParameterSelection.booleanSelection;
+import static li.strolch.model.query.ParameterSelection.floatListSelection;
+import static li.strolch.model.query.ParameterSelection.floatSelection;
+import static li.strolch.model.query.ParameterSelection.integerListSelection;
+import static li.strolch.model.query.ParameterSelection.longListSelection;
+import static li.strolch.model.query.ParameterSelection.stringListSelection;
+import static li.strolch.model.query.ParameterSelection.stringSelection;
+import static li.strolch.utils.StringMatchMode.ci;
+import static li.strolch.utils.StringMatchMode.es;
+import static org.junit.Assert.assertEquals;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+
+import org.junit.Test;
+
+import li.strolch.model.ModelGenerator;
+import li.strolch.model.Order;
+import li.strolch.model.ParameterBag;
+import li.strolch.model.State;
+import li.strolch.model.Version;
+import li.strolch.model.parameter.BooleanParameter;
+import li.strolch.model.parameter.FloatListParameter;
+import li.strolch.model.parameter.FloatParameter;
+import li.strolch.model.parameter.IntegerListParameter;
+import li.strolch.model.parameter.LongListParameter;
+import li.strolch.model.parameter.StringListParameter;
+import li.strolch.model.parameter.StringParameter;
+import li.strolch.model.query.IdSelection;
+import li.strolch.model.query.NameSelection;
+import li.strolch.model.query.OrderQuery;
+import li.strolch.model.query.ParameterSelection;
+import li.strolch.persistence.inmemory.InMemoryOrderDao;
+
+/**
+ * @author Robert von Burg
+ */
+@SuppressWarnings("nls")
+public class InMemoryOrderQueryTest {
+
+ protected InMemoryOrderDao daoInstance() {
+ return new InMemoryOrderDao(false);
+ }
+
+ @Test
+ public void shouldQueryById() {
+
+ List orders = getOrders();
+ InMemoryOrderDao dao = daoInstance();
+ dao.saveAll(orders);
+
+ OrderQuery orderQuery = OrderQuery.query("MyType1");
+ orderQuery.with(new IdSelection("@1"));
+
+ List result = dao.doQuery(orderQuery);
+ assertEquals(1, result.size());
+ assertEquals("@1", result.get(0).getId());
+ }
+
+ @Test
+ public void shouldQueryByIdOr() {
+
+ List orders = getOrders();
+ InMemoryOrderDao dao = daoInstance();
+ dao.saveAll(orders);
+
+ OrderQuery orderQuery = OrderQuery.query("MyType2");
+ orderQuery.or().with(new IdSelection("@3"), new IdSelection("@4"));
+
+ List result = dao.doQuery(orderQuery);
+ assertEquals(2, result.size());
+ assertEquals("@3", result.get(0).getId());
+ assertEquals("@4", result.get(1).getId());
+ }
+
+ @Test
+ public void shouldQueryByIdAnd() {
+
+ List orders = getOrders();
+ InMemoryOrderDao dao = daoInstance();
+ dao.saveAll(orders);
+
+ OrderQuery orderQuery = OrderQuery.query("MyType2");
+ orderQuery.and().with(new IdSelection("@3"), new NameSelection("Res 3", es()));
+
+ List result = dao.doQuery(orderQuery);
+ assertEquals(1, result.size());
+ assertEquals("@3", result.get(0).getId());
+ }
+
+ @Test
+ public void shouldNotQueryByIdAnd() {
+
+ List orders = getOrders();
+ InMemoryOrderDao dao = daoInstance();
+ dao.saveAll(orders);
+
+ OrderQuery orderQuery = OrderQuery.query("MyType1");
+ orderQuery.and().with(new IdSelection("@3"), new NameSelection("@4", es()));
+
+ List result = dao.doQuery(orderQuery);
+ assertEquals(0, result.size());
+ }
+
+ @Test
+ public void shouldQueryByParameter() {
+
+ List orders = getOrders();
+ orders.add(getBallOrder());
+ InMemoryOrderDao dao = daoInstance();
+ dao.saveAll(orders);
+
+ OrderQuery ballQuery = OrderQuery.query("Ball");
+ ballQuery.and().with(
+ //
+ stringSelection("parameters", "color", "red", es()),
+ booleanSelection("parameters", "forChildren", true), floatSelection("parameters", "diameter", 22.0));
+
+ List result = dao.doQuery(ballQuery);
+ assertEquals(1, result.size());
+ }
+
+ @Test
+ public void shouldQueryByListParameter() {
+
+ List orders = getOrders();
+ orders.add(getBallOrder());
+ InMemoryOrderDao dao = daoInstance();
+ dao.saveAll(orders);
+
+ OrderQuery ballQuery;
+ List result;
+
+ // string list
+ {
+ ballQuery = OrderQuery.query("Ball");
+ ballQuery.and().with(stringListSelection("parameters", "stringListValues", Arrays.asList("a", "z")));
+ result = dao.doQuery(ballQuery);
+ assertEquals(0, result.size());
+
+ ballQuery = OrderQuery.query("Ball");
+ ballQuery.and().with(stringListSelection("parameters", "stringListValues", Arrays.asList("a")));
+ result = dao.doQuery(ballQuery);
+ assertEquals(1, result.size());
+
+ ballQuery = OrderQuery.query("Ball");
+ ballQuery.and().with(stringListSelection("parameters", "stringListValues", Arrays.asList("c", "b", "a")));
+ result = dao.doQuery(ballQuery);
+ assertEquals(1, result.size());
+ }
+
+ // integer list
+ {
+ ballQuery = OrderQuery.query("Ball");
+ ballQuery.and().with(integerListSelection("parameters", "intListValues", Arrays.asList(1, 5)));
+ result = dao.doQuery(ballQuery);
+ assertEquals(0, result.size());
+
+ ballQuery = OrderQuery.query("Ball");
+ ballQuery.and().with(integerListSelection("parameters", "intListValues", Arrays.asList(1)));
+ result = dao.doQuery(ballQuery);
+ assertEquals(1, result.size());
+
+ ballQuery = OrderQuery.query("Ball");
+ ballQuery.and().with(integerListSelection("parameters", "intListValues", Arrays.asList(3, 2, 1)));
+ result = dao.doQuery(ballQuery);
+ assertEquals(1, result.size());
+ }
+
+ // float list
+ {
+ ballQuery = OrderQuery.query("Ball");
+ ballQuery.and().with(floatListSelection("parameters", "floatListValues", Arrays.asList(4.0, 8.0)));
+ result = dao.doQuery(ballQuery);
+ assertEquals(0, result.size());
+
+ ballQuery = OrderQuery.query("Ball");
+ ballQuery.and().with(floatListSelection("parameters", "floatListValues", Arrays.asList(4.0)));
+ result = dao.doQuery(ballQuery);
+ assertEquals(1, result.size());
+
+ ballQuery = OrderQuery.query("Ball");
+ ballQuery.and().with(floatListSelection("parameters", "floatListValues", Arrays.asList(6.2, 5.1, 4.0)));
+ result = dao.doQuery(ballQuery);
+ assertEquals(1, result.size());
+ }
+
+ // long list
+ {
+ ballQuery = OrderQuery.query("Ball");
+ ballQuery.and().with(longListSelection("parameters", "longListValues", Arrays.asList(8L, 11L)));
+ result = dao.doQuery(ballQuery);
+ assertEquals(0, result.size());
+
+ ballQuery = OrderQuery.query("Ball");
+ ballQuery.and().with(longListSelection("parameters", "longListValues", Arrays.asList(8L)));
+ result = dao.doQuery(ballQuery);
+ assertEquals(1, result.size());
+
+ ballQuery = OrderQuery.query("Ball");
+ ballQuery.and().with(longListSelection("parameters", "longListValues", Arrays.asList(10L, 9L, 8L)));
+ result = dao.doQuery(ballQuery);
+ assertEquals(1, result.size());
+ }
+ }
+
+ @Test
+ public void shouldQueryByNullParameter1() {
+ List orders = getOrders();
+ orders.add(getBallOrder());
+ InMemoryOrderDao dao = daoInstance();
+ dao.saveAll(orders);
+
+ OrderQuery ballQuery = OrderQuery.query("Ball");
+ ballQuery.and().with( //
+ ParameterSelection.nullSelection("parameters", "color"));
+
+ List result = dao.doQuery(ballQuery);
+ assertEquals(0, result.size());
+ }
+
+ @Test
+ public void shouldQueryByNullParameter2() {
+ List orders = getOrders();
+ orders.add(getBallOrder());
+ InMemoryOrderDao dao = daoInstance();
+ dao.saveAll(orders);
+
+ OrderQuery ballQuery = OrderQuery.query("Ball");
+ ballQuery.and().with( //
+ ParameterSelection.nullSelection("parameters", "weight"));
+
+ List result = dao.doQuery(ballQuery);
+ assertEquals(1, result.size());
+ }
+
+ @Test
+ public void shouldQueryByNullParameter3() {
+ List orders = getOrders();
+ orders.add(getBallOrder());
+ InMemoryOrderDao dao = daoInstance();
+ dao.saveAll(orders);
+
+ OrderQuery ballQuery = OrderQuery.query("Ball");
+ ballQuery.and().with( //
+ ParameterSelection.nullSelection("parameters", "weight"));
+
+ List result = dao.doQuery(ballQuery);
+ assertEquals(1, result.size());
+ }
+
+ @Test
+ public void shouldQueryByName() {
+
+ List orders = getOrders();
+ orders.add(getBallOrder());
+ InMemoryOrderDao dao = daoInstance();
+ dao.saveAll(orders);
+
+ OrderQuery ballQuery = OrderQuery.query("Ball");
+ ballQuery.with(new NameSelection("ball ", ci()));
+
+ List result = dao.doQuery(ballQuery);
+ assertEquals(1, result.size());
+ }
+
+ private Order getBallOrder() {
+ Order o1 = new Order("childrensBall", "Ball 1", "Ball");
+ o1.setVersion(new Version(o1.getLocator(), 0, "ModelGenerator", false));
+ ParameterBag bag = new ParameterBag("parameters", "Ball Details", "Parameters");
+ bag.addParameter(new StringParameter("color", "Color", "red"));
+ bag.addParameter(new BooleanParameter("forChildren", "Color", true));
+ bag.addParameter(new FloatParameter("diameter", "Color", 22.0));
+ bag.addParameter(
+ new StringListParameter("stringListValues", "List of String Values", Arrays.asList("a", "b", "c")));
+ bag.addParameter(new IntegerListParameter("intListValues", "List of Integer Values", Arrays.asList(1, 2, 3)));
+ bag.addParameter(
+ new FloatListParameter("floatListValues", "List of Float Values", Arrays.asList(4.0, 5.1, 6.2)));
+ bag.addParameter(new LongListParameter("longListValues", "List of Long Values", Arrays.asList(8L, 9L, 10L)));
+ o1.addParameterBag(bag);
+ return o1;
+ }
+
+ private List getOrders() {
+ Order res1 = ModelGenerator.createOrder("@1", "Res 1", "MyType1", new Date(), State.CREATED);
+ Order res2 = ModelGenerator.createOrder("@2", "Res 2", "MyType1", new Date(), State.CREATED);
+ Order res3 = ModelGenerator.createOrder("@3", "Res 3", "MyType2", new Date(), State.CREATED);
+ Order res4 = ModelGenerator.createOrder("@4", "Res 4", "MyType2", new Date(), State.CREATED);
+ Order res5 = ModelGenerator.createOrder("@5", "Res 5", "MyType3", new Date(), State.CREATED);
+ Order res6 = ModelGenerator.createOrder("@6", "Res 6", "MyType3", new Date(), State.CREATED);
+ List orders = new ArrayList<>();
+ orders.add(res1);
+ orders.add(res2);
+ orders.add(res3);
+ orders.add(res4);
+ orders.add(res5);
+ orders.add(res6);
+ return orders;
+ }
+}
diff --git a/li.strolch.agent/src/main/java/li/strolch/persistence/inmemory/InMemoryPersistenceHandler.java b/li.strolch.agent/src/test/java/li/strolch/runtime/query/inmemory/InMemoryPersistenceHandler.java
similarity index 94%
rename from li.strolch.agent/src/main/java/li/strolch/persistence/inmemory/InMemoryPersistenceHandler.java
rename to li.strolch.agent/src/test/java/li/strolch/runtime/query/inmemory/InMemoryPersistenceHandler.java
index 2d09ce609..e6adf2420 100644
--- a/li.strolch.agent/src/main/java/li/strolch/persistence/inmemory/InMemoryPersistenceHandler.java
+++ b/li.strolch.agent/src/test/java/li/strolch/runtime/query/inmemory/InMemoryPersistenceHandler.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package li.strolch.persistence.inmemory;
+package li.strolch.runtime.query.inmemory;
import li.strolch.agent.api.ComponentContainer;
import li.strolch.agent.api.StrolchComponent;
@@ -24,6 +24,7 @@ import li.strolch.persistence.api.OrderDao;
import li.strolch.persistence.api.PersistenceHandler;
import li.strolch.persistence.api.ResourceDao;
import li.strolch.persistence.api.StrolchTransaction;
+import li.strolch.persistence.inmemory.InMemoryPersistence;
import li.strolch.privilege.model.Certificate;
import li.strolch.runtime.configuration.ComponentConfiguration;
@@ -44,7 +45,7 @@ public class InMemoryPersistenceHandler extends StrolchComponent implements Pers
@Override
public void initialize(ComponentConfiguration configuration) throws Exception {
- this.persistence = new InMemoryPersistence(getContainer().getPrivilegeHandler());
+ this.persistence = new InMemoryPersistence(getContainer().getPrivilegeHandler(), false);
super.initialize(configuration);
}
diff --git a/li.strolch.agent/src/test/java/li/strolch/runtime/query/inmemory/InMemoryQueryTest.java b/li.strolch.agent/src/test/java/li/strolch/runtime/query/inmemory/InMemoryResourceQueryTest.java
similarity index 75%
rename from li.strolch.agent/src/test/java/li/strolch/runtime/query/inmemory/InMemoryQueryTest.java
rename to li.strolch.agent/src/test/java/li/strolch/runtime/query/inmemory/InMemoryResourceQueryTest.java
index 3dbca950a..c38c08b4a 100644
--- a/li.strolch.agent/src/test/java/li/strolch/runtime/query/inmemory/InMemoryQueryTest.java
+++ b/li.strolch.agent/src/test/java/li/strolch/runtime/query/inmemory/InMemoryResourceQueryTest.java
@@ -1,18 +1,3 @@
-/*
- * Copyright 2013 Robert von Burg
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
package li.strolch.runtime.query.inmemory;
import static li.strolch.model.query.ParameterSelection.booleanSelection;
@@ -28,14 +13,14 @@ import static org.junit.Assert.assertEquals;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Date;
import java.util.List;
+import org.junit.Test;
+
import li.strolch.model.ModelGenerator;
-import li.strolch.model.Order;
import li.strolch.model.ParameterBag;
import li.strolch.model.Resource;
-import li.strolch.model.State;
+import li.strolch.model.Version;
import li.strolch.model.parameter.BooleanParameter;
import li.strolch.model.parameter.FloatListParameter;
import li.strolch.model.parameter.FloatParameter;
@@ -45,39 +30,21 @@ import li.strolch.model.parameter.StringListParameter;
import li.strolch.model.parameter.StringParameter;
import li.strolch.model.query.IdSelection;
import li.strolch.model.query.NameSelection;
-import li.strolch.model.query.OrderQuery;
import li.strolch.model.query.ParameterSelection;
import li.strolch.model.query.ResourceQuery;
-import li.strolch.persistence.inmemory.InMemoryOrderDao;
import li.strolch.persistence.inmemory.InMemoryResourceDao;
-import org.junit.Test;
+public class InMemoryResourceQueryTest {
-/**
- * @author Robert von Burg
- */
-@SuppressWarnings("nls")
-public class InMemoryQueryTest {
-
- @Test
- public void shouldQueryOrderById() {
-
- List orders = getOrders();
- InMemoryOrderDao dao = new InMemoryOrderDao();
- dao.saveAll(orders);
-
- OrderQuery orderQuery = OrderQuery.query("MyType1");
- orderQuery.with(new IdSelection("@1"));
- List result = dao.doQuery(orderQuery);
- assertEquals(1, result.size());
- assertEquals("@1", result.get(0).getId());
+ protected InMemoryResourceDao daoInstance() {
+ return new InMemoryResourceDao(false);
}
@Test
- public void shouldQueryResourceById() {
+ public void shouldQueryById() {
List resources = getResources();
- InMemoryResourceDao dao = new InMemoryResourceDao();
+ InMemoryResourceDao dao = daoInstance();
dao.saveAll(resources);
ResourceQuery resourceQuery = ResourceQuery.query("MyType1");
@@ -89,10 +56,10 @@ public class InMemoryQueryTest {
}
@Test
- public void shouldQueryResourceByIdOr() {
+ public void shouldQueryByIdOr() {
List resources = getResources();
- InMemoryResourceDao dao = new InMemoryResourceDao();
+ InMemoryResourceDao dao = daoInstance();
dao.saveAll(resources);
ResourceQuery resourceQuery = ResourceQuery.query("MyType2");
@@ -105,10 +72,10 @@ public class InMemoryQueryTest {
}
@Test
- public void shouldQueryResourceByIdAnd() {
+ public void shouldQueryByIdAnd() {
List resources = getResources();
- InMemoryResourceDao dao = new InMemoryResourceDao();
+ InMemoryResourceDao dao = daoInstance();
dao.saveAll(resources);
ResourceQuery resourceQuery = ResourceQuery.query("MyType2");
@@ -120,10 +87,10 @@ public class InMemoryQueryTest {
}
@Test
- public void shouldNotQueryResourceByIdAnd() {
+ public void shouldNotQueryByIdAnd() {
List resources = getResources();
- InMemoryResourceDao dao = new InMemoryResourceDao();
+ InMemoryResourceDao dao = daoInstance();
dao.saveAll(resources);
ResourceQuery resourceQuery = ResourceQuery.query("MyType1");
@@ -138,7 +105,7 @@ public class InMemoryQueryTest {
List resources = getResources();
resources.add(getBallResource());
- InMemoryResourceDao dao = new InMemoryResourceDao();
+ InMemoryResourceDao dao = daoInstance();
dao.saveAll(resources);
ResourceQuery ballQuery = ResourceQuery.query("Ball");
@@ -156,7 +123,7 @@ public class InMemoryQueryTest {
List resources = getResources();
resources.add(getBallResource());
- InMemoryResourceDao dao = new InMemoryResourceDao();
+ InMemoryResourceDao dao = daoInstance();
dao.saveAll(resources);
ResourceQuery ballQuery;
@@ -239,7 +206,7 @@ public class InMemoryQueryTest {
public void shouldQueryByNullParameter1() {
List resources = getResources();
resources.add(getBallResource());
- InMemoryResourceDao dao = new InMemoryResourceDao();
+ InMemoryResourceDao dao = daoInstance();
dao.saveAll(resources);
ResourceQuery ballQuery = ResourceQuery.query("Ball");
@@ -254,7 +221,7 @@ public class InMemoryQueryTest {
public void shouldQueryByNullParameter2() {
List resources = getResources();
resources.add(getBallResource());
- InMemoryResourceDao dao = new InMemoryResourceDao();
+ InMemoryResourceDao dao = daoInstance();
dao.saveAll(resources);
ResourceQuery ballQuery = ResourceQuery.query("Ball");
@@ -269,7 +236,7 @@ public class InMemoryQueryTest {
public void shouldQueryByNullParameter3() {
List resources = getResources();
resources.add(getBallResource());
- InMemoryResourceDao dao = new InMemoryResourceDao();
+ InMemoryResourceDao dao = daoInstance();
dao.saveAll(resources);
ResourceQuery ballQuery = ResourceQuery.query("Ball");
@@ -285,7 +252,7 @@ public class InMemoryQueryTest {
List resources = getResources();
resources.add(getBallResource());
- InMemoryResourceDao dao = new InMemoryResourceDao();
+ InMemoryResourceDao dao = daoInstance();
dao.saveAll(resources);
ResourceQuery ballQuery = ResourceQuery.query("Ball");
@@ -297,14 +264,16 @@ public class InMemoryQueryTest {
private Resource getBallResource() {
Resource res1 = new Resource("childrensBall", "Ball 1", "Ball");
+ res1.setVersion(new Version(res1.getLocator(), 0, "ModelGenerator", false));
ParameterBag bag = new ParameterBag("parameters", "Ball Details", "Parameters");
bag.addParameter(new StringParameter("color", "Color", "red"));
bag.addParameter(new BooleanParameter("forChildren", "Color", true));
bag.addParameter(new FloatParameter("diameter", "Color", 22.0));
- bag.addParameter(new StringListParameter("stringListValues", "List of String Values", Arrays.asList("a", "b",
- "c")));
+ bag.addParameter(
+ new StringListParameter("stringListValues", "List of String Values", Arrays.asList("a", "b", "c")));
bag.addParameter(new IntegerListParameter("intListValues", "List of Integer Values", Arrays.asList(1, 2, 3)));
- bag.addParameter(new FloatListParameter("floatListValues", "List of Float Values", Arrays.asList(4.0, 5.1, 6.2)));
+ bag.addParameter(
+ new FloatListParameter("floatListValues", "List of Float Values", Arrays.asList(4.0, 5.1, 6.2)));
bag.addParameter(new LongListParameter("longListValues", "List of Long Values", Arrays.asList(8L, 9L, 10L)));
res1.addParameterBag(bag);
return res1;
@@ -324,23 +293,11 @@ public class InMemoryQueryTest {
resources.add(res4);
resources.add(res5);
resources.add(res6);
+
+ for (Resource resource : resources) {
+ resource.setVersion(new Version(resource.getLocator(), 0, "Test", false));
+ }
+
return resources;
}
-
- private List getOrders() {
- Order res1 = ModelGenerator.createOrder("@1", "Res 1", "MyType1", new Date(), State.CREATED);
- Order res2 = ModelGenerator.createOrder("@2", "Res 2", "MyType1", new Date(), State.CREATED);
- Order res3 = ModelGenerator.createOrder("@3", "Res 3", "MyType2", new Date(), State.CREATED);
- Order res4 = ModelGenerator.createOrder("@4", "Res 4", "MyType2", new Date(), State.CREATED);
- Order res5 = ModelGenerator.createOrder("@5", "Res 5", "MyType3", new Date(), State.CREATED);
- Order res6 = ModelGenerator.createOrder("@6", "Res 6", "MyType3", new Date(), State.CREATED);
- List orders = new ArrayList<>();
- orders.add(res1);
- orders.add(res2);
- orders.add(res3);
- orders.add(res4);
- orders.add(res5);
- orders.add(res6);
- return orders;
- }
}
diff --git a/li.strolch.agent/src/test/resources/cachedtest/config/StrolchConfiguration.xml b/li.strolch.agent/src/test/resources/cachedtest/config/StrolchConfiguration.xml
index 485927bfb..0592be934 100644
--- a/li.strolch.agent/src/test/resources/cachedtest/config/StrolchConfiguration.xml
+++ b/li.strolch.agent/src/test/resources/cachedtest/config/StrolchConfiguration.xml
@@ -44,7 +44,7 @@
PersistenceHandler
li.strolch.persistence.api.PersistenceHandler
- li.strolch.persistence.inmemory.InMemoryPersistenceHandler
+ li.strolch.runtime.query.inmemory.InMemoryPersistenceHandler
\ No newline at end of file
diff --git a/li.strolch.agent/src/test/resources/realmtest/config/StrolchConfiguration.xml b/li.strolch.agent/src/test/resources/realmtest/config/StrolchConfiguration.xml
index 7d8bd7c36..fd116ae0a 100644
--- a/li.strolch.agent/src/test/resources/realmtest/config/StrolchConfiguration.xml
+++ b/li.strolch.agent/src/test/resources/realmtest/config/StrolchConfiguration.xml
@@ -19,7 +19,7 @@
PersistenceHandler
li.strolch.persistence.api.PersistenceHandler
- li.strolch.persistence.inmemory.InMemoryPersistenceHandler
+ li.strolch.runtime.query.inmemory.InMemoryPersistenceHandler
RealmHandler
diff --git a/li.strolch.agent/src/test/resources/transactionaltest/config/StrolchConfiguration.xml b/li.strolch.agent/src/test/resources/transactionaltest/config/StrolchConfiguration.xml
index 8c71a31fc..38e1d8566 100644
--- a/li.strolch.agent/src/test/resources/transactionaltest/config/StrolchConfiguration.xml
+++ b/li.strolch.agent/src/test/resources/transactionaltest/config/StrolchConfiguration.xml
@@ -45,7 +45,7 @@
PersistenceHandler
li.strolch.persistence.api.PersistenceHandler
- li.strolch.persistence.inmemory.InMemoryPersistenceHandler
+ li.strolch.runtime.query.inmemory.InMemoryPersistenceHandler
\ No newline at end of file
diff --git a/li.strolch.agent/src/test/resources/versioningtest/config/PrivilegeConfig.xml b/li.strolch.agent/src/test/resources/versioningtest/config/PrivilegeConfig.xml
new file mode 100644
index 000000000..cfab85b24
--- /dev/null
+++ b/li.strolch.agent/src/test/resources/versioningtest/config/PrivilegeConfig.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+