com.webbfontaine.valuewebb.irms.repo.DefaultAssignmentEventRepository.java Source code

Java tutorial

Introduction

Here is the source code for com.webbfontaine.valuewebb.irms.repo.DefaultAssignmentEventRepository.java

Source

/*
 * Copyrights 2002-2012 Webb Fontaine
 * Developer: Sargis Harutyunyan
 * Date: 05 avr. 2012
 * This software is the proprietary information of Webb Fontaine.
 * Its use is subject to License terms.
 */
package com.webbfontaine.valuewebb.irms.repo;

import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.webbfontaine.valuewebb.irms.eventbus.VWEventBus;
import com.webbfontaine.valuewebb.irms.impl.assignment.AssignmentEventCreator;
import com.webbfontaine.valuewebb.irms.impl.assignment.workload.runtime.WorkloadEvent;
import com.webbfontaine.valuewebb.model.assignment.AssignmentEventType;
import com.webbfontaine.valuewebb.model.assignment.TTAssignmentEvent;
import com.webbfontaine.valuewebb.model.util.Utils;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.Transactional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import java.util.List;

import static com.webbfontaine.valuewebb.irms.repo.JPAUtils.singleResult;
import static com.webbfontaine.valuewebb.model.assignment.AssignmentEventType.ASSIGNED;

@Name("assignmentEventRepository")
@Scope(ScopeType.APPLICATION)
public class DefaultAssignmentEventRepository implements AssignmentEventRepository {

    private static final Logger LOGGER = LoggerFactory.getLogger(DefaultAssignmentEventRepository.class);

    private static final String SELECT_ASSIGNEES_QUERY = "SELECT ASSIGNEE FROM TT_ASSIGNMENT_EVENT WHERE TT_ID=? AND EVENT_TYPE=? GROUP BY ASSIGNEE ORDER BY MAX(ID) DESC";

    private final EntityManagerFactory entityManagerFactory = Utils.getEntityManagerFactory();

    private VWEventBus irmsEventBus;

    private AssignmentEventCreator assignmentEventCreator;

    @Override
    @Transactional
    public void persistAssignment(TTAssignmentEvent ttAssignmentEvent) {
        EntityManager entityManager = entityManagerFactory.createEntityManager();

        try {
            TTAssignmentEvent assignmentEvent = doPersist(entityManager, ttAssignmentEvent);
            triggerCEPEvent(assignmentEvent);
        } finally {
            entityManager.close();
        }
    }

    @Override
    @Transactional
    public void persistDone(TTAssignmentEvent event) {
        Optional<TTAssignmentEvent> optional = tryToRestoreAssignee(event);
        if (optional.isPresent()) {
            persistAssignment(optional.get());
        } else {
            LOGGER.debug("Cannot find prev. assignment for TT with id: {}, probably old processed TT",
                    event.getTtId());
        }
    }

    @Override
    @Transactional
    public TTAssignmentEvent getLastEventByTtId(Long ttId) {
        EntityManager entityManager = entityManagerFactory.createEntityManager();

        try {
            return queryForLastEvent(entityManager, ttId);
        } finally {
            entityManager.close();
        }
    }

    @Override
    @Transactional
    public String getLastAssigneeByTtId(Long ttId, String status) {
        EntityManager entityManager = entityManagerFactory.createEntityManager();

        try {
            return queryForLastAssignee(entityManager, ttId, status);
        } finally {
            entityManager.close();
        }
    }

    @Override
    @Transactional
    public List<String> getAssigneesByTtId(Long ttId) {
        EntityManager entityManager = entityManagerFactory.createEntityManager();

        try {
            @SuppressWarnings("unchecked")
            List<String> assignees = entityManager.createNativeQuery(SELECT_ASSIGNEES_QUERY).setParameter(1, ttId)
                    .setParameter(2, ASSIGNED.name()).getResultList();

            return assignees;
        } finally {
            entityManager.close();
        }
    }

