dk.statsbiblioteket.medieplatform.workflowstatemonitor.HibernatedStateManager.java Source code

Java tutorial

Introduction

Here is the source code for dk.statsbiblioteket.medieplatform.workflowstatemonitor.HibernatedStateManager.java

Source

/*
 * #%L
 * Workflow state monitor
 * %%
 * Copyright (C) 2012 The State and University Library, Denmark
 * %%
 * 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.
 * #L%
 */
package dk.statsbiblioteket.medieplatform.workflowstatemonitor;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/** A state manager backed by a hibernated database. */
public class HibernatedStateManager implements StateManager {
    private final Logger log = LoggerFactory.getLogger(getClass());

    @Override
    public List<State> addState(String entityName, State state, List<String> preservedStates) {
        try {
            List<State> result = new ArrayList<State>();
            log.trace("Enter addState(entityName='{}',state='{}',preservedStates='{}')",
                    new Object[] { entityName, state, preservedStates });
            Session session = HibernateUtil.getSessionFactory().openSession();
            try {
                session.beginTransaction();

                // Get or create entity in database
                Query entityQuery = session.createQuery("from Entity where name = :entityName");
                entityQuery.setParameter("entityName", entityName);
                Entity entity = (Entity) entityQuery.uniqueResult();
                if (entity == null) {
                    entity = new Entity();
                    entity.setName(entityName);
                    session.save(entity);
                }

                // Set entity and date in state
                state.setEntity(entity);
                if (state.getDate() == null) {
                    state.setDate(new Date());
                }

                // See if we have a preserved state now
                State preservedState = null;
                if (preservedStates != null && !preservedStates.isEmpty()) {
                    Query preservedStateQuery = session.createQuery(
                            "from State s where s.entity.name=:entityName AND s.date = (SELECT MAX(s2.date) FROM State s2 WHERE s.entity.id = s2.entity.id) AND s.stateName IN :preservedStates");
                    preservedStateQuery.setParameterList("preservedStates", preservedStates);
                    preservedStateQuery.setParameter("entityName", entityName);
                    preservedState = (State) preservedStateQuery.uniqueResult();
                }

                // Save the given state
                session.save(state);
                result.add(state);

                // If there was a preserved state, readd it with the current date
                if (preservedState != null) {
                    State represervedState = new State();
                    represervedState.setDate(new Date());
                    represervedState.setMessage(preservedState.getMessage());
                    represervedState.setComponent(preservedState.getComponent());
                    represervedState.setEntity(preservedState.getEntity());
                    represervedState.setStateName(preservedState.getStateName());
                    session.save(represervedState);
                    result.add(represervedState);
                }

                session.getTransaction().commit();
                log.debug("Added state '{}'", state);
            } catch (RuntimeException e) {
                Transaction transaction = session.getTransaction();
                if (transaction != null && transaction.isActive()) {
                    transaction.rollback();
                }
                throw e;
            } finally {
                if (session.isOpen()) {
                    session.close();
                }
            }
            log.trace("Exit addState(entityName='{}',state='{}',preservedStates='{} -> {}')",
                    new Object[] { entityName, state, preservedStates, result });
            return result;
        } catch (RuntimeException e) {
            log.error("Failed addState(entityName='{}',state='{}',preservedStates='{}')",
                    new Object[] { entityName, state, preservedStates, e });
            throw e;
        }
    }

    @Override
    public List<Entity> listEntities() {
        try {
            log.trace("Enter listEntities()");
            Session session = HibernateUtil.getSessionFactory().openSession();
            List<Entity> entities;
            try {
                session.beginTransaction();

                entities = session.createQuery("from Entity").list();
                session.getTransaction().commit();
            } finally {
                if (session.isOpen()) {
                    session.close();
                }
            }
            log.trace("Exit listEntities()->entities='{}'", entities.toString());
            return entities;
        } catch (RuntimeException e) {
            log.error("Failed listEntities(): '{}'", e);
            throw e;
        }
    }

