# HG changeset patch # User Raimund Renkert # Date 1423062364 -3600 # Node ID 3dd907dafe71b6106b60f8b6a39146888b139c8f # Parent 7fbf0246012c958ecebe4b01bbaf78e9a061a196 Added utility classes to communicate with the database. diff -r 7fbf0246012c -r 3dd907dafe71 src/main/java/de/intevation/lada/util/AbstractRepository.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/java/de/intevation/lada/util/AbstractRepository.java Wed Feb 04 16:06:04 2015 +0100 @@ -0,0 +1,89 @@ +/* Copyright (C) 2013 by Bundesamt fuer Strahlenschutz + * Software engineering by Intevation GmbH + * + * This file is Free Software under the GNU GPL (v>=3) + * and comes with ABSOLUTELY NO WARRANTY! Check out + * the documentation coming with IMIS-Labordaten-Application for details. + */ +package de.intevation.lada.util; + +import javax.ejb.EJBTransactionRolledbackException; +import javax.ejb.Stateless; +import javax.ejb.TransactionAttribute; +import javax.ejb.TransactionAttributeType; +import javax.persistence.EntityExistsException; +import javax.persistence.EntityManager; +import javax.persistence.Query; +import javax.persistence.TransactionRequiredException; + + +@Stateless +public abstract class AbstractRepository +implements Repository +{ + protected EntityManagerProducer emp; + + protected String dataSource; + + protected String jndiPath; + + /** + * Create or update an object in the database. + * This operation can not be undone. + * + * @param object The object to create or update + * + * @throws EntityExistsException + * @throws IllegalArgumentException + * @throws EJBTransactionRolledbackException + * @throws TransactionRequiredException + */ + @TransactionAttribute(TransactionAttributeType.REQUIRED) + protected void persistInDatabase(Object object) + throws EntityExistsException, + IllegalArgumentException, + EJBTransactionRolledbackException, + TransactionRequiredException + { + emp.entityManager(dataSource).merge(object); + } + + /** + * Remove an object from the datebase. + * This operation can not be undone. + * + * @param object The object to remove + * + * @throws IllegalArgumentException + * @throws TransactionRequiredException + */ + @TransactionAttribute(TransactionAttributeType.REQUIRED) + protected void removeFromDatabase(Object object) + throws IllegalArgumentException, + TransactionRequiredException + { + EntityManager em = emp.entityManager(dataSource); + em.remove( + em.contains(object) ? + object : em.merge(object)); + } + + public Query queryFromString(String sql) { + EntityManager em = emp.entityManager(dataSource); + return em.createNativeQuery(sql); + } + + @Override + public void setDataSource(String dataSource) { + this.dataSource = dataSource; + } + + @Override + public String getDataSource() { + return this.dataSource; + } + + public void setEntityManagerProducer(EntityManagerProducer emp) { + this.emp = emp; + } +} diff -r 7fbf0246012c -r 3dd907dafe71 src/main/java/de/intevation/lada/util/DefaultRepository.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/java/de/intevation/lada/util/DefaultRepository.java Wed Feb 04 16:06:04 2015 +0100 @@ -0,0 +1,81 @@ +/* Copyright (C) 2013 by Bundesamt fuer Strahlenschutz + * Software engineering by Intevation GmbH + * + * This file is Free Software under the GNU GPL (v>=3) + * and comes with ABSOLUTELY NO WARRANTY! Check out + * the documentation coming with IMIS-Labordaten-Application for details. + */ +package de.intevation.lada.util; + +import javax.ejb.EJBTransactionRolledbackException; +import javax.persistence.EntityExistsException; +import javax.persistence.TransactionRequiredException; + +import de.intevation.lada.util.rest.Response; + + +/** + * @author rrenkert + */ +public class DefaultRepository extends ReadOnlyRepository { + + public DefaultRepository() { + } + + @Override + public Response create(Object object) { + Response response = new Response(true, 200, object); + try { + this.persistInDatabase(object); + } + catch (EntityExistsException eee) { + return new Response(false, 601, object); + } + catch (IllegalArgumentException iae) { + return new Response(false, 602, object); + } + catch (TransactionRequiredException tre) { + return new Response(false, 603, object); + } + catch (EJBTransactionRolledbackException ete) { + return new Response(false, 604, object); + } + return response; + } + + @Override + public Response update(Object object) { + Response response = new Response(true, 200, object); + try { + this.persistInDatabase(object); + } + catch (EntityExistsException eee) { + return new Response(false, 601, object); + } + catch (IllegalArgumentException iae) { + return new Response(false, 602, object); + } + catch (TransactionRequiredException tre) { + return new Response(false, 603, object); + } + catch (EJBTransactionRolledbackException ete) { + return new Response(false, 604, object); + } + return response; + } + + @Override + public Response delete(Object object) { + Response response = new Response(true, 200, null); + try { + this.removeFromDatabase(object); + } + catch (IllegalArgumentException iae) { + return new Response(false, 602, object); + } + catch (TransactionRequiredException tre) { + return new Response(false, 603, object); + } + return response; + } +} diff -r 7fbf0246012c -r 3dd907dafe71 src/main/java/de/intevation/lada/util/EntityManagerProducer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/java/de/intevation/lada/util/EntityManagerProducer.java Wed Feb 04 16:06:04 2015 +0100 @@ -0,0 +1,64 @@ +/* Copyright (C) 2013 by Bundesamt fuer Strahlenschutz + * Software engineering by Intevation GmbH + * + * This file is Free Software under the GNU GPL (v>=3) + * and comes with ABSOLUTELY NO WARRANTY! Check out + * the documentation coming with IMIS-Labordaten-Application for details. + */ +package de.intevation.lada.util; + +import javax.annotation.Resource; +import javax.ejb.LocalBean; +import javax.ejb.SessionContext; +import javax.ejb.Stateless; +import javax.persistence.EntityManager; +import javax.validation.UnexpectedTypeException; + + +@Stateless +@LocalBean +public class EntityManagerProducer { + + @Resource + private SessionContext ctx; + + private String jndiPath = "java:app/entitymanager/"; + + /** + * Constructor for multi-tenancy entity manager delegate. + * Default jndi search path is 'java:app/entitymanager'. + */ + public EntityManagerProducer() { + } + + /** + * Constructor for multi-tenancy entity manager delegate. + * + * @param jndiEnv The jndi path to search for datasources. + * Defaults to 'java:app/entitymanager'. + */ + public EntityManagerProducer(String jndiPath) { + this.jndiPath = jndiPath; + } + + /** + * Create an entity manager for a datasource. + * + * @throws UnexpectedTypeException + * @param dataSourceName The jndi name of the datasource. + * @return The entity manager for the datasource. + */ + public EntityManager entityManager(String dataSourceName) { + + EntityManager entityManager = + (EntityManager) this.ctx.lookup(this.jndiPath + dataSourceName); + + if (entityManager == null) { + throw new UnexpectedTypeException("Unknown data source name '" + + dataSourceName + "'."); + } + + return entityManager; + + } +} diff -r 7fbf0246012c -r 3dd907dafe71 src/main/java/de/intevation/lada/util/QueryBuilder.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/java/de/intevation/lada/util/QueryBuilder.java Wed Feb 04 16:06:04 2015 +0100 @@ -0,0 +1,238 @@ +/* Copyright (C) 2013 by Bundesamt fuer Strahlenschutz + * Software engineering by Intevation GmbH + * + * This file is Free Software under the GNU GPL (v>=3) + * and comes with ABSOLUTELY NO WARRANTY! Check out + * the documentation coming with IMIS-Labordaten-Application for details. + */ +package de.intevation.lada.util; + +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Path; +import javax.persistence.criteria.Predicate; +import javax.persistence.criteria.Root; + +/** + * @author Raimund Renkert + */ +public class QueryBuilder { + + private EntityManager manager; + private CriteriaBuilder builder; + private CriteriaQuery query; + private Root root; + private Class clazz; + private Predicate filter; + + /** + * Create a new QueryBuilder for the specified class. + * + * @param manager + * @param clazz + */ + public QueryBuilder(EntityManager manager, Class clazz) { + this.manager = manager; + this.clazz = clazz; + this.builder = this.manager.getCriteriaBuilder(); + this.query = this.builder.createQuery(this.clazz); + this.root = this.query.from(this.clazz); + } + + /** + * Get the criteria query build with this class. + * + * @return The query. + */ + public CriteriaQuery getQuery() { + if (this.filter == null) { + this.query.where(); + return this.query; + } + this.query.where(this.filter); + return this.query; + } + + /** + * Logical AND operation. + * + * @param id The database column name. + * @param value The filter value + * @return The builder itself. + */ + public QueryBuilder and(String id, Object value) { + Predicate p = this.builder.equal(this.root.get(id), value); + if (this.filter != null) { + this.filter = this.builder.and(this.filter, p); + } + else { + this.filter = this.builder.and(p); + } + return this; + } + + /** + * Logical AND with like operation. + * + * @param id The database column name. + * @param value The filter value + * @return The builder itself. + */ + public QueryBuilder andLike(String id, String value) { + Path path = this.root.get(id); + Predicate p = this.builder.like(path, value); + if (this.filter != null) { + this.filter = this.builder.and(this.filter, p); + } + else { + this.filter = this.builder.and(p); + } + return this; + } + + /** + * Logical OR operation. + * + * @param id The database column name + * @param value The filter value. + * @return The builder itself. + */ + public QueryBuilder or(String id, Object value) { + Predicate p = this.builder.equal(this.root.get(id), value); + if (this.filter != null) { + this.filter = this.builder.or(this.filter, p); + } + else { + this.filter = this.builder.or(p); + } + return this; + } + + /** + * Logical OR with like operation. + * + * @param column The database column name. + * @param value The filter value + * @return The builder itself. + */ + public QueryBuilder orLike(String id, String value) { + Path path = this.root.get(id); + Predicate p = this.builder.like(path, value); + if (this.filter != null) { + this.filter = this.builder.or(this.filter, p); + } + else { + this.filter = this.builder.or(p); + } + return this; + } + + /** + * Logical AND operation. + * All elements in values will be concatenated with AND operator. + * + * @param id The database column name. + * @param values List of values. + * @return The builder itself. + */ + public QueryBuilder and(String id, List values) { + for(String v: values) { + this.and(id, v); + } + return this; + } + + /** + * Logical OR operation. + * All elements in values will be concatenated with OR operator. + * + * @param id The database column name. + * @param values List of values. + * @return The builder itself. + */ + public QueryBuilder or(String id, List values) { + for (String v: values) { + this.or(id, v); + } + return this; + } + + /** + * Logical AND operation. + * The actually defined query will be concatenated with the query defined + * in the builder b. + * + * @param b A builder. + * @return The builder itself. + */ + public QueryBuilder and(QueryBuilder b) { + if (b == null || b.filter == null) { + return this; + } + if (this.filter != null) { + this.filter = this.builder.and(this.filter, b.filter); + } + else { + this.filter = this.builder.and(b.filter); + } + return this; + } + + /** + * Logical OR operation. + * The actually defined query will be concatenated with the query defined + * in the builder b. + * + * @param b A builder. + * @return The builder itself. + */ + public QueryBuilder or(QueryBuilder b) { + if (b == null || b.filter == null) { + return this; + } + if (this.filter != null) { + this.filter = this.builder.or(this.filter, b.filter); + } + else { + this.filter = this.builder.or(b.filter); + } + return this; + } + + /** + * Use 'distinct' in the query. + */ + public void distinct() { + this.query.distinct(true); + } + + /** + * Order result by the specified column name + * + * @param id The column name. + * @param asc Ascending(true), Descending(false). + */ + public void orderBy(String id, boolean asc) { + if (asc) { + this.query.orderBy(this.builder.asc(this.root.get(id))); + } + else { + this.query.orderBy(this.builder.desc(this.root.get(id))); + } + } + + /** + * Get an empty instance of this builder to create subfilters. + * + * @return An empty instance of this builder. + */ + public QueryBuilder getEmptyBuilder(){ + QueryBuilder copy = new QueryBuilder(manager, clazz); + copy.builder = this.builder; + copy.root = this.root; + return copy; + } +} diff -r 7fbf0246012c -r 3dd907dafe71 src/main/java/de/intevation/lada/util/ReadOnlyRepository.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/java/de/intevation/lada/util/ReadOnlyRepository.java Wed Feb 04 16:06:04 2015 +0100 @@ -0,0 +1,75 @@ +/* Copyright (C) 2013 by Bundesamt fuer Strahlenschutz + * Software engineering by Intevation GmbH + * + * This file is Free Software under the GNU GPL (v>=3) + * and comes with ABSOLUTELY NO WARRANTY! Check out + * the documentation coming with IMIS-Labordaten-Application for details. + */ +package de.intevation.lada.util; + +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.criteria.CriteriaQuery; + +import de.intevation.lada.util.rest.Response; + +/** + * @author rrenkert + */ +public class ReadOnlyRepository extends AbstractRepository { + + public ReadOnlyRepository() { + } + + @Override + public Response create(Object object) { + return null; + } + + @Override + public Response update(Object object) { + return null; + } + + @Override + public Response delete(Object object) { + return null; + } + + @Override + public Response filter(CriteriaQuery filter) { + List result = + emp.entityManager(dataSource).createQuery(filter).getResultList(); + return new Response(true, 200, result); + } + + @Override + public Response filter(CriteriaQuery filter, int size, int start) { + List result = + emp.entityManager(dataSource).createQuery(filter).getResultList(); + if (size > 0 && start > -1) { + List newList = result.subList(start, size + start); + return new Response(true, 200, newList, result.size()); + } + return new Response(true, 200, result); + } + + public Response getAll(Class clazz) { + EntityManager manager = emp.entityManager(dataSource); + QueryBuilder builder = + new QueryBuilder(manager, clazz); + List result = + manager.createQuery(builder.getQuery()).getResultList(); + return new Response(true, 200, result); + } + + @Override + public Response getById(Class clazz, String id) { + T item = emp.entityManager(dataSource).find(clazz, id); + if (item == null) { + return new Response(false, 600, null); + } + return new Response(true, 200, item); + } +} diff -r 7fbf0246012c -r 3dd907dafe71 src/main/java/de/intevation/lada/util/Repository.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/java/de/intevation/lada/util/Repository.java Wed Feb 04 16:06:04 2015 +0100 @@ -0,0 +1,44 @@ +/* Copyright (C) 2013 by Bundesamt fuer Strahlenschutz + * Software engineering by Intevation GmbH + * + * This file is Free Software under the GNU GPL (v>=3) + * and comes with ABSOLUTELY NO WARRANTY! Check out + * the documentation coming with IMIS-Labordaten-Application for details. + */ +package de.intevation.lada.util; + +import javax.persistence.Query; +import javax.persistence.criteria.CriteriaQuery; + +import de.intevation.lada.util.rest.Response; + +/** + * This generic Container is an interface to request and select Data + * obejcts from the connected database. + * + * @author Raimund Renkert + */ +public interface Repository { + + public Response create(Object object); + + public Response update(Object object); + + public Response delete(Object object); + + public Response filter(CriteriaQuery filter); + + public Response filter(CriteriaQuery filter, int size, int start); + + public Response getAll(Class clazz); + + public Response getById(Class clazz, String id); + + public Query queryFromString(String sql); + + public void setDataSource(String dataSource); + + public String getDataSource(); + + public void setEntityManagerProducer(EntityManagerProducer emp); +} diff -r 7fbf0246012c -r 3dd907dafe71 src/main/java/de/intevation/lada/util/RepositoryType.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/java/de/intevation/lada/util/RepositoryType.java Wed Feb 04 16:06:04 2015 +0100 @@ -0,0 +1,13 @@ +/* Copyright (C) 2013 by Bundesamt fuer Strahlenschutz + * Software engineering by Intevation GmbH + * + * This file is Free Software under the GNU GPL (v>=3) + * and comes with ABSOLUTELY NO WARRANTY! Check out + * the documentation coming with IMIS-Labordaten-Application for details. + */ +package de.intevation.lada.util; + + +public enum RepositoryType { + RO, RW +} diff -r 7fbf0246012c -r 3dd907dafe71 src/main/java/de/intevation/lada/util/annotation/RepositoryConfig.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/java/de/intevation/lada/util/annotation/RepositoryConfig.java Wed Feb 04 16:06:04 2015 +0100 @@ -0,0 +1,20 @@ +/* Copyright (C) 2013 by Bundesamt fuer Strahlenschutz + * Software engineering by Intevation GmbH + * + * This file is Free Software under the GNU GPL (v>=3) + * and comes with ABSOLUTELY NO WARRANTY! Check out + * the documentation coming with IMIS-Labordaten-Application for details. + */ +package de.intevation.lada.util.annotation; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +import de.intevation.lada.util.RepositoryType; + + +@Retention(RetentionPolicy.RUNTIME) +public @interface RepositoryConfig { + RepositoryType type() default RepositoryType.RO; + String dataSource() default ""; +} diff -r 7fbf0246012c -r 3dd907dafe71 src/main/java/de/intevation/lada/util/factory/RepositoryFactory.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/java/de/intevation/lada/util/factory/RepositoryFactory.java Wed Feb 04 16:06:04 2015 +0100 @@ -0,0 +1,48 @@ +/* Copyright (C) 2013 by Bundesamt fuer Strahlenschutz + * Software engineering by Intevation GmbH + * + * This file is Free Software under the GNU GPL (v>=3) + * and comes with ABSOLUTELY NO WARRANTY! Check out + * the documentation coming with IMIS-Labordaten-Application for details. + */ +package de.intevation.lada.util.factory; + +import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.inject.Produces; +import javax.enterprise.inject.spi.Annotated; +import javax.enterprise.inject.spi.InjectionPoint; +import javax.inject.Inject; + +import de.intevation.lada.util.DefaultRepository; +import de.intevation.lada.util.EntityManagerProducer; +import de.intevation.lada.util.ReadOnlyRepository; +import de.intevation.lada.util.Repository; +import de.intevation.lada.util.RepositoryType; +import de.intevation.lada.util.annotation.RepositoryConfig; + + +@ApplicationScoped +public class RepositoryFactory { + + @Inject + private EntityManagerProducer emp; + + @Produces + Repository createRepository(InjectionPoint injectionPoint) { + Annotated annotated = injectionPoint.getAnnotated(); + RepositoryConfig config = annotated.getAnnotation(RepositoryConfig.class); + if (config == null) { + return new ReadOnlyRepository(); + } + Repository repository; + if (config.type() == RepositoryType.RW) { + repository = new DefaultRepository(); + } + else { + repository = new ReadOnlyRepository(); + } + repository.setEntityManagerProducer(emp); + repository.setDataSource(config.dataSource()); + return repository; + } +}