    private Optional<TTAssignmentEvent> tryToRestoreAssignee(final TTAssignmentEvent event) {
        Optional<TTAssignmentEvent> lastAssignment = getLastAssignment(event.getTtId());

        return lastAssignment.transform(new Function<TTAssignmentEvent, TTAssignmentEvent>() {
            @Override
            public TTAssignmentEvent apply(TTAssignmentEvent input) {
                String assignee = input.getAssignee();

                return assignmentEventCreator.copyOfWithNewAssignee(assignee, event);
            }
        });
    }

    private Optional<TTAssignmentEvent> getLastAssignment(Long ttId) {
        return Optional.fromNullable(assignedEventTypeOnly(getLastEventByTtId(ttId)));
    }

    private void triggerCEPEvent(TTAssignmentEvent assignmentEvent) {
        irmsEventBus.postAsync(new WorkloadEvent(assignmentEvent.getAssignee(), assignmentEvent.getWorkload()));
    }

    private static TTAssignmentEvent assignedEventTypeOnly(TTAssignmentEvent assignmentEvent) {
        if (assignmentEvent != null && assignmentEvent.getEventType() == ASSIGNED) {
            return assignmentEvent;
        }

        return null;
    }

    private static TTAssignmentEvent doPersist(EntityManager entityManager, TTAssignmentEvent assignmentEvent) {
        LOGGER.debug("Saving 'Assignment' event: {}", assignmentEvent);

        TTAssignmentEvent lastEvent = queryForLastEvent(entityManager, assignmentEvent.getTtId());
        if (validate(lastEvent, assignmentEvent)) {
            entityManager.persist(assignmentEvent);
            entityManager.flush();
        }

        return assignmentEvent;
    }

    private static boolean validate(TTAssignmentEvent lastEvent, TTAssignmentEvent newEvent) {
        return doneEventIsNotFirstEvent(lastEvent, newEvent) && validSequenceOfEvents(lastEvent, newEvent);
    }

    private static boolean doneEventIsNotFirstEvent(TTAssignmentEvent lastEvent, TTAssignmentEvent newEvent) {
        if (lastEvent == null && newEvent.getEventType() == AssignmentEventType.DONE) {
            LOGGER.warn("Trying to insert {} event as start event for TT with id: {}", AssignmentEventType.DONE,
                    newEvent.getTtId());
            return false;
        }

        return true;
    }

    private static boolean validSequenceOfEvents(TTAssignmentEvent lastEvent, TTAssignmentEvent newEvent) {
        if (lastEvent != null && lastEvent.getEventType() == newEvent.getEventType()) {
            LOGGER.warn("Found events sequence of 'Assignment' with the same type: {}, {}", lastEvent, newEvent);
            return false;
        }

        return true;
    }

    private static String queryForLastAssignee(EntityManager entityManager, Long ttId, String status) {
        @SuppressWarnings("unchecked")
        List<String> assignees = (List<String>) entityManager.createNamedQuery("lastAssigneeByTtId")
                .setParameter("ttId", ttId).setParameter("status", status).setParameter("eventType", ASSIGNED)
                .getResultList();

        return singleResult(assignees);
    }

    private static TTAssignmentEvent queryForLastEvent(EntityManager entityManager, Long ttId) {
        @SuppressWarnings("unchecked")
        List<TTAssignmentEvent> events = (List<TTAssignmentEvent>) entityManager
                .createNamedQuery("lastAssignmentEventByTtId").setParameter("ttId", ttId).getResultList();

        return singleResult(events);
    }

    @In(create = true)
    public void setIrmsEventBus(VWEventBus vwEventBus) {
        this.irmsEventBus = vwEventBus;
    }

    @In(create = true)
    public void setAssignmentEventCreator(AssignmentEventCreator assignmentEventCreator) {
        this.assignmentEventCreator = assignmentEventCreator;
    }
}