    @Override
    public List<State> listStates(String entityName, boolean onlyLast, List<String> includes, List<String> excludes,
            Date startDate, Date endDate) {
        try {
            log.trace("Enter listStates(entityName='{}')", entityName);
            List<State> states = queryStates(entityName, onlyLast, includes, excludes, startDate, endDate);
            log.trace("Exit listStates(entityName='{}')->states='{}'", entityName, states);
            return states;
        } catch (RuntimeException e) {
            log.error("Failed listStates(entityName='{}')", entityName, e);
            throw e;
        }
    }

    @Override
    public List<State> listStates(boolean onlyLast, List<String> includes, List<String> excludes, Date startDate,
            Date endDate) {
        try {
            log.trace("Enter listStates(onlyLast='{}', includes='{}', excludes='{}')",
                    new Object[] { onlyLast, includes, excludes });
            List<State> states = queryStates(null, onlyLast, includes, excludes, startDate, endDate);
            log.trace("Exit listStates(onlyLast='{}', includes='{}', excludes='{}') -> states='{}'",
                    new Object[] { onlyLast, includes, excludes, states });
            return states;
        } catch (RuntimeException e) {
            log.error("Failed listStates(onlyLast='{}', includes='{}', excludes='{}')",
                    new Object[] { onlyLast, includes, excludes, e });
            throw e;
        }
    }

    private List<State> queryStates(String entityName, boolean onlyLast, List<String> includes,
            List<String> excludes, Date startDate, Date endDate) {

        Session session = HibernateUtil.getSessionFactory().openSession();
        List<State> states;
        try {
            session.beginTransaction();
            states = buildQuery(session, entityName, onlyLast, includes, excludes, startDate, endDate).list();
            session.getTransaction().commit();
        } finally {
            if (session.isOpen()) {
                session.close();
            }
        }
        return states;
    }

    private Query buildQuery(Session session, String entityName, boolean onlyLast, List<String> includes,
            List<String> excludes, Date startDate, Date endDate) {
        StringBuilder query = new StringBuilder();
        Map<String, Object> parameters = new HashMap<String, Object>();
        if (entityName != null) {
            initNextClause(query);
            query.append("s.entity.name = :entityName");
            parameters.put("entityName", entityName);
        }

        if (onlyLast) {
            initNextClause(query);
            query.append("s.date = (SELECT MAX(s2.date) FROM State s2 WHERE s.entity.id = s2.entity.id)");
        }

        if (includes != null && includes.size() != 0) {
            initNextClause(query);
            query.append("s.stateName IN (:includes)");
            parameters.put("includes", includes);
        }

        if (excludes != null && excludes.size() != 0) {
            initNextClause(query);
            query.append("NOT s.stateName IN (:excludes)");
            parameters.put("excludes", excludes);
        }

        if (startDate != null) {
            initNextClause(query);
            query.append("s.date >= :startDate");
            parameters.put("startDate", startDate);
        }

        if (endDate != null) {
            initNextClause(query);
            query.append("s.date < :endDate");
            parameters.put("endDate", endDate);
        }

        log.debug("Query: '{}' Parameters: '{}'", query, parameters);
        Query sessionQuery = session
                .createQuery("SELECT s FROM State s " + query.toString() + " ORDER BY s.date DESC");
        for (Map.Entry<String, Object> parameter : parameters.entrySet()) {
            if (parameter.getValue() instanceof Collection) {
                sessionQuery.setParameterList(parameter.getKey(), (Collection) parameter.getValue());
            } else {
                sessionQuery.setParameter(parameter.getKey(), parameter.getValue());
            }
        }
        return sessionQuery;
    }

    private void initNextClause(StringBuilder query) {
        if (query.length() > 0) {
            query.append(" AND ");
        } else {
            query.append("WHERE ");
        }
    }
}