[Major] Implemented CACHED mode
This lead to refactoring of other code: - removed get*Dao() from StrolchTransaction - added StrolchTransaction.getPersistenceHandler() - removed unused variables in TransactionalElementMap - this lead to removal of constructors in subclasses - added ComponentContainer.getDataStoreMode() - added ElementMap.addAll(), removeAll() and updateAll() methods - implemented in all ElementMap implementations
This commit is contained in:
parent
62affa815c
commit
a446a25a2e
|
@ -15,6 +15,7 @@
|
|||
*/
|
||||
package li.strolch.agent.api;
|
||||
|
||||
import li.strolch.agent.impl.DataStoreMode;
|
||||
import li.strolch.agent.impl.StrolchRealm;
|
||||
|
||||
/**
|
||||
|
@ -25,6 +26,8 @@ public interface ComponentContainer {
|
|||
public abstract StrolchAgent getAgent();
|
||||
|
||||
public abstract ComponentState getState();
|
||||
|
||||
public abstract DataStoreMode getDataStoreMode();
|
||||
|
||||
public abstract boolean hasComponent(Class<?> clazz);
|
||||
|
||||
|
|
|
@ -44,7 +44,13 @@ public interface ElementMap<T extends StrolchElement> {
|
|||
|
||||
public void add(StrolchTransaction tx, T element);
|
||||
|
||||
public void addAll(StrolchTransaction tx, List<T> elements);
|
||||
|
||||
public void update(StrolchTransaction tx, T element);
|
||||
|
||||
public void updateAll(StrolchTransaction tx, List<T> elements);
|
||||
|
||||
public void remove(StrolchTransaction tx, T element);
|
||||
|
||||
public void removeAll(StrolchTransaction tx, List<T> elements);
|
||||
}
|
||||
|
|
|
@ -100,7 +100,7 @@ public class StrolchAgent {
|
|||
this.strolchConfiguration.addConfiguration(configuration.getName(), configuration);
|
||||
}
|
||||
|
||||
ComponentContainerImpl container = new ComponentContainerImpl(this);
|
||||
ComponentContainerImpl container = new ComponentContainerImpl(this, dataStoreMode);
|
||||
this.container = container;
|
||||
|
||||
logger.info(MessageFormat.format("Setup Agent {0}", runtimeConfiguration.getApplicationName())); //$NON-NLS-1$
|
||||
|
|
|
@ -0,0 +1,347 @@
|
|||
/*
|
||||
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
|
||||
*
|
||||
* 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.agent.impl;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import li.strolch.agent.api.ElementMap;
|
||||
import li.strolch.model.StrolchElement;
|
||||
import li.strolch.persistence.api.StrolchDao;
|
||||
import li.strolch.persistence.api.StrolchPersistenceException;
|
||||
import li.strolch.persistence.api.StrolchTransaction;
|
||||
import ch.eitchnet.utils.dbc.DBC;
|
||||
|
||||
/**
|
||||
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||
*/
|
||||
public abstract class CachedElementMap<T extends StrolchElement> implements ElementMap<T> {
|
||||
|
||||
private Set<String> allKeys;
|
||||
private Map<String, Map<String, T>> elementMap;
|
||||
|
||||
public CachedElementMap() {
|
||||
this.allKeys = Collections.synchronizedSet(new HashSet<String>());
|
||||
this.elementMap = Collections.synchronizedMap(new HashMap<String, Map<String, T>>());
|
||||
}
|
||||
|
||||
protected abstract StrolchDao<T> getDao(StrolchTransaction tx);
|
||||
|
||||
@Override
|
||||
public boolean hasType(StrolchTransaction tx, String type) {
|
||||
return this.elementMap.containsKey(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasElement(StrolchTransaction tx, String type, String id) {
|
||||
Map<String, T> byType = this.elementMap.get(type);
|
||||
if (byType == null)
|
||||
return false;
|
||||
|
||||
return byType.containsKey(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T getBy(StrolchTransaction tx, String type, String id) {
|
||||
Map<String, T> byType = this.elementMap.get(type);
|
||||
if (byType == null)
|
||||
return null;
|
||||
|
||||
return byType.get(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<T> getAllElements(StrolchTransaction tx) {
|
||||
List<T> allElements = new ArrayList<>();
|
||||
for (String type : this.elementMap.keySet()) {
|
||||
Map<String, T> byType = this.elementMap.get(type);
|
||||
allElements.addAll(byType.values());
|
||||
}
|
||||
|
||||
return allElements;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<T> getElementsBy(StrolchTransaction tx, String type) {
|
||||
Map<String, T> byType = this.elementMap.get(type);
|
||||
if (byType == null)
|
||||
return Collections.emptyList();
|
||||
return new ArrayList<>(byType.values());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getTypes(StrolchTransaction tx) {
|
||||
return new HashSet<>(this.elementMap.keySet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getAllKeys(StrolchTransaction tx) {
|
||||
Set<String> keys = new HashSet<>();
|
||||
for (String type : this.elementMap.keySet()) {
|
||||
Map<String, T> byType = this.elementMap.get(type);
|
||||
keys.addAll(byType.keySet());
|
||||
}
|
||||
return keys;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getKeysBy(StrolchTransaction tx, String type) {
|
||||
Map<String, T> byType = this.elementMap.get(type);
|
||||
if (byType == null)
|
||||
return Collections.emptySet();
|
||||
return byType.keySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(StrolchTransaction tx, T element) {
|
||||
DBC.PRE.assertNotNull("Transaction may not be null!", tx);
|
||||
DBC.PRE.assertNotNull("Element may not be null!", element);
|
||||
|
||||
insert(element, tx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(StrolchTransaction tx, T element) {
|
||||
DBC.PRE.assertNotNull("Transaction may not be null!", tx);
|
||||
DBC.PRE.assertNotNull("Element may not be null!", element);
|
||||
|
||||
String msg = "The element {0} can not be updated as it does not exist!";
|
||||
Map<String, T> byType = this.elementMap.get(element.getType());
|
||||
if (byType == null) {
|
||||
msg = MessageFormat.format(msg, element.getLocator());
|
||||
throw new StrolchPersistenceException(msg);
|
||||
}
|
||||
|
||||
synchronized (byType) {
|
||||
if (byType.remove(element.getId()) == null) {
|
||||
msg = MessageFormat.format(msg, element.getLocator());
|
||||
throw new StrolchPersistenceException(msg);
|
||||
}
|
||||
byType.put(element.getId(), element);
|
||||
getDao(tx).update(element);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(StrolchTransaction tx, T element) {
|
||||
DBC.PRE.assertNotNull("Transaction may not be null!", tx);
|
||||
DBC.PRE.assertNotNull("Element may not be null!", element);
|
||||
|
||||
String msg = "The element {0} can not be removed as it does not exist!";
|
||||
|
||||
synchronized (this.elementMap) {
|
||||
Map<String, T> byType = this.elementMap.get(element.getType());
|
||||
if (byType == null) {
|
||||
msg = MessageFormat.format(msg, element.getLocator());
|
||||
throw new StrolchPersistenceException(msg);
|
||||
}
|
||||
|
||||
// TODO remove empty byType map after element removal, but be wary of synchronisation...
|
||||
|
||||
synchronized (byType) {
|
||||
if (byType.remove(element.getId()) == null) {
|
||||
msg = MessageFormat.format(msg, element.getLocator());
|
||||
throw new StrolchPersistenceException(msg);
|
||||
}
|
||||
if (byType.isEmpty()) {
|
||||
this.elementMap.remove(element.getType());
|
||||
}
|
||||
this.allKeys.remove(element.getId());
|
||||
getDao(tx).remove(element);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Special method used when starting the container to cache the values. Not to be used anywhere else but from the
|
||||
* {@link CachedElementMapHandler} and of course through the {@link #add(StrolchTransaction, StrolchElement)}-call
|
||||
* to not duplicate code
|
||||
*
|
||||
* @param element
|
||||
* @param tx
|
||||
*/
|
||||
void insert(T element, StrolchTransaction tx) {
|
||||
if (this.allKeys.contains(element.getId())) {
|
||||
String msg = "An element already exists with the id " + element.getId()
|
||||
+ ". Elements of the same class must always have a unique id, regardless of their type!";
|
||||
throw new StrolchPersistenceException(msg);
|
||||
}
|
||||
|
||||
Map<String, T> byType;
|
||||
synchronized (this.elementMap) {
|
||||
byType = this.elementMap.get(element.getType());
|
||||
if (byType == null) {
|
||||
byType = Collections.synchronizedMap(new HashMap<String, T>());
|
||||
this.elementMap.put(element.getType(), byType);
|
||||
}
|
||||
}
|
||||
|
||||
synchronized (byType) {
|
||||
if (byType.containsKey(element.getId())) {
|
||||
String msg = MessageFormat.format("The element {0} already exists!", element.getLocator());
|
||||
throw new StrolchPersistenceException(msg);
|
||||
}
|
||||
|
||||
byType.put(element.getId(), element);
|
||||
this.allKeys.add(element.getId());
|
||||
if (tx != null)
|
||||
getDao(tx).save(element);
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, List<T>> sortElementsToType(List<T> elements) {
|
||||
Map<String, List<T>> map = new HashMap<>(1);
|
||||
for (T element : elements) {
|
||||
List<T> byType = map.get(element.getType());
|
||||
if (byType == null) {
|
||||
byType = new ArrayList<>(1);
|
||||
map.put(element.getType(), byType);
|
||||
}
|
||||
byType.add(element);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addAll(StrolchTransaction tx, List<T> elements) {
|
||||
DBC.PRE.assertNotNull("Transaction may not be null!", tx);
|
||||
DBC.PRE.assertNotNull("Elements may not be null!", elements);
|
||||
|
||||
if (elements.isEmpty())
|
||||
return;
|
||||
|
||||
// sort elements by type
|
||||
Map<String, List<T>> map = sortElementsToType(elements);
|
||||
|
||||
// now add elements by type
|
||||
for (String type : map.keySet()) {
|
||||
|
||||
Map<String, T> byType;
|
||||
synchronized (this.elementMap) {
|
||||
byType = this.elementMap.get(type);
|
||||
if (byType == null) {
|
||||
byType = new HashMap<>();
|
||||
this.elementMap.put(type, byType);
|
||||
}
|
||||
|
||||
List<T> newByType = map.get(type);
|
||||
for (T element : newByType) {
|
||||
synchronized (byType) {
|
||||
if (byType.containsKey(element.getId())) {
|
||||
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!";
|
||||
msg = MessageFormat.format(msg, element.getId());
|
||||
throw new StrolchPersistenceException(msg);
|
||||
}
|
||||
|
||||
byType.put(element.getId(), element);
|
||||
this.allKeys.add(element.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// last is to perform DB changes
|
||||
getDao(tx).saveAll(elements);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAll(StrolchTransaction tx, List<T> elements) {
|
||||
DBC.PRE.assertNotNull("Transaction may not be null!", tx);
|
||||
DBC.PRE.assertNotNull("Elements may not be null!", elements);
|
||||
|
||||
if (elements.isEmpty())
|
||||
return;
|
||||
|
||||
// sort elements by type
|
||||
Map<String, List<T>> map = sortElementsToType(elements);
|
||||
|
||||
String msg = "The element {0} can not be updated as it does not exist!";
|
||||
|
||||
// update elements
|
||||
for (String type : map.keySet()) {
|
||||
List<T> list = map.get(type);
|
||||
|
||||
synchronized (this.elementMap) {
|
||||
Map<String, T> byType = this.elementMap.get(type);
|
||||
if (byType == null) {
|
||||
msg = MessageFormat.format(msg, list.get(0).getLocator());
|
||||
throw new StrolchPersistenceException(msg);
|
||||
}
|
||||
|
||||
synchronized (byType) {
|
||||
for (T element : list) {
|
||||
if (byType.remove(element.getId()) == null) {
|
||||
msg = MessageFormat.format(msg, element.getLocator());
|
||||
throw new StrolchPersistenceException(msg);
|
||||
}
|
||||
byType.put(element.getId(), element);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// last is to perform DB changes
|
||||
getDao(tx).updateAll(elements);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAll(StrolchTransaction tx, List<T> elements) {
|
||||
DBC.PRE.assertNotNull("Transaction may not be null!", tx);
|
||||
DBC.PRE.assertNotNull("Elements may not be null!", elements);
|
||||
|
||||
if (elements.isEmpty())
|
||||
return;
|
||||
|
||||
// sort elements by type
|
||||
Map<String, List<T>> map = sortElementsToType(elements);
|
||||
|
||||
String msg = "The element {0} can not be removed as it does not exist!";
|
||||
|
||||
// update elements
|
||||
for (String type : map.keySet()) {
|
||||
List<T> list = map.get(type);
|
||||
|
||||
synchronized (this.elementMap) {
|
||||
Map<String, T> byType = this.elementMap.get(type);
|
||||
if (byType == null) {
|
||||
msg = MessageFormat.format(msg, list.get(0).getLocator());
|
||||
throw new StrolchPersistenceException(msg);
|
||||
}
|
||||
synchronized (byType) {
|
||||
for (T element : list) {
|
||||
if (byType.remove(element.getId()) == null) {
|
||||
msg = MessageFormat.format(msg, element.getLocator());
|
||||
throw new StrolchPersistenceException(msg);
|
||||
}
|
||||
|
||||
if (byType.isEmpty()) {
|
||||
this.elementMap.remove(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// last is to perform DB changes
|
||||
getDao(tx).removeAll(elements);
|
||||
}
|
||||
}
|
|
@ -16,22 +16,26 @@
|
|||
package li.strolch.agent.impl;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import li.strolch.agent.api.OrderMap;
|
||||
import li.strolch.agent.api.ResourceMap;
|
||||
import li.strolch.agent.api.StrolchAgent;
|
||||
import li.strolch.model.Order;
|
||||
import li.strolch.model.Resource;
|
||||
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.runtime.StrolchConstants;
|
||||
import li.strolch.runtime.configuration.ComponentConfiguration;
|
||||
import li.strolch.runtime.configuration.RuntimeConfiguration;
|
||||
import ch.eitchnet.utils.helper.StringHelper;
|
||||
|
||||
/**
|
||||
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||
*/
|
||||
public class CachedElementMapHandler extends InMemoryElementMapHandler {
|
||||
public class CachedElementMapHandler extends AbstractElementMapHandler {
|
||||
|
||||
/**
|
||||
* @param container
|
||||
|
@ -41,6 +45,24 @@ public class CachedElementMapHandler extends InMemoryElementMapHandler {
|
|||
super(container, componentName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(ComponentConfiguration configuration) {
|
||||
|
||||
RuntimeConfiguration runtimeConfiguration = configuration.getRuntimeConfiguration();
|
||||
String[] realms = runtimeConfiguration.getStringArray(StrolchAgent.PROP_REALMS, StrolchConstants.DEFAULT_REALM);
|
||||
|
||||
this.realms = new HashMap<>();
|
||||
for (String realm : realms) {
|
||||
PersistenceHandler persistenceHandler = getContainer().getComponent(PersistenceHandler.class);
|
||||
CachedResourceMap resourceMap = new CachedResourceMap();
|
||||
CachedOrderMap orderMap = new CachedOrderMap();
|
||||
StrolchRealm strolchRealm = new StrolchRealm(realm, persistenceHandler, resourceMap, orderMap);
|
||||
this.realms.put(realm, strolchRealm);
|
||||
}
|
||||
|
||||
super.initialize(configuration);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
|
||||
|
@ -51,28 +73,28 @@ public class CachedElementMapHandler extends InMemoryElementMapHandler {
|
|||
int nrOfResources = 0;
|
||||
|
||||
StrolchRealm strolchRealm = this.realms.get(realm);
|
||||
OrderMap orderMap = strolchRealm.getOrderMap();
|
||||
ResourceMap resourceMap = strolchRealm.getResourceMap();
|
||||
CachedOrderMap orderMap = (CachedOrderMap) strolchRealm.getOrderMap();
|
||||
CachedResourceMap resourceMap = (CachedResourceMap) strolchRealm.getResourceMap();
|
||||
|
||||
try (StrolchTransaction tx = strolchRealm.openTx()) {
|
||||
ResourceDao resourceDao = tx.getResourceDao();
|
||||
ResourceDao resourceDao = tx.getPersistenceHandler().getResourceDao(tx);
|
||||
Set<String> resourceTypes = resourceDao.queryTypes();
|
||||
for (String type : resourceTypes) {
|
||||
List<Resource> resources = resourceDao.queryAll(type);
|
||||
for (Resource resource : resources) {
|
||||
resourceMap.add(tx, resource);
|
||||
resourceMap.insert(resource, null);
|
||||
nrOfResources++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try (StrolchTransaction tx = strolchRealm.openTx()) {
|
||||
OrderDao orderDao = tx.getOrderDao();
|
||||
OrderDao orderDao = tx.getPersistenceHandler().getOrderDao(tx);
|
||||
Set<String> orderTypes = orderDao.queryTypes();
|
||||
for (String type : orderTypes) {
|
||||
List<Order> orders = orderDao.queryAll(type);
|
||||
for (Order order : orders) {
|
||||
orderMap.add(tx, order);
|
||||
orderMap.insert(order, null);
|
||||
nrOfOrders++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
package li.strolch.agent.impl;
|
||||
|
||||
import li.strolch.agent.api.OrderMap;
|
||||
import li.strolch.model.Order;
|
||||
import li.strolch.persistence.api.OrderDao;
|
||||
import li.strolch.persistence.api.StrolchTransaction;
|
||||
|
||||
public class CachedOrderMap extends CachedElementMap<Order> implements OrderMap {
|
||||
|
||||
@Override
|
||||
protected OrderDao getDao(StrolchTransaction tx) {
|
||||
return tx.getPersistenceHandler().getOrderDao(tx);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package li.strolch.agent.impl;
|
||||
|
||||
import li.strolch.agent.api.ResourceMap;
|
||||
import li.strolch.model.Resource;
|
||||
import li.strolch.persistence.api.ResourceDao;
|
||||
import li.strolch.persistence.api.StrolchTransaction;
|
||||
|
||||
public class CachedResourceMap extends CachedElementMap<Resource> implements ResourceMap {
|
||||
|
||||
@Override
|
||||
protected ResourceDao getDao(StrolchTransaction tx) {
|
||||
return tx.getPersistenceHandler().getResourceDao(tx);
|
||||
}
|
||||
}
|
|
@ -39,16 +39,18 @@ public class ComponentContainerImpl implements ComponentContainer {
|
|||
|
||||
private static final Logger logger = LoggerFactory.getLogger(ComponentContainerImpl.class);
|
||||
|
||||
private StrolchAgent agent;
|
||||
private DataStoreMode dataStoreMode;
|
||||
|
||||
private Map<Class<?>, StrolchComponent> componentMap;
|
||||
private Map<String, ComponentController> controllerMap;
|
||||
private ComponentDependencyAnalyzer dependencyAnalyzer;
|
||||
private StrolchConfiguration strolchConfiguration;
|
||||
private ComponentState state;
|
||||
|
||||
private StrolchAgent agent;
|
||||
|
||||
public ComponentContainerImpl(StrolchAgent agent) {
|
||||
public ComponentContainerImpl(StrolchAgent agent, DataStoreMode dataStoreMode) {
|
||||
this.agent = agent;
|
||||
this.dataStoreMode = dataStoreMode;
|
||||
this.state = ComponentState.UNDEFINED;
|
||||
}
|
||||
|
||||
|
@ -61,6 +63,11 @@ public class ComponentContainerImpl implements ComponentContainer {
|
|||
return this.state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataStoreMode getDataStoreMode() {
|
||||
return this.dataStoreMode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasComponent(Class<?> clazz) {
|
||||
return this.componentMap.containsKey(clazz);
|
||||
|
|
|
@ -45,8 +45,8 @@ public class InMemoryElementMapHandler extends AbstractElementMapHandler {
|
|||
this.realms = new HashMap<>();
|
||||
for (String realm : realms) {
|
||||
PersistenceHandler persistenceHandler = getContainer().getComponent(PersistenceHandler.class);
|
||||
TransactionalResourceMap resourceMap = new TransactionalResourceMap(realm, persistenceHandler);
|
||||
TransactionalOrderMap orderMap = new TransactionalOrderMap(realm, persistenceHandler);
|
||||
TransactionalResourceMap resourceMap = new TransactionalResourceMap();
|
||||
TransactionalOrderMap orderMap = new TransactionalOrderMap();
|
||||
StrolchRealm strolchRealm = new StrolchRealm(realm, persistenceHandler, resourceMap, orderMap);
|
||||
this.realms.put(realm, strolchRealm);
|
||||
}
|
||||
|
|
|
@ -5,8 +5,6 @@ import java.util.Set;
|
|||
|
||||
import li.strolch.agent.api.ElementMap;
|
||||
import li.strolch.model.StrolchElement;
|
||||
import li.strolch.model.query.StrolchQuery;
|
||||
import li.strolch.persistence.api.PersistenceHandler;
|
||||
import li.strolch.persistence.api.StrolchDao;
|
||||
import li.strolch.persistence.api.StrolchTransaction;
|
||||
|
||||
|
@ -15,24 +13,7 @@ import li.strolch.persistence.api.StrolchTransaction;
|
|||
*
|
||||
* @param <T>
|
||||
*/
|
||||
public abstract class TransactionalElementMap<T extends StrolchElement, U extends StrolchQuery<?>> implements
|
||||
ElementMap<T> {
|
||||
|
||||
private PersistenceHandler persistenceHandler;
|
||||
private String realm;
|
||||
|
||||
public TransactionalElementMap(String realm, PersistenceHandler persistenceHandler) {
|
||||
this.realm = realm;
|
||||
this.persistenceHandler = persistenceHandler;
|
||||
}
|
||||
|
||||
protected String getRealm() {
|
||||
return this.realm;
|
||||
}
|
||||
|
||||
protected PersistenceHandler getPersistenceHandler() {
|
||||
return this.persistenceHandler;
|
||||
}
|
||||
public abstract class TransactionalElementMap<T extends StrolchElement> implements ElementMap<T> {
|
||||
|
||||
protected abstract StrolchDao<T> getDao(StrolchTransaction tx);
|
||||
|
||||
|
@ -90,4 +71,19 @@ public abstract class TransactionalElementMap<T extends StrolchElement, U extend
|
|||
public void remove(StrolchTransaction tx, T element) {
|
||||
getDao(tx).remove(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addAll(StrolchTransaction tx, List<T> elements) {
|
||||
getDao(tx).saveAll(elements);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAll(StrolchTransaction tx, List<T> elements) {
|
||||
getDao(tx).removeAll(elements);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAll(StrolchTransaction tx, List<T> elements) {
|
||||
getDao(tx).updateAll(elements);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,19 +2,13 @@ package li.strolch.agent.impl;
|
|||
|
||||
import li.strolch.agent.api.OrderMap;
|
||||
import li.strolch.model.Order;
|
||||
import li.strolch.model.query.OrderQuery;
|
||||
import li.strolch.persistence.api.OrderDao;
|
||||
import li.strolch.persistence.api.PersistenceHandler;
|
||||
import li.strolch.persistence.api.StrolchTransaction;
|
||||
|
||||
public class TransactionalOrderMap extends TransactionalElementMap<Order, OrderQuery> implements OrderMap {
|
||||
|
||||
public TransactionalOrderMap(String realm, PersistenceHandler persistenceHandler) {
|
||||
super(realm, persistenceHandler);
|
||||
}
|
||||
public class TransactionalOrderMap extends TransactionalElementMap<Order> implements OrderMap {
|
||||
|
||||
@Override
|
||||
protected OrderDao getDao(StrolchTransaction tx) {
|
||||
return tx.getOrderDao();
|
||||
return tx.getPersistenceHandler().getOrderDao(tx);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,19 +2,13 @@ package li.strolch.agent.impl;
|
|||
|
||||
import li.strolch.agent.api.ResourceMap;
|
||||
import li.strolch.model.Resource;
|
||||
import li.strolch.model.query.ResourceQuery;
|
||||
import li.strolch.persistence.api.PersistenceHandler;
|
||||
import li.strolch.persistence.api.ResourceDao;
|
||||
import li.strolch.persistence.api.StrolchTransaction;
|
||||
|
||||
public class TransactionalResourceMap extends TransactionalElementMap<Resource, ResourceQuery> implements ResourceMap {
|
||||
|
||||
public TransactionalResourceMap(String realm, PersistenceHandler persistenceHandler) {
|
||||
super(realm, persistenceHandler);
|
||||
}
|
||||
public class TransactionalResourceMap extends TransactionalElementMap<Resource> implements ResourceMap {
|
||||
|
||||
@Override
|
||||
protected ResourceDao getDao(StrolchTransaction tx) {
|
||||
return tx.getResourceDao();
|
||||
return tx.getPersistenceHandler().getResourceDao(tx);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,4 +23,8 @@ import li.strolch.agent.impl.StrolchRealm;
|
|||
public interface PersistenceHandler {
|
||||
|
||||
public StrolchTransaction openTx(StrolchRealm realm);
|
||||
|
||||
public OrderDao getOrderDao(StrolchTransaction tx);
|
||||
|
||||
public ResourceDao getResourceDao(StrolchTransaction tx);
|
||||
}
|
||||
|
|
|
@ -34,8 +34,6 @@ public interface StrolchTransaction extends AutoCloseable {
|
|||
public ResourceMap getResourceMap();
|
||||
|
||||
public OrderMap getOrderMap();
|
||||
|
||||
public OrderDao getOrderDao();
|
||||
|
||||
public ResourceDao getResourceDao();
|
||||
|
||||
public PersistenceHandler getPersistenceHandler();
|
||||
}
|
||||
|
|
|
@ -22,13 +22,15 @@ public class InMemoryPersistenceHandler extends StrolchComponent implements Pers
|
|||
return new InMemoryTransaction(realm, this);
|
||||
}
|
||||
|
||||
public OrderDao getOrderDao() {
|
||||
@Override
|
||||
public OrderDao getOrderDao(StrolchTransaction tx) {
|
||||
if (this.orderDao == null)
|
||||
this.orderDao = new InMemoryOrderDao();
|
||||
return this.orderDao;
|
||||
}
|
||||
|
||||
public ResourceDao getResourceDao() {
|
||||
@Override
|
||||
public ResourceDao getResourceDao(StrolchTransaction tx) {
|
||||
if (this.resourceDao == null)
|
||||
this.resourceDao = new InMemoryResourceDao();
|
||||
return this.resourceDao;
|
||||
|
|
|
@ -7,8 +7,7 @@ import li.strolch.agent.impl.StrolchRealm;
|
|||
import li.strolch.model.StrolchElement;
|
||||
import li.strolch.persistence.api.AbstractTransaction;
|
||||
import li.strolch.persistence.api.ModificationResult;
|
||||
import li.strolch.persistence.api.OrderDao;
|
||||
import li.strolch.persistence.api.ResourceDao;
|
||||
import li.strolch.persistence.api.PersistenceHandler;
|
||||
import li.strolch.persistence.api.StrolchPersistenceException;
|
||||
import li.strolch.persistence.api.TransactionCloseStrategy;
|
||||
import li.strolch.persistence.api.TransactionResult;
|
||||
|
@ -153,12 +152,7 @@ public class InMemoryTransaction extends AbstractTransaction {
|
|||
}
|
||||
|
||||
@Override
|
||||
public OrderDao getOrderDao() {
|
||||
return this.persistenceHandler.getOrderDao();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceDao getResourceDao() {
|
||||
return this.persistenceHandler.getResourceDao();
|
||||
public PersistenceHandler getPersistenceHandler() {
|
||||
return this.persistenceHandler;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,9 +22,13 @@ import java.io.File;
|
|||
import java.text.MessageFormat;
|
||||
|
||||
import li.strolch.agent.api.ComponentContainer;
|
||||
import li.strolch.agent.api.OrderMap;
|
||||
import li.strolch.agent.api.ResourceMap;
|
||||
import li.strolch.agent.api.StrolchAgent;
|
||||
import li.strolch.model.ModelGenerator;
|
||||
import li.strolch.model.Order;
|
||||
import li.strolch.model.Resource;
|
||||
import li.strolch.persistence.api.OrderDao;
|
||||
import li.strolch.persistence.api.ResourceDao;
|
||||
import li.strolch.persistence.api.StrolchTransaction;
|
||||
import li.strolch.runtime.configuration.RuntimeConfiguration;
|
||||
|
@ -88,6 +92,7 @@ public class ComponentContainerTest {
|
|||
try {
|
||||
StrolchAgent agent = startContainer(PATH_TRANSACTIONAL_RUNTIME, PATH_TRANSACTIONAL_CONTAINER);
|
||||
testPersistenceContainer(agent);
|
||||
testElementMaps(agent);
|
||||
destroyContainer(agent);
|
||||
} catch (Exception e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
|
@ -101,6 +106,7 @@ public class ComponentContainerTest {
|
|||
try {
|
||||
StrolchAgent agent = startContainer(PATH_CACHED_RUNTIME, PATH_CACHED_CONTAINER);
|
||||
testPersistenceContainer(agent);
|
||||
testElementMaps(agent);
|
||||
destroyContainer(agent);
|
||||
} catch (Exception e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
|
@ -129,7 +135,8 @@ public class ComponentContainerTest {
|
|||
ServiceResultTest result = serviceHandler.doService();
|
||||
assertEquals(1, result.getResult());
|
||||
|
||||
ResourceGeneratorHandlerTest resourceGeneratorHandler = container.getComponent(ResourceGeneratorHandlerTest.class);
|
||||
ResourceGeneratorHandlerTest resourceGeneratorHandler = container
|
||||
.getComponent(ResourceGeneratorHandlerTest.class);
|
||||
Resource resource = resourceGeneratorHandler.getTestResource("@testRes", "Test Res", "Test");
|
||||
assertNotNull(resource);
|
||||
assertEquals("@testRes", resource.getId());
|
||||
|
@ -144,11 +151,40 @@ public class ComponentContainerTest {
|
|||
assertEquals(1, result.getResult());
|
||||
|
||||
try (StrolchTransaction tx = container.getDefaultRealm().openTx()) {
|
||||
ResourceDao resourceDao = tx.getResourceDao();
|
||||
resourceDao.save(ModelGenerator.createResource("@testRes", "Test Res", "Test"));
|
||||
Resource queriesRes = resourceDao.queryBy("Test", "@testRes");
|
||||
assertNotNull(queriesRes);
|
||||
assertEquals("@testRes", queriesRes.getId());
|
||||
ResourceDao resourceDao = tx.getPersistenceHandler().getResourceDao(tx);
|
||||
resourceDao.save(ModelGenerator.createResource("@testRes0", "Test Res", "Test"));
|
||||
Resource queriedRes = resourceDao.queryBy("Test", "@testRes0");
|
||||
assertNotNull(queriedRes);
|
||||
assertEquals("@testRes0", queriedRes.getId());
|
||||
}
|
||||
|
||||
try (StrolchTransaction tx = container.getDefaultRealm().openTx()) {
|
||||
OrderDao orderDao = tx.getPersistenceHandler().getOrderDao(tx);
|
||||
orderDao.save(ModelGenerator.createOrder("@testOrder0", "Test Order", "Test"));
|
||||
Order queriedOrder = orderDao.queryBy("Test", "@testOrder0");
|
||||
assertNotNull(queriedOrder);
|
||||
assertEquals("@testOrder0", queriedOrder.getId());
|
||||
}
|
||||
}
|
||||
|
||||
private static void testElementMaps(StrolchAgent agent) {
|
||||
|
||||
ComponentContainer container = agent.getContainer();
|
||||
|
||||
try (StrolchTransaction tx = container.getDefaultRealm().openTx()) {
|
||||
ResourceMap resourceMap = tx.getResourceMap();
|
||||
resourceMap.add(tx, ModelGenerator.createResource("@testRes1", "Test Res", "Test"));
|
||||
Resource queriedRes = resourceMap.getBy(tx, "Test", "@testRes1");
|
||||
assertNotNull(queriedRes);
|
||||
assertEquals("@testRes1", queriedRes.getId());
|
||||
}
|
||||
|
||||
try (StrolchTransaction tx = container.getDefaultRealm().openTx()) {
|
||||
OrderMap orderMap = tx.getOrderMap();
|
||||
orderMap.add(tx, ModelGenerator.createOrder("@testOrder1", "Test Order", "Test"));
|
||||
Order queriedOrder = orderMap.getBy(tx, "Test", "@testOrder1");
|
||||
assertNotNull(queriedOrder);
|
||||
assertEquals("@testOrder1", queriedOrder.getId());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ import li.strolch.agent.api.StrolchComponent;
|
|||
import li.strolch.agent.impl.ComponentContainerImpl;
|
||||
import li.strolch.agent.impl.ComponentController;
|
||||
import li.strolch.agent.impl.ComponentDependencyAnalyzer;
|
||||
import li.strolch.agent.impl.DataStoreMode;
|
||||
import li.strolch.runtime.configuration.ConfigurationParser;
|
||||
import li.strolch.runtime.configuration.StrolchConfiguration;
|
||||
import li.strolch.runtime.configuration.StrolchConfigurationException;
|
||||
|
@ -110,7 +111,7 @@ public class ControllerDependencyTest {
|
|||
@Before
|
||||
public void setupModel() {
|
||||
|
||||
this.container = new ComponentContainerImpl(null);
|
||||
this.container = new ComponentContainerImpl(null, DataStoreMode.EMPTY);
|
||||
|
||||
this.con2 = new ComponentController(new StrolchComponent(this.container, "2"));
|
||||
this.con5 = new ComponentController(new StrolchComponent(this.container, "5"));
|
||||
|
@ -539,7 +540,7 @@ public class ControllerDependencyTest {
|
|||
@Test
|
||||
public void shouldAddDepedencies() {
|
||||
|
||||
ComponentContainerImpl container = new ComponentContainerImpl(null);
|
||||
ComponentContainerImpl container = new ComponentContainerImpl(null, DataStoreMode.EMPTY);
|
||||
StrolchComponent component = new StrolchComponent(container, "1"); //$NON-NLS-1$
|
||||
ComponentController controller = new ComponentController(component);
|
||||
|
||||
|
|
|
@ -77,7 +77,7 @@ public class QueryTest {
|
|||
InMemoryQuery<Resource> inMemoryQuery = resourceQuery.visit(query);
|
||||
List<Resource> result;
|
||||
try (StrolchTransaction tx = container.getDefaultRealm().openTx()) {
|
||||
result = inMemoryQuery.doQuery(tx.getResourceDao());
|
||||
result = inMemoryQuery.doQuery(tx.getPersistenceHandler().getResourceDao(tx));
|
||||
}
|
||||
assertEquals(1, result.size());
|
||||
assertEquals("@1", result.get(0).getId());
|
||||
|
@ -108,7 +108,7 @@ public class QueryTest {
|
|||
InMemoryQuery<Order> inMemoryQuery = orderQuery.visit(query);
|
||||
List<Order> result;
|
||||
try (StrolchTransaction tx = container.getDefaultRealm().openTx()) {
|
||||
result = inMemoryQuery.doQuery(tx.getOrderDao());
|
||||
result = inMemoryQuery.doQuery(tx.getPersistenceHandler().getOrderDao(tx));
|
||||
}
|
||||
assertEquals(1, result.size());
|
||||
assertEquals("@1", result.get(0).getId());
|
||||
|
|
Loading…
Reference in New Issue