[New][Devel] Work in progress of implementing ActivityMap

- Implemented PostgreSQL persistence

Still missing is the xml persistence implementation and fixing
the tests. Currently no tests were run, just trying to fix compile
errors
This commit is contained in:
Robert von Burg 2015-06-29 08:34:14 +02:00
parent 82ce5a7261
commit e2ac84ecdc
8 changed files with 312 additions and 29 deletions

View File

@ -0,0 +1,51 @@
/*
* 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.model.xml;
import java.text.MessageFormat;
import li.strolch.model.ActivityVisitor;
import li.strolch.model.Tags;
import li.strolch.model.activity.Activity;
import org.xml.sax.ContentHandler;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*/
public class ActivityToSaxVisitor extends StrolchElementToSaxVisitor implements ActivityVisitor<Void> {
public ActivityToSaxVisitor(ContentHandler contentHandler) {
super(contentHandler);
}
@Override
public Void visit(Activity activity) {
try {
this.contentHandler.startElement(null, null, Tags.ACTIVITY, attributesFor(activity));
toSax(activity);
this.contentHandler.endElement(null, null, Tags.ACTIVITY);
} catch (Exception e) {
String msg = "Failed to transform Activity {0} to XML due to {1}"; //$NON-NLS-1$
msg = MessageFormat.format(msg, activity.getLocator(), e.getMessage());
throw new RuntimeException(msg, e);
}
return null;
}
}

View File

