[New] basic implementation of Order and Resource DAOs implemented

Including tests for both DAOs. Only for DOM. SAX is not yet supported!
This commit is contained in:
Robert von Burg 2013-10-24 21:49:56 +02:00
parent 081937d453
commit 9ad71317f7
14 changed files with 445 additions and 18 deletions

View File

@ -50,6 +50,12 @@
<artifactId>ch.eitchnet.xmlpers</artifactId>
</dependency>
<dependency>
<groupId>li.strolch</groupId>
<artifactId>li.strolch.testbase</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>

View File

@ -1,19 +1,18 @@
package li.strolch.persistence.impl;
import li.strolch.model.Order;
import li.strolch.model.Tags;
import li.strolch.persistence.api.OrderDao;
import li.strolch.persistence.api.StrolchTransaction;
public class XmlOrderDao extends AbstractDao<Order> implements OrderDao {
private static final String CLASS_TYPE = Order.class.getName();
protected XmlOrderDao(StrolchTransaction tx) {
super(tx);
}
@Override
protected String getClassType() {
return CLASS_TYPE;
return Tags.ORDER;
}
}

View File

@ -23,10 +23,18 @@ package li.strolch.persistence.impl;
import java.util.Properties;
import li.strolch.model.Order;
import li.strolch.model.Resource;
import li.strolch.model.Tags;
import li.strolch.persistence.api.OrderDao;
import li.strolch.persistence.api.ResourceDao;
import li.strolch.persistence.api.StrolchPersistenceHandler;
import li.strolch.persistence.api.StrolchTransaction;
import li.strolch.persistence.impl.model.OrderContextFactory;
import li.strolch.persistence.impl.model.ResourceContextFactory;
import li.strolch.runtime.ComponentConfiguration;
import ch.eitchnet.xmlpers.api.IoMode;
import ch.eitchnet.xmlpers.api.PersistenceConstants;
import ch.eitchnet.xmlpers.api.PersistenceManager;
import ch.eitchnet.xmlpers.api.PersistenceManagerLoader;
import ch.eitchnet.xmlpers.api.PersistenceTransaction;
@ -35,20 +43,35 @@ import ch.eitchnet.xmlpers.api.PersistenceTransaction;
* @author Robert von Burg <eitch@eitchnet.ch>
*
*/
public class StrolchPersistenceHandlerImpl implements StrolchPersistenceHandler {
public class XmlPersistenceHandler implements StrolchPersistenceHandler {
public static final String DB_STORE_PATH = "dbStore/"; //$NON-NLS-1$
private PersistenceManager persistenceManager;
public void initialize() {
public void initialize(ComponentConfiguration componentConfiguration) {
String basePath = componentConfiguration.getRuntimeConfiguration().getRootPath();
basePath = basePath + DB_STORE_PATH;
Properties properties = new Properties();
properties.setProperty(PersistenceConstants.PROP_VERBOSE, "true"); //$NON-NLS-1$
properties.setProperty(PersistenceConstants.PROP_XML_IO_MOD, IoMode.DOM.name());
properties.setProperty(PersistenceConstants.PROP_BASEPATH, basePath);
this.persistenceManager = PersistenceManagerLoader.load(properties);
this.persistenceManager.getCtxFactory().registerPersistenceContextFactory(Resource.class, Tags.RESOURCE,
new ResourceContextFactory());
this.persistenceManager.getCtxFactory().registerPersistenceContextFactory(Order.class, Tags.ORDER,
new OrderContextFactory());
}
public StrolchTransaction openTx() {
return openTx(PersistenceManager.DEFAULT_REALM);
}
@SuppressWarnings("resource") // caller must close
@SuppressWarnings("resource")
// caller must close
public StrolchTransaction openTx(String realm) {
PersistenceTransaction tx = this.persistenceManager.openTx(realm);
XmlStrolchTransaction strolchTx = new XmlStrolchTransaction(tx);
@ -64,5 +87,4 @@ public class StrolchPersistenceHandlerImpl implements StrolchPersistenceHandler
public ResourceDao getResourceDao(StrolchTransaction tx) {
return new XmlResourceDao(tx);
}
}

View File

@ -1,19 +1,18 @@
package li.strolch.persistence.impl;
import li.strolch.model.Resource;
import li.strolch.model.Tags;
import li.strolch.persistence.api.ResourceDao;
import li.strolch.persistence.api.StrolchTransaction;
public class XmlResourceDao extends AbstractDao<Resource> implements ResourceDao {
private static final String CLASS_TYPE = Resource.class.getName();
protected XmlResourceDao(StrolchTransaction tx) {
super(tx);
}
@Override
protected String getClassType() {
return CLASS_TYPE;
return Tags.RESOURCE;
}
}

View File

@ -12,6 +12,7 @@ public class XmlStrolchTransaction implements StrolchTransaction {
public XmlStrolchTransaction(PersistenceTransaction tx) {
this.tx = tx;
this.closeStrategy = TransactionCloseStrategy.COMMIT;
}
PersistenceTransaction getTx() {

View File

@ -0,0 +1,26 @@
package li.strolch.persistence.impl.model;
import li.strolch.model.Order;
import li.strolch.model.Tags;
import ch.eitchnet.xmlpers.api.PersistenceContext;
import ch.eitchnet.xmlpers.api.PersistenceContextFactory;
import ch.eitchnet.xmlpers.objref.IdOfSubTypeRef;
import ch.eitchnet.xmlpers.objref.ObjectRef;
import ch.eitchnet.xmlpers.objref.ObjectReferenceCache;
public class OrderContextFactory implements PersistenceContextFactory<Order> {
@Override
public PersistenceContext<Order> createCtx(ObjectRef objectRef) {
PersistenceContext<Order> ctx = new PersistenceContext<>(objectRef);
ctx.setParserFactory(new OrderParserFactory());
return ctx;
}
@Override
public PersistenceContext<Order> createCtx(ObjectReferenceCache objectRefCache, Order t) {
IdOfSubTypeRef objectRef = objectRefCache.getIdOfSubTypeRef(Tags.ORDER, t.getType(), t.getId());
return createCtx(objectRef);
}
}

View File

@ -0,0 +1,47 @@
package li.strolch.persistence.impl.model;
import javax.xml.parsers.DocumentBuilder;
import li.strolch.model.Order;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import ch.eitchnet.xmlpers.api.DomParser;
import ch.eitchnet.xmlpers.util.DomUtil;
public class OrderDomParser implements DomParser<Order> {
private Order order;
@Override
public Order getObject() {
return this.order;
}
@Override
public void setObject(Order object) {
this.order = object;
}
@Override
public Document toDom() {
DocumentBuilder documentBuilder = DomUtil.createDocumentBuilder();
Document document = documentBuilder.getDOMImplementation().createDocument(null, null, null);
Element orderDom = this.order.toDom(document);
document.appendChild(orderDom);
return document;
}
@Override
public void fromDom(Document document) {
Element rootElement = document.getDocumentElement();
Order order = new Order(rootElement);
this.order = order;
}
}

View File

@ -0,0 +1,19 @@
package li.strolch.persistence.impl.model;
import li.strolch.model.Order;
import ch.eitchnet.xmlpers.api.DomParser;
import ch.eitchnet.xmlpers.api.ParserFactory;
import ch.eitchnet.xmlpers.api.SaxParser;
public class OrderParserFactory implements ParserFactory<Order> {
@Override
public DomParser<Order> getDomParser() {
return new OrderDomParser();
}
@Override
public SaxParser<Order> getSaxParser() {
throw new UnsupportedOperationException("Not yet implemented!"); //$NON-NLS-1$
}
}

View File

@ -0,0 +1,25 @@
package li.strolch.persistence.impl.model;
import li.strolch.model.Resource;
import li.strolch.model.Tags;
import ch.eitchnet.xmlpers.api.PersistenceContext;
import ch.eitchnet.xmlpers.api.PersistenceContextFactory;
import ch.eitchnet.xmlpers.objref.IdOfSubTypeRef;
import ch.eitchnet.xmlpers.objref.ObjectRef;
import ch.eitchnet.xmlpers.objref.ObjectReferenceCache;
public class ResourceContextFactory implements PersistenceContextFactory<Resource> {
@Override
public PersistenceContext<Resource> createCtx(ObjectRef objectRef) {
PersistenceContext<Resource> ctx = new PersistenceContext<>(objectRef);
ctx.setParserFactory(new ResourceParserFactory());
return ctx;
}
@Override
public PersistenceContext<Resource> createCtx(ObjectReferenceCache objectRefCache, Resource t) {
IdOfSubTypeRef objectRef = objectRefCache.getIdOfSubTypeRef(Tags.RESOURCE, t.getType(), t.getId());
return createCtx(objectRef);
}
}

View File

@ -0,0 +1,67 @@
/*
* Copyright (c) 2012, Robert von Burg
*
* All rights reserved.
*
* This file is part of the XXX.
*
* XXX is free software: you can redistribute
* it and/or modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the License,
* or (at your option) any later version.
*
* XXX is distributed in the hope that it will
* be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with XXX. If not, see
* <http://www.gnu.org/licenses/>.
*/
package li.strolch.persistence.impl.model;
import javax.xml.parsers.DocumentBuilder;
import li.strolch.model.Resource;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import ch.eitchnet.xmlpers.api.DomParser;
import ch.eitchnet.xmlpers.util.DomUtil;
public class ResourceDomParser implements DomParser<Resource> {
private Resource resource;
@Override
public Resource getObject() {
return this.resource;
}
@Override
public void setObject(Resource resource) {
this.resource = resource;
}
@Override
public Document toDom() {
DocumentBuilder documentBuilder = DomUtil.createDocumentBuilder();
Document document = documentBuilder.getDOMImplementation().createDocument(null, null, null);
Element resourceDom = this.resource.toDom(document);
document.appendChild(resourceDom);
return document;
}
@Override
public void fromDom(Document document) {
Element rootElement = document.getDocumentElement();
Resource resource = new Resource(rootElement);
this.resource = resource;
}
}

View File

@ -0,0 +1,40 @@
/*
* Copyright (c) 2012, Robert von Burg
*
* All rights reserved.
*
* This file is part of the XXX.
*
* XXX is free software: you can redistribute
* it and/or modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the License,
* or (at your option) any later version.
*
* XXX is distributed in the hope that it will
* be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with XXX. If not, see
* <http://www.gnu.org/licenses/>.
*/
package li.strolch.persistence.impl.model;
import li.strolch.model.Resource;
import ch.eitchnet.xmlpers.api.DomParser;
import ch.eitchnet.xmlpers.api.ParserFactory;
import ch.eitchnet.xmlpers.api.SaxParser;
public class ResourceParserFactory implements ParserFactory<Resource> {
@Override
public DomParser<Resource> getDomParser() {
return new ResourceDomParser();
}
@Override
public SaxParser<Resource> getSaxParser() {
throw new UnsupportedOperationException("Not yet implemented!"); //$NON-NLS-1$
}
}

View File

@ -21,11 +21,66 @@
*/
package li.strolch.persistence.impl.dao.test;
import java.io.File;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;
import li.strolch.persistence.api.StrolchPersistenceHandler;
import li.strolch.persistence.impl.XmlPersistenceHandler;
import li.strolch.runtime.ComponentConfiguration;
import li.strolch.runtime.RuntimeConfiguration;
import org.junit.BeforeClass;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ch.eitchnet.utils.helper.FileHelper;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*
*
*/
public class AbstractDaoImplTest {
public abstract class AbstractDaoImplTest {
private static final String RUNTIME_PATH = "target/strolchRuntime/"; //$NON-NLS-1$
protected static final Logger logger = LoggerFactory.getLogger(AbstractDaoImplTest.class);
protected static XmlPersistenceHandler persistenceHandler;
@BeforeClass
public static void beforeClass() {
File file = new File(RUNTIME_PATH);
if (file.exists()) {
if (!FileHelper.deleteFile(file, true)) {
String msg = "Failed to delete {0}"; //$NON-NLS-1$
msg = MessageFormat.format(msg, file.getAbsolutePath());
throw new RuntimeException(msg);
}
}
file = new File(file, XmlPersistenceHandler.DB_STORE_PATH);
if (!file.mkdirs()) {
String msg = "Failed to create path {0}"; //$NON-NLS-1$
msg = MessageFormat.format(msg, file.getAbsolutePath());
throw new RuntimeException(msg);
}
// initialize a runtime configuration
Map<String, String> runtimeConfigurationValues = new HashMap<>();
String rootPath = RUNTIME_PATH;
RuntimeConfiguration runtimeConfiguration = new RuntimeConfiguration(runtimeConfigurationValues, rootPath);
// initialize the component configuration
String componentName = StrolchPersistenceHandler.class.getName();
Map<String, String> configurationValues = new HashMap<>();
ComponentConfiguration componentConfiguration = new ComponentConfiguration(runtimeConfiguration, componentName,
configurationValues);
persistenceHandler = new XmlPersistenceHandler();
persistenceHandler.initialize(componentConfiguration);
}
}

View File

@ -1,14 +1,68 @@
package li.strolch.persistence.impl.dao.test;
import static org.junit.Assert.*;
import static li.strolch.testbase.model.ModelBuilder.BAG_ID;
import static li.strolch.testbase.model.ModelBuilder.PARAM_STRING_ID;
import static li.strolch.testbase.model.ModelBuilder.createOrder;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import li.strolch.model.Order;
import li.strolch.model.State;
import li.strolch.model.parameter.Parameter;
import li.strolch.persistence.api.StrolchTransaction;
import org.junit.Test;
public class XmlOrderDaoTest {
public class XmlOrderDaoTest extends AbstractDaoImplTest {
private static final String ID = "@testOrder"; //$NON-NLS-1$
private static final String NAME = "Test Order"; //$NON-NLS-1$
private static final String TYPE = "ToStock"; //$NON-NLS-1$
@Test
public void test() {
fail("Not yet implemented");
}
public void shouldCrud() {
// create
Order newOrder = createOrder(ID, NAME, TYPE, System.currentTimeMillis(), State.CREATED);
try (StrolchTransaction tx = persistenceHandler.openTx();) {
persistenceHandler.getOrderDao(tx).save(newOrder);
}
// read
Order readOrder = null;
try (StrolchTransaction tx = persistenceHandler.openTx();) {
readOrder = persistenceHandler.getOrderDao(tx).queryBy(TYPE, ID);
}
assertNotNull("Should read Order with id " + ID, readOrder); //$NON-NLS-1$
// update
Parameter<String> sParam = readOrder.getParameter(BAG_ID, PARAM_STRING_ID);
String newStringValue = "Giddiya!"; //$NON-NLS-1$
sParam.setValue(newStringValue);
try (StrolchTransaction tx = persistenceHandler.openTx();) {
persistenceHandler.getOrderDao(tx).update(readOrder);
}
// read updated
Order updatedOrder = null;
try (StrolchTransaction tx = persistenceHandler.openTx();) {
updatedOrder = persistenceHandler.getOrderDao(tx).queryBy(TYPE, ID);
}
assertNotNull("Should read Order with id " + ID, updatedOrder); //$NON-NLS-1$
assertFalse("Objects can't be the same reference after re-reading!", readOrder == updatedOrder); //$NON-NLS-1$
Parameter<String> updatedParam = readOrder.getParameter(BAG_ID, PARAM_STRING_ID);
assertEquals(newStringValue, updatedParam.getValue());
// delete
try (StrolchTransaction tx = persistenceHandler.openTx();) {
persistenceHandler.getOrderDao(tx).remove(readOrder);
}
// fail to re-read
try (StrolchTransaction tx = persistenceHandler.openTx();) {
Order order = persistenceHandler.getOrderDao(tx).queryBy(TYPE, ID);
assertNull("Should no read Order with id " + ID, order); //$NON-NLS-1$
}
}
}

View File

@ -0,0 +1,67 @@
package li.strolch.persistence.impl.dao.test;
import static li.strolch.testbase.model.ModelBuilder.BAG_ID;
import static li.strolch.testbase.model.ModelBuilder.PARAM_STRING_ID;
import static li.strolch.testbase.model.ModelBuilder.createResource;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import li.strolch.model.Resource;
import li.strolch.model.parameter.Parameter;
import li.strolch.persistence.api.StrolchTransaction;
import org.junit.Test;
public class XmlResourceDaoTest extends AbstractDaoImplTest {
private static final String ID = "@testResource"; //$NON-NLS-1$
private static final String NAME = "Test Resource"; //$NON-NLS-1$
private static final String TYPE = "Box"; //$NON-NLS-1$
@Test
public void shouldCrud() {
// create
Resource newResource = createResource(ID, NAME, TYPE);
try (StrolchTransaction tx = persistenceHandler.openTx();) {
persistenceHandler.getResourceDao(tx).save(newResource);
}
// read
Resource readResource = null;
try (StrolchTransaction tx = persistenceHandler.openTx();) {
readResource = persistenceHandler.getResourceDao(tx).queryBy(TYPE, ID);
}
assertNotNull("Should read Resource with id " + ID, readResource); //$NON-NLS-1$
// update
Parameter<String> sParam = readResource.getParameter(BAG_ID, PARAM_STRING_ID);
String newStringValue = "Giddiya!"; //$NON-NLS-1$
sParam.setValue(newStringValue);
try (StrolchTransaction tx = persistenceHandler.openTx();) {
persistenceHandler.getResourceDao(tx).update(readResource);
}
// read updated
Resource updatedResource = null;
try (StrolchTransaction tx = persistenceHandler.openTx();) {
updatedResource = persistenceHandler.getResourceDao(tx).queryBy(TYPE, ID);
}
assertNotNull("Should read Resource with id " + ID, updatedResource); //$NON-NLS-1$
assertFalse("Objects can't be the same reference after re-reading!", readResource == updatedResource); //$NON-NLS-1$
Parameter<String> updatedParam = readResource.getParameter(BAG_ID, PARAM_STRING_ID);
assertEquals(newStringValue, updatedParam.getValue());
// delete
try (StrolchTransaction tx = persistenceHandler.openTx();) {
persistenceHandler.getResourceDao(tx).remove(readResource);
}
// fail to re-read
try (StrolchTransaction tx = persistenceHandler.openTx();) {
Resource resource = persistenceHandler.getResourceDao(tx).queryBy(TYPE, ID);
assertNull("Should no read Resource with id " + ID, resource); //$NON-NLS-1$
}
}
}