[Major] (Re-)Implemented XML Persistence

This commit is contained in:
Robert von Burg 2018-02-27 09:00:26 +01:00
parent 0575ee1795
commit 315879ebe1
89 changed files with 1297 additions and 3534 deletions

View File

@ -1,12 +1,12 @@
/*
* 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.
@ -118,8 +118,10 @@ public class CachedRealm extends InternalStrolchRealm {
try (StrolchTransaction tx = openTx(privilegeContext.getCertificate(), "strolch_boot")) {
ResourceDao resourceDao = tx.getPersistenceHandler().getResourceDao(tx);
logger.info("Reading " + resourceDao.querySize() + " Resources from DB...");
Set<String> resourceTypes = resourceDao.queryTypes();
for (String type : resourceTypes) {
logger.info("Reading " + resourceDao.querySize(type) + " Resources of type " + type + " from DB...");
List<Resource> resources = resourceDao.queryAll(type);
for (Resource resource : resources) {
this.resourceMap.insert(resource);
@ -132,8 +134,10 @@ public class CachedRealm extends InternalStrolchRealm {
try (StrolchTransaction tx = openTx(privilegeContext.getCertificate(), "strolch_boot")) {
OrderDao orderDao = tx.getPersistenceHandler().getOrderDao(tx);
logger.info("Reading " + orderDao.querySize() + " Orders from DB...");
Set<String> orderTypes = orderDao.queryTypes();
for (String type : orderTypes) {
logger.info("Reading " + orderDao.querySize(type) + " Orders of type " + type + " from DB...");
List<Order> orders = orderDao.queryAll(type);
for (Order order : orders) {
this.orderMap.insert(order);
@ -146,8 +150,10 @@ public class CachedRealm extends InternalStrolchRealm {
try (StrolchTransaction tx = openTx(privilegeContext.getCertificate(), "strolch_boot")) {
ActivityDao activityDao = tx.getPersistenceHandler().getActivityDao(tx);
logger.info("Reading " + activityDao.querySize() + " Activities from DB...");
Set<String> activityTypes = activityDao.queryTypes();
for (String type : activityTypes) {
logger.info("Reading " + activityDao.querySize(type) + " Activities of type " + type + " from DB...");
List<Activity> activities = activityDao.queryAll(type);
for (Activity activity : activities) {
this.activityMap.insert(activity);
@ -160,7 +166,8 @@ public class CachedRealm extends InternalStrolchRealm {
long duration = System.nanoTime() - start;
String durationS = StringHelper.formatNanoDuration(duration);
logger.info(MessageFormat.format("Loading Model from Database for realm {0} took {1}.", getRealm(), durationS)); //$NON-NLS-1$
logger.info(MessageFormat
.format("Loading Model from Database for realm {0} took {1}.", getRealm(), durationS)); //$NON-NLS-1$
logger.info(MessageFormat.format("Loaded {0} Orders", nrOfOrders)); //$NON-NLS-1$
logger.info(MessageFormat.format("Loaded {0} Resources", nrOfResources)); //$NON-NLS-1$
logger.info(MessageFormat.format("Loaded {0} Activities", nrOfActivities)); //$NON-NLS-1$

View File

@ -15,15 +15,12 @@
*/
package li.strolch.persistence.api;
import java.util.List;
import li.strolch.model.activity.Activity;
import li.strolch.model.query.ActivityQuery;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*/
public interface ActivityDao extends StrolchDao<Activity> {
public <U> List<U> doQuery(ActivityQuery<U> query);
// marker interface
}

View File

@ -15,15 +15,12 @@
*/
package li.strolch.persistence.api;
import java.util.List;
import li.strolch.model.Order;
import li.strolch.model.query.OrderQuery;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*/
public interface OrderDao extends StrolchDao<Order> {
public <U> List<U> doQuery(OrderQuery<U> query);
// marker interface
}

View File

@ -93,9 +93,4 @@ public interface PersistenceHandler {
* @return the {@link AuditDao}
*/
public AuditDao getAuditDao(StrolchTransaction tx);
/**
* Performs a database specific initialization of the underlying database for each realm.
*/
public void performDbInitialization();
}

View File

@ -15,15 +15,12 @@
*/
package li.strolch.persistence.api;
import java.util.List;
import li.strolch.model.Resource;
import li.strolch.model.query.ResourceQuery;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*/
public interface ResourceDao extends StrolchDao<Resource> {
public <U> List<U> doQuery(ResourceQuery<U> query);
// marker interface
}

View File