@ -0,0 +1,179 @@
/*
* 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 java.io.IOException;
import java.io.InputStream;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.SQLXML;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.sax.SAXResult;
import li.strolch.model.ActivityVisitor;
import li.strolch.model.Tags;
import li.strolch.model.activity.Activity;
import li.strolch.model.query.ActivityQuery;
import li.strolch.model.xml.ActivityToSaxVisitor;
import li.strolch.model.xml.SimpleStrolchElementListener;
import li.strolch.model.xml.XmlModelSaxReader;
import li.strolch.persistence.api.ActivityDao;
import li.strolch.persistence.api.StrolchPersistenceException;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
@SuppressWarnings("nls")
public class PostgreSqlActivityDao extends PostgresqlDao<Activity> implements ActivityDao {
public static final String ACTIVITIES = "activities";
protected PostgreSqlActivityDao(PostgreSqlStrolchTransaction tx) {
super(tx);
}
@Override
protected String getClassName() {
return Tags.ACTIVITY;
}
@Override
protected String getTableName() {
return ACTIVITIES;
}
@Override
protected Activity parseFromXml(String id, String type, SQLXML sqlxml) {
SimpleStrolchElementListener listener = new SimpleStrolchElementListener();
try (InputStream binaryStream = sqlxml.getBinaryStream()) {
SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
parser.parse(binaryStream, new XmlModelSaxReader(listener));
} catch (SQLException | IOException | SAXException | ParserConfigurationException e) {
throw new StrolchPersistenceException(MessageFormat.format(
"Failed to extract Activity from sqlxml value for {0} / {1}", id, type), e);
}
if (listener.getActivities().size() == 0)
throw new StrolchPersistenceException(MessageFormat.format(
"No Activity parsed from sqlxml value for {0} / {1}", id, type));
if (listener.getActivities().size() > 1)
throw new StrolchPersistenceException(MessageFormat.format(
"Multiple Activities parsed from sqlxml value for {0} / {1}", id, type));
return listener.getActivities().get(0);
}
protected SQLXML createSqlXml(Activity activity, PreparedStatement preparedStatement) throws SQLException,
SAXException {
SQLXML sqlxml = tx().getConnection().createSQLXML();
SAXResult saxResult = sqlxml.setResult(SAXResult.class);
ContentHandler contentHandler = saxResult.getHandler();
contentHandler.startDocument();
new ActivityToSaxVisitor(contentHandler).visit(activity);
contentHandler.endDocument();
return sqlxml;
}
@Override
protected void internalSave(final Activity activity) {
String sql = "insert into " + getTableName() + " (id, name, type, asxml) values (?, ?, ?, ?)";
try (PreparedStatement preparedStatement = tx().getConnection().prepareStatement(sql)) {
preparedStatement.setString(1, activity.getId());
preparedStatement.setString(2, activity.getName());
preparedStatement.setString(3, activity.getType());
SQLXML sqlxml = createSqlXml(activity, preparedStatement);
preparedStatement.setSQLXML(4, sqlxml);
try {
int modCount = preparedStatement.executeUpdate();
if (modCount != 1) {
String msg = "Expected to save 1 element with id {0} but SQL statement modified {1} elements!";
msg = MessageFormat.format(msg, activity.getId(), modCount);
throw new StrolchPersistenceException(msg);
}
} finally {
sqlxml.free();
}
} catch (SQLException | SAXException e) {
throw new StrolchPersistenceException(MessageFormat.format("Failed to insert Activity {0} due to {1}",
activity.getLocator(), e.getLocalizedMessage()), e);
}
}
@Override
protected void internalUpdate(final Activity activity) {
String sql = "update " + getTableName() + " set name = ?, type = ?, asxml = ? where id = ? ";
try (PreparedStatement preparedStatement = tx().getConnection().prepareStatement(sql)) {
preparedStatement.setString(1, activity.getName());
preparedStatement.setString(2, activity.getType());
preparedStatement.setString(4, activity.getId());
SQLXML sqlxml = createSqlXml(activity, preparedStatement);
preparedStatement.setSQLXML(3, sqlxml);
try {
int modCount = preparedStatement.executeUpdate();
if (modCount != 1) {
String msg = "Expected to update 1 element with id {0} but SQL statement modified {1} elements!";
msg = MessageFormat.format(msg, activity.getId(), modCount);
throw new StrolchPersistenceException(msg);
}
} finally {
sqlxml.free();
}
} catch (SQLException | SAXException 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 query, ActivityVisitor<U> activityVisitor) {
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(activityVisitor.visit(t));
}
}
} catch (SQLException e) {
throw new StrolchPersistenceException("Failed to perform query due to: " + e.getMessage(), e);
}
return list;
}
}

View File

@ -0,0 +1,42 @@
/*
* 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;
/**
* @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;
}
}

View File

@ -50,9 +50,6 @@ public class PostgreSqlOrderDao extends PostgresqlDao<Order> implements OrderDao
public static final String ORDERS = "orders";
/**
* @param tx
*/
public PostgreSqlOrderDao(PostgreSqlStrolchTransaction tx) {
super(tx);
}
@ -89,7 +86,7 @@ public class PostgreSqlOrderDao extends PostgresqlDao<Order> implements OrderDao
}
protected SQLXML createSqlXml(Order order, PreparedStatement preparedStatement) throws SQLException, SAXException {
SQLXML sqlxml = this.tx.getConnection().createSQLXML();
SQLXML sqlxml = tx().getConnection().createSQLXML();
SAXResult saxResult = sqlxml.setResult(SAXResult.class);
ContentHandler contentHandler = saxResult.getHandler();
contentHandler.startDocument();
@ -102,7 +99,7 @@ public class PostgreSqlOrderDao extends PostgresqlDao<Order> implements OrderDao
protected void internalSave(final Order order) {
String sql = "insert into " + getTableName()
+ " (id, name, type, state, date, asxml) values (?, ?, ?, ?::order_state, ?, ?)";
try (PreparedStatement preparedStatement = PostgreSqlOrderDao.this.tx.getConnection().prepareStatement(sql)) {
try (PreparedStatement preparedStatement = tx().getConnection().prepareStatement(sql)) {
preparedStatement.setString(1, order.getId());
preparedStatement.setString(2, order.getName());
preparedStatement.setString(3, order.getType());
@ -132,7 +129,7 @@ public class PostgreSqlOrderDao extends PostgresqlDao<Order> implements OrderDao
protected void internalUpdate(final Order order) {
String sql = "update " + getTableName()
+ " set name = ?, type = ?, state = ?::order_state, date = ?, asxml = ? where id = ? ";
try (PreparedStatement preparedStatement = PostgreSqlOrderDao.this.tx.getConnection().prepareStatement(sql)) {
try (PreparedStatement preparedStatement = tx().getConnection().prepareStatement(sql)) {
preparedStatement.setString(1, order.getName());
preparedStatement.setString(2, order.getType());
@ -169,7 +166,7 @@ public class PostgreSqlOrderDao extends PostgresqlDao<Order> implements OrderDao
List<U> list = new ArrayList<>();
String sql = queryVisitor.getSql();
try (PreparedStatement ps = PostgreSqlOrderDao.this.tx.getConnection().prepareStatement(sql)) {
try (PreparedStatement ps = tx().getConnection().prepareStatement(sql)) {
queryVisitor.setValues(ps);
try (ResultSet result = ps.executeQuery()) {

View File

@ -33,6 +33,7 @@ import li.strolch.agent.api.RealmHandler;
import li.strolch.agent.api.StrolchAgent;
import li.strolch.agent.api.StrolchComponent;
import li.strolch.agent.api.StrolchRealm;
import li.strolch.persistence.api.ActivityDao;
import li.strolch.persistence.api.AuditDao;
import li.strolch.persistence.api.OrderDao;
import li.strolch.persistence.api.PersistenceHandler;
@ -155,6 +156,11 @@ public class PostgreSqlPersistenceHandler extends StrolchComponent implements Pe
return ((PostgreSqlStrolchTransaction) tx).getResourceDao();
}
@Override
public ActivityDao getActivityDao(StrolchTransaction tx) {
return ((PostgreSqlStrolchTransaction) tx).getActivityDao();
}
@Override
public AuditDao getAuditDao(StrolchTransaction tx) {
return ((PostgreSqlStrolchTransaction) tx).getAuditDao();

View File

@ -84,7 +84,7 @@ public class PostgreSqlResourceDao extends PostgresqlDao<Resource> implements Re
}
protected SQLXML createSqlXml(Resource res, PreparedStatement preparedStatement) throws SQLException, SAXException {
SQLXML sqlxml = this.tx.getConnection().createSQLXML();
SQLXML sqlxml = tx().getConnection().createSQLXML();
SAXResult saxResult = sqlxml.setResult(SAXResult.class);
ContentHandler contentHandler = saxResult.getHandler();
contentHandler.startDocument();
@ -96,7 +96,7 @@ public class PostgreSqlResourceDao extends PostgresqlDao<Resource> implements Re
@Override
protected void internalSave(final Resource res) {
String sql = "insert into " + getTableName() + " (id, name, type, asxml) values (?, ?, ?, ?)";
try (PreparedStatement preparedStatement = PostgreSqlResourceDao.this.tx.getConnection().prepareStatement(sql)) {
try (PreparedStatement preparedStatement = tx().getConnection().prepareStatement(sql)) {
preparedStatement.setString(1, res.getId());
preparedStatement.setString(2, res.getName());
preparedStatement.setString(3, res.getType());
@ -123,7 +123,7 @@ public class PostgreSqlResourceDao extends PostgresqlDao<Resource> implements Re
@Override
protected void internalUpdate(final Resource resource) {
String sql = "update " + getTableName() + " set name = ?, type = ?, asxml = ? where id = ? ";
try (PreparedStatement preparedStatement = PostgreSqlResourceDao.this.tx.getConnection().prepareStatement(sql)) {
try (PreparedStatement preparedStatement = tx().getConnection().prepareStatement(sql)) {
preparedStatement.setString(1, resource.getName());
preparedStatement.setString(2, resource.getType());
@ -158,7 +158,7 @@ public class PostgreSqlResourceDao extends PostgresqlDao<Resource> implements Re
List<U> list = new ArrayList<>();
String sql = queryVisitor.getSql();
try (PreparedStatement ps = PostgreSqlResourceDao.this.tx.getConnection().prepareStatement(sql)) {
try (PreparedStatement ps = tx().getConnection().prepareStatement(sql)) {
queryVisitor.setValues(ps);
try (ResultSet result = ps.executeQuery()) {

View File

@ -19,6 +19,7 @@ import java.sql.Connection;
import li.strolch.agent.api.StrolchRealm;
import li.strolch.persistence.api.AbstractTransaction;
import li.strolch.persistence.api.ActivityDao;
import li.strolch.persistence.api.AuditDao;
import li.strolch.persistence.api.OrderDao;
import li.strolch.persistence.api.PersistenceHandler;
@ -36,8 +37,9 @@ public class PostgreSqlStrolchTransaction extends AbstractTransaction {
private static final Logger logger = LoggerFactory.getLogger(PostgreSqlStrolchTransaction.class);
private PostgreSqlPersistenceHandler persistenceHandler;
private PostgresqlDao<?> orderDao;
private PostgresqlDao<?> resourceDao;
private PostgreSqlOrderDao orderDao;
private PostgreSqlResourceDao resourceDao;
private PostgreSqlActivityDao activityDao;
private AuditDao auditDao;
private Connection connection;
@ -94,9 +96,12 @@ public class PostgreSqlStrolchTransaction extends AbstractTransaction {
return (ResourceDao) this.resourceDao;
}
/**
* @return
*/
ActivityDao getActivityDao() {
if (this.activityDao == null)
this.activityDao = new PostgreSqlActivityDao(this);
return (ActivityDao) this.activityDao;
}
public AuditDao getAuditDao() {
if (this.auditDao == null)
this.auditDao = new PostgreSqlAuditDao(this);
@ -114,5 +119,4 @@ public class PostgreSqlStrolchTransaction extends AbstractTransaction {
public PersistenceHandler getPersistenceHandler() {
return this.persistenceHandler;
}
}

View File

@ -41,6 +41,10 @@ public abstract class PostgresqlDao<T extends StrolchElement> implements Strolch
this.commands = new ArrayList<>();
}
protected PostgreSqlStrolchTransaction tx() {
return this.tx;
}
protected abstract String getClassName();
protected abstract String getTableName();
@ -50,7 +54,7 @@ public abstract class PostgresqlDao<T extends StrolchElement> implements Strolch
@Override
public boolean hasElement(String type, String id) {
String sql = "select count(*) from " + getTableName() + " where type = ? and id = ?";
try (PreparedStatement statement = this.tx.getConnection().prepareStatement(sql)) {
try (PreparedStatement statement = tx().getConnection().prepareStatement(sql)) {
statement.setString(1, type);
statement.setString(2, id);
try (ResultSet result = statement.executeQuery()) {
@ -72,7 +76,7 @@ public abstract class PostgresqlDao<T extends StrolchElement> implements Strolch
@Override
public long querySize() {
String sql = "select count(*) from " + getTableName();
try (PreparedStatement statement = this.tx.getConnection().prepareStatement(sql)) {
try (PreparedStatement statement = tx().getConnection().prepareStatement(sql)) {
try (ResultSet result = statement.executeQuery()) {
result.next();
return result.getLong(1);
@ -85,7 +89,7 @@ public abstract class PostgresqlDao<T extends StrolchElement> implements Strolch
@Override
public long querySize(String type) {
String sql = "select count(*) from " + getTableName() + " where type = ?";
try (PreparedStatement statement = this.tx.getConnection().prepareStatement(sql)) {
try (PreparedStatement statement = tx().getConnection().prepareStatement(sql)) {
statement.setString(1, type);
try (ResultSet result = statement.executeQuery()) {
result.next();
@ -102,7 +106,7 @@ public abstract class PostgresqlDao<T extends StrolchElement> implements Strolch
Set<String> keySet = new HashSet<>();
String sql = "select id from " + getTableName();
try (PreparedStatement statement = this.tx.getConnection().prepareStatement(sql)) {
try (PreparedStatement statement = tx().getConnection().prepareStatement(sql)) {
try (ResultSet result = statement.executeQuery()) {
while (result.next()) {
keySet.add(result.getString("id"));
@ -120,7 +124,7 @@ public abstract class PostgresqlDao<T extends StrolchElement> implements Strolch
Set<String> keySet = new HashSet<>();
String sql = "select id from " + getTableName() + " where type = ?";
try (PreparedStatement statement = this.tx.getConnection().prepareStatement(sql)) {
try (PreparedStatement statement = tx().getConnection().prepareStatement(sql)) {
statement.setString(1, type);
try (ResultSet result = statement.executeQuery()) {
while (result.next()) {
@ -139,7 +143,7 @@ public abstract class PostgresqlDao<T extends StrolchElement> implements Strolch
Set<String> keySet = new HashSet<>();
String sql = "select distinct type from " + getTableName();
try (PreparedStatement statement = this.tx.getConnection().prepareStatement(sql)) {
try (PreparedStatement statement = tx().getConnection().prepareStatement(sql)) {
try (ResultSet result = statement.executeQuery()) {
while (result.next()) {
keySet.add(result.getString("type"));
@ -156,7 +160,7 @@ public abstract class PostgresqlDao<T extends StrolchElement> implements Strolch
public T queryBy(String type, String id) {
String sql = "select id, name, type, asxml from " + getTableName() + " where id = ? and type = ?";
try (PreparedStatement statement = this.tx.getConnection().prepareStatement(sql)) {
try (PreparedStatement statement = tx().getConnection().prepareStatement(sql)) {
statement.setString(1, id);
statement.setString(2, type);
try (ResultSet result = statement.executeQuery()) {
@ -180,7 +184,7 @@ public abstract class PostgresqlDao<T extends StrolchElement> implements Strolch
List<T> list = new ArrayList<>();
String sql = "select id, name, type, asxml from " + getTableName();
try (PreparedStatement statement = this.tx.getConnection().prepareStatement(sql)) {
try (PreparedStatement statement = tx().getConnection().prepareStatement(sql)) {
try (ResultSet result = statement.executeQuery()) {
while (result.next()) {
String id = result.getString("id");
@ -202,7 +206,7 @@ public abstract class PostgresqlDao<T extends StrolchElement> implements Strolch
List<T> list = new ArrayList<>();
String sql = "select id, name, type, asxml from " + getTableName() + " where type = ?";
try (PreparedStatement statement = this.tx.getConnection().prepareStatement(sql)) {
try (PreparedStatement statement = tx().getConnection().prepareStatement(sql)) {
statement.setString(1, type);
try (ResultSet result = statement.executeQuery()) {
while (result.next()) {
@ -335,7 +339,7 @@ public abstract class PostgresqlDao<T extends StrolchElement> implements Strolch
protected void internalRemove(final T element) {
String sql = "delete from " + getTableName() + " where id = ?";
try (PreparedStatement preparedStatement = this.tx.getConnection().prepareStatement(sql)) {
try (PreparedStatement preparedStatement = tx().getConnection().prepareStatement(sql)) {
preparedStatement.setString(1, element.getId());
int modCount = preparedStatement.executeUpdate();
@ -353,7 +357,7 @@ public abstract class PostgresqlDao<T extends StrolchElement> implements Strolch
protected void internalRemoveAll(final long toRemove) {
String sql = "delete from " + getTableName();
try (PreparedStatement preparedStatement = this.tx.getConnection().prepareStatement(sql)) {
try (PreparedStatement preparedStatement = tx().getConnection().prepareStatement(sql)) {
int modCount = preparedStatement.executeUpdate();
if (modCount != toRemove) {
String msg = "Expected to delete {0} elements but SQL statement removed {1} elements!";
@ -369,7 +373,7 @@ public abstract class PostgresqlDao<T extends StrolchElement> implements Strolch
protected void internalRemoveAllBy(final long toRemove, String type) {
String sql = "delete from " + getTableName() + " where type = ?";
try (PreparedStatement preparedStatement = this.tx.getConnection().prepareStatement(sql)) {
try (PreparedStatement preparedStatement = tx().getConnection().prepareStatement(sql)) {
preparedStatement.setString(1, type);
int modCount = preparedStatement.executeUpdate();
if (modCount != toRemove) {