org.sofun.core.kup.policy.KupActiveLifeCyclePolicyManager.java Source code

Java tutorial

Introduction

Here is the source code for org.sofun.core.kup.policy.KupActiveLifeCyclePolicyManager.java

Source

/*
 * Copyright (c)  Sofun Gaming SAS.
 * Copyright (c)  Julien Anguenot <julien@anguenot.org>
 * Copyright (c)  Julien De Preaumont <juliendepreaumont@gmail.com>
 * 
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     Julien Anguenot <julien@anguenot.org> - initial API and implementation
*/

package org.sofun.core.kup.policy;

import java.util.Calendar;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;

import javax.ejb.EJB;
import javax.ejb.Schedule;
import javax.ejb.Singleton;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.sofun.core.CoreConstants;
import org.sofun.core.api.kup.Kup;
import org.sofun.core.api.kup.KupService;
import org.sofun.core.api.kup.KupStatus;
import org.sofun.core.api.kup.KupType;
import org.sofun.core.api.local.KupServiceLocal;
import org.sofun.core.api.local.PredictionServiceLocal;
import org.sofun.core.api.prediction.PredictionService;

/**
 * Kup Policy Timer.
 * 
 * <p/>
 * 
 * triggering Kup life cycle checks on regular basis out of process for active
 * Kups only.
 * 
 * <p/>
 * 
 * This singleton is responsible to perform Kups status transitions. This is not
 * responsible for any kind of computations whatsover.
 * 
 * <p/>
 * 
 * @author <a href="mailto:julien@anguenot.org">Julien Anguenot</a>
 * 
 */
@Singleton
public class KupActiveLifeCyclePolicyManager extends AbstractKupLifeCycleManager {

    private static final Log log = LogFactory.getLog(KupActiveLifeCyclePolicyManager.class);

    @EJB(beanName = "KupServiceImpl", beanInterface = KupServiceLocal.class)
    private KupService kups;

    @EJB(beanName = "PredictionServiceImpl", beanInterface = PredictionServiceLocal.class)
    private PredictionService predictions;

    @PersistenceContext(unitName = CoreConstants.PERSISTENCE_UNIT)
    protected transient EntityManager em;

    @Override
    public KupService getKups() {
        return kups;
    }

    @Override
    public PredictionService getPredictions() {
        return predictions;
    }

    /**
     * Kup life cycle management.
     * 
     * @throws Exception
     */
    @Schedule(minute = "*/4", hour = "*", persistent = false)
    public void check() throws Exception {

        if (!available) {
            return;
        } else {
            available = false;
        }

        try {

            log.debug("Checking Kups and apply policy...");

            final byte[] activesAndCreated = new byte[3];
            activesAndCreated[0] = KupStatus.CREATED;
            activesAndCreated[1] = KupStatus.OPENED;
            activesAndCreated[2] = KupStatus.ON_GOING;
            final List<Kup> activeKups = kups.getKupsByStatus(activesAndCreated, null);

            final Calendar ref = getReferenceTime();

            ListIterator<Kup> kupsIter = activeKups.listIterator();
            while (kupsIter.hasNext()) {

                Kup kup = kupsIter.next();
                // Ensure no changes have been made by another transaction in
                // the mean time.
                em.refresh(kup);

                if (KupStatus.CREATED == kup.getStatus()) {
                    final Calendar startDate = Calendar.getInstance();
                    startDate.setTime(kup.getStartDate());
                    if (ref.compareTo(startDate) >= 0) {
                        kup.setStatus(KupStatus.OPENED);
                        log.info("Kup with id=" + String.valueOf(kup.getId()) + " has now status="
                                + KupStatus.OPENED);
                    }
                } else if (KupStatus.OPENED == kup.getStatus()) {
                    final Calendar startDate = Calendar.getInstance();
                    startDate.setTime(kup.getEffectiveStartDate());
                    if (ref.compareTo(startDate) >= 0) {
                        boolean cancelled = false;
                        if (kup.getParticipants().size() < 2) {
                            // Cancel gambling Kup if only one (1) participant.
                            if (KupType.GAMBLING_FR.equals(kup.getType())) {
                                kups.cancelKup(kup);
                                log.info("Kup with id=" + String.valueOf(kup.getId())
                                        + " has been cancelled because the " + "number of participants is < 2");
                                cancelled = true;
                            }
                        }
                        if (!cancelled) {
                            kup.setStatus(KupStatus.ON_GOING);
                            log.info("Kup with id=" + String.valueOf(kup.getId()) + " has now status="
                                    + KupStatus.ON_GOING);
                        }
                    }
                } else if (KupStatus.ON_GOING == kup.getStatus()) {
                    final Calendar endDate = Calendar.getInstance();
                    // Kup is closed if the last event of the Kup is less
                    // than 5 minutes to begin.
                    endDate.setTime(kup.getEffectiveEndDate());
                    if (ref.compareTo(endDate) >= 0) {
                        Map<Integer, Float> repartition = kups.getWinningsRepartitionRulesFor(kup);
                        final int numberOfWinners = repartition.size();
                        boolean cancelled = false;
                        if (kup.getParticipants().size() < numberOfWinners) {
                            // Cancel gambling Kup participants below amount of
                            // announced winners.
                            if (KupType.GAMBLING_FR.equals(kup.getType())) {
                                kups.cancelKup(kup);
                                log.info("Kup with id=" + String.valueOf(kup.getId())
                                        + " has been cancelled because the " + "number of participants is < 2");
                                cancelled = true;
                            }
                        }
                        if (!cancelled) {
                            kup.setStatus(KupStatus.CLOSED);
                            log.info("Kup with id=" + String.valueOf(kup.getId()) + " has now status="
                                    + KupStatus.CLOSED);
                        }
                    }
                }

            }

        } catch (Throwable t) {
            log.error(t.getMessage());
            t.printStackTrace();
        } finally {
            available = true;
        }

        // Cancel status in exceptional situations will be handled manually per
        // administrator request.
        // @see KupeService.cancelKup()

    }

}