[Lada-commits] [PATCH 08 of 14] Added utility classes to communicate with the database

Wald Commits scm-commit at wald.intevation.org
Wed Feb 4 16:16:30 CET 2015


# HG changeset patch
# User Raimund Renkert <raimund.renkert at intevation.de>
# 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;
+
+
+ at 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;
+
+
+ at Stateless
+ at 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 <a href="mailto:rrenkert at intevation.de">Raimund Renkert</a>
+ */
+public class QueryBuilder<T> {
+
+    private EntityManager manager;
+    private CriteriaBuilder builder;
+    private CriteriaQuery<T> query;
+    private Root<T> root;
+    private Class<T> clazz;
+    private Predicate filter;
+
+    /**
+     * Create a new QueryBuilder for the specified class.
+     *
+     * @param manager
+     * @param clazz
+     */
+    public QueryBuilder(EntityManager manager, Class<T> 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<T> 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<T> 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<T> andLike(String id, String value) {
+        Path<String> 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<T> 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<T> orLike(String id, String value) {
+        Path<String> 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 <i>values</i> will be concatenated with AND operator.
+     *
+     * @param id        The database column name.
+     * @param values    List of values.
+     * @return The builder itself.
+     */
+    public QueryBuilder<T> and(String id, List<String> values) {
+        for(String v: values) {
+            this.and(id, v);
+        }
+        return this;
+    }
+
+    /**
+     * Logical OR operation.
+     * All elements in <i>values</i> will be concatenated with OR operator.
+     *
+     * @param id        The database column name.
+     * @param values    List of values.
+     * @return The builder itself.
+     */
+    public QueryBuilder<T> or(String id, List<String> 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 <i>b</i>.
+     *
+     * @param b     A builder.
+     * @return The builder itself.
+     */
+    public QueryBuilder<T> and(QueryBuilder<T> 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 <i>b</i>.
+     *
+     * @param b     A builder.
+     * @return The builder itself.
+     */
+    public QueryBuilder<T> or(QueryBuilder<T> 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<T> getEmptyBuilder(){
+        QueryBuilder<T> copy = new QueryBuilder<T>(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 <T> Response filter(CriteriaQuery<T> filter) {
+        List<T> result =
+            emp.entityManager(dataSource).createQuery(filter).getResultList();
+        return new Response(true, 200, result);
+    }
+
+    @Override
+    public <T> Response filter(CriteriaQuery<T> filter, int size, int start) {
+        List<T> result =
+            emp.entityManager(dataSource).createQuery(filter).getResultList();
+        if (size > 0 && start > -1) {
+            List<T> newList = result.subList(start, size + start);
+            return new Response(true, 200, newList, result.size());
+        }
+        return new Response(true, 200, result);
+    }
+
+    public <T> Response getAll(Class<T> clazz) {
+        EntityManager manager = emp.entityManager(dataSource);
+        QueryBuilder<T> builder =
+            new QueryBuilder<T>(manager, clazz);
+        List<T> result =
+            manager.createQuery(builder.getQuery()).getResultList();
+        return new Response(true, 200, result);
+    }
+
+    @Override
+    public <T> Response getById(Class<T> 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 <a href="mailto:rrenkert at intevation.de">Raimund Renkert</a>
+ */
+public interface Repository {
+
+    public Response create(Object object);
+
+    public Response update(Object object);
+
+    public Response delete(Object object);
+
+    public <T> Response filter(CriteriaQuery<T> filter);
+
+    public <T> Response filter(CriteriaQuery<T> filter, int size, int start);
+
+    public <T> Response getAll(Class<T> clazz);
+
+    public <T> Response getById(Class<T> 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;
+
+
+ at 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;
+
+
+ at 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;
+    }
+}


More information about the Lada-commits mailing list