@ -39,6 +39,20 @@ import li.strolch.model.StrolchRootElement;
*/
public interface StrolchDao<T extends StrolchRootElement> {
/**
* Returns the number of elements in the underlying persistence layer, regardless of type
*
* @return the number of elements in the underlying persistence layer
*/
public long querySize();
/**
* Returns the number of elements in the underlying persistence layer for the given type
*
* @return the number of elements in the underlying persistence layer for the given type
*/
public long querySize(String type);
/**
* Queries the current list of types from the underlying persistence layer
*

View File

@ -15,12 +15,10 @@
*/
package li.strolch.runtime.configuration;
import static li.strolch.db.DbConstants.PROP_DB_IGNORE_REALM;
import static li.strolch.db.DbConstants.PROP_DB_PASSWORD;
import static li.strolch.db.DbConstants.PROP_DB_URL;
import static li.strolch.db.DbConstants.PROP_DB_USERNAME;
import static li.strolch.db.DbConstants.*;
import static li.strolch.runtime.StrolchConstants.makeRealmKey;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.HashMap;
@ -28,15 +26,12 @@ import java.util.Map;
import java.util.Properties;
import java.util.Set;
import javax.sql.DataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import li.strolch.agent.api.ComponentContainer;
import li.strolch.agent.api.StrolchRealm;
import li.strolch.persistence.api.StrolchPersistenceException;
import li.strolch.runtime.StrolchConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
@ -50,10 +45,6 @@ public abstract class DbConnectionBuilder {
private ComponentContainer container;
private ComponentConfiguration configuration;
/**
* @param container
* @param persistenceHandlerConfiguration
*/
public DbConnectionBuilder(ComponentContainer container, ComponentConfiguration persistenceHandlerConfiguration) {
this.container = container;
this.configuration = persistenceHandlerConfiguration;

View File

@ -1,12 +1,12 @@
/*
* 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.
@ -15,6 +15,13 @@
*/
package li.strolch.model.audit;
import java.text.MessageFormat;
import java.util.function.Consumer;
import li.strolch.model.Tags;
import li.strolch.utils.iso8601.ISO8601FormatFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
/**
@ -22,4 +29,113 @@ import org.xml.sax.helpers.DefaultHandler;
*/
public class AuditSaxReader extends DefaultHandler {
private final Consumer<Audit> auditConsumer;
private Audit currentAudit;
private StringBuilder sb = new StringBuilder();
public AuditSaxReader(Consumer<Audit> auditConsumer) {
this.auditConsumer = auditConsumer;
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
switch (qName) {
case Tags.AUDIT:
this.currentAudit = new Audit();
this.currentAudit.setId(Long.valueOf(attributes.getValue(Tags.Audit.ID)));
break;
case Tags.Audit.USERNAME:
case Tags.Audit.FIRSTNAME:
case Tags.Audit.LASTNAME:
case Tags.Audit.DATE:
case Tags.Audit.ELEMENT_TYPE:
case Tags.Audit.ELEMENT_SUB_TYPE:
case Tags.Audit.ELEMENT_ACCESSED:
case Tags.Audit.NEW_VERSION:
case Tags.Audit.ACTION:
case Tags.Audit.ACCESS_TYPE:
this.sb = new StringBuilder();
break;
default:
throw new IllegalArgumentException(
MessageFormat.format("The element ''{0}'' is unhandled!", qName)); //$NON-NLS-1$
}
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
switch (qName) {
case Tags.AUDIT:
this.auditConsumer.accept(this.currentAudit);
this.currentAudit = null;
break;
case Tags.Audit.USERNAME:
this.currentAudit.setUsername(this.sb.toString());
this.sb = null;
break;
case Tags.Audit.FIRSTNAME:
this.currentAudit.setFirstname(this.sb.toString());
this.sb = null;
break;
case Tags.Audit.LASTNAME:
this.currentAudit.setLastname(this.sb.toString());
this.sb = null;
break;
case Tags.Audit.DATE:
this.currentAudit.setDate(ISO8601FormatFactory.getInstance().parseDate(this.sb.toString()));
this.sb = null;
break;
case Tags.Audit.ELEMENT_TYPE:
this.currentAudit.setElementType(this.sb.toString());
this.sb = null;
break;
case Tags.Audit.ELEMENT_SUB_TYPE:
this.currentAudit.setElementSubType(this.sb.toString());
this.sb = null;
break;
case Tags.Audit.ELEMENT_ACCESSED:
this.currentAudit.setElementAccessed(this.sb.toString());
this.sb = null;
break;
case Tags.Audit.NEW_VERSION:
this.currentAudit.setNewVersion(ISO8601FormatFactory.getInstance().parseDate(this.sb.toString()));
this.sb = null;
break;
case Tags.Audit.ACTION:
this.currentAudit.setAction(this.sb.toString());
this.sb = null;
break;
case Tags.Audit.ACCESS_TYPE:
this.currentAudit.setAccessType(AccessType.valueOf(this.sb.toString()));
this.sb = null;
break;
default:
throw new IllegalArgumentException(
MessageFormat.format("The element ''{0}'' is unhandled!", qName)); //$NON-NLS-1$
}
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
if (this.sb != null)
this.sb.append(ch, start, length);
}
}

View File

@ -39,8 +39,8 @@ public class AuditToDomVisitor implements AuditVisitor<Document> {
auditE.appendChild(elem(doc, Tags.Audit.USERNAME, audit.getUsername()));
auditE.appendChild(elem(doc, Tags.Audit.FIRSTNAME, audit.getUsername()));
auditE.appendChild(elem(doc, Tags.Audit.LASTNAME, audit.getUsername()));
auditE.appendChild(elem(doc, Tags.Audit.FIRSTNAME, audit.getFirstname()));
auditE.appendChild(elem(doc, Tags.Audit.LASTNAME, audit.getLastname()));
auditE.appendChild(elem(doc, Tags.Audit.DATE, ISO8601FormatFactory.getInstance().formatDate(audit.getDate())));
auditE.appendChild(elem(doc, Tags.Audit.ELEMENT_TYPE, audit.getElementType()));

View File

@ -0,0 +1,67 @@
package li.strolch.model.audit;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import java.text.MessageFormat;
import li.strolch.exception.StrolchException;
import li.strolch.model.Tags;
import li.strolch.utils.helper.StringHelper;
import li.strolch.utils.iso8601.ISO8601FormatFactory;
public class AuditToSaxWriterVisitor implements AuditVisitor<Void> {
protected XMLStreamWriter writer;
public AuditToSaxWriterVisitor(XMLStreamWriter writer) {
this.writer = writer;
}
@Override
public Void visitAudit(Audit audit) {
try {
writeElement(audit);
this.writer.flush();
} catch (XMLStreamException e) {
String msg = "Failed to write Audit {0} due to {1}"; //$NON-NLS-1$
msg = MessageFormat.format(msg, audit.getId(), e.getMessage());
throw new StrolchException(msg, e);
}
return null;
}
private void writeElement(Audit audit) throws XMLStreamException {
this.writer.writeStartElement(Tags.AUDIT);
this.writer.writeAttribute(Tags.Audit.ID, audit.getId().toString());
writeElem(Tags.Audit.USERNAME, audit.getUsername());
writeElem(Tags.Audit.FIRSTNAME, audit.getFirstname());
writeElem(Tags.Audit.LASTNAME, audit.getLastname());
writeElem(Tags.Audit.DATE, ISO8601FormatFactory.getInstance().formatDate(audit.getDate()));
writeElem(Tags.Audit.ELEMENT_TYPE, audit.getElementType());
writeElem(Tags.Audit.ELEMENT_SUB_TYPE, audit.getElementSubType());
writeElem(Tags.Audit.ELEMENT_ACCESSED, audit.getElementAccessed());
if (audit.getNewVersion() != null)
writeElem(Tags.Audit.NEW_VERSION, ISO8601FormatFactory.getInstance().formatDate(audit.getNewVersion()));
writeElem(Tags.Audit.ACTION, audit.getAction());
writeElem(Tags.Audit.ACCESS_TYPE, audit.getAccessType().name());
this.writer.writeEndElement();
}
private void writeElem(String tag, String text) throws XMLStreamException {
if (StringHelper.isEmpty(text))
return;
this.writer.writeStartElement(tag);
this.writer.writeCharacters(text);
this.writer.writeEndElement();
}
}

View File

@ -1,12 +1,12 @@
/*
* 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.
@ -18,29 +18,14 @@ package li.strolch.model.xml;
import static li.strolch.model.StrolchModelConstants.INTERPRETATION_NONE;
import static li.strolch.model.StrolchModelConstants.UOM_NONE;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import java.text.MessageFormat;
import java.util.*;
import java.util.Map.Entry;
import li.strolch.exception.StrolchException;
import li.strolch.model.GroupedParameterizedElement;
import li.strolch.model.Order;
import li.strolch.model.ParameterBag;
import li.strolch.model.ParameterizedElement;
import li.strolch.model.Resource;
import li.strolch.model.StrolchElement;
import li.strolch.model.StrolchRootElement;
import li.strolch.model.Tags;
import li.strolch.model.Version;
import li.strolch.model.*;
import li.strolch.model.activity.Action;
import li.strolch.model.activity.Activity;
import li.strolch.model.activity.IActivityElement;
@ -154,8 +139,8 @@ public class StrolchElementToSaxWriterVisitor implements StrolchRootElementVisit
}
protected void writeElement(Activity activity) throws XMLStreamException {
boolean empty = activity.hasVersion() && !activity.hasParameterBags() && !activity.hasElements()
&& !activity.hasPolicyDefs();
boolean empty = activity.hasVersion() && !activity.hasParameterBags() && !activity.hasElements() && !activity
.hasPolicyDefs();
writeStartStrolchElement(Tags.ACTIVITY, empty, activity);
this.writer.writeAttribute(Tags.TIME_ORDERING, activity.getTimeOrdering().getName());
@ -191,8 +176,8 @@ public class StrolchElementToSaxWriterVisitor implements StrolchRootElementVisit
Version version = rootElement.getVersion();
this.writer.writeAttribute(Tags.VERSION, Integer.toString(version.getVersion()));
this.writer.writeAttribute(Tags.CREATED_BY, version.getCreatedBy());
this.writer.writeAttribute(Tags.CREATED_AT,
ISO8601FormatFactory.getInstance().formatDate(version.getCreatedAt()));
this.writer
.writeAttribute(Tags.CREATED_AT, ISO8601FormatFactory.getInstance().formatDate(version.getCreatedAt()));
this.writer.writeAttribute(Tags.DELETED, Boolean.toString(version.isDeleted()));
}
@ -261,8 +246,8 @@ public class StrolchElementToSaxWriterVisitor implements StrolchRootElementVisit
for (ITimeValue<IValue<?>> timeValue : values) {
this.writer.writeEmptyElement(Tags.VALUE);
this.writer.writeAttribute(Tags.TIME,
ISO8601FormatFactory.getInstance().formatDate(timeValue.getTime()));
this.writer
.writeAttribute(Tags.TIME, ISO8601FormatFactory.getInstance().formatDate(timeValue.getTime()));
this.writer.writeAttribute(Tags.VALUE, timeValue.getValue().getValueAsString());
}
@ -299,7 +284,7 @@ public class StrolchElementToSaxWriterVisitor implements StrolchRootElementVisit
protected void writeParameters(ParameterizedElement element) throws XMLStreamException {
List<Parameter<?>> parameters = new ArrayList<>(element.getParameters());
Collections.sort(parameters, (o1, o2) -> Integer.valueOf(o1.getIndex()).compareTo(o2.getIndex()));
parameters.sort(Comparator.comparingInt(Parameter::getIndex));
for (Parameter<?> parameter : parameters) {
writeStartStrolchElement(Tags.PARAMETER, true, parameter);

View File

@ -15,19 +15,17 @@
*/
package li.strolch.model.xml;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.IOException;
import java.io.InputStream;
import java.text.MessageFormat;
import java.util.Date;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import li.strolch.exception.StrolchException;
import li.strolch.model.Tags;
import li.strolch.utils.helper.StringHelper;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
@ -38,10 +36,6 @@ public class XmlModelSaxStreamReader extends XmlModelSaxReader {
private InputStream stream;
/**
* @param listener
* @param stream
*/
public XmlModelSaxStreamReader(StrolchElementListener listener, InputStream stream) {
super(listener);
this.stream = stream;

View File

@ -1,12 +1,12 @@
/*
* Copyright 2015 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.
@ -21,15 +21,15 @@ import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.sax.SAXResult;
import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.SQLXML;
import java.sql.Timestamp;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import li.strolch.model.Tags;
import li.strolch.model.activity.Activity;
import li.strolch.model.query.ActivityQuery;
import li.strolch.model.xml.SimpleStrolchElementListener;
import li.strolch.model.xml.StrolchElementToSaxVisitor;
import li.strolch.model.xml.XmlModelSaxReader;
@ -129,8 +129,9 @@ public class PostgreSqlActivityDao extends PostgresqlDao<Activity> implements Ac
}
} catch (SQLException | SAXException e) {
throw new StrolchPersistenceException(MessageFormat.format("Failed to insert Activity {0} due to {1}",
activity.getLocator(), e.getLocalizedMessage()), e);
throw new StrolchPersistenceException(MessageFormat
.format("Failed to insert Activity {0} due to {1}", activity.getLocator(), e.getLocalizedMessage()),
e);
}
if (activity.getVersion().isFirstVersion()) {
@ -153,10 +154,9 @@ public class PostgreSqlActivityDao extends PostgresqlDao<Activity> implements Ac
}
} catch (SQLException e) {
throw new StrolchPersistenceException(
MessageFormat.format("Failed to update previous version of Activity {0} due to {1}",
activity.getVersion(), e.getLocalizedMessage()),
e);
throw new StrolchPersistenceException(MessageFormat
.format("Failed to update previous version of Activity {0} due to {1}", activity.getVersion(),
e.getLocalizedMessage()), e);
}
}
@ -171,15 +171,15 @@ public class PostgreSqlActivityDao extends PostgresqlDao<Activity> implements Ac
// make sure is first version when versioning is not enabled
if (!activity.getVersion().isFirstVersion()) {
throw new StrolchPersistenceException(MessageFormat.format(
"Versioning is not enabled, so version must always be 0 to perform an update, but it is {0}",
activity.getVersion()));
throw new StrolchPersistenceException(MessageFormat
.format("Versioning is not enabled, so version must always be 0 to perform an update, but it is {0}",
activity.getVersion()));
}
// and also not marked as deleted!
if (activity.getVersion().isDeleted()) {
throw new StrolchPersistenceException(
MessageFormat.format("Versioning is not enabled, so version can not be marked as deleted for {0}",
throw new StrolchPersistenceException(MessageFormat
.format("Versioning is not enabled, so version can not be marked as deleted for {0}",
activity.getVersion()));
}
@ -220,36 +220,9 @@ public class PostgreSqlActivityDao extends PostgresqlDao<Activity> implements Ac
}
} catch (SQLException | SAXException e) {
throw new StrolchPersistenceException(MessageFormat.format("Failed to update Activity {0} due to {1}",
activity.getLocator(), e.getLocalizedMessage()), e);
throw new StrolchPersistenceException(MessageFormat
.format("Failed to update Activity {0} due to {1}", activity.getLocator(), e.getLocalizedMessage()),
e);
}
}
@Override
public <U> List<U> doQuery(ActivityQuery<U> query) {
PostgreSqlActivityQueryVisitor queryVisitor = new PostgreSqlActivityQueryVisitor("id, asxml");
query.accept(queryVisitor);
queryVisitor.validate();
List<U> list = new ArrayList<>();
String sql = queryVisitor.getSql();
try (PreparedStatement ps = tx().getConnection().prepareStatement(sql)) {
queryVisitor.setValues(ps);
try (ResultSet result = ps.executeQuery()) {
while (result.next()) {
String id = result.getString("id");
SQLXML sqlxml = result.getSQLXML("asxml");
Activity t = parseFromXml(id, queryVisitor.getType(), sqlxml);
list.add(t.accept(query.getVisitor()));
}
}
} catch (SQLException e) {
throw new StrolchPersistenceException("Failed to perform query due to: " + e.getMessage(), e);
}
return list;
}
}

View File

@ -1,50 +0,0 @@
/*
* Copyright 2015 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.persistence.postgresql;
import li.strolch.model.Tags;
import li.strolch.model.query.ActivityQueryVisitor;
import li.strolch.model.query.ActivityStateSelection;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*/
public class PostgreSqlActivityQueryVisitor extends PostgreSqlQueryVisitor implements ActivityQueryVisitor {
/**
* @param fields
*/
public PostgreSqlActivityQueryVisitor(String fields) {
super(fields);
}
@Override
protected String getClassName() {
return Tags.ACTIVITY;
}
@Override
protected String getTableName() {
return PostgreSqlActivityDao.ACTIVITIES;
}
@Override
public void visit(ActivityStateSelection selection) {
this.sb.append(this.indent);
this.sb.append("state = ?::order_state\n");
this.values.add(selection.getState().name());
}
}

View File

@ -1,103 +0,0 @@
/*
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
*/
package li.strolch.persistence.postgresql;
import static li.strolch.db.DbConstants.PROP_ALLOW_SCHEMA_CREATION;
import static li.strolch.db.DbConstants.PROP_ALLOW_SCHEMA_DROP;
import static li.strolch.db.DbConstants.PROP_ALLOW_SCHEMA_MIGRATION;
import java.util.Map;
import java.util.Map.Entry;
import javax.sql.DataSource;
import li.strolch.agent.api.StrolchAgent;
import li.strolch.agent.api.StrolchRealm;
import li.strolch.db.DbConnectionCheck;
import li.strolch.db.DbException;
import li.strolch.db.DbMigrationState;
import li.strolch.db.DbSchemaVersionCheck;
import li.strolch.privilege.model.Certificate;
import li.strolch.privilege.model.PrivilegeContext;
import li.strolch.runtime.configuration.ComponentConfiguration;
import li.strolch.runtime.configuration.RuntimeConfiguration;
import li.strolch.runtime.configuration.StrolchConfiguration;
import li.strolch.runtime.configuration.StrolchConfigurationException;
public class PostgreSqlDbInitializer extends PostgreSqlInitializer {
private StrolchAgent agent;
private PostgreSqlPersistenceHandler persistenceHandler;
private RuntimeConfiguration runtimeConfig;
private Certificate certificate;
private boolean allowSchemaCreation;
private boolean allowSchemaMigration;
private boolean allowSchemaDrop;
/**
* @param agent
* @param persistenceHandler
*/
public PostgreSqlDbInitializer(StrolchAgent agent, PostgreSqlPersistenceHandler persistenceHandler,
ComponentConfiguration persistenceConfig) {
super(agent, persistenceHandler);
this.agent = agent;
StrolchConfiguration strolchConfiguration = agent.getStrolchConfiguration();
this.runtimeConfig = strolchConfiguration.getRuntimeConfiguration();
this.persistenceHandler = persistenceHandler;
this.allowSchemaCreation = persistenceConfig.getBoolean(PROP_ALLOW_SCHEMA_CREATION, Boolean.FALSE);
this.allowSchemaMigration = persistenceConfig.getBoolean(PROP_ALLOW_SCHEMA_MIGRATION, Boolean.FALSE);
this.allowSchemaDrop = persistenceConfig.getBoolean(PROP_ALLOW_SCHEMA_DROP, Boolean.FALSE);
}
@Override
protected Certificate getCertificate() {
return this.certificate;
}
@Override
public void execute(PrivilegeContext privilegeContext) {
this.certificate = privilegeContext.getCertificate();
// first make sure we can connect to the database
Map<String, DataSource> dsMap = this.persistenceHandler.getDataSources();
DbConnectionCheck connectionCheck = new DbConnectionCheck(dsMap);
try {
connectionCheck.checkConnections();
} catch (DbException e) {
throw new StrolchConfigurationException("At least one of the configured DB connections is invalid: "
+ e.getMessage(), e);
}
// first make sure that the data store files exist
for (String realmName : this.agent.getContainer().getRealmNames()) {
// throws exception if does not exist
getDataStoreFile(this.runtimeConfig, this.realmConfig, realmName);
}
// for each connection info:
// - make sure schema exists
// - if it didn't exist, initialize with a set of data defined by the data store file
DbSchemaVersionCheck schemaVersionCheck = new DbSchemaVersionCheck(PostgreSqlPersistenceHandler.SCRIPT_PREFIX,
this.getClass(), this.allowSchemaCreation, this.allowSchemaMigration, this.allowSchemaDrop);
for (Entry<String, DataSource> entry : dsMap.entrySet()) {
String realmName = entry.getKey();
DataSource ds = entry.getValue();
StrolchRealm realm = this.agent.getContainer().getRealm(realmName);
if (realm.getMode().isTransient())
continue;
// check that the schema exists
DbMigrationState migrationType;
try {
migrationType = schemaVersionCheck.checkSchemaVersion(realmName, ds);
} catch (DbException e) {
throw new RuntimeException("Failed to validate schema for connection " + ds, e);
}
// now init the DB if needed
initSchemaFromDataStore(migrationType, realmName);
}
}
}

View File

@ -1,12 +1,12 @@
/*
* 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 exporders or implied.
@ -21,15 +21,15 @@ import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.sax.SAXResult;
import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.SQLXML;
import java.sql.Timestamp;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import li.strolch.model.Order;
import li.strolch.model.Tags;
import li.strolch.model.query.OrderQuery;
import li.strolch.model.xml.SimpleStrolchElementListener;
import li.strolch.model.xml.StrolchElementToSaxVisitor;
import li.strolch.model.xml.XmlModelSaxReader;
@ -129,8 +129,8 @@ public class PostgreSqlOrderDao extends PostgresqlDao<Order> implements OrderDao
}
} catch (SQLException | SAXException e) {
throw new StrolchPersistenceException(MessageFormat.format("Failed to insert Order {0} due to {1}",
order.getVersion(), e.getLocalizedMessage()), e);
throw new StrolchPersistenceException(MessageFormat
.format("Failed to insert Order {0} due to {1}", order.getVersion(), e.getLocalizedMessage()), e);
}
if (order.getVersion().isFirstVersion()) {
@ -153,10 +153,9 @@ public class PostgreSqlOrderDao extends PostgresqlDao<Order> implements OrderDao
}
} catch (SQLException e) {
throw new StrolchPersistenceException(
MessageFormat.format("Failed to update previous version of Order {0} due to {1}",
order.getVersion(), e.getLocalizedMessage()),
e);
throw new StrolchPersistenceException(MessageFormat
.format("Failed to update previous version of Order {0} due to {1}", order.getVersion(),
e.getLocalizedMessage()), e);
}
}
@ -171,15 +170,16 @@ public class PostgreSqlOrderDao extends PostgresqlDao<Order> implements OrderDao
// make sure is first version when versioning is not enabled
if (!order.getVersion().isFirstVersion()) {
throw new StrolchPersistenceException(MessageFormat.format(
"Versioning is not enabled, so version must always be 0 to perform an update, but it is {0}",
order.getVersion()));
throw new StrolchPersistenceException(MessageFormat
.format("Versioning is not enabled, so version must always be 0 to perform an update, but it is {0}",
order.getVersion()));
}
// and also not marked as deleted!
if (order.getVersion().isDeleted()) {
throw new StrolchPersistenceException(MessageFormat.format(
"Versioning is not enabled, so version can not be marked as deleted for {0}", order.getVersion()));
throw new StrolchPersistenceException(MessageFormat
.format("Versioning is not enabled, so version can not be marked as deleted for {0}",
order.getVersion()));
}
// now we update the existing object
@ -220,36 +220,8 @@ public class PostgreSqlOrderDao extends PostgresqlDao<Order> implements OrderDao
}
} catch (SQLException | SAXException e) {
throw new StrolchPersistenceException(MessageFormat.format("Failed to update Order {0} due to {1}",
order.getLocator(), e.getLocalizedMessage()), e);
throw new StrolchPersistenceException(MessageFormat
.format("Failed to update Order {0} due to {1}", order.getLocator(), e.getLocalizedMessage()), e);
}
}
@Override
public <U> List<U> doQuery(OrderQuery<U> query) {
PostgreSqlOrderQueryVisitor queryVisitor = new PostgreSqlOrderQueryVisitor("id, asxml");
query.accept(queryVisitor);
queryVisitor.validate();
List<U> list = new ArrayList<>();
String sql = queryVisitor.getSql();
try (PreparedStatement ps = tx().getConnection().prepareStatement(sql)) {
queryVisitor.setValues(ps);
try (ResultSet result = ps.executeQuery()) {
while (result.next()) {
String id = result.getString("id");
SQLXML sqlxml = result.getSQLXML("asxml");
Order t = parseFromXml(id, queryVisitor.getType(), sqlxml);
list.add(t.accept(query.getVisitor()));
}
}
} catch (SQLException e) {
throw new StrolchPersistenceException("Failed to perform query due to: " + e.getMessage(), e);
}
return list;
}
}

View File

@ -1,56 +0,0 @@
/*
* 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.persistence.postgresql;
import li.strolch.model.Tags;
import li.strolch.model.query.DateSelection;
import li.strolch.model.query.OrderQueryVisitor;
import li.strolch.model.query.OrderStateSelection;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*/
public class PostgreSqlOrderQueryVisitor extends PostgreSqlQueryVisitor implements OrderQueryVisitor {
/**
* @param fields
*/
public PostgreSqlOrderQueryVisitor(String fields) {
super(fields);
}
@Override
protected String getClassName() {
return Tags.ORDER;
}
@Override
protected String getTableName() {
return PostgreSqlOrderDao.ORDERS;
}
@Override
public void visit(DateSelection selection) {
PostgreSqlHelper.toSql(this.indent, this.sb, this.values, "date", selection.getDateRange());
}
@Override
public void visit(OrderStateSelection selection) {
this.sb.append(this.indent);
this.sb.append("state = ?::order_state\n");
this.values.add(selection.getState().name());
}
}

View File

@ -1,12 +1,12 @@
/*
* 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.
@ -34,7 +34,6 @@ import li.strolch.persistence.postgresql.PostgreSqlDbConnectionBuilder.StrolchPo
import li.strolch.privilege.model.Certificate;
import li.strolch.runtime.configuration.ComponentConfiguration;
import li.strolch.runtime.configuration.DbConnectionBuilder;
import li.strolch.runtime.configuration.StrolchConfiguration;
import li.strolch.runtime.privilege.PrivilegeHandler;
import org.postgresql.Driver;
@ -64,7 +63,7 @@ public class PostgreSqlPersistenceHandler extends StrolchComponent implements Pe
/**
* Returns the map of {@link DataSource} which can be used in maintenance mode
*
*
* @return the dsMap
*/
public Map<String, DataSource> getDataSources() {
@ -78,8 +77,8 @@ public class PostgreSqlPersistenceHandler extends StrolchComponent implements Pe
boolean allowSchemaCreation = configuration.getBoolean(PROP_ALLOW_SCHEMA_CREATION, Boolean.FALSE);
boolean allowSchemaMigration = configuration.getBoolean(PROP_ALLOW_SCHEMA_MIGRATION, Boolean.FALSE);
boolean allowSchemaDrop = configuration.getBoolean(PROP_ALLOW_SCHEMA_DROP, Boolean.FALSE);
boolean allowDataInitOnSchemaCreate = configuration.getBoolean(PROP_ALLOW_DATA_INIT_ON_SCHEMA_CREATE,
Boolean.FALSE);
boolean allowDataInitOnSchemaCreate = configuration
.getBoolean(PROP_ALLOW_DATA_INIT_ON_SCHEMA_CREATE, Boolean.FALSE);
DbSchemaVersionCheck schemaVersionCheck = new DbSchemaVersionCheck(SCRIPT_PREFIX, this.getClass(),
allowSchemaCreation, allowSchemaMigration, allowSchemaDrop);
@ -125,7 +124,8 @@ public class PostgreSqlPersistenceHandler extends StrolchComponent implements Pe
Connection getConnection(String realm) {
DataSource ds = this.dsMap.get(realm);
if (ds == null) {
String msg = MessageFormat.format("There is no DataSource registered for the realm {0}", realm); //$NON-NLS-1$
String msg = MessageFormat
.format("There is no DataSource registered for the realm {0}", realm); //$NON-NLS-1$
throw new StrolchPersistenceException(msg);
}
@ -156,15 +156,4 @@ public class PostgreSqlPersistenceHandler extends StrolchComponent implements Pe
public AuditDao getAuditDao(StrolchTransaction tx) {
return ((PostgreSqlStrolchTransaction) tx).getAuditDao();
}
@Override
public void performDbInitialization() {
ComponentContainer container = getContainer();
StrolchAgent agent = container.getAgent();
PrivilegeHandler privilegeHandler = container.getPrivilegeHandler();
StrolchConfiguration strolchConfiguration = getContainer().getAgent().getStrolchConfiguration();
PostgreSqlDbInitializer sqlDbInitializer = new PostgreSqlDbInitializer(agent, this,
strolchConfiguration.getComponentConfiguration(getName()));
privilegeHandler.runAsAgent(sqlDbInitializer);
}
}

View File

@ -1,434 +0,0 @@
/*
* 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.persistence.postgresql;
import static li.strolch.persistence.postgresql.PostgreSqlHelper.toSql;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import li.strolch.model.query.AndSelection;
import li.strolch.model.query.IdSelection;
import li.strolch.model.query.NameSelection;
import li.strolch.model.query.NotSelection;
import li.strolch.model.query.OrSelection;
import li.strolch.model.query.ParameterBagSelection;
import li.strolch.model.query.ParameterBagSelection.NullParameterBagSelection;
import li.strolch.model.query.ParameterSelection.AnyTypeParameterSelection;
import li.strolch.model.query.ParameterSelection.BooleanParameterSelection;
import li.strolch.model.query.ParameterSelection.DateParameterSelection;
import li.strolch.model.query.ParameterSelection.DateRangeParameterSelection;
import li.strolch.model.query.ParameterSelection.DurationParameterSelection;
import li.strolch.model.query.ParameterSelection.FloatListParameterSelection;
import li.strolch.model.query.ParameterSelection.FloatParameterSelection;
import li.strolch.model.query.ParameterSelection.IntegerListParameterSelection;
import li.strolch.model.query.ParameterSelection.IntegerParameterSelection;
import li.strolch.model.query.ParameterSelection.LongListParameterSelection;
import li.strolch.model.query.ParameterSelection.LongParameterSelection;
import li.strolch.model.query.ParameterSelection.NullParameterSelection;
import li.strolch.model.query.ParameterSelection.StringListParameterSelection;
import li.strolch.model.query.ParameterSelection.StringParameterSelection;
import li.strolch.model.query.ParameterSelectionVisitor;
import li.strolch.model.query.Selection;
import li.strolch.model.query.StrolchRootElementSelectionVisitor;
import li.strolch.model.query.StrolchTypeNavigation;
import li.strolch.model.query.ordering.OrderById;
import li.strolch.model.query.ordering.OrderByName;
import li.strolch.model.query.ordering.OrderByParameter;
import li.strolch.model.query.ordering.StrolchQueryOrderingVisitor;
import li.strolch.utils.StringMatchMode;
import li.strolch.utils.dbc.DBC;
import li.strolch.utils.helper.StringHelper;
import li.strolch.utils.iso8601.ISO8601FormatFactory;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*/
public abstract class PostgreSqlQueryVisitor
implements StrolchRootElementSelectionVisitor, ParameterSelectionVisitor, StrolchQueryOrderingVisitor {
protected StringBuilder sql;
protected StringBuilder sb;
protected String ordering;
protected String type;
protected List<Object> values;
protected boolean any;
protected String indent;
private String sqlAsString;
public PostgreSqlQueryVisitor(String fields) {
this.indent = "";
this.sql = new StringBuilder();
this.sb = new StringBuilder();
this.values = new ArrayList<>();
this.sql.append("SELECT ");
this.sql.append(fields);
this.sql.append("\nFROM\n");
this.sql.append(" ");
this.sql.append(getTableName());
this.indent = " ";
}
public String getSql() {
if (this.sqlAsString != null)
return this.sqlAsString;
this.sql.append("\nWHERE\n");
this.sql.append(this.indent);
if (this.any) {
this.sql.append("type = ?");
appendOrdering();
this.sqlAsString = this.sql.toString();
return this.sqlAsString;
}
this.sql.append("type = ? AND latest = true AND\n");
this.sql.append(this.sb.toString());
appendOrdering();
this.sqlAsString = this.sql.toString();
return this.sqlAsString;
}
private void appendOrdering() {
if (StringHelper.isNotEmpty(this.ordering)) {
this.sql.append("\n");
this.sql.append(this.ordering);
}
}
/**
* @return the any
*/
public boolean isAny() {
return this.any;
}
public String getType() {
return this.type;
}
public void validate() {
DBC.INTERIM.assertNotEmpty("No navigation was set!", this.type);
}
protected abstract String getClassName();
protected abstract String getTableName();
@Override
public void visit(StrolchTypeNavigation navigation) {
this.type = navigation.getType();
}
@Override
public void visit(IdSelection selection) {
this.sb.append(this.indent);
List<String> ids = selection.getIds();
if (ids.isEmpty())
return;
int size = ids.size();
if (size == 1) {
this.sb.append("id = ?\n");
this.values.add(ids.get(0));
} else {
this.sb.append("id IN (");
Iterator<String> iter = ids.iterator();
while (iter.hasNext()) {
String id = iter.next();
this.sb.append("?");
this.values.add(id);
if (iter.hasNext())
this.sb.append(", ");
}
this.sb.append(" )\n");
}
}
@Override
public void visit(NameSelection selection) {
this.sb.append(this.indent);
String name = selection.getName();
StringMatchMode mm = selection.getMatchMode();
this.sb.append(toSql("name", this.indent, mm, this.values, name));
}
@Override
public void visitAny() {
this.any = true;
}
@Override
public void visitAnd(AndSelection andSelection) {
this.sb.append(this.indent);
List<Selection> selections = andSelection.getSelections();
this.sb.append("( \n");
Iterator<Selection> iter = selections.iterator();
String indent = this.indent;
this.indent += " ";
while (iter.hasNext()) {
Selection selection = iter.next();
selection.accept(this);
if (iter.hasNext()) {
this.sb.append(indent);
this.sb.append("AND\n");
}
}
this.indent = indent;
this.sb.append(this.indent);
this.sb.append(")\n");
}
@Override
public void visitOr(OrSelection orSelection) {
this.sb.append(this.indent);
List<Selection> selections = orSelection.getSelections();
this.sb.append("( \n");
Iterator<Selection> iter = selections.iterator();
String indent = this.indent;
this.indent += " ";
while (iter.hasNext()) {
Selection selection = iter.next();
selection.accept(this);
if (iter.hasNext()) {
this.sb.append(indent);
this.sb.append("OR\n");
}
}
this.indent = indent;
this.sb.append(this.indent);
this.sb.append(")\n");
}
@Override
public void visitNot(NotSelection notSelection) {
this.sb.append(this.indent);
List<Selection> selections = notSelection.getSelections();
this.sb.append("NOT ( \n");
Iterator<Selection> iter = selections.iterator();
String indent = this.indent;
this.indent += " ";
while (iter.hasNext()) {
Selection selection = iter.next();
selection.accept(this);
if (iter.hasNext()) {
this.sb.append(indent);
this.sb.append("AND\n");
}
}
this.indent = indent;
this.sb.append(this.indent);
this.sb.append(")\n");
}
private void xpath(String bagKey, String paramKey, String paramValue) {
String xpath = "CAST(XPATH('//${className}/ParameterBag[@Id=\"${bagKey}\"]/Parameter[@Id=\"${paramKey}\" and @Value=\"${paramValue}\"]', asxml) AS TEXT[]) != '{}'\n";
this.sb.append(this.indent);
xpath = xpath.replace("${className}", getClassName());
xpath = xpath.replace("${bagKey}", bagKey);
xpath = xpath.replace("${paramKey}", paramKey);
xpath = xpath.replace("${paramValue}", paramValue);
this.sb.append(xpath);
}
private void xpath(String bagKey, String paramKey, String value, StringMatchMode matchMode) {
String xpath = "XPATH('//${className}/ParameterBag[@Id=\"${bagKey}\"]/Parameter[@Id=\"${paramKey}\"]/@Value', asxml))::TEXT AS content";
xpath = xpath.replace("${className}", getClassName());
xpath = xpath.replace("${bagKey}", bagKey);
xpath = xpath.replace("${paramKey}", paramKey);
this.sb.append(this.indent);
this.sb.append("id IN (\n");
this.sb.append(this.indent);
this.sb.append(" SELECT id\n");
this.sb.append(this.indent);
this.sb.append(" FROM (\n");
this.sb.append(this.indent);
this.sb.append(" SELECT id, UNNEST(");
this.sb.append(xpath);
this.sb.append("\n");
this.sb.append(this.indent);
this.sb.append("FROM ");
this.sb.append(getTableName());
this.sb.append("\n");
this.sb.append(this.indent);
this.sb.append(") AS alias\n");
this.sb.append(this.indent);
this.sb.append("WHERE ");
if (matchMode.isEquals()) {
if (matchMode.isCaseSensitve()) {
this.sb.append("content = ?\n");
} else {
this.sb.append("content ILIKE ?\n");
}
} else {
value = "%" + value + "%";
if (matchMode.isCaseSensitve()) {
this.sb.append("content LIKE ?\n");
} else {
this.sb.append("content ILIKE ?\n");
}
}
this.sb.append(this.indent);
this.sb.append(")\n");
this.values.add(value);
}
@Override
public void visit(StringParameterSelection sel) {
xpath(sel.getBagKey(), sel.getParamKey(), sel.getValue(), sel.getMatchMode());
}
@Override
public void visit(IntegerParameterSelection selection) {
xpath(selection.getBagKey(), selection.getParamKey(), selection.getValue().toString());
}
@Override
public void visit(BooleanParameterSelection selection) {
xpath(selection.getBagKey(), selection.getParamKey(), selection.getValue().toString());
}
@Override
public void visit(LongParameterSelection selection) {
xpath(selection.getBagKey(), selection.getParamKey(), selection.getValue().toString());
}
@Override
public void visit(FloatParameterSelection selection) {
xpath(selection.getBagKey(), selection.getParamKey(), selection.getValue().toString());
}
@Override
public void visit(DateParameterSelection selection) {
xpath(selection.getBagKey(), selection.getParamKey(),
ISO8601FormatFactory.getInstance().formatDate(selection.getValue()));
}
@Override
public void visit(DurationParameterSelection selection) {
xpath(selection.getBagKey(), selection.getParamKey(),
ISO8601FormatFactory.getInstance().formatDuration(selection.getValue()));
}
@Override
public void visit(NullParameterSelection selection) {
String xpath = "CAST(XPATH('//${className}/ParameterBag[@Id=\"${bagKey}\"]/Parameter[@Id=\"${paramKey}\"]', asxml) AS text[]) = '{}'\n";
this.sb.append(this.indent);
xpath = xpath.replace("${className}", getClassName());
xpath = xpath.replace("${bagKey}", selection.getBagKey());
xpath = xpath.replace("${paramKey}", selection.getParamKey());
this.sb.append(xpath);
}
@Override
public void visit(ParameterBagSelection selection) {
String xpath = "CAST(XPATH('//${className}/ParameterBag[@Id=\"${bagKey}\"]', asxml) AS text[]) != '{}'\n";
this.sb.append(this.indent);
xpath = xpath.replace("${className}", getClassName());
xpath = xpath.replace("${bagKey}", selection.getBagKey());
this.sb.append(xpath);
}
@Override
public void visit(NullParameterBagSelection selection) {
String xpath = "CAST(XPATH('//${className}/ParameterBag[@Id=\"${bagKey}\"]', asxml) AS text[]) = '{}'\n";
this.sb.append(this.indent);
xpath = xpath.replace("${className}", getClassName());
xpath = xpath.replace("${bagKey}", selection.getBagKey());
this.sb.append(xpath);
}
@Override
public void visit(DateRangeParameterSelection selection) {
throw new UnsupportedOperationException("Not yet supported!");
}
@Override
public void visit(StringListParameterSelection selection) {
throw new UnsupportedOperationException("Not yet supported!");
}
@Override
public void visit(IntegerListParameterSelection selection) {
throw new UnsupportedOperationException("Not yet supported!");
}
@Override
public void visit(FloatListParameterSelection selection) {
throw new UnsupportedOperationException("Not yet supported!");
}
@Override
public void visit(LongListParameterSelection selection) {
throw new UnsupportedOperationException("Not yet supported!");
}
@Override
public PostgreSqlQueryVisitor visit(OrderById ordering) {
if (ordering.isAscending())
this.ordering = "ORDER BY id";
else
this.ordering = "ORDER BY id DESC";
return this;
}
@Override
public PostgreSqlQueryVisitor visit(OrderByName ordering) {
if (ordering.isAscending())
this.ordering = "ORDER BY name";
else
this.ordering = "ORDER BY name DESC";
return this;
}
@Override
public PostgreSqlQueryVisitor visit(OrderByParameter ordering) {
throw new UnsupportedOperationException("Not yet supported!");
}
@Override
public void visit(AnyTypeParameterSelection sel) {
xpath(sel.getBagKey(), sel.getParamKey(), sel.getValue(), sel.getMatchMode());
}
/**
* @param ps
* @throws SQLException
*/
public void setValues(PreparedStatement ps) throws SQLException {
if (this.any) {
ps.setString(1, this.type);
return;
}
ps.setString(1, this.type);
for (int i = 0; i < this.values.size(); i++) {
ps.setObject(i + 2, this.values.get(i));
}
}
}

View File

@ -1,12 +1,12 @@
/*
* 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.
@ -21,15 +21,15 @@ import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.sax.SAXResult;
import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.SQLXML;
import java.sql.Timestamp;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import li.strolch.model.Resource;
import li.strolch.model.Tags;
import li.strolch.model.query.ResourceQuery;
import li.strolch.model.xml.SimpleStrolchElementListener;
import li.strolch.model.xml.StrolchElementToSaxVisitor;
import li.strolch.model.xml.XmlModelSaxReader;
@ -100,8 +100,8 @@ public class PostgreSqlResourceDao extends PostgresqlDao<Resource> implements Re
// version
preparedStatement.setInt(2, res.getVersion().getVersion());
preparedStatement.setString(3, res.getVersion().getCreatedBy());
preparedStatement.setTimestamp(4, new Timestamp(res.getVersion().getCreatedAt().getTime()),
Calendar.getInstance());
preparedStatement
.setTimestamp(4, new Timestamp(res.getVersion().getCreatedAt().getTime()), Calendar.getInstance());
preparedStatement.setBoolean(5, res.getVersion().isDeleted());
preparedStatement.setBoolean(6, !res.getVersion().isDeleted());
@ -124,8 +124,8 @@ public class PostgreSqlResourceDao extends PostgresqlDao<Resource> implements Re
}
} catch (SQLException | SAXException e) {
throw new StrolchPersistenceException(MessageFormat.format("Failed to insert Resource {0} due to {1}",
res.getLocator(), e.getLocalizedMessage()), e);
throw new StrolchPersistenceException(MessageFormat
.format("Failed to insert Resource {0} due to {1}", res.getLocator(), e.getLocalizedMessage()), e);
}
if (res.getVersion().isFirstVersion()) {
@ -148,8 +148,8 @@ public class PostgreSqlResourceDao extends PostgresqlDao<Resource> implements Re
}
} catch (SQLException e) {
throw new StrolchPersistenceException(MessageFormat.format("Failed to insert Resource {0} due to {1}",
res.getLocator(), e.getLocalizedMessage()), e);
throw new StrolchPersistenceException(MessageFormat
.format("Failed to insert Resource {0} due to {1}", res.getLocator(), e.getLocalizedMessage()), e);
}
}
@ -164,15 +164,15 @@ public class PostgreSqlResourceDao extends PostgresqlDao<Resource> implements Re
// make sure is first version when versioning is not enabled
if (!resource.getVersion().isFirstVersion()) {
throw new StrolchPersistenceException(MessageFormat.format(
"Versioning is not enabled, so version must always be 0 to perform an update, but it is {0}",
resource.getVersion()));
throw new StrolchPersistenceException(MessageFormat
.format("Versioning is not enabled, so version must always be 0 to perform an update, but it is {0}",
resource.getVersion()));
}
// and also not marked as deleted!
if (resource.getVersion().isDeleted()) {
throw new StrolchPersistenceException(
MessageFormat.format("Versioning is not enabled, so version can not be marked as deleted for {0}",
throw new StrolchPersistenceException(MessageFormat
.format("Versioning is not enabled, so version can not be marked as deleted for {0}",
resource.getVersion()));
}
@ -212,36 +212,9 @@ public class PostgreSqlResourceDao extends PostgresqlDao<Resource> implements Re
}
} catch (SQLException | SAXException e) {
throw new StrolchPersistenceException(MessageFormat.format("Failed to update Resource {0} due to {1}",
resource.getLocator(), e.getLocalizedMessage()), e);
throw new StrolchPersistenceException(MessageFormat
.format("Failed to update Resource {0} due to {1}", resource.getLocator(), e.getLocalizedMessage()),
e);
}
}
@Override
public <U> List<U> doQuery(ResourceQuery<U> query) {
PostgreSqlResourceQueryVisitor queryVisitor = new PostgreSqlResourceQueryVisitor("id, asxml");
query.accept(queryVisitor);
queryVisitor.validate();
List<U> list = new ArrayList<>();
String sql = queryVisitor.getSql();
try (PreparedStatement ps = tx().getConnection().prepareStatement(sql)) {
queryVisitor.setValues(ps);
try (ResultSet result = ps.executeQuery()) {
while (result.next()) {
String id = result.getString("id");
SQLXML sqlxml = result.getSQLXML("asxml");
Resource t = parseFromXml(id, queryVisitor.getType(), sqlxml);
list.add(t.accept(query.getVisitor()));
}
}
} catch (SQLException e) {
throw new StrolchPersistenceException("Failed to perform query due to: " + e.getMessage(), e);
}
return list;
}
}

View File

@ -1,42 +0,0 @@
/*
* 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.persistence.postgresql;
import li.strolch.model.Tags;
import li.strolch.model.query.ResourceQueryVisitor;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*/
public class PostgreSqlResourceQueryVisitor extends PostgreSqlQueryVisitor implements ResourceQueryVisitor {
/**
* @param fields
*/
public PostgreSqlResourceQueryVisitor(String fields) {
super(fields);
}
@Override
protected String getClassName() {
return Tags.RESOURCE;
}
@Override
protected String getTableName() {
return PostgreSqlResourceDao.RESOURCES;
}
}

View File

@ -1,12 +1,12 @@
/*
* 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.
@ -30,11 +30,6 @@ public class PostgreSqlSchemaInitializer extends PostgreSqlInitializer {
private Map<String, DbMigrationState> dbMigrationStates;
/**
* @param agent
* @param persistenceHandler
* @param dbMigrationStates
*/
public PostgreSqlSchemaInitializer(StrolchAgent agent, PostgreSqlPersistenceHandler persistenceHandler,
Map<String, DbMigrationState> dbMigrationStates) {
super(agent, persistenceHandler);

View File

@ -52,6 +52,37 @@ public abstract class PostgresqlDao<T extends StrolchRootElement> implements Str
protected abstract T parseFromXml(String id, String type, SQLXML xml);
@Override
public long querySize() {
String sql = "select count(*) from " + getTableName() + " where latest = true";
try (PreparedStatement statement = tx().getConnection().prepareStatement(sql)) {
try (ResultSet result = statement.executeQuery()) {
result.next();
return result.getLong(1);
}
} catch (SQLException e) {
throw new StrolchPersistenceException("Failed to query size due to: " + e.getMessage(), e);
}
}
@Override
public long querySize(String type) {
String sql = "select count(*) from " + getTableName() + " where type = ? and latest = true";
try (PreparedStatement statement = tx().getConnection().prepareStatement(sql)) {
statement.setString(1, type);
try (ResultSet result = statement.executeQuery()) {
result.next();
return result.getLong(1);
}
} catch (SQLException e) {
throw new StrolchPersistenceException("Failed to query size due to: " + e.getMessage(), e);
}
}
@Override
public Set<String> queryTypes() {
Set<String> keySet = new HashSet<>();
@ -345,35 +376,6 @@ public abstract class PostgresqlDao<T extends StrolchRootElement> implements Str
});
}
private long querySize() {
String sql = "select count(*) from " + getTableName() + " where latest = true";
try (PreparedStatement statement = tx().getConnection().prepareStatement(sql)) {
try (ResultSet result = statement.executeQuery()) {
result.next();
return result.getLong(1);
}
} catch (SQLException e) {
throw new StrolchPersistenceException("Failed to query size due to: " + e.getMessage(), e);
}
}
private long querySize(String type) {
String sql = "select count(*) from " + getTableName() + " where type = ? and latest = true";
try (PreparedStatement statement = tx().getConnection().prepareStatement(sql)) {
statement.setString(1, type);
try (ResultSet result = statement.executeQuery()) {
result.next();
return result.getLong(1);
}
} catch (SQLException e) {
throw new StrolchPersistenceException("Failed to query size due to: " + e.getMessage(), e);
}
}
/**
* @param element
*/

View File

@ -1,251 +0,0 @@
package li.strolch.persistence.postgresql.dao.test;
import static li.strolch.persistence.postgresql.dao.test.CachedDaoTest.CONFIG_SRC;
import static li.strolch.persistence.postgresql.dao.test.CachedDaoTest.DB_PASSWORD;
import static li.strolch.persistence.postgresql.dao.test.CachedDaoTest.DB_STORE_PATH_DIR;
import static li.strolch.persistence.postgresql.dao.test.CachedDaoTest.DB_URL;
import static li.strolch.persistence.postgresql.dao.test.CachedDaoTest.DB_USERNAME;
import static li.strolch.persistence.postgresql.dao.test.CachedDaoTest.RUNTIME_PATH;
import static li.strolch.persistence.postgresql.dao.test.CachedDaoTest.dropSchema;
import java.io.File;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import li.strolch.agent.api.ActivityMap;
import li.strolch.agent.api.StrolchRealm;
import li.strolch.model.ModelGenerator;
import li.strolch.model.State;
import li.strolch.model.activity.Action;
import li.strolch.model.activity.Activity;
import li.strolch.model.activity.TimeOrdering;
import li.strolch.model.query.ActivityQuery;
import li.strolch.model.query.ActivityStateSelection;
import li.strolch.model.query.IdSelection;
import li.strolch.model.query.NameSelection;
import li.strolch.model.query.ParameterBagSelection;
import li.strolch.model.query.ParameterBagSelection.NullParameterBagSelection;
import li.strolch.model.query.ParameterSelection;
import li.strolch.model.query.ordering.OrderById;
import li.strolch.persistence.api.StrolchTransaction;
import li.strolch.privilege.model.Certificate;
import li.strolch.runtime.StrolchConstants;
import li.strolch.testbase.runtime.RuntimeMock;
import li.strolch.utils.StringMatchMode;
import li.strolch.utils.collections.DateRange;
public class ActivityQueryTest extends QueryTest {
private static RuntimeMock runtimeMock;
@BeforeClass
public static void beforeClass() throws Exception {
dropSchema(DB_URL, DB_USERNAME, DB_PASSWORD);
File rootPath = new File(RUNTIME_PATH);
File configSrc = new File(CONFIG_SRC);
runtimeMock = new RuntimeMock();
runtimeMock.mockRuntime(rootPath, configSrc);
new File(rootPath, DB_STORE_PATH_DIR).mkdir();
runtimeMock.startContainer();
Certificate cert = runtimeMock.getPrivilegeHandler().authenticate("test", "test".toCharArray());
StrolchRealm realm = runtimeMock.getRealm(StrolchConstants.DEFAULT_REALM);
try (StrolchTransaction tx = realm.openTx(cert, "test")) {
ActivityMap activityMap = tx.getActivityMap();
Activity activity = ModelGenerator.createActivity("@1", "Activity 1", "MyType1", TimeOrdering.SERIES);
activityMap.add(tx, activity);
activity = ModelGenerator.createActivity("@2", "Activity 2", "MyType1", TimeOrdering.SERIES);
((Action) activity.getElement("action_" + activity.getId())).setState(State.EXECUTION);
activityMap.add(tx, activity);
activity = ModelGenerator.createActivity("@3", "Activity 3", "MyType1", TimeOrdering.SERIES);
((Action) activity.getElement("action_" + activity.getId())).setState(State.CLOSED);
activityMap.add(tx, activity);
activity = ModelGenerator.createActivity("@4", "Activity 4", "MyType2", TimeOrdering.SERIES);
((Action) activity.getElement("action_" + activity.getId())).setState(State.CREATED);
activityMap.add(tx, activity);
activity = ModelGenerator.createActivity("@5", "Activity 5", "MyType2", TimeOrdering.SERIES);
((Action) activity.getElement("action_" + activity.getId())).setState(State.CLOSED);
activityMap.add(tx, activity);
activity = ModelGenerator.createActivity("@6", "Activity 6", "MyType2", TimeOrdering.SERIES);
((Action) activity.getElement("action_" + activity.getId())).setState(State.CLOSED);
activityMap.add(tx, activity);
tx.commitOnClose();
}
}
@AfterClass
public static void afterClass() {
if (runtimeMock != null)
runtimeMock.destroyRuntime();
}
public Connection openConn() throws SQLException {
String url = "jdbc:postgresql://localhost/testdb";
String username = "testuser";
String password = "test";
Connection connection = DriverManager.getConnection(url, username, password);
connection.setAutoCommit(false);
return connection;
}
@Test
public void shouldQueryActivityAll() throws SQLException {
ActivityQuery<Activity> query = ActivityQuery.query("MyType1", new OrderById());
query.withAny();
performActivityQuery(query, Arrays.asList("@1", "@2", "@3"));
}
@Test
public void shouldQueryActivityByState() throws SQLException {
ActivityQuery<Activity> query = ActivityQuery.query("MyType1");
query.and().with(new ActivityStateSelection(State.CREATED));
performActivityQuery(query, Arrays.asList("@1", "@3"));
query = ActivityQuery.query("MyType1");
query.and().with(new ActivityStateSelection(State.EXECUTION));
performActivityQuery(query, Arrays.<String> asList("@2"));
}
@Test
public void shouldQueryActivity1() throws SQLException {
ActivityQuery<Activity> query = ActivityQuery.query("MyType1", new OrderById());
query.and().with(new IdSelection("@1", "@2"),
new NameSelection("Activity 1", StringMatchMode.EQUALS_CASE_SENSITIVE));
performActivityQuery(query, Arrays.asList("@1"));
}
@Test
public void shouldQueryActivity2() throws SQLException {
ActivityQuery<Activity> query = ActivityQuery.query("MyType1", new OrderById());
query.or().with(new IdSelection("@1", "@2"),
new NameSelection("activity 1", StringMatchMode.EQUALS_CASE_SENSITIVE));
performActivityQuery(query, Arrays.asList("@1", "@2"));
}
@Test
public void shouldQueryActivityByBooleParam() throws SQLException {
ActivityQuery<Activity> query = ActivityQuery.query("MyType1", new OrderById());
query.and().with(ParameterSelection.booleanSelection("@bag01", "@param1", true));
performActivityQuery(query, Arrays.asList("@1", "@2", "@3"));
}
@Test
public void shouldQueryActivityByFloatParam() throws SQLException {
ActivityQuery<Activity> query = ActivityQuery.query("MyType1", new OrderById());
query.and().with(ParameterSelection.floatSelection("@bag01", "@param2", 44.3));
performActivityQuery(query, Arrays.asList("@1", "@2", "@3"));
}
@Test
public void shouldQueryActivityByIntegerParam() throws SQLException {
ActivityQuery<Activity> query = ActivityQuery.query("MyType1", new OrderById());
query.and().with(ParameterSelection.integerSelection("@bag01", "@param3", 77));
performActivityQuery(query, Arrays.asList("@1", "@2", "@3"));
}
@Test
public void shouldQueryActivityByLongParam() throws SQLException {
ActivityQuery<Activity> query = ActivityQuery.query("MyType2", new OrderById());
query.and().with(ParameterSelection.longSelection("@bag01", "@param4", 4453234566L));
performActivityQuery(query, Arrays.asList("@4", "@5", "@6"));
}
@Test
public void shouldQueryActivityByStringParam() throws SQLException {
List<String> expected = Arrays.asList("@1", "@2", "@3");
ActivityQuery<Activity> query = ActivityQuery.query("MyType1", new OrderById());
query.and().with(ParameterSelection.stringSelection("@bag01", "@param5", "Strolch",
StringMatchMode.EQUALS_CASE_SENSITIVE));
performActivityQuery(query, expected);
query = ActivityQuery.query("MyType1", new OrderById());
query.and().with(ParameterSelection.stringSelection("@bag01", "@param5", "strolch",
StringMatchMode.EQUALS_CASE_SENSITIVE));
performActivityQuery(query, Arrays.<String> asList());
query = ActivityQuery.query("MyType1", new OrderById());
query.and().with(ParameterSelection.stringSelection("@bag01", "@param5", "strolch",
StringMatchMode.EQUALS_CASE_INSENSITIVE));
performActivityQuery(query, expected);
query = ActivityQuery.query("MyType1", new OrderById());
query.and().with(ParameterSelection.stringSelection("@bag01", "@param5", "olch",
StringMatchMode.CONTAINS_CASE_INSENSITIVE));
performActivityQuery(query, expected);
}
@Test
public void shouldQueryActivityByDateParam() throws SQLException {
ActivityQuery<Activity> query = ActivityQuery.query("MyType1", new OrderById());
query.and().with(ParameterSelection.dateSelection("@bag01", "@param6", new Date(1354295525628L)));
performActivityQuery(query, Arrays.asList("@1", "@2", "@3"));
}
@Ignore("Not yet implemented")
@Test
public void shouldQueryActivityByDateRange() throws SQLException {
ActivityQuery<Activity> query = ActivityQuery.query("MyType1", new OrderById());
query.and().with(ParameterSelection.dateRangeSelection("@bag01", "@param6",
new DateRange().from(new Date(1354295525627L), false).to(new Date(1354295525629L), false)));
performActivityQuery(query, Arrays.asList("@1", "@2", "@3"));
}
@Test
public void shouldQueryActivityByDurationParam() throws SQLException {
ActivityQuery<Activity> query = ActivityQuery.query("MyType1", new OrderById());
query.and().with(ParameterSelection.durationSelection("@bag01", "@param8", "P1D"));
performActivityQuery(query, Arrays.asList("@1", "@2", "@3"));
}
@Test
public void shouldQueryActivityByNullParam1() throws SQLException {
ActivityQuery<Activity> query = ActivityQuery.query("MyType1", new OrderById());
query.and().with(ParameterSelection.nullSelection("@bag01", "@param6"));
performActivityQuery(query, Arrays.<String> asList());
}
@Test
public void shouldQueryActivityByNullParam2() throws SQLException {
ActivityQuery<Activity> query = ActivityQuery.query("MyType1", new OrderById());
query.and().with(ParameterSelection.nullSelection("@bag01", "@param"));
performActivityQuery(query, Arrays.asList("@1", "@2", "@3"));
}
@Test
public void shouldQueryActivityByBag() throws SQLException {
ActivityQuery<Activity> query = ActivityQuery.query("MyType1", new OrderById());
query.and().with(new ParameterBagSelection("@bag01"));
performActivityQuery(query, Arrays.asList("@1", "@2", "@3"));
}
@Test
public void shouldQueryActivityByNullBag() throws SQLException {
ActivityQuery<Activity> query = ActivityQuery.query("MyType1", new OrderById());
query.and().with(new NullParameterBagSelection("@bag01"));
performActivityQuery(query, Arrays.<String> asList());
}
}

View File

@ -1,298 +0,0 @@
package li.strolch.persistence.postgresql.dao.test;
import static li.strolch.persistence.postgresql.dao.test.CachedDaoTest.CONFIG_SRC;
import static li.strolch.persistence.postgresql.dao.test.CachedDaoTest.DB_PASSWORD;
import static li.strolch.persistence.postgresql.dao.test.CachedDaoTest.DB_STORE_PATH_DIR;
import static li.strolch.persistence.postgresql.dao.test.CachedDaoTest.DB_URL;
import static li.strolch.persistence.postgresql.dao.test.CachedDaoTest.DB_USERNAME;
import static li.strolch.persistence.postgresql.dao.test.CachedDaoTest.RUNTIME_PATH;
import static li.strolch.persistence.postgresql.dao.test.CachedDaoTest.dropSchema;
import java.io.File;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import li.strolch.agent.api.OrderMap;
import li.strolch.agent.api.StrolchRealm;
import li.strolch.model.ModelGenerator;
import li.strolch.model.Order;
import li.strolch.model.State;
import li.strolch.model.query.DateSelection;
import li.strolch.model.query.IdSelection;
import li.strolch.model.query.NameSelection;
import li.strolch.model.query.OrderQuery;
import li.strolch.model.query.OrderStateSelection;
import li.strolch.model.query.ParameterBagSelection;
import li.strolch.model.query.ParameterBagSelection.NullParameterBagSelection;
import li.strolch.model.query.ParameterSelection;
import li.strolch.model.query.ordering.OrderById;
import li.strolch.persistence.api.StrolchTransaction;
import li.strolch.privilege.model.Certificate;
import li.strolch.runtime.StrolchConstants;
import li.strolch.testbase.runtime.RuntimeMock;
import li.strolch.utils.StringMatchMode;
import li.strolch.utils.collections.DateRange;
public class OrderQueryTest extends QueryTest {
private static RuntimeMock runtimeMock;
private static Date past;
private static Date earlier;
private static Date current;
private static Date later;
private static Date future;
@BeforeClass
public static void beforeClass() throws Exception {
dropSchema(DB_URL, DB_USERNAME, DB_PASSWORD);
File rootPath = new File(RUNTIME_PATH);
File configSrc = new File(CONFIG_SRC);
runtimeMock = new RuntimeMock();
runtimeMock.mockRuntime(rootPath, configSrc);
new File(rootPath, DB_STORE_PATH_DIR).mkdir();
runtimeMock.startContainer();
Calendar cal = Calendar.getInstance();
cal.clear();
cal.set(2000, 1, 1);
past = cal.getTime();
cal.set(2000, 4, 1);
earlier = cal.getTime();
cal.set(2000, 6, 1);
current = cal.getTime();
cal.set(2000, 8, 1);
later = cal.getTime();
cal.set(2000, 11, 1);
future = cal.getTime();
Certificate cert = runtimeMock.getPrivilegeHandler().authenticate("test", "test".toCharArray());
StrolchRealm realm = runtimeMock.getRealm(StrolchConstants.DEFAULT_REALM);
try (StrolchTransaction tx = realm.openTx(cert, "test")) {
OrderMap orderMap = tx.getOrderMap();
orderMap.add(tx, ModelGenerator.createOrder("@1", "Order 1", "MyType1", earlier, State.CREATED));
orderMap.add(tx, ModelGenerator.createOrder("@2", "Order 2", "MyType1", current, State.EXECUTION));
orderMap.add(tx, ModelGenerator.createOrder("@3", "Order 3", "MyType1", later, State.CLOSED));
orderMap.add(tx, ModelGenerator.createOrder("@4", "Order 4", "MyType2", earlier, State.CREATED));
orderMap.add(tx, ModelGenerator.createOrder("@5", "Order 5", "MyType2", current, State.CLOSED));
orderMap.add(tx, ModelGenerator.createOrder("@6", "Order 6", "MyType2", later, State.CLOSED));
tx.commitOnClose();
}
}
@AfterClass
public static void afterClass() {
if (runtimeMock != null)
runtimeMock.destroyRuntime();
}
public Connection openConn() throws SQLException {
String url = "jdbc:postgresql://localhost/testdb";
String username = "testuser";
String password = "test";
Connection connection = DriverManager.getConnection(url, username, password);
connection.setAutoCommit(false);
return connection;
}
@Test
public void shouldQueryOrderAll() throws SQLException {
OrderQuery<Order> query = OrderQuery.query("MyType1", new OrderById());
query.withAny();
performOrderQuery(query, Arrays.asList("@1", "@2", "@3"));
}
@Test
public void shouldQueryOrderByDate() throws SQLException {
// range
OrderQuery<Order> query = OrderQuery.query("MyType1", new OrderById());
query.and().with(new DateSelection().from(earlier, false).to(later, false));
performOrderQuery(query, Arrays.asList("@1", "@2", "@3"));
// equals current
query = OrderQuery.query("MyType1");
query.and().with(new DateSelection().from(current, false).to(current, false));
performOrderQuery(query, Arrays.asList("@2"));
// equals later
query = OrderQuery.query("MyType1");
query.and().with(new DateSelection().from(later, false).to(later, false));
performOrderQuery(query, Arrays.<String> asList("@3"));
// equals earlier
query = OrderQuery.query("MyType1");
query.and().with(new DateSelection().from(earlier, false).to(earlier, false));
performOrderQuery(query, Arrays.<String> asList("@1"));
// past
query = OrderQuery.query("MyType1");
query.and().with(new DateSelection().to(past, false));
performOrderQuery(query, Arrays.<String> asList());
// future
query = OrderQuery.query("MyType1");
query.and().with(new DateSelection().from(future, false));
performOrderQuery(query, Arrays.<String> asList());
// earlier
query = OrderQuery.query("MyType1");
query.and().with(new DateSelection().from(past, false).to(earlier, true));
performOrderQuery(query, Arrays.<String> asList("@1"));
// later
query = OrderQuery.query("MyType1");
query.and().with(new DateSelection().from(later, false).to(future, true));
performOrderQuery(query, Arrays.<String> asList("@3"));
}
@Test
public void shouldQueryOrderByState() throws SQLException {
OrderQuery<Order> query = OrderQuery.query("MyType1");
query.and().with(new OrderStateSelection(State.CREATED));
performOrderQuery(query, Arrays.asList("@1"));
query = OrderQuery.query("MyType1");
query.and().with(new OrderStateSelection(State.EXECUTION));
performOrderQuery(query, Arrays.<String> asList("@2"));
}
@Test
public void shouldQueryOrder1() throws SQLException {
OrderQuery<Order> query = OrderQuery.query("MyType1", new OrderById());
query.and().with(new IdSelection("@1", "@2"),
new NameSelection("Order 1", StringMatchMode.EQUALS_CASE_SENSITIVE));
performOrderQuery(query, Arrays.asList("@1"));
}
@Test
public void shouldQueryOrder2() throws SQLException {
OrderQuery<Order> query = OrderQuery.query("MyType1", new OrderById());
query.or().with(new IdSelection("@1", "@2"),
new NameSelection("order 1", StringMatchMode.EQUALS_CASE_SENSITIVE));
performOrderQuery(query, Arrays.asList("@1", "@2"));
}
@Test
public void shouldQueryOrderByBooleParam() throws SQLException {
OrderQuery<Order> query = OrderQuery.query("MyType1", new OrderById());
query.and().with(ParameterSelection.booleanSelection("@bag01", "@param1", true));
performOrderQuery(query, Arrays.asList("@1", "@2", "@3"));
}
@Test
public void shouldQueryOrderByFloatParam() throws SQLException {
OrderQuery<Order> query = OrderQuery.query("MyType1", new OrderById());
query.and().with(ParameterSelection.floatSelection("@bag01", "@param2", 44.3));
performOrderQuery(query, Arrays.asList("@1", "@2", "@3"));
}
@Test
public void shouldQueryOrderByIntegerParam() throws SQLException {
OrderQuery<Order> query = OrderQuery.query("MyType1", new OrderById());
query.and().with(ParameterSelection.integerSelection("@bag01", "@param3", 77));
performOrderQuery(query, Arrays.asList("@1", "@2", "@3"));
}
@Test
public void shouldQueryOrderByLongParam() throws SQLException {
OrderQuery<Order> query = OrderQuery.query("MyType2", new OrderById());
query.and().with(ParameterSelection.longSelection("@bag01", "@param4", 4453234566L));
performOrderQuery(query, Arrays.asList("@4", "@5", "@6"));
}
@Test
public void shouldQueryOrderByStringParam() throws SQLException {
List<String> expected = Arrays.asList("@1", "@2", "@3");
OrderQuery<Order> query = OrderQuery.query("MyType1", new OrderById());
query.and().with(ParameterSelection.stringSelection("@bag01", "@param5", "Strolch",
StringMatchMode.EQUALS_CASE_SENSITIVE));
performOrderQuery(query, expected);
query = OrderQuery.query("MyType1", new OrderById());
query.and().with(ParameterSelection.stringSelection("@bag01", "@param5", "strolch",
StringMatchMode.EQUALS_CASE_SENSITIVE));
performOrderQuery(query, Arrays.<String> asList());
query = OrderQuery.query("MyType1", new OrderById());
query.and().with(ParameterSelection.stringSelection("@bag01", "@param5", "strolch",
StringMatchMode.EQUALS_CASE_INSENSITIVE));
performOrderQuery(query, expected);
query = OrderQuery.query("MyType1", new OrderById());
query.and().with(ParameterSelection.stringSelection("@bag01", "@param5", "olch",
StringMatchMode.CONTAINS_CASE_INSENSITIVE));
performOrderQuery(query, expected);
}
@Test
public void shouldQueryOrderByDateParam() throws SQLException {
OrderQuery<Order> query = OrderQuery.query("MyType1", new OrderById());
query.and().with(ParameterSelection.dateSelection("@bag01", "@param6", new Date(1354295525628L)));
performOrderQuery(query, Arrays.asList("@1", "@2", "@3"));
}
@Ignore("Not yet implemented")
@Test
public void shouldQueryOrderByDateRange() throws SQLException {
OrderQuery<Order> query = OrderQuery.query("MyType1", new OrderById());
query.and().with(ParameterSelection.dateRangeSelection("@bag01", "@param6",
new DateRange().from(new Date(1354295525627L), false).to(new Date(1354295525629L), false)));
performOrderQuery(query, Arrays.asList("@1", "@2", "@3"));
}
@Test
public void shouldQueryOrderByDurationParam() throws SQLException {
OrderQuery<Order> query = OrderQuery.query("MyType1", new OrderById());
query.and().with(ParameterSelection.durationSelection("@bag01", "@param8", "P1D"));
performOrderQuery(query, Arrays.asList("@1", "@2", "@3"));
}
@Test
public void shouldQueryOrderByNullParam1() throws SQLException {
OrderQuery<Order> query = OrderQuery.query("MyType1", new OrderById());
query.and().with(ParameterSelection.nullSelection("@bag01", "@param6"));
performOrderQuery(query, Arrays.<String> asList());
}
@Test
public void shouldQueryOrderByNullParam2() throws SQLException {
OrderQuery<Order> query = OrderQuery.query("MyType1", new OrderById());
query.and().with(ParameterSelection.nullSelection("@bag01", "@param"));
performOrderQuery(query, Arrays.asList("@1", "@2", "@3"));
}
@Test
public void shouldQueryOrderByBag() throws SQLException {
OrderQuery<Order> query = OrderQuery.query("MyType1", new OrderById());
query.and().with(new ParameterBagSelection("@bag01"));
performOrderQuery(query, Arrays.asList("@1", "@2", "@3"));
}
@Test
public void shouldQueryOrderByNullBag() throws SQLException {
OrderQuery<Order> query = OrderQuery.query("MyType1", new OrderById());
query.and().with(new NullParameterBagSelection("@bag01"));
performOrderQuery(query, Arrays.<String> asList());
}
}

View File

@ -1,97 +0,0 @@
/*
* 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.persistence.postgresql.dao.test;
import static org.junit.Assert.assertEquals;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import li.strolch.model.Order;
import li.strolch.model.Resource;
import li.strolch.model.activity.Activity;
import li.strolch.model.query.ActivityQuery;
import li.strolch.model.query.OrderQuery;
import li.strolch.model.query.ResourceQuery;
import li.strolch.persistence.postgresql.PostgreSqlActivityQueryVisitor;
import li.strolch.persistence.postgresql.PostgreSqlOrderQueryVisitor;
import li.strolch.persistence.postgresql.PostgreSqlQueryVisitor;
import li.strolch.persistence.postgresql.PostgreSqlResourceQueryVisitor;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*/
public class QueryTest {
protected static final Logger logger = LoggerFactory.getLogger(QueryTest.class);
protected Connection openConn() throws SQLException {
String url = "jdbc:postgresql://localhost/testdb";
String username = "testuser";
String password = "test";
Connection connection = DriverManager.getConnection(url, username, password);
connection.setAutoCommit(false);
return connection;
}
protected void performOrderQuery(OrderQuery<Order> query, List<String> expected) throws SQLException {
PostgreSqlOrderQueryVisitor visitor = new PostgreSqlOrderQueryVisitor("id");
query.accept(visitor);
List<String> ids = queryIds(visitor);
assertEquals(expected, ids);
}
protected void performActivityQuery(ActivityQuery<Activity> query, List<String> expected) throws SQLException {
PostgreSqlActivityQueryVisitor visitor = new PostgreSqlActivityQueryVisitor("id");
query.accept(visitor);
List<String> ids = queryIds(visitor);
assertEquals(expected, ids);
}
protected void performResourceQuery(ResourceQuery<Resource> query, List<String> expected) throws SQLException {
PostgreSqlResourceQueryVisitor visitor = new PostgreSqlResourceQueryVisitor("id");
query.accept(visitor);
List<String> ids = queryIds(visitor);
assertEquals(expected, ids);
}
private List<String> queryIds(PostgreSqlQueryVisitor visitor) throws SQLException {
String sql = visitor.getSql();
logger.info("\n" + sql);
List<String> ids = new ArrayList<>();
try (Connection con = openConn()) {
try (PreparedStatement ps = con.prepareStatement(sql)) {
visitor.setValues(ps);
try (ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
ids.add(rs.getString(1));
}
}
}
}
return ids;
}
}

View File

@ -1,234 +0,0 @@
package li.strolch.persistence.postgresql.dao.test;
import static li.strolch.persistence.postgresql.dao.test.CachedDaoTest.CONFIG_SRC;
import static li.strolch.persistence.postgresql.dao.test.CachedDaoTest.DB_PASSWORD;
import static li.strolch.persistence.postgresql.dao.test.CachedDaoTest.DB_STORE_PATH_DIR;
import static li.strolch.persistence.postgresql.dao.test.CachedDaoTest.DB_URL;
import static li.strolch.persistence.postgresql.dao.test.CachedDaoTest.DB_USERNAME;
import static li.strolch.persistence.postgresql.dao.test.CachedDaoTest.RUNTIME_PATH;
import static li.strolch.persistence.postgresql.dao.test.CachedDaoTest.dropSchema;
import java.io.File;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import li.strolch.agent.api.ResourceMap;
import li.strolch.agent.api.StrolchRealm;
import li.strolch.model.ModelGenerator;
import li.strolch.model.Resource;
import li.strolch.model.query.IdSelection;
import li.strolch.model.query.NameSelection;
import li.strolch.model.query.OrSelection;
import li.strolch.model.query.ParameterBagSelection;
import li.strolch.model.query.ParameterBagSelection.NullParameterBagSelection;
import li.strolch.model.query.ParameterSelection;
import li.strolch.model.query.ResourceQuery;
import li.strolch.model.query.ordering.OrderById;
import li.strolch.persistence.api.StrolchTransaction;
import li.strolch.privilege.model.Certificate;
import li.strolch.runtime.StrolchConstants;
import li.strolch.testbase.runtime.RuntimeMock;
import li.strolch.utils.StringMatchMode;
import li.strolch.utils.collections.DateRange;
import li.strolch.utils.iso8601.ISO8601FormatFactory;
public class ResourceDaoTest extends QueryTest {
private static RuntimeMock runtimeMock;
@BeforeClass
public static void beforeClass() throws Exception {
dropSchema(DB_URL, DB_USERNAME, DB_PASSWORD);
File rootPath = new File(RUNTIME_PATH);
File configSrc = new File(CONFIG_SRC);
runtimeMock = new RuntimeMock();
runtimeMock.mockRuntime(rootPath, configSrc);
new File(rootPath, DB_STORE_PATH_DIR).mkdir();
runtimeMock.startContainer();
Certificate cert = runtimeMock.getPrivilegeHandler().authenticate("test", "test".toCharArray());
StrolchRealm realm = runtimeMock.getRealm(StrolchConstants.DEFAULT_REALM);
try (StrolchTransaction tx = realm.openTx(cert, "test")) {
ResourceMap resourceMap = tx.getResourceMap();
resourceMap.add(tx, ModelGenerator.createResource("@1", "Resource 1", "MyType1"));
resourceMap.add(tx, ModelGenerator.createResource("@2", "Resource 2", "MyType1"));
resourceMap.add(tx, ModelGenerator.createResource("@3", "Resource 3", "MyType1"));
resourceMap.add(tx, ModelGenerator.createResource("@4", "Resource 4", "MyType2"));
resourceMap.add(tx, ModelGenerator.createResource("@5", "Resource 5", "MyType2"));
resourceMap.add(tx, ModelGenerator.createResource("@6", "Resource 6", "MyType2"));
tx.commitOnClose();
}
}
@AfterClass
public static void afterClass() {
if (runtimeMock != null)
runtimeMock.destroyRuntime();
}
@Test
public void shouldQueryResourceAll() throws SQLException {
ResourceQuery<Resource> query = ResourceQuery.query("MyType2", new OrderById(false));
query.withAny();
performResourceQuery(query, Arrays.asList("@6", "@5", "@4"));
}
@Test
public void shouldQueryResource1() throws SQLException {
ResourceQuery<Resource> query = ResourceQuery.query("MyType1", new OrderById());
query.or().with(new IdSelection("@1", "@2"),
new NameSelection("Resource 1", StringMatchMode.EQUALS_CASE_SENSITIVE));
performResourceQuery(query, Arrays.asList("@1", "@2"));
}
@Test
public void shouldQueryResource2() throws SQLException {
ResourceQuery<Resource> query = ResourceQuery.query("MyType1", new OrderById());
query.and().with(new OrSelection(new IdSelection("@1"), new IdSelection("@2")),
new OrSelection(new NameSelection("Resource 1", StringMatchMode.EQUALS_CASE_SENSITIVE),
new NameSelection("Resource 2", StringMatchMode.EQUALS_CASE_SENSITIVE)));
performResourceQuery(query, Arrays.asList("@1", "@2"));
}
@Test
public void shouldQueryResourceByBooleParam() throws SQLException {
ResourceQuery<Resource> query = ResourceQuery.query("MyType1", new OrderById());
query.and().with(ParameterSelection.booleanSelection("@bag01", "@param1", true));
performResourceQuery(query, Arrays.asList("@1", "@2", "@3"));
}
@Test
public void shouldQueryResourceByFloatParam() throws SQLException {
ResourceQuery<Resource> query = ResourceQuery.query("MyType1", new OrderById());
query.and().with(ParameterSelection.floatSelection("@bag01", "@param2", 44.3));
performResourceQuery(query, Arrays.asList("@1", "@2", "@3"));
}
@Test
public void shouldQueryResourceByIntegerParam() throws SQLException {
ResourceQuery<Resource> query = ResourceQuery.query("MyType1", new OrderById());
query.and().with(ParameterSelection.integerSelection("@bag01", "@param3", 77));
performResourceQuery(query, Arrays.asList("@1", "@2", "@3"));
}
@Test
public void shouldQueryResourceByLongParam() throws SQLException {
ResourceQuery<Resource> query = ResourceQuery.query("MyType2", new OrderById());
query.and().with(ParameterSelection.longSelection("@bag01", "@param4", 4453234566L));
performResourceQuery(query, Arrays.asList("@4", "@5", "@6"));
}
@Test
public void shouldQueryResourceByStringParam() throws SQLException {
List<String> expected = Arrays.asList("@1", "@2", "@3");
ResourceQuery<Resource> query = ResourceQuery.query("MyType1", new OrderById());
query.and().with(ParameterSelection.stringSelection("@bag01", "@param5", "Strolch",
StringMatchMode.EQUALS_CASE_SENSITIVE));
performResourceQuery(query, expected);
query = ResourceQuery.query("MyType1", new OrderById());
query.and().with(ParameterSelection.stringSelection("@bag01", "@param5", "strolch",
StringMatchMode.EQUALS_CASE_SENSITIVE));
performResourceQuery(query, Arrays.<String> asList());
query = ResourceQuery.query("MyType1", new OrderById());
query.and().with(ParameterSelection.stringSelection("@bag01", "@param5", "strolch",
StringMatchMode.EQUALS_CASE_INSENSITIVE));
performResourceQuery(query, expected);
query = ResourceQuery.query("MyType1", new OrderById());
query.and().with(ParameterSelection.stringSelection("@bag01", "@param5", "olch",
StringMatchMode.CONTAINS_CASE_INSENSITIVE));
performResourceQuery(query, expected);
query = ResourceQuery.query("MyType1", new OrderById());
query.and()
.with(ParameterSelection.stringSelection("@bag01", "@param5", "olch",
StringMatchMode.CONTAINS_CASE_INSENSITIVE),
ParameterSelection.stringSelection("@bag01", "@param5", "strolch",
StringMatchMode.CONTAINS_CASE_INSENSITIVE),
ParameterSelection.stringSelection("@bag01", "@param5", "Strolch",
StringMatchMode.EQUALS_CASE_SENSITIVE));
performResourceQuery(query, expected);
}
@Test
public void shouldQueryResourceByAnyTypeParam() throws SQLException {
ResourceQuery<Resource> query = ResourceQuery.query("MyType1", new OrderById());
query.and().with(ParameterSelection.anyTypeSelection("@bag01", "@param6",
ISO8601FormatFactory.getInstance().formatDate(new Date(1354295525628L)), StringMatchMode.ci()));
performResourceQuery(query, Arrays.asList("@1", "@2", "@3"));
query = ResourceQuery.query("MyType1", new OrderById());
query.and().with(ParameterSelection.anyTypeSelection("@bag01", "@param8", "P1D", StringMatchMode.ci()));
performResourceQuery(query, Arrays.asList("@1", "@2", "@3"));
}
@Test
public void shouldQueryResourceByDateParam() throws SQLException {
ResourceQuery<Resource> query = ResourceQuery.query("MyType1", new OrderById());
query.and().with(ParameterSelection.dateSelection("@bag01", "@param6", new Date(1354295525628L)));
performResourceQuery(query, Arrays.asList("@1", "@2", "@3"));
}
@Ignore("Not yet implemented")
@Test
public void shouldQueryResourceByDateRange() throws SQLException {
ResourceQuery<Resource> query = ResourceQuery.query("MyType1", new OrderById());
query.and().with(ParameterSelection.dateRangeSelection("@bag01", "@param6",
new DateRange().from(new Date(1354295525627L), false).to(new Date(1354295525629L), false)));
performResourceQuery(query, Arrays.asList("@1", "@2", "@3"));
}
@Test
public void shouldQueryResourceByDurationParam() throws SQLException {
ResourceQuery<Resource> query = ResourceQuery.query("MyType1", new OrderById());
query.and().with(ParameterSelection.durationSelection("@bag01", "@param8", "P1D"));
performResourceQuery(query, Arrays.asList("@1", "@2", "@3"));
}
@Test
public void shouldQueryResourceByNullParam1() throws SQLException {
ResourceQuery<Resource> query = ResourceQuery.query("MyType1", new OrderById());
query.and().with(ParameterSelection.nullSelection("@bag01", "@param6"));
performResourceQuery(query, Arrays.<String> asList());
}
@Test
public void shouldQueryResourceByNullParam2() throws SQLException {
ResourceQuery<Resource> query = ResourceQuery.query("MyType1", new OrderById());
query.and().with(ParameterSelection.nullSelection("@bag01", "@param"));
performResourceQuery(query, Arrays.asList("@1", "@2", "@3"));
}
@Test
public void shouldQueryResourceByBag() throws SQLException {
ResourceQuery<Resource> query = ResourceQuery.query("MyType1", new OrderById());
query.and().with(new ParameterBagSelection("@bag01"));
performResourceQuery(query, Arrays.asList("@1", "@2", "@3"));
}
@Test
public void shouldQueryResourceByNullBag() throws SQLException {
ResourceQuery<Resource> query = ResourceQuery.query("MyType1", new OrderById());
query.and().with(new NullParameterBagSelection("@bag01"));
performResourceQuery(query, Arrays.<String> asList());
}
}

View File

@ -1,62 +1,102 @@
<?xml version="1.0"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>li.strolch</groupId>
<artifactId>li.strolch</artifactId>
<version>1.5.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<parent>
<groupId>li.strolch</groupId>
<artifactId>li.strolch</artifactId>
<version>1.6.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>li.strolch.persistence.xml</artifactId>
<name>li.strolch.persistence.xml</name>
<description>Reference Persistence Implementation for Strolch</description>
<inceptionYear>2011</inceptionYear>
<artifactId>li.strolch.persistence.xml</artifactId>
<name>li.strolch.persistence.xml</name>
<description>Reference Persistence Implementation for Strolch</description>
<inceptionYear>2011</inceptionYear>
<dependencies>
<!-- main -->
<dependency>
<groupId>li.strolch</groupId>
<artifactId>li.strolch.model</artifactId>
</dependency>
<dependency>
<groupId>li.strolch</groupId>
<artifactId>li.strolch.agent</artifactId>
</dependency>
<dependency>
<groupId>li.strolch</groupId>
<artifactId>li.strolch.xmlpers</artifactId>
</dependency>
<dependencies>
<!-- test -->
<dependency>
<groupId>li.strolch</groupId>
<artifactId>li.strolch.testbase</artifactId>
<scope>test</scope>
</dependency>
<!-- Base -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
</dependencies>
<!-- main -->
<dependency>
<groupId>li.strolch</groupId>
<artifactId>li.strolch.model</artifactId>
</dependency>
<dependency>
<groupId>li.strolch</groupId>
<artifactId>li.strolch.agent</artifactId>
</dependency>
<dependency>
<groupId>li.strolch</groupId>
<artifactId>li.strolch.xmlpers</artifactId>
</dependency>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/*.properties</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>buildnumber-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
</plugin>
</plugins>
</build>
<!-- test -->
<dependency>
<groupId>li.strolch</groupId>
<artifactId>li.strolch.testbase</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-library</artifactId>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>false</filtering>
<excludes>
<exclude>**/componentVersion.properties</exclude>
</excludes>
<includes>
<include>**/*.properties</include>
<include>**/*.sql</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/componentVersion.properties</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>buildnumber-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@ -1,12 +1,12 @@
/*
* 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.
@ -16,7 +16,6 @@
package li.strolch.persistence.xml;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@ -31,30 +30,21 @@ import li.strolch.xmlpers.objref.TypeRef;
public abstract class AbstractDao<T extends StrolchRootElement> implements StrolchDao<T> {
private XmlStrolchTransaction strolchTx;
protected PersistenceTransaction tx;
protected AbstractDao(StrolchTransaction tx) {
this.strolchTx = (XmlStrolchTransaction) tx;
XmlStrolchTransaction strolchTx = (XmlStrolchTransaction) tx;
this.tx = strolchTx.getTx();
}
protected abstract String getClassType();
protected IdOfSubTypeRef getIdRef(String type, String id) {
IdOfSubTypeRef idRef = this.tx.getObjectRefCache().getIdOfSubTypeRef(getClassType(), type, id);
return idRef;
return this.tx.getManager().getObjectRefCache().getIdOfSubTypeRef(getClassType(), type, id);
}
protected SubTypeRef getTypeRef(String type) {
SubTypeRef typeRef = this.tx.getObjectRefCache().getSubTypeRef(getClassType(), type);
return typeRef;
}
@Override
public boolean hasElement(String type, String id) {
IdOfSubTypeRef ref = getIdRef(type, id);
return this.tx.getObjectDao().hasElement(ref);
private SubTypeRef getTypeRef(String type) {
return this.tx.getManager().getObjectRefCache().getSubTypeRef(getClassType(), type);
}
@Override
@ -75,52 +65,10 @@ public abstract class AbstractDao<T extends StrolchRootElement> implements Strol
return this.tx.getMetadataDao().querySize(subTypeRef);
}
@Override
public Set<String> queryKeySet() {
Set<String> keys = new HashSet<>();
Set<String> types = queryTypes();
for (String type : types) {
keys.addAll(queryKeySet(type));
}
return keys;
}
@Override
public Set<String> queryKeySet(String type) {
SubTypeRef typeRef = getTypeRef(type);
Set<String> keys = this.tx.getMetadataDao().queryKeySet(typeRef);
return keys;
}
@Override
public Set<String> queryTypes() {
TypeRef typeRef = this.tx.getObjectRefCache().getTypeRef(getClassType());
Set<String> types = this.tx.getMetadataDao().queryTypeSet(typeRef);
return types;
}
@Override
public T queryBy(String type, String id) {
T t = this.tx.getObjectDao().queryById(getIdRef(type, id));
return t;
}
@Override
public T queryBy(String type, String id, int version) {
// TODO Auto-generated method stub
return null;
}
@Override
public List<T> queryVersionsFor(String type, String id) {
// TODO Auto-generated method stub
return null;
}
@Override
public long queryVersionsSizeFor(String type, String id) {
// TODO Auto-generated method stub
return 0;
TypeRef typeRef = this.tx.getManager().getObjectRefCache().getTypeRef(getClassType());
return this.tx.getMetadataDao().queryTypeSet(typeRef);
}
@Override
@ -137,8 +85,7 @@ public abstract class AbstractDao<T extends StrolchRootElement> implements Strol
@Override
public List<T> queryAll(String type) {
List<T> objectsByType = this.tx.getObjectDao().queryAll(getTypeRef(type));
return objectsByType;
return this.tx.getObjectDao().queryAll(getTypeRef(type));
}
@Override
@ -173,7 +120,7 @@ public abstract class AbstractDao<T extends StrolchRootElement> implements Strol
@Override
public long removeAll() {
TypeRef typeRef = this.tx.getObjectRefCache().getTypeRef(getClassType());
TypeRef typeRef = this.tx.getManager().getObjectRefCache().getTypeRef(getClassType());
return this.tx.getObjectDao().removeAllBy(typeRef);
}
@ -184,14 +131,32 @@ public abstract class AbstractDao<T extends StrolchRootElement> implements Strol
}
@Override
public void removeVersion(T element) throws StrolchPersistenceException {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("not yet implemented!");
public void flush() {
// nothing to do
}
@Override
public void flush() {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("not yet implemented!");
public void removeVersion(T element) throws StrolchPersistenceException {
throw new UnsupportedOperationException("Versioning is not supported!");
}
@Override
public T queryBy(String type, String id, int version) {
throw new UnsupportedOperationException("Versioning is not supported!");
}
@Override
public List<T> queryVersionsFor(String type, String id) {
throw new UnsupportedOperationException("Versioning is not supported!");
}
@Override
public long queryVersionsSizeFor(String type, String id) {
throw new UnsupportedOperationException("Versioning is not supported!");
}
@Override
public int queryLatestVersionFor(String type, String id) throws StrolchPersistenceException {
throw new UnsupportedOperationException("Versioning is not supported!");
}
}

View File

@ -1,12 +1,12 @@
/*
* 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.
@ -15,11 +15,8 @@
*/
package li.strolch.persistence.xml;
import java.util.List;
import li.strolch.model.Tags;
import li.strolch.model.activity.Activity;
import li.strolch.model.query.ActivityQuery;
import li.strolch.persistence.api.ActivityDao;
import li.strolch.persistence.api.StrolchTransaction;
@ -33,10 +30,4 @@ public class XmlActivityDao extends AbstractDao<Activity> implements ActivityDao
protected String getClassType() {
return Tags.ACTIVITY;
}
@Override
public <U> List<U> doQuery(ActivityQuery<U> query) {
// TODO implement XML file based querying...
throw new UnsupportedOperationException("not yet implemented!");
}
}

View File

@ -1,12 +1,12 @@
/*
* 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.
@ -49,13 +49,11 @@ public class XmlAuditDao implements AuditDao {
}
protected IdOfSubTypeRef getIdRef(String type, Long id) {
IdOfSubTypeRef idRef = this.tx.getObjectRefCache().getIdOfSubTypeRef(getClassType(), type, id.toString());
return idRef;
return this.tx.getManager().getObjectRefCache().getIdOfSubTypeRef(getClassType(), type, id.toString());
}
protected SubTypeRef getTypeRef(String type) {
SubTypeRef typeRef = this.tx.getObjectRefCache().getSubTypeRef(getClassType(), type);
return typeRef;
return this.tx.getManager().getObjectRefCache().getSubTypeRef(getClassType(), type);
}
@Override
@ -97,15 +95,13 @@ public class XmlAuditDao implements AuditDao {
@Override
public Set<String> queryTypes() {
TypeRef typeRef = this.tx.getObjectRefCache().getTypeRef(getClassType());
Set<String> types = this.tx.getMetadataDao().queryTypeSet(typeRef);
return types;
TypeRef typeRef = this.tx.getManager().getObjectRefCache().getTypeRef(getClassType());
return this.tx.getMetadataDao().queryTypeSet(typeRef);
}
@Override
public Audit queryBy(String type, Long id) {
Audit t = this.tx.getObjectDao().queryById(getIdRef(type, id));
return t;
return this.tx.getObjectDao().queryById(getIdRef(type, id));
}
@Override
@ -190,7 +186,6 @@ public class XmlAuditDao implements AuditDao {
@Override
public <U> List<U> doQuery(AuditQuery<U> query) {
// TODO implement XML file based querying...
throw new UnsupportedOperationException("not yet implemented!");
throw new UnsupportedOperationException("not yet supported!");
}
}

View File

@ -15,11 +15,8 @@
*/
package li.strolch.persistence.xml;
import java.util.List;
import li.strolch.model.Order;
import li.strolch.model.Tags;
import li.strolch.model.query.OrderQuery;
import li.strolch.persistence.api.OrderDao;
import li.strolch.persistence.api.StrolchTransaction;
@ -33,10 +30,4 @@ public class XmlOrderDao extends AbstractDao<Order> implements OrderDao {
protected String getClassType() {
return Tags.ORDER;
}
@Override
public <U> List<U> doQuery(OrderQuery<U> query) {
// TODO implement XML file based querying...
throw new UnsupportedOperationException("not yet implemented!");
}
}

View File

@ -1,12 +1,12 @@
/*
* 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.
@ -15,77 +15,172 @@
*/
package li.strolch.persistence.xml;
import static li.strolch.agent.impl.DefaultRealmHandler.PREFIX_DATA_STORE_FILE;
import static li.strolch.runtime.StrolchConstants.makeRealmKey;
import java.io.File;
import java.util.Properties;
import java.text.MessageFormat;
import java.util.*;
import li.strolch.agent.api.ComponentContainer;
import li.strolch.agent.api.RealmHandler;
import li.strolch.agent.api.StrolchComponent;
import li.strolch.agent.api.StrolchRealm;
import li.strolch.agent.impl.StoreToDaoElementListener;
import li.strolch.model.ModelStatistics;
import li.strolch.model.Order;
import li.strolch.model.Resource;
import li.strolch.model.Tags;
import li.strolch.model.activity.Activity;
import li.strolch.model.audit.Audit;
import li.strolch.persistence.api.ActivityDao;
import li.strolch.persistence.api.AuditDao;
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.model.xml.XmlModelSaxFileReader;
import li.strolch.persistence.api.*;
import li.strolch.persistence.xml.model.ActivityContextFactory;
import li.strolch.persistence.xml.model.AuditContextFactory;
import li.strolch.persistence.xml.model.OrderContextFactory;
import li.strolch.persistence.xml.model.ResourceContextFactory;
import li.strolch.privilege.model.Certificate;
import li.strolch.runtime.configuration.ComponentConfiguration;
import li.strolch.runtime.configuration.RuntimeConfiguration;
import li.strolch.runtime.configuration.StrolchConfiguration;
import li.strolch.runtime.configuration.StrolchConfigurationException;
import li.strolch.xmlpers.api.IoMode;
import li.strolch.xmlpers.api.PersistenceConstants;
import li.strolch.xmlpers.api.PersistenceManager;
import li.strolch.xmlpers.api.PersistenceManagerLoader;
import li.strolch.xmlpers.api.PersistenceTransaction;
import li.strolch.xmlpers.api.*;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*/
public class XmlPersistenceHandler extends StrolchComponent implements PersistenceHandler {
public static final String DB_STORE_PATH = "dbStore/"; //$NON-NLS-1$
private PersistenceManager persistenceManager;
public static final String PROP_DB_STORE_PATH = "dbStorePath";
public static final String PROP_DB_IGNORE_REALM = "ignoreRealm"; //$NON-NLS-1$
public static final String PROP_ALLOW_DATA_INIT_ON_EMPTY_DB = "allowDataInitOnEmptyDb";
public static final String PROP_VERBOSE = "verbose"; //$NON-NLS-1$
private Map<String, PersistenceStore> persistenceStoreMap;
public XmlPersistenceHandler(ComponentContainer container, String componentName) {
super(container, componentName);
}
@Override
public void initialize(ComponentConfiguration componentConfiguration) throws Exception {
public void initialize(ComponentConfiguration configuration) throws Exception {
File basePathF = componentConfiguration.getRuntimeConfiguration().getDataPath();
File dbStorePathF = new File(basePathF, DB_STORE_PATH);
if (!dbStorePathF.exists() && !dbStorePathF.mkdir()) {
throw new StrolchConfigurationException("Could not create store path at " + dbStorePathF.getAbsolutePath());
this.persistenceStoreMap = new HashMap<>();
Set<String> dbStorePaths = new HashSet<>();
Set<String> realmNames = getContainer().getRealmNames();
for (String realmName : realmNames) {
StrolchRealm realm = getContainer().getRealm(realmName);
if (realm.getMode().isTransient())
continue;
String dbIgnoreRealmKey = makeRealmKey(realmName, PROP_DB_IGNORE_REALM);
String dbStorePathKey = makeRealmKey(realmName, PROP_DB_STORE_PATH);
String dbVerboseKey = makeRealmKey(realmName, PROP_VERBOSE);
boolean dbIgnoreRealm = configuration.getBoolean(dbIgnoreRealmKey, Boolean.FALSE);
if (dbIgnoreRealm) {
logger.info("Ignoring any DB configuration for Realm " + realmName);
continue;
}
String dbStorePath = configuration.getString(dbStorePathKey, null);
boolean verbose = configuration.getBoolean(dbVerboseKey, Boolean.FALSE);
// validate URL
if (dbStorePaths.contains(dbStorePath))
throw new IllegalStateException(
"The " + PROP_DB_STORE_PATH + " " + dbStorePath + " is already used by another realm!");
dbStorePaths.add(dbStorePath);
File basePathF = configuration.getRuntimeConfiguration().getDataPath();
File dbStorePathF = new File(basePathF, dbStorePath);
if (!dbStorePathF.exists() && !dbStorePathF.mkdir()) {
throw new StrolchConfigurationException(
"Could not create store path at " + dbStorePathF.getAbsolutePath());
}
// build a PersistenceManager
Properties properties = new Properties();
properties.setProperty(PersistenceConstants.PROP_VERBOSE, Boolean.toString(verbose));
properties.setProperty(PersistenceConstants.PROP_XML_IO_MOD, IoMode.SAX.name());
properties.setProperty(PersistenceConstants.PROP_BASEPATH, dbStorePathF.getAbsolutePath());
PersistenceManager persistenceManager = PersistenceManagerLoader.load(properties);
PersistenceContextFactoryDelegator ctxFactory = persistenceManager.getCtxFactory();
ctxFactory.registerPersistenceContextFactory(Resource.class, Tags.RESOURCE, new ResourceContextFactory());
ctxFactory.registerPersistenceContextFactory(Order.class, Tags.ORDER, new OrderContextFactory());
ctxFactory.registerPersistenceContextFactory(Audit.class, Tags.AUDIT, new AuditContextFactory());
ctxFactory.registerPersistenceContextFactory(Activity.class, Tags.ACTIVITY, new ActivityContextFactory());
PersistenceStore persistenceStore = new PersistenceStore();
persistenceStore.dbStorePathF = dbStorePathF;
persistenceStore.persistenceManager = persistenceManager;
this.persistenceStoreMap.put(realmName, persistenceStore);
}
Properties properties = new Properties();
properties.setProperty(PersistenceConstants.PROP_VERBOSE, componentConfiguration.getString("verbose", "false")); //$NON-NLS-1$
properties.setProperty(PersistenceConstants.PROP_XML_IO_MOD, IoMode.DOM.name());
properties.setProperty(PersistenceConstants.PROP_BASEPATH, dbStorePathF.getAbsolutePath());
super.initialize(configuration);
}
this.persistenceManager = PersistenceManagerLoader.load(properties);
@Override
public void start() throws Exception {
this.persistenceManager.getCtxFactory().registerPersistenceContextFactory(Resource.class, Tags.RESOURCE,
new ResourceContextFactory());
this.persistenceManager.getCtxFactory().registerPersistenceContextFactory(Order.class, Tags.ORDER,
new OrderContextFactory());
this.persistenceManager.getCtxFactory().registerPersistenceContextFactory(Audit.class, Tags.AUDIT,
new AuditContextFactory());
for (String realmName : this.persistenceStoreMap.keySet()) {
super.initialize(componentConfiguration);
String allowDataInitOnEmptyDbKey = makeRealmKey(realmName, PROP_ALLOW_DATA_INIT_ON_EMPTY_DB);
boolean allowDataInitOnEmptyDb = getConfiguration().getBoolean(allowDataInitOnEmptyDbKey, Boolean.FALSE);
PersistenceStore persistenceStore = this.persistenceStoreMap.get(realmName);
File[] files = persistenceStore.dbStorePathF.listFiles();
if (files == null)
throw new IllegalStateException(persistenceStore.dbStorePathF.getAbsolutePath() + " does not exist!");
if (files.length == 0 && allowDataInitOnEmptyDb) {
logger.info("Initializing realm " + realmName + " as DB is empty.");
StrolchConfiguration strolchConfiguration = getContainer().getAgent().getStrolchConfiguration();
ComponentConfiguration realmConfiguration = strolchConfiguration
.getComponentConfiguration(RealmHandler.class.getSimpleName());
String dataStoreKey = makeRealmKey(realmName, PREFIX_DATA_STORE_FILE);
RuntimeConfiguration runtimeConfiguration = strolchConfiguration.getRuntimeConfiguration();
File dataStoreF = realmConfiguration.getDataFile(dataStoreKey, null, runtimeConfiguration, true);
runAsAgent(ctx -> {
ModelStatistics statistics;
try (StrolchTransaction tx = openTx(getContainer().getRealm(realmName), ctx.getCertificate(),
getClass().getSimpleName())) {
StoreToDaoElementListener listener = new StoreToDaoElementListener(tx);
XmlModelSaxFileReader handler = new XmlModelSaxFileReader(listener, dataStoreF, true);
handler.parseFile();
statistics = handler.getStatistics();
tx.commitOnClose();
}
logger.info(
MessageFormat.format("Realm {0} initialization statistics: {1}", realmName, statistics));
});
}
}
super.start();
}
class PersistenceStore {
PersistenceManager persistenceManager;
File dbStorePathF;
}
@SuppressWarnings("resource")
@Override
public StrolchTransaction openTx(StrolchRealm realm, Certificate certificate, String action) {
PersistenceTransaction tx = this.persistenceManager.openTx(realm.getRealm());
return new XmlStrolchTransaction(getContainer().getPrivilegeHandler(), realm, certificate, action, tx, this);
PersistenceStore persistenceStore = this.persistenceStoreMap.get(realm.getRealm());
if (persistenceStore == null)
throw new IllegalStateException("No XML persistence enabled for realm " + realm.getRealm());
PersistenceTransaction tx = persistenceStore.persistenceManager.openTx();
return new XmlStrolchTransaction(getContainer(), realm, certificate, action, tx, this);
}
@Override
@ -107,9 +202,4 @@ public class XmlPersistenceHandler extends StrolchComponent implements Persisten
public AuditDao getAuditDao(StrolchTransaction tx) {
return new XmlAuditDao(tx);
}
@Override
public void performDbInitialization() {
throw new UnsupportedOperationException("Not yet implemented!");
}
}

View File

@ -1,12 +1,12 @@
/*
* 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.
@ -15,11 +15,8 @@
*/
package li.strolch.persistence.xml;
import java.util.List;
import li.strolch.model.Resource;
import li.strolch.model.Tags;
import li.strolch.model.query.ResourceQuery;
import li.strolch.persistence.api.ResourceDao;
import li.strolch.persistence.api.StrolchTransaction;
@ -33,10 +30,4 @@ public class XmlResourceDao extends AbstractDao<Resource> implements ResourceDao
protected String getClassType() {
return Tags.RESOURCE;
}
@Override
public <U> List<U> doQuery(ResourceQuery<U> query) {
// TODO implement XML file based querying...
throw new UnsupportedOperationException("not yet implemented!");
}
}

View File

@ -1,12 +1,12 @@
/*
* 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.
@ -17,11 +17,11 @@ package li.strolch.persistence.xml;
import java.util.Set;
import li.strolch.agent.api.ComponentContainer;
import li.strolch.agent.api.StrolchRealm;
import li.strolch.persistence.api.AbstractTransaction;
import li.strolch.persistence.api.PersistenceHandler;
import li.strolch.privilege.model.Certificate;
import li.strolch.runtime.privilege.PrivilegeHandler;
import li.strolch.xmlpers.api.ModificationResult;
import li.strolch.xmlpers.api.PersistenceTransaction;
import li.strolch.xmlpers.api.TransactionResult;
@ -31,9 +31,9 @@ public class XmlStrolchTransaction extends AbstractTransaction {
private XmlPersistenceHandler persistenceHandler;
private PersistenceTransaction tx;
public XmlStrolchTransaction(PrivilegeHandler privilegeHandler, StrolchRealm realm, Certificate certificate,
public XmlStrolchTransaction(ComponentContainer container, StrolchRealm realm, Certificate certificate,
String action, PersistenceTransaction tx, XmlPersistenceHandler persistenceHandler) {
super(privilegeHandler, realm, certificate, action);
super(container, realm, certificate, action);
this.persistenceHandler = persistenceHandler;
this.tx = tx;
}
@ -44,9 +44,29 @@ public class XmlStrolchTransaction extends AbstractTransaction {
@Override
protected void writeChanges() throws Exception {
TransactionResult result = new TransactionResult();
this.tx.setTransactionResult(result);
// do nothing
}
@Override
protected void rollback() throws Exception {
this.tx.autoCloseableRollback();
}
@Override
protected void commit() throws Exception {
if (!this.tx.hasTransactionResult()) {
TransactionResult result = new TransactionResult();
this.tx.setTransactionResult(result);
}
this.tx.autoCloseableCommit();
TransactionResult txResult = this.tx.getTransactionResult();
updateTxResult(txResult);
txResult.clear();
}
private void updateTxResult(TransactionResult result) {
Set<String> keys = result.getKeys();
for (String key : keys) {
ModificationResult modificationResult = result.getModificationResult(key);
@ -56,16 +76,6 @@ public class XmlStrolchTransaction extends AbstractTransaction {
}
}
@Override
protected void rollback() throws Exception {
this.tx.autoCloseableRollback();
}
@Override
protected void commit() throws Exception {
// no-op
}
@Override
public PersistenceHandler getPersistenceHandler() {
return this.persistenceHandler;

View File

@ -1,51 +0,0 @@
/*
* 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.persistence.xml.model;
import li.strolch.model.activity.Activity;
import li.strolch.model.xml.ActivityFromDomVisitor;
import li.strolch.model.xml.ActivityToDomVisitor;
import li.strolch.xmlpers.api.DomParser;
import org.w3c.dom.Document;
public class ActivityDomParser implements DomParser<Activity> {
private Activity activity;
@Override
public Activity getObject() {
return this.activity;
}
@Override
public void setObject(Activity activity) {
this.activity = activity;
}
@Override
public Document toDom() {
ActivityToDomVisitor activityDomVisitor = new ActivityToDomVisitor();
activityDomVisitor.visit(this.activity);
return activityDomVisitor.getDocument();
}
@Override
public void fromDom(Document document) {
Activity activity = new ActivityFromDomVisitor().visit(document);
this.activity = activity;
}
}

View File

@ -1,12 +1,12 @@
/*
* 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.
@ -24,7 +24,7 @@ public class ActivityParserFactory implements ParserFactory<Activity> {
@Override
public DomParser<Activity> getDomParser() {
return new ActivityDomParser();
throw new UnsupportedOperationException("DOM Mode is not supported!");
}
@Override

View File

@ -1,12 +1,12 @@
/*
* Copyright 2015 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.
@ -21,11 +21,11 @@ import javax.xml.stream.XMLStreamWriter;
import li.strolch.model.Order;
import li.strolch.model.Resource;
import li.strolch.model.activity.Activity;
import li.strolch.model.xml.ActivityToSaxWriterVisitor;
import li.strolch.model.xml.StrolchElementListener;
import li.strolch.model.xml.StrolchElementToSaxWriterVisitor;
import li.strolch.model.xml.XmlModelSaxReader;
import li.strolch.utils.dbc.DBC;
import li.strolch.xmlpers.api.SaxParser;
import org.xml.sax.helpers.DefaultHandler;
/**
@ -61,6 +61,7 @@ public class ActivitySaxParser implements SaxParser<Activity> {
@Override
public void notifyActivity(Activity activity) {
DBC.PRE.assertNull("Only expected one activity!", ActivitySaxParser.this.activity);
ActivitySaxParser.this.activity = activity;
}
});
@ -68,6 +69,6 @@ public class ActivitySaxParser implements SaxParser<Activity> {
@Override
public void write(XMLStreamWriter xmlWriter) throws XMLStreamException {
new ActivityToSaxWriterVisitor(xmlWriter);
this.activity.accept(new StrolchElementToSaxWriterVisitor(xmlWriter));
}
}

View File

@ -46,7 +46,6 @@ public class AuditDomParser implements DomParser<Audit> {
@Override
public void fromDom(Document document) {
Element rootElement = document.getDocumentElement();
Audit audit = new AuditFromDomReader().from(rootElement);
this.audit = audit;
this.audit = new AuditFromDomReader().from(rootElement);
}
}

View File

@ -29,6 +29,6 @@ public class AuditParserFactory implements ParserFactory<Audit> {
@Override
public SaxParser<Audit> getSaxParser() {
throw new UnsupportedOperationException("Not yet implemented!"); //$NON-NLS-1$
return new AuditSaxParser();
}
}

View File

@ -0,0 +1,53 @@
/*
* Copyright 2015 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.persistence.xml.model;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import li.strolch.model.audit.Audit;
import li.strolch.model.audit.AuditSaxReader;
import li.strolch.model.audit.AuditToSaxWriterVisitor;
import li.strolch.xmlpers.api.SaxParser;
import org.xml.sax.helpers.DefaultHandler;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*/
public class AuditSaxParser implements SaxParser<Audit> {
private Audit audit;
@Override
public Audit getObject() {
return this.audit;
}
@Override
public void setObject(Audit audit) {
this.audit = audit;
}
@Override
public DefaultHandler getDefaultHandler() {
return new AuditSaxReader(audit1 -> this.audit = audit1);
}
@Override
public void write(XMLStreamWriter xmlWriter) throws XMLStreamException {
this.audit.accept(new AuditToSaxWriterVisitor(xmlWriter));
}
}

View File

@ -1,51 +0,0 @@
/*
* 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.persistence.xml.model;
import li.strolch.model.Order;
import li.strolch.model.xml.OrderFromDomVisitor;
import li.strolch.model.xml.OrderToDomVisitor;
import li.strolch.xmlpers.api.DomParser;
import org.w3c.dom.Document;
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() {
OrderToDomVisitor orderDomVisitor = new OrderToDomVisitor();
orderDomVisitor.visit(this.order);
return orderDomVisitor.getDocument();
}
@Override
public void fromDom(Document document) {
Order order = new OrderFromDomVisitor().visit(document);
this.order = order;
}
}

View File

@ -24,7 +24,7 @@ public class OrderParserFactory implements ParserFactory<Order> {
@Override
public DomParser<Order> getDomParser() {
return new OrderDomParser();
throw new UnsupportedOperationException("DOM Mode is not supported!");
}
@Override

View File

@ -1,12 +1,12 @@
/*
* Copyright 2015 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.
@ -21,11 +21,11 @@ import javax.xml.stream.XMLStreamWriter;
import li.strolch.model.Order;
import li.strolch.model.Resource;
import li.strolch.model.activity.Activity;
import li.strolch.model.xml.OrderToSaxWriterVisitor;
import li.strolch.model.xml.StrolchElementListener;
import li.strolch.model.xml.StrolchElementToSaxWriterVisitor;
import li.strolch.model.xml.XmlModelSaxReader;
import li.strolch.utils.dbc.DBC;
import li.strolch.xmlpers.api.SaxParser;
import org.xml.sax.helpers.DefaultHandler;
/**
@ -56,6 +56,7 @@ public class OrderSaxParser implements SaxParser<Order> {
@Override
public void notifyOrder(Order order) {
DBC.PRE.assertNull("Only expected one order!", OrderSaxParser.this.order);
OrderSaxParser.this.order = order;
}
@ -68,6 +69,6 @@ public class OrderSaxParser implements SaxParser<Order> {
@Override
public void write(XMLStreamWriter xmlWriter) throws XMLStreamException {
new OrderToSaxWriterVisitor(xmlWriter);
this.order.accept(new StrolchElementToSaxWriterVisitor(xmlWriter));
}
}

View File

@ -1,51 +0,0 @@
/*
* 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.persistence.xml.model;
import li.strolch.model.Resource;
import li.strolch.model.xml.ResourceFromDomVisitor;
import li.strolch.model.xml.ResourceToDomVisitor;
import li.strolch.xmlpers.api.DomParser;
import org.w3c.dom.Document;
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() {
ResourceToDomVisitor domVisitor = new ResourceToDomVisitor();
domVisitor.visit(this.resource);
return domVisitor.getDocument();
}
@Override
public void fromDom(Document document) {
Resource resource = new ResourceFromDomVisitor().visit(document);
this.resource = resource;
}
}

View File

@ -1,12 +1,12 @@
/*
* 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.
@ -24,7 +24,7 @@ public class ResourceParserFactory implements ParserFactory<Resource> {
@Override
public DomParser<Resource> getDomParser() {
return new ResourceDomParser();
throw new UnsupportedOperationException("DOM Mode is not supported!");
}
@Override

View File

@ -1,12 +1,12 @@
/*
* Copyright 2015 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.
@ -21,11 +21,11 @@ import javax.xml.stream.XMLStreamWriter;
import li.strolch.model.Order;
import li.strolch.model.Resource;
import li.strolch.model.activity.Activity;
import li.strolch.model.xml.ResourceToSaxWriterVisitor;
import li.strolch.model.xml.StrolchElementListener;
import li.strolch.model.xml.StrolchElementToSaxWriterVisitor;
import li.strolch.model.xml.XmlModelSaxReader;
import li.strolch.utils.dbc.DBC;
import li.strolch.xmlpers.api.SaxParser;
import org.xml.sax.helpers.DefaultHandler;
/**
@ -51,6 +51,7 @@ public class ResourceSaxParser implements SaxParser<Resource> {
@Override
public void notifyResource(Resource resource) {
DBC.PRE.assertNull("Only expected one resource!", ResourceSaxParser.this.resource);
ResourceSaxParser.this.resource = resource;
}
@ -68,6 +69,6 @@ public class ResourceSaxParser implements SaxParser<Resource> {
@Override
public void write(XMLStreamWriter xmlWriter) throws XMLStreamException {
new ResourceToSaxWriterVisitor(xmlWriter);
this.resource.accept(new StrolchElementToSaxWriterVisitor(xmlWriter));
}
}

View File

@ -19,19 +19,17 @@ import static org.junit.Assert.assertNotNull;
import java.io.File;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import li.strolch.model.Order;
import li.strolch.model.Resource;
import li.strolch.persistence.api.StrolchTransaction;
import li.strolch.persistence.xml.XmlPersistenceHandler;
import li.strolch.privilege.model.Certificate;
import li.strolch.runtime.StrolchConstants;
import li.strolch.runtime.privilege.PrivilegeHandler;
import li.strolch.testbase.runtime.RuntimeMock;
import li.strolch.utils.helper.FileHelper;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
public class ExistingDbTest {
@ -49,8 +47,8 @@ public class ExistingDbTest {
runtimeMock = new RuntimeMock();
runtimeMock.mockRuntime(rootPath, configSrc);
File dbStoreSrcPath = new File(CONFIG_SRC, "data/" + XmlPersistenceHandler.DB_STORE_PATH);
File dbStoreDstPath = new File(RUNTIME_PATH, "data/" + XmlPersistenceHandler.DB_STORE_PATH);
File dbStoreSrcPath = new File(CONFIG_SRC, "data/dbStore");
File dbStoreDstPath = new File(RUNTIME_PATH, "data/dbStore");
if (!dbStoreDstPath.exists() && !dbStoreDstPath.mkdir()) {
throw new RuntimeException("Could not create db store " + dbStoreDstPath.getAbsolutePath());
}
@ -70,7 +68,7 @@ public class ExistingDbTest {
public void shouldQueryExistingData() {
PrivilegeHandler privilegeHandler = runtimeMock.getAgent().getContainer().getPrivilegeHandler();
Certificate certificate = privilegeHandler.authenticate(TEST, TEST.getBytes());
Certificate certificate = privilegeHandler.authenticate(TEST, TEST.toCharArray());
try (StrolchTransaction tx = runtimeMock.getRealm(StrolchConstants.DEFAULT_REALM).openTx(certificate, TEST)) {
Resource resource = tx.getResourceMap().getBy(tx, "MyType", "@1"); //$NON-NLS-1$ //$NON-NLS-2$

View File

@ -1,12 +1,12 @@
/*
* 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.
@ -112,19 +112,19 @@ public class ObserverUpdateTest {
realm.getObserverHandler().registerObserver(Tags.RESOURCE, observer);
PrivilegeHandler privilegeHandler = runtimeMock.getAgent().getContainer().getPrivilegeHandler();
Certificate certificate = privilegeHandler.authenticate(TEST, TEST.getBytes());
Certificate certificate = privilegeHandler.authenticate(TEST, TEST.toCharArray());
// create order
Order newOrder = createOrder("MyTestOrder", "Test Name", "TestType", new Date(), State.CREATED); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
Order newOrder = createOrder("MyTestOrder", "Test Name", "TestType", new Date(), State.CREATED);
try (StrolchTransaction tx = realm.openTx(certificate, TEST)) {
tx.getOrderMap().add(tx, newOrder);
tx.add(newOrder);
tx.commitOnClose();
}
// create resource
Resource newResource = createResource("MyTestResource", "Test Name", "TestType"); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
Resource newResource = createResource("MyTestResource", "Test Name", "TestType");
try (StrolchTransaction tx = realm.openTx(certificate, TEST)) {
tx.getResourceMap().add(tx, newResource);
tx.add(newResource);
tx.commitOnClose();
}

View File

@ -1,12 +1,12 @@
/*
* 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.
@ -15,13 +15,17 @@
*/
package li.strolch.persistence.impl.dao.test;
import static org.junit.Assert.assertTrue;
import java.io.File;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import li.strolch.persistence.api.StrolchTransaction;
import li.strolch.privilege.model.Certificate;
import li.strolch.runtime.StrolchConstants;
import li.strolch.testbase.runtime.AbstractModelTest;
import li.strolch.testbase.runtime.RuntimeMock;
import org.junit.AfterClass;
import org.junit.BeforeClass;
public class XmlCachedDaoTest extends AbstractModelTest {
@ -43,6 +47,13 @@ public class XmlCachedDaoTest extends AbstractModelTest {
runtimeMock = new RuntimeMock();
runtimeMock.mockRuntime(rootPath, configSrc);
runtimeMock.startContainer();
// check that the data was initialized
Certificate certificate = runtimeMock.getPrivilegeHandler().authenticate("test", "test".toCharArray());
try (StrolchTransaction tx = runtimeMock.getRealm(StrolchConstants.DEFAULT_REALM).openTx(certificate, "test")) {
assertTrue("Model was not properly initialized!", tx.hasResource("Template", "TestType"));
assertTrue("Model was not properly initialized!", tx.hasOrder("Template", "MyTestOrder"));
}
}
@AfterClass

View File

@ -1,52 +0,0 @@
/*
* 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.persistence.impl.dao.test;
import java.io.File;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import li.strolch.testbase.runtime.AbstractModelTest;
import li.strolch.testbase.runtime.RuntimeMock;
public class XmlTransactionalDaoTest extends AbstractModelTest {
public static final String RUNTIME_PATH = "target/transactionalStrolchRuntime/"; //$NON-NLS-1$
public static final String CONFIG_SRC = "src/test/resources/transactionalruntime"; //$NON-NLS-1$
protected static RuntimeMock runtimeMock;
@Override
protected RuntimeMock getRuntimeMock() {
return runtimeMock;
}
@BeforeClass
public static void beforeClass() {
File rootPath = new File(RUNTIME_PATH);
File configSrc = new File(CONFIG_SRC);
runtimeMock = new RuntimeMock();
runtimeMock.mockRuntime(rootPath, configSrc);
runtimeMock.startContainer();
}
@AfterClass
public static void afterClass() {
runtimeMock.destroyRuntime();
}
}

View File

@ -1,39 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<StrolchConfiguration>
<env id="dev">
<Runtime>
<applicationName>StrolchPersistenceTest</applicationName>
<Properties>
<verbose>true</verbose>
</Properties>
</Runtime>
<Component>
<name>PrivilegeHandler</name>
<api>li.strolch.runtime.privilege.PrivilegeHandler</api>
<impl>li.strolch.runtime.privilege.DefaultStrolchPrivilegeHandler</impl>
<Properties>
<privilegeConfigFile>PrivilegeConfig.xml</privilegeConfigFile>
</Properties>
</Component>
<Component>
<name>RealmHandler</name>
<api>li.strolch.agent.api.RealmHandler</api>
<impl>li.strolch.agent.impl.DefaultRealmHandler</impl>
<depends>PrivilegeHandler</depends>
<depends>PersistenceHandler</depends>
<Properties>
<dataStoreMode>CACHED</dataStoreMode>
<enableAuditTrail>true</enableAuditTrail>
<enableObserverUpdates>true</enableObserverUpdates>
</Properties>
</Component>
<Component>
<name>PersistenceHandler</name>
<api>li.strolch.persistence.api.PersistenceHandler</api>
<impl>li.strolch.persistence.xml.XmlPersistenceHandler</impl>
<Properties>
<verbose>true</verbose>
</Properties>
</Component>
</env>
<env id="dev">
<Runtime>
<applicationName>StrolchPersistenceTest</applicationName>
<Properties>
<verbose>true</verbose>
</Properties>
</Runtime>
<Component>
<name>PrivilegeHandler</name>
<api>li.strolch.runtime.privilege.PrivilegeHandler</api>
<impl>li.strolch.runtime.privilege.DefaultStrolchPrivilegeHandler</impl>
<Properties>
<privilegeConfigFile>PrivilegeConfig.xml</privilegeConfigFile>
</Properties>
</Component>
<Component>
<name>RealmHandler</name>
<api>li.strolch.agent.api.RealmHandler</api>
<impl>li.strolch.agent.impl.DefaultRealmHandler</impl>
<depends>PrivilegeHandler</depends>
<depends>PersistenceHandler</depends>
<Properties>
<dataStoreMode>CACHED</dataStoreMode>
<enableAuditTrail>true</enableAuditTrail>
<enableObserverUpdates>true</enableObserverUpdates>
<dataStoreFile>DefaultRealm.xml</dataStoreFile>
</Properties>
</Component>
<Component>
<name>PersistenceHandler</name>
<api>li.strolch.persistence.api.PersistenceHandler</api>
<impl>li.strolch.persistence.xml.XmlPersistenceHandler</impl>
<Properties>
<dbStorePath>dbStore</dbStorePath>
<allowDataInitOnEmptyDb>true</allowDataInitOnEmptyDb>
</Properties>
</Component>
</env>
</StrolchConfiguration>

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<StrolchModel>
<Resource Id="TestType" Name="TestType Template" Type="Template">
<ParameterBag Id="@bag01" Name="Test Bag" Type="TestBag">
<Parameter Id="@param7" Name="StringList Param" Type="StringList" Value="Hello;World" />
<Parameter Id="@param6" Name="Date Param" Type="Date" Value="2012-11-30T18:12:05.628+01:00" />
<Parameter Id="@param5" Name="String Param" Type="String" Value="Strolch" />
<Parameter Id="@param4" Name="Long Param" Type="Long" Value="4453234566" />
<Parameter Id="@param3" Name="Integer Param" Type="Integer" Value="77" />
<Parameter Id="@param2" Name="Float Param" Type="Float" Value="44.3" />
<Parameter Id="@param1" Name="Boolean Param" Type="Boolean" Value="true" />
</ParameterBag>
</Resource>
<Order Id="MyTestOrder" Name="MyTestOrder Template" Type="Template">
<ParameterBag Id="@bag01" Name="Test Bag" Type="TestBag">
<Parameter Id="@param7" Name="StringList Param" Type="StringList" Value="Hello;World" />
<Parameter Id="@param6" Name="Date Param" Type="Date" Value="2012-11-30T18:12:05.628+01:00" />
<Parameter Id="@param5" Name="String Param" Type="String" Value="Strolch" />
<Parameter Id="@param4" Name="Long Param" Type="Long" Value="4453234566" />
<Parameter Id="@param3" Name="Integer Param" Type="Integer" Value="77" />
<Parameter Id="@param2" Name="Float Param" Type="Float" Value="44.3" />
<Parameter Id="@param1" Name="Boolean Param" Type="Boolean" Value="true" />
</ParameterBag>
</Order>
</StrolchModel>

View File

@ -30,7 +30,7 @@
<api>li.strolch.persistence.api.PersistenceHandler</api>
<impl>li.strolch.persistence.xml.XmlPersistenceHandler</impl>
<Properties>
<verbose>true</verbose>
<dbStorePath>dbStore</dbStorePath>
</Properties>
</Component>
</env>

View File

@ -1,41 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Privilege>
<Container>
<Parameters>
<!-- parameters for the container itself -->
<Parameter name="autoPersistOnUserChangesData" value="true" />
</Parameters>
<EncryptionHandler class="li.strolch.privilege.handler.DefaultEncryptionHandler">
<Parameters>
<!-- WARNING: If you change iterations or keyLength, then all passwords are invalid -->
<!-- default algorithm is: PBKDF2WithHmacSHA512 -->
<Parameter name="hashAlgorithm" value="PBKDF2WithHmacSHA512" />
<!-- default iterations: 200000 -->
<Parameter name="hashIterations" value="10000" />
<!-- default key length: 256 -->
<Parameter name="hashKeyLength" value="256" />
</Parameters>
</EncryptionHandler>
<PersistenceHandler class="li.strolch.privilege.handler.XmlPersistenceHandler">
<Parameters>
<Parameter name="usersXmlFile" value="PrivilegeUsers.xml" />
<Parameter name="rolesXmlFile" value="PrivilegeRoles.xml" />
</Parameters>
</PersistenceHandler>
<UserChallengeHandler class="li.strolch.privilege.handler.ConsoleUserChallengeHandler">
</UserChallengeHandler>
</Container>
<Policies>
<Policy name="DefaultPrivilege" class="li.strolch.privilege.policy.DefaultPrivilege" />
<Policy name="RoleAccessPrivilege" class="li.strolch.privilege.policy.RoleAccessPrivilege" />
<Policy name="UserAccessPrivilege" class="li.strolch.privilege.policy.UserAccessPrivilege" />
</Policies>
</Privilege>

View File

@ -1,17 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Roles>
<Role name="agent">
<Privilege name="li.strolch.privilege.handler.SystemAction" policy="DefaultPrivilege">
<Allow>li.strolch.runtime.privilege.StrolchSystemAction</Allow>
<Allow>li.strolch.runtime.privilege.StrolchSystemActionWithResult</Allow>
</Privilege>
</Role>
<Role name="AppUser">
<Privilege name="li.strolch.service.api.Service" policy="DefaultPrivilege">
<AllAllowed>true</AllAllowed>
</Privilege>
<Privilege name="li.strolch.model.query.StrolchQuery" policy="DefaultPrivilege">
<AllAllowed>true</AllAllowed>
</Privilege>
</Role>
</Roles>

View File

@ -1,18 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Users>
<User userId="1" username="agent">
<State>SYSTEM</State>
<Roles>
<Role>agent</Role>
</Roles>
</User>
<User userId="2" username="test" password="fdd9d2def3475e1d5cc87107b87e14fd6adbca664c2874fc379a1e53931c0428" salt="74657374">
<Firstname>Application</Firstname>
<Lastname>Administrator</Lastname>
<State>ENABLED</State>
<Locale>en_GB</Locale>
<Roles>
<Role>AppUser</Role>
</Roles>
</User>
</Users>

View File

@ -1,38 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<StrolchConfiguration>
<env id="dev">
<Runtime>
<applicationName>StrolchPersistenceTest</applicationName>
<Properties>
<verbose>true</verbose>
</Properties>
</Runtime>
<Component>
<name>PrivilegeHandler</name>
<api>li.strolch.runtime.privilege.PrivilegeHandler</api>
<impl>li.strolch.runtime.privilege.DefaultStrolchPrivilegeHandler</impl>
<Properties>
<privilegeConfigFile>PrivilegeConfig.xml</privilegeConfigFile>
</Properties>
</Component>
<Component>
<name>RealmHandler</name>
<api>li.strolch.agent.api.RealmHandler</api>
<impl>li.strolch.agent.impl.DefaultRealmHandler</impl>
<depends>PrivilegeHandler</depends>
<depends>PersistenceHandler</depends>
<Properties>
<dataStoreMode>TRANSACTIONAL</dataStoreMode>
<enableAuditTrail>true</enableAuditTrail>
</Properties>
</Component>
<Component>
<name>PersistenceHandler</name>
<api>li.strolch.persistence.api.PersistenceHandler</api>
<impl>li.strolch.persistence.xml.XmlPersistenceHandler</impl>
<Properties>
<verbose>true</verbose>
</Properties>
</Component>
</env>
</StrolchConfiguration>

View File

@ -24,10 +24,12 @@ public class DbConstants {
public static final String PROP_DB_IGNORE_REALM = "db.ignore.realm"; //$NON-NLS-1$
public static final String PROP_DB_USERNAME = "db.username"; //$NON-NLS-1$
public static final String PROP_DB_PASSWORD = "db.password"; //$NON-NLS-1$
public static final String PROP_DB_VERBOSE = "db.verbose"; //$NON-NLS-1$
public static final String PROP_ALLOW_SCHEMA_CREATION = "allowSchemaCreation";
public static final String PROP_ALLOW_SCHEMA_MIGRATION = "allowSchemaMigration";
public static final String PROP_ALLOW_SCHEMA_DROP = "allowSchemaDrop";
public static final String PROP_ALLOW_DATA_INIT_ON_SCHEMA_CREATE = "allowDataInitOnSchemaCreate";
public static final String PROP_ALLOW_DATA_INIT_ON_EMPTY_DB = "allowDataInitOnEmptyDb";
public static final String PROP_DB_VERSION = "db_version";
public static final String RESOURCE_DB_VERSION = "/{0}_db_version.properties";
}

View File

@ -1,12 +1,12 @@
/*
* 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.
@ -18,6 +18,7 @@ package li.strolch.xmlpers.api;
import java.io.File;
import java.text.MessageFormat;
import li.strolch.utils.dbc.DBC;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -33,6 +34,8 @@ public class FileDao {
private final PathBuilder pathBuilder;
public FileDao(PersistenceTransaction tx, PathBuilder pathBuilder, boolean verbose) {
DBC.PRE.assertNotNull("TX must not be null!", tx);
DBC.PRE.assertNotNull("pathBuilder must not be null!", pathBuilder);
this.tx = tx;
this.pathBuilder = pathBuilder;
this.verbose = verbose;
@ -61,7 +64,7 @@ public class FileDao {
assertPathNotExists(path, objectRef);
createMissingParents(path, objectRef);
FileIo fileIo = new FileIo(path);
this.tx.getIoMode().write(ctx, fileIo);
this.tx.getManager().getIoMode().write(ctx, fileIo);
}
public <T> void performRead(PersistenceContext<T> ctx) {
@ -75,7 +78,7 @@ public class FileDao {
logPath(IoOperation.READ, path, objectRef);
FileIo fileIo = new FileIo(path);
this.tx.getIoMode().read(ctx, fileIo);
this.tx.getManager().getIoMode().read(ctx, fileIo);
}
public <T> void performUpdate(PersistenceContext<T> ctx) {
@ -85,7 +88,7 @@ public class FileDao {
logPath(IoOperation.UPDATE, path, objectRef);
assertPathIsFileAndWritable(path, objectRef);
FileIo fileIo = new FileIo(path);
this.tx.getIoMode().write(ctx, fileIo);
this.tx.getManager().getIoMode().write(ctx, fileIo);
}
public <T> void performDelete(PersistenceContext<T> ctx) {
@ -118,14 +121,27 @@ public class FileDao {
try {
File directoryPath = objectRef.getPath(this.pathBuilder);
if (!directoryPath.getAbsolutePath().startsWith(this.pathBuilder.getRootPath().getAbsolutePath())) {
String msg = "The path for {0} is invalid as not child of {1}"; //$NON-NLS-1$
msg = MessageFormat
.format(msg, directoryPath.getAbsolutePath(), this.pathBuilder.getRootPath().getAbsolutePath());
throw new IllegalArgumentException(msg);
}
if (!directoryPath.isDirectory()) {
String msg = "The path for {0} is not a directory: {1}"; //$NON-NLS-1$
msg = MessageFormat.format(msg, objectRef.getName(), directoryPath.getAbsolutePath());
throw new IllegalArgumentException(msg);
}
String[] list = directoryPath.list();
if (list == null) {
String msg = "The path for {0} is not a directory: {1}"; //$NON-NLS-1$
msg = MessageFormat.format(msg, objectRef.getName(), directoryPath.getAbsolutePath());
throw new IllegalArgumentException(msg);
}
// stop if empty
if (directoryPath.list().length != 0)
if (list.length != 0)
return;
// delete
@ -195,5 +211,4 @@ public class FileDao {
throw new XmlPersistenceException(msg);
}
}
}

View File

@ -1,12 +1,12 @@
/*
* 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.
@ -45,7 +45,7 @@ public class ObjectDao {
this.tx = tx;
this.fileDao = fileDao;
this.objectFilter = objectFilter;
this.ctxFactoryDelegator = this.tx.getRealm().getCtxFactoryDelegator();
this.ctxFactoryDelegator = this.tx.getManager().getCtxFactory();
}
public <T> void add(T object) {
@ -258,15 +258,14 @@ public class ObjectDao {
}
}
public Set<String> queryKeySet(ObjectRef parentRef) {
private Set<String> queryKeySet(ObjectRef parentRef) {
assertNotClosed();
assertIsNotIdRef(parentRef);
parentRef.lock();
try {
MetadataDao metadataDao = this.tx.getMetadataDao();
Set<String> keySet = metadataDao.queryKeySet(parentRef);
return keySet;
return metadataDao.queryKeySet(parentRef);
} finally {
parentRef.unlock();
}
@ -279,8 +278,7 @@ public class ObjectDao {
parentRef.lock();
try {
MetadataDao metadataDao = this.tx.getMetadataDao();
long size = metadataDao.querySize(parentRef);
return size;
return metadataDao.querySize(parentRef);
} finally {
parentRef.unlock();
}
@ -288,7 +286,7 @@ public class ObjectDao {
public <T> PersistenceContext<T> createCtx(T object) {
return this.ctxFactoryDelegator.<T>getCtxFactory(object.getClass())
.createCtx(this.tx.getObjectRefCache(), object);
.createCtx(this.tx.getManager().getObjectRefCache(), object);
}
public <T> PersistenceContext<T> createCtx(ObjectRef objectRef) {

View File

@ -1,12 +1,12 @@
/*
* 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.
@ -17,7 +17,6 @@ package li.strolch.xmlpers.api;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*
*/
@SuppressWarnings("nls")
public class PersistenceConstants {

View File

@ -1,12 +1,12 @@
/*
* 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.
@ -15,17 +15,21 @@
*/
package li.strolch.xmlpers.api;
import li.strolch.xmlpers.impl.PathBuilder;
import li.strolch.xmlpers.objref.ObjectReferenceCache;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*
*/
public interface PersistenceManager {
public static final String DEFAULT_REALM = "defaultRealm"; //$NON-NLS-1$
PathBuilder getPathBuilder();
public PersistenceContextFactoryDelegator getCtxFactory();
ObjectReferenceCache getObjectRefCache();
public PersistenceTransaction openTx();
PersistenceContextFactoryDelegator getCtxFactory();
public PersistenceTransaction openTx(String realm);
IoMode getIoMode();
PersistenceTransaction openTx();
}

View File

@ -1,12 +1,12 @@
/*
* 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.
@ -21,12 +21,10 @@ import li.strolch.xmlpers.impl.DefaultPersistenceManager;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*
*/
public class PersistenceManagerLoader {
public static PersistenceManager load(Properties properties) {
DefaultPersistenceManager persistenceManager = new DefaultPersistenceManager();
persistenceManager.initialize(properties);
return persistenceManager;

View File

@ -1,39 +0,0 @@
/*
* 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.xmlpers.api;
import li.strolch.xmlpers.objref.ObjectReferenceCache;
public interface PersistenceRealm {
/**
* @return the realm
*/
public abstract String getRealmName();
public abstract PersistenceContextFactoryDelegator getCtxFactoryDelegator();
/**
* @return the objectRefCache
*/
public abstract ObjectReferenceCache getObjectRefCache();
/**
* @return the persistenceManager
*/
public abstract PersistenceManager getPersistenceManager();
}

View File

@ -1,12 +1,12 @@
/*
* 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.
@ -15,27 +15,31 @@
*/
package li.strolch.xmlpers.api;
import li.strolch.xmlpers.objref.ObjectReferenceCache;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*
*/
public interface PersistenceTransaction extends AutoCloseable {
/**
* Return true if the TX already has a {@link TransactionResult}
*
* @return true if the TX already has a {@link TransactionResult}
*/
public boolean hasTransactionResult();
/**
* Returns the {@link TransactionResult} for this transaction
*
*
* @return the {@link TransactionResult}
*
*
* @throws IllegalStateException
* if the transaction has not yet been closed
* if the transaction has not yet been closed
*/
public TransactionResult getTransactionResult() throws IllegalStateException;
/**
* @throws IllegalStateException
* if a result is already set
* if a result is already set
*/
public void setTransactionResult(TransactionResult txResult) throws IllegalStateException;
@ -56,11 +60,5 @@ public interface PersistenceTransaction extends AutoCloseable {
public FileDao getFileDao();
public ObjectReferenceCache getObjectRefCache();
public PersistenceRealm getRealm();
public IoMode getIoMode();
public void setIoMode(IoMode ioMode);
public PersistenceManager getManager();
}

View File

@ -1,12 +1,12 @@
/*
* 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.
@ -24,7 +24,6 @@ import li.strolch.utils.helper.StringHelper;
public class TransactionResult {
private String realm;
private TransactionState state;
private Exception failCause;
@ -39,128 +38,58 @@ public class TransactionResult {
this.modificationByKey = new HashMap<>();
}
/**
* @return the realm
*/
public String getRealm() {
return this.realm;
}
/**
* @param realm
* the realm to set
*/
public void setRealm(String realm) {
this.realm = realm;
}
/**
* @return the state
*/
public TransactionState getState() {
return this.state;
}
/**
* @param state
* the state to set
*/
public void setState(TransactionState state) {
this.state = state;
}
/**
* The internal exception why the transaction failed
*
* @return the failCause
*/
public Exception getFailCause() {
return this.failCause;
}
/**
* @param failCause
* the failCause to set
*/
public void setFailCause(Exception failCause) {
this.failCause = failCause;
}
/**
* Start time of the transaction
*
* @return the startTime
*/
public Date getStartTime() {
return this.startTime;
}
/**
* @param startTime
* the startTime to set
*/
public void setStartTime(Date startTime) {
this.startTime = startTime;
}
/**
* The duration the transaction was open in nanoseconds
*
* @return the txDuration
*/
public long getTxDuration() {
return this.txDuration;
}
/**
* @param txDuration
* the txDuration to set
*/
public void setTxDuration(long txDuration) {
this.txDuration = txDuration;
}
/**
* The duration the transaction took to close in nanoseconds
*
* @return the closeDuration
*/
public long getCloseDuration() {
return this.closeDuration;
}
/**
* @param closeDuration
* the closeDuration to set
*/
public void setCloseDuration(long closeDuration) {
this.closeDuration = closeDuration;
}
/**
* @param modificationByKey
* the modificationByKey to set
*/
public void setModificationByKey(Map<String, ModificationResult> modificationByKey) {
this.modificationByKey = modificationByKey;
}
/**
* @return
*/
public Set<String> getKeys() {
return this.modificationByKey.keySet();
}
/**
* @param key
* @return
*/
public ModificationResult getModificationResult(String key) {
return this.modificationByKey.get(key);
}
@SuppressWarnings("nls")
public String getLogMessage() {
int nrOfObjects = 0;
@ -171,8 +100,7 @@ public class TransactionResult {
}
StringBuilder sb = new StringBuilder();
sb.append("TX for realm ");
sb.append(getRealm());
sb.append("TX");
switch (this.state) {
case OPEN:
sb.append(" is still open after ");
@ -208,7 +136,6 @@ public class TransactionResult {
* Clears all fields of this result, allowing it to be reused
*/
public void clear() {
this.realm = null;
this.state = null;
this.failCause = null;
this.startTime = null;

View File

@ -1,12 +1,12 @@
/*
* 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.
@ -18,27 +18,18 @@ package li.strolch.xmlpers.impl;
import java.io.File;
import java.lang.reflect.Field;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import li.strolch.utils.helper.PropertiesHelper;
import li.strolch.utils.helper.StringHelper;
import li.strolch.xmlpers.api.IoMode;
import li.strolch.xmlpers.api.PersistenceConstants;
import li.strolch.xmlpers.api.PersistenceContextFactoryDelegator;
import li.strolch.xmlpers.api.PersistenceManager;
import li.strolch.xmlpers.api.PersistenceTransaction;
import li.strolch.xmlpers.api.XmlPersistenceException;
import li.strolch.xmlpers.api.*;
import li.strolch.xmlpers.objref.LockableObject;
import li.strolch.xmlpers.objref.ObjectReferenceCache;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*
*/
public class DefaultPersistenceManager implements PersistenceManager {
@ -46,10 +37,10 @@ public class DefaultPersistenceManager implements PersistenceManager {
protected boolean initialized;
protected boolean verbose;
protected IoMode defaultIoMode;
protected Properties properties;
protected Map<String, DefaultPersistenceRealm> realmMap;
protected IoMode ioMode;
private PersistenceContextFactoryDelegator ctxFactory;
private ObjectReferenceCache objectRefCache;
private PathBuilder pathBuilder;
public void initialize(Properties properties) {
if (this.initialized)
@ -58,46 +49,44 @@ public class DefaultPersistenceManager implements PersistenceManager {
String context = DefaultPersistenceManager.class.getSimpleName();
// get properties
boolean verbose = PropertiesHelper.getPropertyBool(properties, context, PersistenceConstants.PROP_VERBOSE,
Boolean.FALSE).booleanValue();
String ioModeS = PropertiesHelper.getProperty(properties, context, PersistenceConstants.PROP_XML_IO_MOD,
IoMode.DOM.name());
boolean verbose = PropertiesHelper
.getPropertyBool(properties, context, PersistenceConstants.PROP_VERBOSE, Boolean.FALSE);
String ioModeS = PropertiesHelper
.getProperty(properties, context, PersistenceConstants.PROP_XML_IO_MOD, IoMode.DOM.name());
IoMode ioMode = IoMode.valueOf(ioModeS);
long lockTime = PropertiesHelper.getPropertyLong(properties, context,
PersistenceConstants.PROP_LOCK_TIME_MILLIS, 10000L);
long lockTime = PropertiesHelper
.getPropertyLong(properties, context, PersistenceConstants.PROP_LOCK_TIME_MILLIS, 10000L);
String basePath = PropertiesHelper.getProperty(properties, context, PersistenceConstants.PROP_BASEPATH, null);
// set lock time on LockableObject
try {
Field lockTimeField = LockableObject.class.getDeclaredField("tryLockTime");//$NON-NLS-1$
lockTimeField.setAccessible(true);
lockTimeField.setLong(null, lockTime);
logger.info("Using a max lock acquire time of " + StringHelper.formatMillisecondsDuration(lockTime)); //$NON-NLS-1$
logger.info("Using a max lock acquire time of " + StringHelper
.formatMillisecondsDuration(lockTime)); //$NON-NLS-1$
} catch (SecurityException | NoSuchFieldException | IllegalArgumentException | IllegalAccessException e) {
throw new RuntimeException("Failed to configure tryLockTime on LockableObject!", e); //$NON-NLS-1$
}
// validate base path
validateBasePath(properties);
this.properties = properties;
this.verbose = verbose;
this.defaultIoMode = ioMode;
this.realmMap = new HashMap<>();
this.ctxFactory = new PersistenceContextFactoryDelegator();
}
private void validateBasePath(Properties properties) {
String context = DefaultPersistenceManager.class.getSimpleName();
String basePath = PropertiesHelper.getProperty(properties, context, PersistenceConstants.PROP_BASEPATH, null);
// validate base path exists and is writable
File basePathF = new File(basePath);
File basePathF = new File(basePath).getAbsoluteFile();
if (!basePathF.exists())
throw new XmlPersistenceException(MessageFormat.format("The database store path does not exist at {0}", //$NON-NLS-1$
basePathF.getAbsolutePath()));
throw new XmlPersistenceException(
MessageFormat.format("The database store path does not exist at {0}", //$NON-NLS-1$
basePathF.getAbsolutePath()));
if (!basePathF.canWrite())
throw new XmlPersistenceException(MessageFormat.format("The database store path is not writeable at {0}", //$NON-NLS-1$
basePathF.getAbsolutePath()));
throw new XmlPersistenceException(
MessageFormat.format("The database store path is not writeable at {0}", //$NON-NLS-1$
basePathF.getAbsolutePath()));
logger.info(MessageFormat.format("Using base path {0}", basePathF)); //$NON-NLS-1$
this.verbose = verbose;
this.ioMode = ioMode;
this.ctxFactory = new PersistenceContextFactoryDelegator();
this.pathBuilder = new PathBuilder(basePathF);
this.objectRefCache = new ObjectReferenceCache();
}
@Override
@ -106,26 +95,22 @@ public class DefaultPersistenceManager implements PersistenceManager {
}
@Override
public PersistenceTransaction openTx() {
return openTx(DEFAULT_REALM);
public ObjectReferenceCache getObjectRefCache() {
return this.objectRefCache;
}
@Override
public synchronized PersistenceTransaction openTx(String realmName) {
public PathBuilder getPathBuilder() {
return this.pathBuilder;
}
DefaultPersistenceRealm persistenceRealm = this.realmMap.get(realmName);
if (persistenceRealm == null) {
@Override
public IoMode getIoMode() {
return this.ioMode;
}
PathBuilder pathBuilder = new PathBuilder(realmName, this.properties);
ObjectReferenceCache objectRefCache = new ObjectReferenceCache(realmName);
persistenceRealm = new DefaultPersistenceRealm(realmName, this, this.ctxFactory, pathBuilder,
objectRefCache);
this.realmMap.put(realmName, persistenceRealm);
}
PersistenceTransaction tx = new DefaultPersistenceTransaction(persistenceRealm, this.verbose);
tx.setIoMode(this.defaultIoMode);
return tx;
@Override
public synchronized PersistenceTransaction openTx() {
return new DefaultPersistenceTransaction(this, this.ioMode, this.verbose);
}
}

View File

@ -1,74 +0,0 @@
/*
* 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.xmlpers.impl;
import li.strolch.xmlpers.api.PersistenceContextFactoryDelegator;
import li.strolch.xmlpers.api.PersistenceManager;
import li.strolch.xmlpers.api.PersistenceRealm;
import li.strolch.xmlpers.objref.ObjectReferenceCache;
public class DefaultPersistenceRealm implements PersistenceRealm {
private final PersistenceManager persistenceManager;
private final PersistenceContextFactoryDelegator ctxFactory;
private final String realmName;
private final ObjectReferenceCache objectRefCache;
private final PathBuilder pathBuilder;
public DefaultPersistenceRealm(String realm, PersistenceManager persistenceManager,
PersistenceContextFactoryDelegator ctxFactory, PathBuilder pathBuilder, ObjectReferenceCache objectRefCache) {
this.ctxFactory = ctxFactory;
this.pathBuilder = pathBuilder;
this.realmName = realm;
this.persistenceManager = persistenceManager;
this.objectRefCache = objectRefCache;
}
/**
* @return the realm
*/
@Override
public String getRealmName() {
return this.realmName;
}
@Override
public PersistenceContextFactoryDelegator getCtxFactoryDelegator() {
return this.ctxFactory;
}
/**
* @return the objectRefCache
*/
@Override
public ObjectReferenceCache getObjectRefCache() {
return this.objectRefCache;
}
/**
* @return the persistenceManager
*/
@Override
public PersistenceManager getPersistenceManager() {
return this.persistenceManager;
}
/**
* @return the pathBuilder
*/
PathBuilder getPathBuilder() {
return this.pathBuilder;
}
}

View File

@ -1,12 +1,12 @@
/*
* 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.
@ -15,42 +15,24 @@
*/
package li.strolch.xmlpers.impl;
import java.text.MessageFormat;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static li.strolch.utils.helper.StringHelper.formatNanoDuration;
import java.text.MessageFormat;
import java.util.*;
import li.strolch.utils.objectfilter.ObjectFilter;
import li.strolch.xmlpers.api.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import li.strolch.utils.helper.StringHelper;
import li.strolch.utils.objectfilter.ObjectFilter;
import li.strolch.xmlpers.api.FileDao;
import li.strolch.xmlpers.api.IoMode;
import li.strolch.xmlpers.api.MetadataDao;
import li.strolch.xmlpers.api.ModificationResult;
import li.strolch.xmlpers.api.ObjectDao;
import li.strolch.xmlpers.api.PersistenceContext;
import li.strolch.xmlpers.api.PersistenceRealm;
import li.strolch.xmlpers.api.PersistenceTransaction;
import li.strolch.xmlpers.api.TransactionCloseStrategy;
import li.strolch.xmlpers.api.TransactionResult;
import li.strolch.xmlpers.api.TransactionState;
import li.strolch.xmlpers.api.XmlPersistenceException;
import li.strolch.xmlpers.objref.ObjectReferenceCache;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*
*/
public class DefaultPersistenceTransaction implements PersistenceTransaction {
private static final Logger logger = LoggerFactory.getLogger(DefaultPersistenceTransaction.class);
private final DefaultPersistenceRealm realm;
private final PersistenceManager manager;
private final boolean verbose;
private final ObjectFilter objectFilter;
@ -58,7 +40,6 @@ public class DefaultPersistenceTransaction implements PersistenceTransaction {
private final MetadataDao metadataDao;
private FileDao fileDao;
private IoMode ioMode;
private TransactionCloseStrategy closeStrategy;
@ -67,20 +48,25 @@ public class DefaultPersistenceTransaction implements PersistenceTransaction {
private Date startTimeDate;
private TransactionResult txResult;
public DefaultPersistenceTransaction(DefaultPersistenceRealm realm, boolean verbose) {
public DefaultPersistenceTransaction(PersistenceManager manager, IoMode ioMode, boolean verbose) {
this.startTime = System.nanoTime();
this.startTimeDate = new Date();
this.realm = realm;
this.manager = manager;
this.verbose = verbose;
this.objectFilter = new ObjectFilter();
this.fileDao = new FileDao(this, realm.getPathBuilder(), verbose);
this.fileDao = new FileDao(this, manager.getPathBuilder(), verbose);
this.objectDao = new ObjectDao(this, this.fileDao, this.objectFilter);
this.metadataDao = new MetadataDao(realm.getPathBuilder(), this, verbose);
this.metadataDao = new MetadataDao(manager.getPathBuilder(), this, verbose);
this.closeStrategy = TransactionCloseStrategy.COMMIT;
this.state = TransactionState.OPEN;
}
@Override
public PersistenceManager getManager() {
return this.manager;
}
@Override
public void setTransactionResult(TransactionResult txResult) throws IllegalStateException {
if (this.txResult != null) {
@ -92,16 +78,12 @@ public class DefaultPersistenceTransaction implements PersistenceTransaction {
@Override
public TransactionResult getTransactionResult() throws IllegalStateException {
if (isOpen()) {
String msg = "The transaction is still open thus has no result yet! Either commit or rollback before calling this method"; //$NON-NLS-1$
throw new IllegalStateException(msg);
}
return this.txResult;
}
@Override
public PersistenceRealm getRealm() {
return this.realm;
public boolean hasTransactionResult() {
return this.txResult != null;
}
@Override
@ -119,11 +101,6 @@ public class DefaultPersistenceTransaction implements PersistenceTransaction {
return this.fileDao;
}
@Override
public ObjectReferenceCache getObjectRefCache() {
return this.realm.getObjectRefCache();
}
@Override
public void setCloseStrategy(TransactionCloseStrategy closeStrategy) {
this.closeStrategy = closeStrategy;
@ -155,12 +132,80 @@ public class DefaultPersistenceTransaction implements PersistenceTransaction {
this.txResult.setStartTime(this.startTimeDate);
this.txResult.setTxDuration(txDuration);
this.txResult.setCloseDuration(closeDuration);
this.txResult.setRealm(this.realm.getRealmName());
this.txResult.setModificationByKey(Collections.<String, ModificationResult> emptyMap());
this.txResult.setModificationByKey(Collections.emptyMap());
}
}
}
private void internalCommit() {
Set<String> keySet = this.objectFilter.keySet();
Map<String, ModificationResult> modifications;
if (this.txResult == null)
modifications = null;
else
modifications = new HashMap<>(keySet.size());
for (String key : keySet) {
List<Object> removed = this.objectFilter.getRemoved(key);
if (removed.isEmpty()) {
if (this.verbose)
logger.info("No objects removed in this tx."); //$NON-NLS-1$
} else {
if (this.verbose)
logger.info(removed.size() + " objects removed in this tx."); //$NON-NLS-1$
for (Object object : removed) {
@SuppressWarnings("unchecked")
PersistenceContext<Object> ctx = (PersistenceContext<Object>) object;
this.fileDao.performDelete(ctx);
}
}
List<Object> updated = this.objectFilter.getUpdated(key);
if (updated.isEmpty()) {
if (this.verbose)
logger.info("No objects updated in this tx."); //$NON-NLS-1$
} else {
if (this.verbose)
logger.info(updated.size() + " objects updated in this tx."); //$NON-NLS-1$
for (Object object : updated) {
@SuppressWarnings("unchecked")
PersistenceContext<Object> ctx = (PersistenceContext<Object>) object;
this.fileDao.performUpdate(ctx);
}
}
List<Object> added = this.objectFilter.getAdded(key);
if (added.isEmpty()) {
if (this.verbose)
logger.info("No objects added in this tx."); //$NON-NLS-1$
} else {
if (this.verbose)
logger.info(added.size() + " objects added in this tx."); //$NON-NLS-1$
for (Object object : added) {
@SuppressWarnings("unchecked")
PersistenceContext<Object> ctx = (PersistenceContext<Object>) object;
this.fileDao.performCreate(ctx);
}
}
if (modifications != null) {
ModificationResult result = new ModificationResult(key, added, updated, removed);
modifications.put(key, result);
}
}
if (this.txResult != null) {
this.txResult.clear();
this.txResult.setState(TransactionState.COMMITTED);
this.txResult.setModificationByKey(modifications);
}
}
@Override
public void autoCloseableCommit() throws XmlPersistenceException {
@ -173,73 +218,10 @@ public class DefaultPersistenceTransaction implements PersistenceTransaction {
logger.info(MessageFormat.format(msg, this.objectFilter.sizeCache()));
}
Set<String> keySet = this.objectFilter.keySet();
Map<String, ModificationResult> modifications;
if (this.txResult == null)
modifications = null;
else
modifications = new HashMap<>(keySet.size());
for (String key : keySet) {
List<Object> removed = this.objectFilter.getRemoved(key);
if (removed.isEmpty()) {
if (this.verbose)
logger.info("No objects removed in this tx."); //$NON-NLS-1$
} else {
if (this.verbose)
logger.info(removed.size() + " objects removed in this tx."); //$NON-NLS-1$
for (Object object : removed) {
@SuppressWarnings("unchecked")
PersistenceContext<Object> ctx = (PersistenceContext<Object>) object;
this.fileDao.performDelete(ctx);
}
}
List<Object> updated = this.objectFilter.getUpdated(key);
if (updated.isEmpty()) {
if (this.verbose)
logger.info("No objects updated in this tx."); //$NON-NLS-1$
} else {
if (this.verbose)
logger.info(updated.size() + " objects updated in this tx."); //$NON-NLS-1$
for (Object object : updated) {
@SuppressWarnings("unchecked")
PersistenceContext<Object> ctx = (PersistenceContext<Object>) object;
this.fileDao.performUpdate(ctx);
}
}
List<Object> added = this.objectFilter.getAdded(key);
if (added.isEmpty()) {
if (this.verbose)
logger.info("No objects added in this tx."); //$NON-NLS-1$
} else {
if (this.verbose)
logger.info(added.size() + " objects added in this tx."); //$NON-NLS-1$
for (Object object : added) {
@SuppressWarnings("unchecked")
PersistenceContext<Object> ctx = (PersistenceContext<Object>) object;
this.fileDao.performCreate(ctx);
}
}
if (modifications != null) {
ModificationResult result = new ModificationResult(key, added, updated, removed);
modifications.put(key, result);
}
}
if (this.txResult != null) {
this.txResult.clear();
this.txResult.setState(TransactionState.COMMITTED);
this.txResult.setModificationByKey(modifications);
}
internalCommit();
} catch (Exception e) {
logger.error("Failed to commit!", e);
if (this.txResult == null) {
@ -247,19 +229,16 @@ public class DefaultPersistenceTransaction implements PersistenceTransaction {
long txDuration = end - this.startTime;
long closeDuration = end - start;
StringBuilder sb = new StringBuilder();
sb.append("TX has failed after "); //$NON-NLS-1$
sb.append(StringHelper.formatNanoDuration(txDuration));
sb.append(" with close operation taking "); //$NON-NLS-1$
sb.append(StringHelper.formatNanoDuration(closeDuration));
logger.info(sb.toString());
String sb = "TX has failed after " + formatNanoDuration(txDuration) + " with close operation taking "
+ formatNanoDuration(closeDuration);
logger.error(sb);
throw e;
}
this.txResult.clear();
this.txResult.setState(TransactionState.FAILED);
this.txResult.setModificationByKey(Collections.<String, ModificationResult> emptyMap());
this.txResult.setModificationByKey(Collections.emptyMap());
this.txResult.setFailCause(e);
} finally {
@ -275,24 +254,20 @@ public class DefaultPersistenceTransaction implements PersistenceTransaction {
if (this.txResult == null) {
StringBuilder sb = new StringBuilder();
sb.append("TX was completed after "); //$NON-NLS-1$
sb.append(StringHelper.formatNanoDuration(txDuration));
sb.append(" with close operation taking "); //$NON-NLS-1$
sb.append(StringHelper.formatNanoDuration(closeDuration));
logger.info(sb.toString());
String sb = "TX was completed after " + formatNanoDuration(txDuration) + " with close operation taking "
+ formatNanoDuration(closeDuration);
logger.info(sb);
} else {
this.txResult.setStartTime(this.startTimeDate);
this.txResult.setTxDuration(txDuration);
this.txResult.setCloseDuration(closeDuration);
this.txResult.setRealm(this.realm.getRealmName());
if (this.txResult.getState() == TransactionState.FAILED) {
String msg = "Failed to commit TX due to underlying exception: {0}"; //$NON-NLS-1$
String causeMsg = this.txResult.getFailCause() == null ? null : this.txResult.getFailCause()
.getMessage();
String msg = "Failed to commit TX due to underlying exception: {0}";
String causeMsg =
this.txResult.getFailCause() == null ? null : this.txResult.getFailCause().getMessage();
msg = MessageFormat.format(msg, causeMsg);
throw new XmlPersistenceException(msg, this.txResult.getFailCause());
}
@ -311,14 +286,4 @@ public class DefaultPersistenceTransaction implements PersistenceTransaction {
public boolean isOpen() {
return this.state == TransactionState.OPEN;
}
@Override
public void setIoMode(IoMode ioMode) {
this.ioMode = ioMode;
}
@Override
public IoMode getIoMode() {
return this.ioMode;
}
}

View File

@ -1,12 +1,12 @@
/*
* 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.
@ -16,18 +16,11 @@
package li.strolch.xmlpers.impl;
import java.io.File;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.Properties;
import li.strolch.xmlpers.objref.ObjectRef;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import li.strolch.utils.helper.PropertiesHelper;
import li.strolch.utils.helper.StringHelper;
import li.strolch.xmlpers.api.PersistenceConstants;
import li.strolch.xmlpers.api.XmlPersistenceException;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*/
@ -38,86 +31,24 @@ public class PathBuilder {
public static final String FILE_EXT = ".xml"; //$NON-NLS-1$
public static final int EXT_LENGTH = PathBuilder.FILE_EXT.length();
private final String basePath;
private final File basePath;
public PathBuilder(String realm, Properties properties) {
// get properties
String context = PathBuilder.class.getSimpleName();
String basePath = PropertiesHelper.getProperty(properties, context, PersistenceConstants.PROP_BASEPATH, null);
// validate base path exists and is writable
File basePathF = new File(basePath);
if (!basePathF.exists())
throw new XmlPersistenceException(MessageFormat.format("The database store path does not exist at {0}", //$NON-NLS-1$
basePathF.getAbsolutePath()));
if (!basePathF.canWrite())
throw new XmlPersistenceException(MessageFormat.format("The database store path is not writeable at {0}", //$NON-NLS-1$
basePathF.getAbsolutePath()));
File realmPathF = new File(basePathF, realm);
if (!realmPathF.exists() && !realmPathF.mkdir())
throw new XmlPersistenceException(MessageFormat.format("Could not create path for realm {0} at {1}", //$NON-NLS-1$
realm, basePathF.getAbsolutePath()));
// we want a clean base path
String canonicalBasePath;
try {
canonicalBasePath = realmPathF.getCanonicalPath();
} catch (IOException e) {
throw new XmlPersistenceException(MessageFormat.format(
"Failed to build canonical path from {0}", realmPathF.getAbsolutePath()), e); //$NON-NLS-1$
}
// this.basePathF = basePathF;
this.basePath = canonicalBasePath;
logger.info(MessageFormat.format("Using base path {0}", this.basePath)); //$NON-NLS-1$
public PathBuilder(File basePath) {
this.basePath = basePath;
}
String getFilename(String id) {
private String getFilename(String id) {
return id.concat(PathBuilder.FILE_EXT);
}
String getPathAsString(String type, String subType, String id) {
StringBuilder sb = new StringBuilder(this.basePath);
if (StringHelper.isNotEmpty(type)) {
sb.append(File.separatorChar);
sb.append(type);
}
if (StringHelper.isNotEmpty(subType)) {
sb.append(File.separatorChar);
sb.append(subType);
}
if (StringHelper.isNotEmpty(id)) {
sb.append(File.separatorChar);
sb.append(getFilename(id));
}
return sb.toString();
}
public File getRootPath() {
File path = new File(getPathAsString(null, null, null));
return path;
return this.basePath;
}
public File getTypePath(String type) {
File path = new File(getPathAsString(type, null, null));
return path;
}
public File getSubTypePath(String type, String subType) {
File path = new File(getPathAsString(type, subType, null));
return path;
}
public File getIdOfTypePath(String type, String id) {
File path = new File(getPathAsString(type, null, id));
return path;
}
public File getIdOfSubTypePath(String type, String subType, String id) {
File path = new File(getPathAsString(type, subType, id));
return path;
public File getPath(ObjectRef objectRef) {
if (objectRef.isLeaf())
return new File(this.basePath, getFilename(objectRef.getName()));
else
return new File(this.basePath, objectRef.getName());
}
}

View File

@ -1,12 +1,12 @@
/*
* 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.
@ -15,35 +15,32 @@
*/
package li.strolch.xmlpers.objref;
import java.io.File;
import java.text.MessageFormat;
import java.util.Objects;
import li.strolch.xmlpers.api.PersistenceContext;
import li.strolch.xmlpers.api.PersistenceContextFactory;
import li.strolch.xmlpers.api.PersistenceContextFactoryDelegator;
import li.strolch.xmlpers.api.PersistenceTransaction;
import li.strolch.xmlpers.impl.PathBuilder;
public class IdOfSubTypeRef extends ObjectRef {
private final String type;
private final String subType;
private final SubTypeRef parent;
private final String id;
public IdOfSubTypeRef(String realmName, String type, String subType, String id) {
super(realmName, RefNameCreator.createIdOfSubTypeName(realmName, type, subType, id));
this.type = type;
this.subType = subType;
public IdOfSubTypeRef(SubTypeRef parent, String id) {
super(RefNameCreator.createIdOfSubTypeName(parent.getType(), parent.getSubType(), id));
this.parent = parent;
this.id = id;
}
@Override
public String getType() {
return this.type;
return this.parent.getType();
}
public String getSubType() {
return this.subType;
return this.parent.getSubType();
}
/**
@ -65,7 +62,7 @@ public class IdOfSubTypeRef extends ObjectRef {
@Override
public ObjectRef getParent(PersistenceTransaction tx) {
return tx.getRealm().getObjectRefCache().getSubTypeRef(this.type, this.subType);
return tx.getManager().getObjectRefCache().getSubTypeRef(getType(), getSubType());
}
@Override
@ -80,58 +77,25 @@ public class IdOfSubTypeRef extends ObjectRef {
throw new UnsupportedOperationException(msg);
}
@Override
public File getPath(PathBuilder pathBuilder) {
return pathBuilder.getIdOfSubTypePath(this.type, this.subType, this.id);
}
@Override
public <T> PersistenceContext<T> createPersistenceContext(PersistenceTransaction tx) {
PersistenceContextFactoryDelegator ctxFactoryDelegator = tx.getRealm().getCtxFactoryDelegator();
PersistenceContextFactory<T> persistenceContextFactory = ctxFactoryDelegator.<T> getCtxFactory(this.type);
PersistenceContextFactoryDelegator ctxFactoryDelegator = tx.getManager().getCtxFactory();
PersistenceContextFactory<T> persistenceContextFactory = ctxFactoryDelegator.getCtxFactory(getType());
return persistenceContextFactory.createCtx(this);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((this.id == null) ? 0 : this.id.hashCode());
result = prime * result + ((this.realmName == null) ? 0 : this.realmName.hashCode());
result = prime * result + ((this.subType == null) ? 0 : this.subType.hashCode());
result = prime * result + ((this.type == null) ? 0 : this.type.hashCode());
return result;
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
ObjectRef objectRef = (ObjectRef) o;
return Objects.equals(this.name, objectRef.name);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
IdOfSubTypeRef other = (IdOfSubTypeRef) obj;
if (this.realmName == null) {
if (other.realmName != null)
return false;
} else if (!this.realmName.equals(other.realmName))
return false;
if (this.id == null) {
if (other.id != null)
return false;
} else if (!this.id.equals(other.id))
return false;
if (this.subType == null) {
if (other.subType != null)
return false;
} else if (!this.subType.equals(other.subType))
return false;
if (this.type == null) {
if (other.type != null)
return false;
} else if (!this.type.equals(other.type))
return false;
return true;
public int hashCode() {
return Objects.hash(this.name);
}
}

View File

@ -1,12 +1,12 @@
/*
* 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.
@ -15,29 +15,28 @@
*/
package li.strolch.xmlpers.objref;
import java.io.File;
import java.text.MessageFormat;
import java.util.Objects;
import li.strolch.xmlpers.api.PersistenceContext;
import li.strolch.xmlpers.api.PersistenceContextFactory;
import li.strolch.xmlpers.api.PersistenceContextFactoryDelegator;
import li.strolch.xmlpers.api.PersistenceTransaction;
import li.strolch.xmlpers.impl.PathBuilder;
public class IdOfTypeRef extends ObjectRef {
private final String type;
private final TypeRef parent;
private final String id;
public IdOfTypeRef(String realmName, String type, String id) {
super(realmName, RefNameCreator.createIdOfTypeName(realmName, type, id));
this.type = type;
public IdOfTypeRef(TypeRef parent, String id) {
super(RefNameCreator.createIdOfTypeName(parent.getType(), id));
this.parent = parent;
this.id = id;
}
@Override
public String getType() {
return this.type;
return this.parent.getType();
}
/**
@ -59,7 +58,7 @@ public class IdOfTypeRef extends ObjectRef {
@Override
public ObjectRef getParent(PersistenceTransaction tx) {
return tx.getRealm().getObjectRefCache().getTypeRef(this.type);
return this.parent;
}
@Override
@ -74,52 +73,25 @@ public class IdOfTypeRef extends ObjectRef {
throw new UnsupportedOperationException(msg);
}
@Override
public File getPath(PathBuilder pathBuilder) {
return pathBuilder.getIdOfTypePath(this.type, this.id);
}
@Override
public <T> PersistenceContext<T> createPersistenceContext(PersistenceTransaction tx) {
PersistenceContextFactoryDelegator ctxFactoryDelegator = tx.getRealm().getCtxFactoryDelegator();
PersistenceContextFactory<T> persistenceContextFactory = ctxFactoryDelegator.<T> getCtxFactory(this.type);
PersistenceContextFactoryDelegator ctxFactoryDelegator = tx.getManager().getCtxFactory();
PersistenceContextFactory<T> persistenceContextFactory = ctxFactoryDelegator.getCtxFactory(getType());
return persistenceContextFactory.createCtx(this);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((this.id == null) ? 0 : this.id.hashCode());
result = prime * result + ((this.realmName == null) ? 0 : this.realmName.hashCode());
result = prime * result + ((this.type == null) ? 0 : this.type.hashCode());
return result;
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
ObjectRef objectRef = (ObjectRef) o;
return Objects.equals(this.name, objectRef.name);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
IdOfTypeRef other = (IdOfTypeRef) obj;
if (this.realmName == null) {
if (other.realmName != null)
return false;
} else if (!this.realmName.equals(other.realmName))
return false;
if (this.id == null) {
if (other.id != null)
return false;
} else if (!this.id.equals(other.id))
return false;
if (this.type == null) {
if (other.type != null)
return false;
} else if (!this.type.equals(other.type))
return false;
return true;
public int hashCode() {
return Objects.hash(this.name);
}
}

View File

@ -1,12 +1,12 @@
/*
* 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.
@ -16,6 +16,7 @@
package li.strolch.xmlpers.objref;
import java.io.File;
import java.util.Objects;
import li.strolch.xmlpers.api.PersistenceContext;
import li.strolch.xmlpers.api.PersistenceTransaction;
@ -23,22 +24,20 @@ import li.strolch.xmlpers.impl.PathBuilder;
public abstract class ObjectRef extends LockableObject {
protected final String realmName;
protected final String name;
protected ObjectRef(String realmName, String name) {
this.realmName = realmName;
protected ObjectRef(String name) {
this.name = name;
}
public String getRealmName() {
return this.realmName;
}
public String getName() {
return this.name;
}
public File getPath(PathBuilder pathBuilder) {
return pathBuilder.getPath(this);
}
public abstract boolean isRoot();
public abstract boolean isLeaf();
@ -51,18 +50,25 @@ public abstract class ObjectRef extends LockableObject {
public abstract ObjectRef getChildTypeRef(PersistenceTransaction tx, String type);
public abstract File getPath(PathBuilder pathBuilder);
public abstract <T> PersistenceContext<T> createPersistenceContext(PersistenceTransaction tx);
@Override
public String toString() {
return getName();
return this.name;
}
@Override
public abstract boolean equals(Object obj);
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
ObjectRef objectRef = (ObjectRef) o;
return Objects.equals(this.name, objectRef.name);
}
@Override
public abstract int hashCode();
public int hashCode() {
return Objects.hash(this.name);
}
}

View File

@ -1,12 +1,12 @@
/*
* 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.
@ -18,42 +18,27 @@ package li.strolch.xmlpers.objref;
import java.util.HashMap;
import java.util.Map;
import li.strolch.utils.helper.StringHelper;
public class ObjectReferenceCache {
private final String realmName;
private final RootRef rootRef;
private final Map<String, TypeRef> typeRefMap;
private final Map<String, SubTypeRef> subTypeRefMap;
private final Map<String, IdOfTypeRef> idOfTypeRefMap;
private final Map<String, IdOfSubTypeRef> idOfSubTypeRefMap;
public ObjectReferenceCache(String realmName) {
if (StringHelper.isEmpty(realmName))
throw new IllegalArgumentException("Realm name may not be empty!"); //$NON-NLS-1$
this.realmName = realmName;
this.rootRef = new RootRef(this.realmName);
public ObjectReferenceCache() {
this.rootRef = new RootRef();
this.typeRefMap = new HashMap<>();
this.subTypeRefMap = new HashMap<>();
this.idOfTypeRefMap = new HashMap<>();
this.idOfSubTypeRefMap = new HashMap<>();
}
public String getRealmName() {
return this.realmName;
}
public synchronized RootRef getRootRef() {
return this.rootRef;
}
public synchronized TypeRef getTypeRef(String type) {
String key = RefNameCreator.createTypeName(this.realmName, type);
String key = RefNameCreator.createTypeName(type);
TypeRef ref = this.typeRefMap.get(key);
if (ref == null) {
ref = new TypeRef(this.realmName, type);
ref = new TypeRef(this.rootRef, type);
this.typeRefMap.put(key, ref);
}
@ -61,10 +46,10 @@ public class ObjectReferenceCache {
}
public synchronized SubTypeRef getSubTypeRef(String type, String subType) {
String key = RefNameCreator.createSubTypeName(this.realmName, type, subType);
String key = RefNameCreator.createSubTypeName(type, subType);
SubTypeRef ref = this.subTypeRefMap.get(key);
if (ref == null) {
ref = new SubTypeRef(this.realmName, type, subType);
ref = new SubTypeRef(getTypeRef(type), subType);
this.subTypeRefMap.put(key, ref);
}
@ -72,10 +57,10 @@ public class ObjectReferenceCache {
}
public synchronized IdOfTypeRef getIdOfTypeRef(String type, String id) {
String key = RefNameCreator.createIdOfTypeName(this.realmName, type, id);
String key = RefNameCreator.createIdOfTypeName(type, id);
IdOfTypeRef idRef = this.idOfTypeRefMap.get(key);
if (idRef == null) {
idRef = new IdOfTypeRef(this.realmName, type, id);
idRef = new IdOfTypeRef(getTypeRef(type), id);
this.idOfTypeRefMap.put(key, idRef);
}
@ -83,10 +68,10 @@ public class ObjectReferenceCache {
}
public synchronized IdOfSubTypeRef getIdOfSubTypeRef(String type, String subType, String id) {
String key = RefNameCreator.createIdOfSubTypeName(this.realmName, type, subType, id);
String key = RefNameCreator.createIdOfSubTypeName(type, subType, id);
IdOfSubTypeRef idRef = this.idOfSubTypeRefMap.get(key);
if (idRef == null) {
idRef = new IdOfSubTypeRef(this.realmName, type, subType, id);
idRef = new IdOfSubTypeRef(getSubTypeRef(type, subType), id);
this.idOfSubTypeRefMap.put(key, idRef);
}

View File

@ -1,12 +1,12 @@
/*
* 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.
@ -23,43 +23,32 @@ public class RefNameCreator {
// FIXME validate each name part that it is a valid literal for file names...
public static String createRootName(String realmName) {
assertRealmName(realmName);
return SLASH + realmName + SLASH;
public static String createRootName() {
return SLASH;
}
public static String createTypeName(String realmName, String type) {
assertRealmName(realmName);
public static String createTypeName(String type) {
assertType(type);
return SLASH + realmName + SLASH + type + SLASH;
return SLASH + type + SLASH;
}
public static String createIdOfTypeName(String realmName, String type, String id) {
assertRealmName(realmName);
public static String createIdOfTypeName(String type, String id) {
assertType(type);
assertId(id);
return SLASH + realmName + SLASH + type + SLASH + id;
return SLASH + type + SLASH + id;
}
public static String createSubTypeName(String realmName, String type, String subType) {
assertRealmName(realmName);
public static String createSubTypeName(String type, String subType) {
assertType(type);
assertSubType(subType);
return SLASH + realmName + SLASH + type + SLASH + subType + SLASH;
return SLASH + type + SLASH + subType + SLASH;
}
public static String createIdOfSubTypeName(String realmName, String type, String subType, String id) {
assertRealmName(realmName);
public static String createIdOfSubTypeName(String type, String subType, String id) {
assertType(type);
assertSubType(subType);
assertId(id);
return SLASH + realmName + SLASH + type + SLASH + subType + SLASH + id;
}
private static void assertRealmName(String realmName) {
if (StringHelper.isEmpty(realmName)) {
throw new IllegalArgumentException("Realm name may not be empty!"); //$NON-NLS-1$
}
return SLASH + type + SLASH + subType + SLASH + id;
}
private static void assertType(String type) {

View File

@ -1,12 +1,12 @@
/*
* 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.
@ -17,6 +17,7 @@ package li.strolch.xmlpers.objref;
import java.io.File;
import java.text.MessageFormat;
import java.util.Objects;
import li.strolch.xmlpers.api.PersistenceContext;
import li.strolch.xmlpers.api.PersistenceTransaction;
@ -24,8 +25,8 @@ import li.strolch.xmlpers.impl.PathBuilder;
public class RootRef extends ObjectRef {
public RootRef(String realmName) {
super(realmName, RefNameCreator.createRootName(realmName));
public RootRef() {
super(RefNameCreator.createRootName());
}
@Override
@ -58,7 +59,7 @@ public class RootRef extends ObjectRef {
@Override
public ObjectRef getChildTypeRef(PersistenceTransaction tx, String type) {
return tx.getRealm().getObjectRefCache().getTypeRef(type);
return tx.getManager().getObjectRefCache().getTypeRef(type);
}
@Override
@ -68,32 +69,23 @@ public class RootRef extends ObjectRef {
@Override
public <T> PersistenceContext<T> createPersistenceContext(PersistenceTransaction tx) {
String msg = MessageFormat.format("{0} is not a leaf and can thus not have a Persistence Context", getName()); //$NON-NLS-1$
String msg = MessageFormat
.format("{0} is not a leaf and can thus not have a Persistence Context", getName()); //$NON-NLS-1$
throw new UnsupportedOperationException(msg);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((this.realmName == null) ? 0 : this.realmName.hashCode());
return result;
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
ObjectRef objectRef = (ObjectRef) o;
return Objects.equals(this.name, objectRef.name);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
RootRef other = (RootRef) obj;
if (this.realmName == null) {
if (other.realmName != null)
return false;
} else if (!this.realmName.equals(other.realmName))
return false;
return true;
public int hashCode() {
return Objects.hash(this.name);
}
}

View File

@ -1,12 +1,12 @@
/*
* 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.
@ -15,27 +15,26 @@
*/
package li.strolch.xmlpers.objref;
import java.io.File;
import java.text.MessageFormat;
import java.util.Objects;
import li.strolch.xmlpers.api.PersistenceContext;
import li.strolch.xmlpers.api.PersistenceTransaction;
import li.strolch.xmlpers.impl.PathBuilder;
public class SubTypeRef extends ObjectRef {
private final String type;
private final TypeRef parent;
private final String subType;
public SubTypeRef(String realmName, String type, String subType) {
super(realmName, RefNameCreator.createSubTypeName(realmName, type, subType));
this.type = type;
public SubTypeRef(TypeRef parent, String subType) {
super(RefNameCreator.createSubTypeName(parent.getType(), subType));
this.parent = parent;
this.subType = subType;
}
@Override
public String getType() {
return this.type;
return this.parent.getType();
}
public String getSubType() {
@ -54,12 +53,12 @@ public class SubTypeRef extends ObjectRef {
@Override
public ObjectRef getParent(PersistenceTransaction tx) {
return tx.getRealm().getObjectRefCache().getTypeRef(this.type);
return this.parent;
}
@Override
public ObjectRef getChildIdRef(PersistenceTransaction tx, String id) {
return tx.getRealm().getObjectRefCache().getIdOfSubTypeRef(this.type, this.subType, id);
return tx.getManager().getObjectRefCache().getIdOfSubTypeRef(getType(), this.subType, id);
}
@Override
@ -68,51 +67,25 @@ public class SubTypeRef extends ObjectRef {
throw new UnsupportedOperationException(msg);
}
@Override
public File getPath(PathBuilder pathBuilder) {
return pathBuilder.getSubTypePath(this.type, this.subType);
}
@Override
public <T> PersistenceContext<T> createPersistenceContext(PersistenceTransaction tx) {
String msg = MessageFormat.format("{0} is not a leaf and can thus not have a Persistence Context", getName()); //$NON-NLS-1$
String msg = MessageFormat
.format("{0} is not a leaf and can thus not have a Persistence Context", getName()); //$NON-NLS-1$
throw new UnsupportedOperationException(msg);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((this.realmName == null) ? 0 : this.realmName.hashCode());
result = prime * result + ((this.subType == null) ? 0 : this.subType.hashCode());
result = prime * result + ((this.type == null) ? 0 : this.type.hashCode());
return result;
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
ObjectRef objectRef = (ObjectRef) o;
return Objects.equals(this.name, objectRef.name);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
SubTypeRef other = (SubTypeRef) obj;
if (this.realmName == null) {
if (other.realmName != null)
return false;
} else if (!this.realmName.equals(other.realmName))
return false;
if (this.subType == null) {
if (other.subType != null)
return false;
} else if (!this.subType.equals(other.subType))
return false;
if (this.type == null) {
if (other.type != null)
return false;
} else if (!this.type.equals(other.type))
return false;
return true;
public int hashCode() {
return Objects.hash(this.name);
}
}

View File

@ -1,12 +1,12 @@
/*
* 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.
@ -15,19 +15,19 @@
*/
package li.strolch.xmlpers.objref;
import java.io.File;
import java.text.MessageFormat;
import li.strolch.xmlpers.api.PersistenceContext;
import li.strolch.xmlpers.api.PersistenceTransaction;
import li.strolch.xmlpers.impl.PathBuilder;
public class TypeRef extends ObjectRef {
private final ObjectRef parent;
private final String type;
public TypeRef(String realmName, String type) {
super(realmName, RefNameCreator.createTypeName(realmName, type));
public TypeRef(ObjectRef parent, String type) {
super(RefNameCreator.createTypeName(type));
this.parent = parent;
this.type = type;
}
@ -48,27 +48,23 @@ public class TypeRef extends ObjectRef {
@Override
public ObjectRef getParent(PersistenceTransaction tx) {
return tx.getRealm().getObjectRefCache().getRootRef();
return this.parent;
}
@Override
public ObjectRef getChildIdRef(PersistenceTransaction tx, String id) {
return tx.getRealm().getObjectRefCache().getIdOfTypeRef(this.type, id);
return tx.getManager().getObjectRefCache().getIdOfTypeRef(this.type, id);
}
@Override
public ObjectRef getChildTypeRef(PersistenceTransaction tx, String type) {
return tx.getRealm().getObjectRefCache().getSubTypeRef(this.type, type);
}
@Override
public File getPath(PathBuilder pathBuilder) {
return pathBuilder.getTypePath(this.type);
return tx.getManager().getObjectRefCache().getSubTypeRef(this.type, type);
}
@Override
public <T> PersistenceContext<T> createPersistenceContext(PersistenceTransaction tx) {
String msg = MessageFormat.format("{0} is not a leaf and can thus not have a Persistence Context", getName()); //$NON-NLS-1$
String msg = MessageFormat
.format("{0} is not a leaf and can thus not have a Persistence Context", getName()); //$NON-NLS-1$
throw new UnsupportedOperationException(msg);
}
@ -76,7 +72,7 @@ public class TypeRef extends ObjectRef {
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((this.realmName == null) ? 0 : this.realmName.hashCode());
result = prime * result + ((this.name == null) ? 0 : this.name.hashCode());
result = prime * result + ((this.type == null) ? 0 : this.type.hashCode());
return result;
}
@ -90,10 +86,10 @@ public class TypeRef extends ObjectRef {
if (getClass() != obj.getClass())
return false;
TypeRef other = (TypeRef) obj;
if (this.realmName == null) {
if (other.realmName != null)
if (this.name == null) {
if (other.name != null)
return false;
} else if (!this.realmName.equals(other.realmName))
} else if (!this.name.equals(other.name))
return false;
if (this.type == null) {
if (other.type != null)

View File

@ -1,12 +1,12 @@
/*
* 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.

View File

@ -1,12 +1,12 @@
/*
* 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.
@ -15,42 +15,25 @@
*/
package li.strolch.xmlpers.test;
import static li.strolch.xmlpers.test.model.ModelBuilder.assertResource;
import static li.strolch.xmlpers.test.model.ModelBuilder.assertResourceUpdated;
import static li.strolch.xmlpers.test.model.ModelBuilder.createResource;
import static li.strolch.xmlpers.test.model.ModelBuilder.updateResource;
import static li.strolch.xmlpers.test.model.ModelBuilder.*;
import static org.junit.Assert.assertNull;
import java.util.Properties;
import li.strolch.xmlpers.api.*;
import li.strolch.xmlpers.objref.ObjectReferenceCache;
import li.strolch.xmlpers.test.model.MyModel;
import org.junit.BeforeClass;
import org.junit.Test;
import li.strolch.xmlpers.api.FileDao;
import li.strolch.xmlpers.api.IoMode;
import li.strolch.xmlpers.api.PersistenceConstants;
import li.strolch.xmlpers.api.PersistenceContext;
import li.strolch.xmlpers.api.PersistenceContextFactory;
import li.strolch.xmlpers.api.PersistenceContextFactoryDelegator;
import li.strolch.xmlpers.api.PersistenceManager;
import li.strolch.xmlpers.api.PersistenceTransaction;
import li.strolch.xmlpers.impl.DefaultPersistenceRealm;
import li.strolch.xmlpers.impl.DefaultPersistenceTransaction;
import li.strolch.xmlpers.impl.PathBuilder;
import li.strolch.xmlpers.objref.ObjectReferenceCache;
import li.strolch.xmlpers.test.model.MyModel;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*
*/
@SuppressWarnings("nls")
public class FileDaoTest extends AbstractPersistenceTest {
private static final String TEST_PATH = "target/db/FileDaoTest/";
private static final boolean VERBOSE = true;
private DefaultPersistenceRealm realm;
private PathBuilder pathBuilder;
@BeforeClass
public static void beforeClass() {
@ -59,42 +42,36 @@ public class FileDaoTest extends AbstractPersistenceTest {
private void setup(IoMode ioMode) {
Properties properties = new Properties();
properties.setProperty(PersistenceConstants.PROP_XML_IO_MOD, ioMode.name());
properties.setProperty(PersistenceConstants.PROP_BASEPATH, TEST_PATH + ioMode.name());
setup(properties);
ObjectReferenceCache objectRefCache = new ObjectReferenceCache(PersistenceManager.DEFAULT_REALM);
this.pathBuilder = new PathBuilder(PersistenceManager.DEFAULT_REALM, properties);
this.realm = new DefaultPersistenceRealm(PersistenceManager.DEFAULT_REALM, this.persistenceManager,
this.persistenceManager.getCtxFactory(), this.pathBuilder, objectRefCache);
}
@Test
public void testCrudSax() {
setup(IoMode.SAX);
try (PersistenceTransaction tx = new DefaultPersistenceTransaction(this.realm, VERBOSE)) {
FileDao fileDao = new FileDao(tx, this.pathBuilder, VERBOSE);
tx.setIoMode(IoMode.SAX);
testCrud(this.realm.getCtxFactoryDelegator(), fileDao);
try (PersistenceTransaction tx = this.persistenceManager.openTx()) {
FileDao fileDao = new FileDao(tx, this.persistenceManager.getPathBuilder(), VERBOSE);
testCrud(tx, fileDao);
}
}
@Test
public void testCrudDom() {
setup(IoMode.DOM);
try (PersistenceTransaction tx = new DefaultPersistenceTransaction(this.realm, VERBOSE)) {
FileDao fileDao = new FileDao(tx, this.pathBuilder, VERBOSE);
tx.setIoMode(IoMode.DOM);
testCrud(this.realm.getCtxFactoryDelegator(), fileDao);
try (PersistenceTransaction tx = this.persistenceManager.openTx()) {
FileDao fileDao = new FileDao(tx, this.persistenceManager.getPathBuilder(), VERBOSE);
testCrud(tx, fileDao);
}
}
private void testCrud(PersistenceContextFactoryDelegator ctxFactoryDelegator, FileDao fileDao) {
private void testCrud(PersistenceTransaction tx, FileDao fileDao) {
MyModel resource = createResource();
assertResource(resource);
Class<? extends MyModel> classType = resource.getClass();
PersistenceContextFactory<MyModel> ctxFactory = ctxFactoryDelegator.getCtxFactory(classType);
ObjectReferenceCache objectRefCache = this.realm.getObjectRefCache();
PersistenceContextFactory<MyModel> ctxFactory = tx.getManager().getCtxFactory().getCtxFactory(classType);
ObjectReferenceCache objectRefCache = tx.getManager().getObjectRefCache();
PersistenceContext<MyModel> context = ctxFactory.createCtx(objectRefCache, resource);
context.setObject(resource);
fileDao.performCreate(context);

View File

@ -1,12 +1,12 @@
/*
* 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.
@ -39,7 +39,6 @@ import li.strolch.xmlpers.test.model.MyModel;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*
*/
public class LockingTest extends AbstractPersistenceTest {
@ -56,6 +55,7 @@ public class LockingTest extends AbstractPersistenceTest {
@Before
public void before() {
Properties properties = new Properties();
properties.setProperty(PersistenceConstants.PROP_XML_IO_MOD, IoMode.DOM.name());
properties.setProperty(PersistenceConstants.PROP_BASEPATH, BASE_PATH + IoMode.DOM.name());
properties.setProperty(PersistenceConstants.PROP_LOCK_TIME_MILLIS, Long.toString(500L));
setup(properties);
@ -222,7 +222,8 @@ public class LockingTest extends AbstractPersistenceTest {
@Override
protected void doWork(PersistenceTransaction tx) {
IdOfSubTypeRef objectRef = tx.getObjectRefCache().getIdOfSubTypeRef(TYPE_RES, RES_TYPE, this.resourceId);
IdOfSubTypeRef objectRef = tx.getManager().getObjectRefCache()
.getIdOfSubTypeRef(TYPE_RES, RES_TYPE, this.resourceId);
MyModel resource = tx.getObjectDao().queryById(objectRef);
assertNotNull(resource);
updateResource(resource);

View File

@ -1,12 +1,12 @@
/*
* 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.
@ -43,7 +43,6 @@ import li.strolch.xmlpers.test.model.Book;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*
*/
public class ObjectDaoBookTest extends AbstractPersistenceTest {
@ -56,6 +55,7 @@ public class ObjectDaoBookTest extends AbstractPersistenceTest {
private void setup(IoMode ioMode) {
Properties properties = new Properties();
properties.setProperty(PersistenceConstants.PROP_XML_IO_MOD, ioMode.name());
properties.setProperty(PersistenceConstants.PROP_BASEPATH, BASEPATH + ioMode.name());
setup(properties);
}
@ -63,35 +63,29 @@ public class ObjectDaoBookTest extends AbstractPersistenceTest {
@Test
public void testCrudSax() {
setup(IoMode.SAX);
testCrud(IoMode.SAX);
testCrud();
}
@Test
public void testCrudDom() {
setup(IoMode.DOM);
testCrud(IoMode.DOM);
testCrud();
}
private PersistenceTransaction freshTx(IoMode ioMode) {
PersistenceTransaction tx = this.persistenceManager.openTx();
tx.setIoMode(ioMode);
return tx;
}
private void testCrud(IoMode ioMode) {
private void testCrud() {
ObjectDao objectDao;
// create new book
Book book = createBook();
try (PersistenceTransaction tx = freshTx(ioMode);) {
try (PersistenceTransaction tx = this.persistenceManager.openTx()) {
objectDao = tx.getObjectDao();
objectDao.add(book);
}
// read book
try (PersistenceTransaction tx = freshTx(ioMode);) {
IdOfTypeRef bookRef = tx.getObjectRefCache()
try (PersistenceTransaction tx = this.persistenceManager.openTx()) {
IdOfTypeRef bookRef = tx.getManager().getObjectRefCache()
.getIdOfTypeRef(TestConstants.TYPE_BOOK, Long.toString(BOOK_ID));
objectDao = tx.getObjectDao();
book = objectDao.queryById(bookRef);
@ -103,8 +97,8 @@ public class ObjectDaoBookTest extends AbstractPersistenceTest {
}
// read modified book
try (PersistenceTransaction tx = freshTx(ioMode);) {
IdOfTypeRef bookRef = tx.getObjectRefCache()
try (PersistenceTransaction tx = this.persistenceManager.openTx()) {
IdOfTypeRef bookRef = tx.getManager().getObjectRefCache()
.getIdOfTypeRef(TestConstants.TYPE_BOOK, Long.toString(BOOK_ID));
objectDao = tx.getObjectDao();
book = objectDao.queryById(bookRef);
@ -112,14 +106,14 @@ public class ObjectDaoBookTest extends AbstractPersistenceTest {
}
// delete book
try (PersistenceTransaction tx = freshTx(ioMode);) {
try (PersistenceTransaction tx = this.persistenceManager.openTx()) {
objectDao = tx.getObjectDao();
objectDao.remove(book);
}
// fail to read
try (PersistenceTransaction tx = freshTx(ioMode);) {
IdOfTypeRef bookRef = tx.getObjectRefCache()
try (PersistenceTransaction tx = this.persistenceManager.openTx()) {
IdOfTypeRef bookRef = tx.getManager().getObjectRefCache()
.getIdOfTypeRef(TestConstants.TYPE_BOOK, Long.toString(BOOK_ID));
objectDao = tx.getObjectDao();
book = objectDao.queryById(bookRef);
@ -149,26 +143,25 @@ public class ObjectDaoBookTest extends AbstractPersistenceTest {
// create a list of books
List<Book> books = new ArrayList<>(10);
for (int i = 0; i < 10; i++) {
long id = i;
String title = "Bulk Test Book. " + i; //$NON-NLS-1$
String author = "Nick Hornby"; //$NON-NLS-1$
String press = "Penguin Books"; //$NON-NLS-1$
double price = 21.30;
Book book = createBook(id, title, author, press, price);
Book book = createBook((long) i, title, author, press, price);
books.add(book);
}
// save all
try (PersistenceTransaction tx = freshTx(ioMode);) {
try (PersistenceTransaction tx = this.persistenceManager.openTx()) {
ObjectDao objectDao = tx.getObjectDao();
objectDao.addAll(books);
books.clear();
}
// query all
try (PersistenceTransaction tx = freshTx(ioMode);) {
TypeRef typeRef = tx.getObjectRefCache().getTypeRef(TestConstants.TYPE_BOOK);
try (PersistenceTransaction tx = this.persistenceManager.openTx()) {
TypeRef typeRef = tx.getManager().getObjectRefCache().getTypeRef(TestConstants.TYPE_BOOK);
ObjectDao objectDao = tx.getObjectDao();
books = objectDao.queryAll(typeRef);
assertEquals("Expected to find 10 entries!", 10, books.size()); //$NON-NLS-1$
@ -178,8 +171,8 @@ public class ObjectDaoBookTest extends AbstractPersistenceTest {
}
// now query them again
try (PersistenceTransaction tx = freshTx(ioMode);) {
TypeRef typeRef = tx.getObjectRefCache().getTypeRef(TestConstants.TYPE_BOOK);
try (PersistenceTransaction tx = this.persistenceManager.openTx()) {
TypeRef typeRef = tx.getManager().getObjectRefCache().getTypeRef(TestConstants.TYPE_BOOK);
ObjectDao objectDao = tx.getObjectDao();
books = objectDao.queryAll(typeRef);
assertEquals("Expected to find 0 entries!", 0, books.size()); //$NON-NLS-1$
@ -205,20 +198,20 @@ public class ObjectDaoBookTest extends AbstractPersistenceTest {
// read by id
try (PersistenceTransaction tx = this.persistenceManager.openTx()) {
ObjectRef objectRef = tx.getObjectRefCache().getIdOfTypeRef(classType, Long.toString(id));
ObjectRef objectRef = tx.getManager().getObjectRefCache().getIdOfTypeRef(classType, Long.toString(id));
Book book = tx.getObjectDao().queryById(objectRef);
assertNotNull("Expected to read book by ID", book); //$NON-NLS-1$
}
// delete by id
try (PersistenceTransaction tx = this.persistenceManager.openTx()) {
ObjectRef objectRef = tx.getObjectRefCache().getIdOfTypeRef(classType, Long.toString(id));
ObjectRef objectRef = tx.getManager().getObjectRefCache().getIdOfTypeRef(classType, Long.toString(id));
tx.getObjectDao().removeById(objectRef);
}
// fail to read by id
try (PersistenceTransaction tx = this.persistenceManager.openTx()) {
ObjectRef objectRef = tx.getObjectRefCache().getIdOfTypeRef(classType, Long.toString(id));
ObjectRef objectRef = tx.getManager().getObjectRefCache().getIdOfTypeRef(classType, Long.toString(id));
Book book = tx.getObjectDao().queryById(objectRef);
assertNull("Expected that book was deleted by ID, thus can not be read anymore", book); //$NON-NLS-1$
}

View File

@ -1,12 +1,12 @@
/*
* 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.
@ -50,7 +50,6 @@ import li.strolch.xmlpers.test.model.MyModel;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*
*/
public class ObjectDaoResourceTest extends AbstractPersistenceTest {
@ -66,6 +65,7 @@ public class ObjectDaoResourceTest extends AbstractPersistenceTest {
private void setup(IoMode ioMode) {
Properties properties = new Properties();
properties.setProperty(PersistenceConstants.PROP_XML_IO_MOD, ioMode.name());
properties.setProperty(PersistenceConstants.PROP_BASEPATH, BASEPATH + ioMode.name());
setup(properties);
}
@ -73,35 +73,30 @@ public class ObjectDaoResourceTest extends AbstractPersistenceTest {
@Test
public void testCrudSax() {
setup(IoMode.SAX);
testCrud(IoMode.SAX);
testCrud();
}
@Test
public void testCrudDom() {
setup(IoMode.DOM);
testCrud(IoMode.DOM);
testCrud();
}
private PersistenceTransaction freshTx(IoMode ioMode) {
PersistenceTransaction tx = this.persistenceManager.openTx();
tx.setIoMode(ioMode);
return tx;
}
private void testCrud(IoMode ioMode) {
private void testCrud() {
ObjectDao objectDao;
// create new resource
MyModel resource = createResource();
try (PersistenceTransaction tx = freshTx(ioMode);) {
try (PersistenceTransaction tx = this.persistenceManager.openTx()) {
objectDao = tx.getObjectDao();
objectDao.add(resource);
}
// read resource
try (PersistenceTransaction tx = freshTx(ioMode);) {
IdOfSubTypeRef resRef = tx.getObjectRefCache().getIdOfSubTypeRef(TestConstants.TYPE_RES, RES_TYPE, RES_ID);
try (PersistenceTransaction tx = this.persistenceManager.openTx()) {
IdOfSubTypeRef resRef = tx.getManager().getObjectRefCache()
.getIdOfSubTypeRef(TestConstants.TYPE_RES, RES_TYPE, RES_ID);
objectDao = tx.getObjectDao();
resource = objectDao.queryById(resRef);
assertResource(resource);
@ -112,22 +107,24 @@ public class ObjectDaoResourceTest extends AbstractPersistenceTest {
}
// read modified resource
try (PersistenceTransaction tx = freshTx(ioMode);) {
IdOfSubTypeRef resRef = tx.getObjectRefCache().getIdOfSubTypeRef(TestConstants.TYPE_RES, RES_TYPE, RES_ID);
try (PersistenceTransaction tx = this.persistenceManager.openTx()) {
IdOfSubTypeRef resRef = tx.getManager().getObjectRefCache()
.getIdOfSubTypeRef(TestConstants.TYPE_RES, RES_TYPE, RES_ID);
objectDao = tx.getObjectDao();
resource = objectDao.queryById(resRef);
assertResourceUpdated(resource);
}
// delete resource
try (PersistenceTransaction tx = freshTx(ioMode);) {
try (PersistenceTransaction tx = this.persistenceManager.openTx()) {
objectDao = tx.getObjectDao();
objectDao.remove(resource);
}
// fail to read
try (PersistenceTransaction tx = freshTx(ioMode);) {
IdOfSubTypeRef resRef = tx.getObjectRefCache().getIdOfSubTypeRef(TestConstants.TYPE_RES, RES_TYPE, RES_ID);
try (PersistenceTransaction tx = this.persistenceManager.openTx()) {
IdOfSubTypeRef resRef = tx.getManager().getObjectRefCache()
.getIdOfSubTypeRef(TestConstants.TYPE_RES, RES_TYPE, RES_ID);
objectDao = tx.getObjectDao();
resource = objectDao.queryById(resRef);
assertNull(resource);
@ -167,15 +164,15 @@ public class ObjectDaoResourceTest extends AbstractPersistenceTest {
}
// save all
try (PersistenceTransaction tx = freshTx(ioMode);) {
try (PersistenceTransaction tx = this.persistenceManager.openTx()) {
ObjectDao objectDao = tx.getObjectDao();
objectDao.addAll(resources);
resources.clear();
}
// query all
try (PersistenceTransaction tx = freshTx(ioMode);) {
SubTypeRef subTypeRef = tx.getObjectRefCache().getSubTypeRef(TestConstants.TYPE_RES, type);
try (PersistenceTransaction tx = this.persistenceManager.openTx()) {
SubTypeRef subTypeRef = tx.getManager().getObjectRefCache().getSubTypeRef(TestConstants.TYPE_RES, type);
ObjectDao objectDao = tx.getObjectDao();
resources = objectDao.queryAll(subTypeRef);
assertEquals("Expected to find 10 entries!", 10, resources.size()); //$NON-NLS-1$
@ -185,8 +182,8 @@ public class ObjectDaoResourceTest extends AbstractPersistenceTest {
}
// now query them again
try (PersistenceTransaction tx = freshTx(ioMode);) {
SubTypeRef subTypeRef = tx.getObjectRefCache().getSubTypeRef(TestConstants.TYPE_RES, type);
try (PersistenceTransaction tx = this.persistenceManager.openTx()) {
SubTypeRef subTypeRef = tx.getManager().getObjectRefCache().getSubTypeRef(TestConstants.TYPE_RES, type);
ObjectDao objectDao = tx.getObjectDao();
resources = objectDao.queryAll(subTypeRef);
assertEquals("Expected to find 0 entries!", 0, resources.size()); //$NON-NLS-1$
@ -210,22 +207,23 @@ public class ObjectDaoResourceTest extends AbstractPersistenceTest {
// read by id
try (PersistenceTransaction tx = this.persistenceManager.openTx()) {
ObjectRef objectRef = tx.getObjectRefCache().getIdOfSubTypeRef(classType, subType, id);
ObjectRef objectRef = tx.getManager().getObjectRefCache().getIdOfSubTypeRef(classType, subType, id);
MyModel resource = tx.getObjectDao().queryById(objectRef);
assertNotNull("Expected to read resource by ID", resource); //$NON-NLS-1$
}
// delete by id
try (PersistenceTransaction tx = this.persistenceManager.openTx()) {
ObjectRef objectRef = tx.getObjectRefCache().getIdOfSubTypeRef(classType, subType, id);
ObjectRef objectRef = tx.getManager().getObjectRefCache().getIdOfSubTypeRef(classType, subType, id);
tx.getObjectDao().removeById(objectRef);
}
// fail to read by id
try (PersistenceTransaction tx = this.persistenceManager.openTx()) {
ObjectRef objectRef = tx.getObjectRefCache().getIdOfSubTypeRef(classType, subType, id);
ObjectRef objectRef = tx.getManager().getObjectRefCache().getIdOfSubTypeRef(classType, subType, id);
MyModel resource = tx.getObjectDao().queryById(objectRef);
assertNull("Expected that resource was deleted by ID, thus can not be read anymore", resource); //$NON-NLS-1$
assertNull("Expected that resource was deleted by ID, thus can not be read anymore",
resource); //$NON-NLS-1$
}
}
@ -317,7 +315,7 @@ public class ObjectDaoResourceTest extends AbstractPersistenceTest {
// read / modify
try (PersistenceTransaction tx = this.persistenceManager.openTx()) {
ObjectRef objectRef = tx.getObjectRefCache().getIdOfSubTypeRef(TYPE_RES, subType, id);
ObjectRef objectRef = tx.getManager().getObjectRefCache().getIdOfSubTypeRef(TYPE_RES, subType, id);
Object resource = tx.getObjectDao().queryById(objectRef);
assertNotNull(resource);
tx.getObjectDao().update(resource);
@ -326,7 +324,7 @@ public class ObjectDaoResourceTest extends AbstractPersistenceTest {
// read / delete
try (PersistenceTransaction tx = this.persistenceManager.openTx()) {
ObjectRef objectRef = tx.getObjectRefCache().getIdOfSubTypeRef(TYPE_RES, subType, id);
ObjectRef objectRef = tx.getManager().getObjectRefCache().getIdOfSubTypeRef(TYPE_RES, subType, id);
Object resource = tx.getObjectDao().queryById(objectRef);
assertNotNull(resource);
tx.getObjectDao().remove(resource);
@ -335,7 +333,7 @@ public class ObjectDaoResourceTest extends AbstractPersistenceTest {
// make sure deleted, then recreate
try (PersistenceTransaction tx = this.persistenceManager.openTx()) {
ObjectRef objectRef = tx.getObjectRefCache().getIdOfSubTypeRef(TYPE_RES, subType, id);
ObjectRef objectRef = tx.getManager().getObjectRefCache().getIdOfSubTypeRef(TYPE_RES, subType, id);
Object resource = tx.getObjectDao().queryById(objectRef);
assertNull(resource);
@ -347,7 +345,7 @@ public class ObjectDaoResourceTest extends AbstractPersistenceTest {
// read / modify / delete
try (PersistenceTransaction tx = this.persistenceManager.openTx()) {
ObjectRef objectRef = tx.getObjectRefCache().getIdOfSubTypeRef(TYPE_RES, subType, id);
ObjectRef objectRef = tx.getManager().getObjectRefCache().getIdOfSubTypeRef(TYPE_RES, subType, id);
Object resource = tx.getObjectDao().queryById(objectRef);
assertNotNull(resource);
tx.getObjectDao().update(resource);

View File

@ -1,125 +0,0 @@
/*
* 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.xmlpers.test;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import java.util.Properties;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import li.strolch.xmlpers.api.IoMode;
import li.strolch.xmlpers.api.PersistenceConstants;
import li.strolch.xmlpers.api.PersistenceTransaction;
import li.strolch.xmlpers.objref.ObjectRef;
import li.strolch.xmlpers.test.impl.TestConstants;
import li.strolch.xmlpers.test.model.ModelBuilder;
import li.strolch.xmlpers.test.model.MyModel;
@SuppressWarnings("nls")
public class RealmTest extends AbstractPersistenceTest {
private static final String REALM_2 = "Realm2";
private static final String REALM_1 = "Realm1";
protected static final String BASE_PATH = "target/db/RealmTest/";
@BeforeClass
public static void beforeClass() {
cleanPath(BASE_PATH);
}
@Before
public void before() {
Properties properties = new Properties();
properties.setProperty(PersistenceConstants.PROP_BASEPATH, BASE_PATH + IoMode.DOM.name());
setup(properties);
}
@Test
public void shouldNotFindObjInBothRealms() {
// object details
String objType = TestConstants.TYPE_RES;
String type = ModelBuilder.RES_TYPE;
String name = ModelBuilder.RES_NAME;
String id = "shouldNotFindObjInBothRealms";
// create in first realm
try (PersistenceTransaction txRealm1 = this.persistenceManager.openTx(REALM_1);) {
MyModel resource1 = ModelBuilder.createResource(id, name, type);
txRealm1.getObjectDao().add(resource1);
}
// find in first realm
try (PersistenceTransaction txRealm1 = this.persistenceManager.openTx(REALM_1);) {
ObjectRef objectRef = txRealm1.getObjectRefCache().getIdOfSubTypeRef(objType, type, id);
MyModel resource = txRealm1.getObjectDao().queryById(objectRef);
assertNotNull("Resource was not found in first realm!", resource);
}
// fail to find in second realm
try (PersistenceTransaction txRealm2 = this.persistenceManager.openTx(REALM_2);) {
ObjectRef objectRef = txRealm2.getObjectRefCache().getIdOfSubTypeRef(objType, type, id);
MyModel resource = txRealm2.getObjectDao().queryById(objectRef);
assertNull("Resource was not created in second realm, thus not expected to be found there!", resource);
}
}
@Test
public void shouldNotDeleteObjInWrongRealm() {
// object details
String objType = TestConstants.TYPE_RES;
String subType = ModelBuilder.RES_TYPE;
String name = ModelBuilder.RES_NAME;
String id = "shouldNotDeleteObjInWrongRealm";
// create in first realm
try (PersistenceTransaction txRealm1 = this.persistenceManager.openTx(REALM_1);) {
MyModel resource1 = ModelBuilder.createResource(id, name, subType);
txRealm1.getObjectDao().add(resource1);
}
// create in second realm
try (PersistenceTransaction txRealm2 = this.persistenceManager.openTx(REALM_2);) {
MyModel resource1 = ModelBuilder.createResource(id, name, subType);
txRealm2.getObjectDao().add(resource1);
}
// delete in second realm
try (PersistenceTransaction txRealm2 = this.persistenceManager.openTx(REALM_2);) {
ObjectRef objectRef = txRealm2.getObjectRefCache().getIdOfSubTypeRef(objType, subType, id);
txRealm2.getObjectDao().removeById(objectRef);
}
// fail to find in second realm
try (PersistenceTransaction txRealm2 = this.persistenceManager.openTx(REALM_2);) {
ObjectRef objectRef = txRealm2.getObjectRefCache().getIdOfSubTypeRef(objType, subType, id);
MyModel resource = txRealm2.getObjectDao().queryById(objectRef);
assertNull("Resource was not deleted from second realm, thus not expected to be found there!", resource);
}
// find in first realm
try (PersistenceTransaction txRealm1 = this.persistenceManager.openTx(REALM_1);) {
ObjectRef objectRef = txRealm1.getObjectRefCache().getIdOfSubTypeRef(objType, subType, id);
MyModel resource = txRealm1.getObjectDao().queryById(objectRef);
assertNotNull("Resource was not found in first realm!", resource);
}
}
}

View File

@ -1,12 +1,12 @@
/*
* 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.
@ -26,23 +26,16 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import li.strolch.xmlpers.api.*;
import li.strolch.xmlpers.test.model.Book;
import li.strolch.xmlpers.test.model.MyModel;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import li.strolch.xmlpers.api.IoMode;
import li.strolch.xmlpers.api.ModificationResult;
import li.strolch.xmlpers.api.ObjectDao;
import li.strolch.xmlpers.api.PersistenceConstants;
import li.strolch.xmlpers.api.PersistenceTransaction;
import li.strolch.xmlpers.api.TransactionResult;
import li.strolch.xmlpers.test.model.Book;
import li.strolch.xmlpers.test.model.MyModel;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*
*/
public class TransactionResultTest extends AbstractPersistenceTest {
@ -59,12 +52,6 @@ public class TransactionResultTest extends AbstractPersistenceTest {
setup(properties);
}
private PersistenceTransaction freshTx() {
PersistenceTransaction tx = this.persistenceManager.openTx();
tx.setIoMode(IoMode.SAX);
return tx;
}
@Test
public void testWithTxResult() {
@ -72,7 +59,7 @@ public class TransactionResultTest extends AbstractPersistenceTest {
performChanges(txResult);
String logMessage = txResult.getLogMessage();
logger.info(logMessage);
assertThat(logMessage, containsString("TX for realm defaultRealm was completed after")); //$NON-NLS-1$
assertThat(logMessage, containsString("TX was completed after")); //$NON-NLS-1$
assertThat(logMessage, containsString("30 objects in 2 types were modified")); //$NON-NLS-1$
assertThat(txResult.getKeys(), containsInAnyOrder("Resource", "Book")); //$NON-NLS-1$ //$NON-NLS-2$
@ -119,12 +106,13 @@ public class TransactionResultTest extends AbstractPersistenceTest {
i = 0;
for (; i < 10; i++) {
String title = "Tx Result Test Book " + i; //$NON-NLS-1$
Book book = new Book((long) i, title, "Douglas Adams", "Apress", Math.random() * i); //$NON-NLS-1$ //$NON-NLS-2$
Book book = new Book((long) i, title, "Douglas Adams", "Apress",
Math.random() * i); //$NON-NLS-1$ //$NON-NLS-2$
books.add(book);
}
// save all
try (PersistenceTransaction tx = freshTx();) {
try (PersistenceTransaction tx = this.persistenceManager.openTx()) {
tx.setTransactionResult(txResult);
ObjectDao objectDao = tx.getObjectDao();
objectDao.addAll(resources);

View File

@ -129,9 +129,8 @@
<module>li.strolch.model</module>
<module>li.strolch.testbase</module>
<!-- Deactivate XML Persistence and see later if we want to add it back <module>li.strolch.persistence.xml</module> -->
<module>li.strolch.persistence.postgresql</module>
<module>li.strolch.persistence.xml</module>
<module>li.strolch.agent</module>
<module>li.strolch.service</module>
<module>li.strolch.rest</module>