org.sofun.core.member.MemberServiceImpl.java Source code

Java tutorial

Introduction

Here is the source code for org.sofun.core.member.MemberServiceImpl.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.member;

import java.net.URL;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.ejb.EJB;
import javax.ejb.Local;
import javax.ejb.Remote;
import javax.ejb.Schedule;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.sofun.core.Configuration;
import org.sofun.core.CoreConstants;
import org.sofun.core.api.exception.CoreException;
import org.sofun.core.api.kup.bet.KupMemberBet;
import org.sofun.core.api.local.NotificationServiceLocal;
import org.sofun.core.api.member.Member;
import org.sofun.core.api.member.MemberAccountStatus;
import org.sofun.core.api.member.MemberAccountType;
import org.sofun.core.api.member.MemberConnectionLog;
import org.sofun.core.api.member.MemberService;
import org.sofun.core.api.member.MemberTransaction;
import org.sofun.core.api.member.MemberTransactionType;
import org.sofun.core.api.member.PasswordResetToken;
import org.sofun.core.api.member.ejb.MemberServiceLocal;
import org.sofun.core.api.member.ejb.MemberServiceRemote;
import org.sofun.core.api.notification.NotificationService;
import org.sofun.core.api.session.Session;
import org.sofun.core.kup.bet.KupMemberBetImpl;

/**
 * Mermber Service Impl
 * 
 * @author <a href="mailto:julien@anguenot.org">Julien Anguenot</a>
 * 
 */
@Stateless
@Local(MemberServiceLocal.class)
@Remote(MemberServiceRemote.class)
public class MemberServiceImpl implements MemberService {

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

    private static final long serialVersionUID = 4805045845124861253L;

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

    @EJB(beanName = "NotificationServiceImpl", beanInterface = NotificationServiceLocal.class)
    private NotificationService notificationService;

    public MemberServiceImpl() {
    }

    public MemberServiceImpl(EntityManager em) {
        this();
        this.em = em;
    }

    protected Query createQuery(String queryStr) {
        Query query = em.createQuery(queryStr);
        return query;
    }

    @Override
    public Member createMember(Member member) throws CoreException {
        if (member == null) {
            return null;
        }
        Member existing = getMember(member.getEmail());
        if (existing == null) {
            em.persist(member);
        } else {
            return existing;
        }
        return getMember(member.getEmail());
    }

    @Override
    public Member createMember(String email, String status, String type) throws CoreException {
        Member member = getMember(email);
        if (member == null) {
            member = new MemberImpl(email, status, type);
            em.persist(member);
        }
        member = getMember(email);
        return member;
    }

    @Override
    public Member getMember(String email) {

        String queryStr = "from " + MemberImpl.class.getSimpleName() + " m where m.email=:email";
        Query query = createQuery(queryStr);
        query.setParameter("email", email);

        try {
            return (Member) query.getSingleResult();
        } catch (NoResultException nre) {
            return null;
        }

    }

    @Override
    public Member getMember(long memberId) {
        String queryStr = "from " + MemberImpl.class.getSimpleName() + " m where m.id=:id";
        Query query = createQuery(queryStr);
        query.setParameter("id", memberId);

        try {
            return (Member) query.getSingleResult();
        } catch (NoResultException nre) {
            return null;
        }

    }

    @Override
    public long countMembers() {
        String queryStr = "SELECT COUNT(m.id) FROM " + MemberImpl.class.getSimpleName() + " m";
        Query query = createQuery(queryStr);
        return (Long) query.getSingleResult();

    }

    @Override
    public Member deleteMember(String email) {
        Member member = getMember(email);
        if (member != null) {
            String queryStr = "delete from " + MemberImpl.class.getSimpleName() + " m where m.email=:email";
            Query query = createQuery(queryStr);
            query.setParameter("email", email);
            query.setMaxResults(1);
            query.executeUpdate();
        }
        return member;

    }

    @SuppressWarnings("unchecked")
    @Override
    public Iterator<Member> listMembers(int offset, int batchSize) {
        String queryStr = "from " + MemberImpl.class.getSimpleName() + " ORDER BY id";
        Query query = createQuery(queryStr);
        query.setFirstResult(offset);
        query.setMaxResults(batchSize);
        return query.getResultList().iterator();
    }

    @SuppressWarnings("unchecked")
    @Override
    public List<Member> getGamblingMembers() {

        String queryStr = "from " + MemberImpl.class.getSimpleName() + " m where m.type=:type and m.status=:status";
        Query query = createQuery(queryStr);
        query.setParameter("type", MemberAccountType.GAMBLING_FR);
        query.setParameter("status", MemberAccountStatus.VERIFIED_FR);
        return query.getResultList();
    }

    @Override
    public Member getMemberByFacebookId(String facebookId) {
        String queryStr = "from " + MemberImpl.class.getSimpleName() + " m where m.facebookId=:facebookId";
        Query query = createQuery(queryStr);
        query.setParameter("facebookId", facebookId);

        try {
            return (Member) query.getSingleResult();
        } catch (NoResultException nre) {
            return null;
        }

    }

    @Override
    public boolean nickNameExists(String nickName) {
        if (nickName == null || nickName.isEmpty()) {
            return false;
        }
        final String queryStr = "SELECT count(m.nickName) FROM " + MemberImpl.class.getSimpleName()
                + " m WHERE m.nickName=:nickName";
        final Query query = createQuery(queryStr);
        query.setParameter("nickName", nickName);

        try {
            int count = ((Long) query.getSingleResult()).intValue();
            if (count > 0) {
                return true;
            }
        } catch (NoResultException nre) {

        }
        return false;
    }

    @Override
    public boolean emailExists(String email) {
        if (email == null || email.isEmpty()) {
            return false;
        }
        final String queryStr = "SELECT count(m.email) FROM " + MemberImpl.class.getSimpleName()
                + " m WHERE m.email=:email";
        final Query query = createQuery(queryStr);
        query.setParameter("email", email);

        try {
            int count = ((Long) query.getSingleResult()).intValue();
            if (count > 0) {
                return true;
            }
        } catch (NoResultException nre) {

        }
        return false;
    }

    @Override
    public boolean facebookIdExists(String facebookId) {
        if (facebookId == null || facebookId.isEmpty()) {
            return false;
        }
        final String queryStr = "SELECT count(m.facebookId) FROM " + MemberImpl.class.getSimpleName()
                + " m WHERE m.facebookId=:facebookId";
        final Query query = createQuery(queryStr);
        query.setParameter("facebookId", facebookId);

        try {
            int count = ((Long) query.getSingleResult()).intValue();
            if (count > 0) {
                return true;
            }
        } catch (NoResultException nre) {

        }
        return false;

    }

    @SuppressWarnings("unchecked")
    @Override
    public List<MemberTransaction> getTransactionHistory(Member member) {

        String queryStr = "from " + MemberTransactionImpl.class.getSimpleName()
                + " t where t.member.id=:id ORDER BY txn_date DESC";
        Query query = createQuery(queryStr);
        query.setParameter("id", member.getId());

        try {
            return query.getResultList();
        } catch (NoResultException nre) {
            return new ArrayList<MemberTransaction>();
        }

    }

    @SuppressWarnings("unchecked")
    @Override
    public List<MemberTransaction> getCreditHistory(Member member) {

        String queryStr = "from " + MemberTransactionImpl.class.getSimpleName()
                + " t where t.member.id=:member_id AND t.credit=:credit AND t.type=:type ORDER BY txn_date DESC";
        Query query = createQuery(queryStr);
        query.setParameter("member_id", member.getId());
        query.setParameter("type", MemberTransactionType.CC_CREDIT);
        query.setParameter("credit", true);

        try {
            return query.getResultList();
        } catch (NoResultException nre) {
            return new ArrayList<MemberTransaction>();
        }

    }

    @SuppressWarnings("unchecked")
    @Override
    public List<MemberTransaction> getBonusCreditHistory(Member member) {

        String queryStr = "from " + MemberTransactionImpl.class.getSimpleName()
                + " t where t.member.id=:member_id AND t.bonus=:bonus ORDER BY txn_date DESC";
        Query query = createQuery(queryStr);
        query.setParameter("member_id", member.getId());
        query.setParameter("bonus", true);

        try {
            return query.getResultList();
        } catch (NoResultException nre) {
            return new ArrayList<MemberTransaction>();
        }

    }

    @SuppressWarnings("unchecked")
    @Override
    public List<MemberTransaction> getDebitHistory(Member member) {

        String queryStr = "from " + MemberTransactionImpl.class.getSimpleName()
                + " t where t.member.id=:member_id AND t.debit=:debit ORDER BY txn_date DESC";
        Query query = createQuery(queryStr);
        query.setParameter("member_id", member.getId());
        query.setParameter("debit", true);

        try {
            return query.getResultList();
        } catch (NoResultException nre) {
            return new ArrayList<MemberTransaction>();
        }

    }

    @SuppressWarnings("unchecked")
    @Override
    public List<MemberTransaction> getWireHistory(Member member) {

        String queryStr = "from " + MemberTransactionImpl.class.getSimpleName()
                + " t where t.member.id=:member_id AND t.debit=:debit AND t.type=:type ORDER BY txn_date DESC";
        Query query = createQuery(queryStr);
        query.setParameter("member_id", member.getId());
        query.setParameter("type", MemberTransactionType.WIRE_DEBIT);
        query.setParameter("debit", true);

        try {
            return query.getResultList();
        } catch (NoResultException nre) {
            return new ArrayList<MemberTransaction>();
        }

    }

    @SuppressWarnings("unchecked")
    @Override
    public List<MemberTransaction> getBetDebitHistory(Member member) {

        String queryStr = "from " + MemberTransactionImpl.class.getSimpleName()
                + " t where t.member.id=:member_id AND t.type=:type ORDER BY txn_date DESC";
        Query query = createQuery(queryStr);
        query.setParameter("member_id", member.getId());
        query.setParameter("type", MemberTransactionType.BET_DEBIT);

        try {
            return query.getResultList();
        } catch (NoResultException nre) {
            return new ArrayList<MemberTransaction>();
        }

    }

    @SuppressWarnings("unchecked")
    @Override
    public List<MemberTransaction> getBetCreditHistory(Member member) {

        String queryStr = "from " + MemberTransactionImpl.class.getSimpleName()
                + " t where t.member.id=:member_id AND t.type=:type ORDER BY txn_date DESC";
        Query query = createQuery(queryStr);
        query.setParameter("member_id", member.getId());
        query.setParameter("type", MemberTransactionType.BET_CREDIT);

        try {
            return query.getResultList();
        } catch (NoResultException nre) {
            return new ArrayList<MemberTransaction>();
        }

    }

    private PasswordResetToken createPasswordResetTokenFor(Member member) {
        final String token = UUID.randomUUID().toString();
        PasswordResetToken iToken = new PasswordResetTokenImpl(member, token);
        em.persist(iToken);
        return iToken;
    }

    private PasswordResetToken getPasswordResetTokenFor(Member member) {

        String queryStr = "from " + PasswordResetTokenImpl.class.getSimpleName()
                + " t where t.member.id=:member_id";
        Query query = createQuery(queryStr);
        query.setParameter("member_id", member.getId());

        try {
            return (PasswordResetToken) query.getSingleResult();
        } catch (NoResultException nre) {
            return null;
        }

    }

    @Override
    public void passwordForgotten(Member member, URL redirectUrl) throws CoreException {

        // Check if member already has a token and remove it.
        PasswordResetToken token = getPasswordResetTokenFor(member);
        if (token != null) {
            em.remove(token);
        }

        // Generate a new password reset token.
        token = createPasswordResetTokenFor(member);

        // List of params that will be forwarded to the template engine.
        Map<String, String> params = new HashMap<String, String>();
        params.put("subject", "BetKup : demande de changement de mot de passe"); // XXX
                                                                                 // translate
        params.put("format", "text/html"); // XXX make this is a incoming app
                                           // level parameter in the future.
        params.put("redirect_url",
                redirectUrl.toString() + "?token=" + token.getToken() + "&email=" + member.getEmail());
        params.put("templateId", "password-forgotten_fr"); // XXX make this is a
                                                           // incoming app level
                                                           // parameter in the
                                                           // future.

        SimpleDateFormat sf = new SimpleDateFormat("dd-MM-yyyy");
        params.put("hrBirthdate", sf.format(member.getBirthDate()));

        // Send an email to user with linke to reset URL w/ token.
        notificationService.sendEmail(member, params);

    }

    @Override
    public boolean passwordVerifyResetToken(Member member, String token) {
        PasswordResetToken iToken = getPasswordResetTokenFor(member);
        if (iToken != null && !iToken.isExpired()) {
            return iToken.getToken().equals(token);
        }
        return false;
    }

    @Schedule(minute = "*/5", hour = "*", persistent = false)
    @Override
    public void passwordDestroyExpiredTokens() {

        log.debug("Cleaning up password reset tokens...");

        String queryStr = "from " + PasswordResetTokenImpl.class.getSimpleName();
        Query query = createQuery(queryStr);

        try {
            @SuppressWarnings("unchecked")
            List<PasswordResetToken> tokens = query.getResultList();
            for (PasswordResetToken token : tokens) {
                if (token.isExpired()) {
                    log.debug("Deleting expired password reset token for member=" + token.getMember().getEmail());
                }
            }
        } catch (NoResultException nre) {
            log.debug("No password reset tokens stored. Nothing to do.");
        }

    }

    @Override
    public void passwordReset(Member member, String password, String token) throws CoreException {

        if (!passwordVerifyResetToken(member, token)) {
            throw new CoreException("Token is invalid!");
        }

        // Change password.
        member.setPassword(password);

        PasswordResetToken iToken = getPasswordResetTokenFor(member);
        em.remove(iToken);

        // List of params that will be forwarded to the template engine.
        Map<String, String> params = new HashMap<String, String>();
        params.put("subject", "BetKup : confirmation de changement de mot de passe"); // XXX
                                                                                      // translate
        params.put("format", "text/html"); // XXX make this is a incoming app
                                           // level parameter in the future.
        params.put("templateId", "password-reset_fr"); // XXX make this is a
                                                       // incoming app level
                                                       // parameter in the
                                                       // future.

        // Send an email to user with linke to reset URL w/ token.
        notificationService.sendEmail(member, params);

    }

    @Override
    public void addConnectionLog(Member member, Session session, Date loginTime, String remoteAddress) {
        MemberConnectionLog log = new MemberConnectionLogImpl(member, loginTime, session.getKey(), remoteAddress);
        em.persist(log);
    }

    @Override
    public MemberConnectionLog getConnectionLogFor(Member member, Session session) {

        String queryStr = "from " + MemberConnectionLogImpl.class.getSimpleName()
                + " l where l.member.id=:member_id AND l.sessionKey=:sessionKey";
        Query query = createQuery(queryStr);
        query.setParameter("member_id", member.getId());
        query.setParameter("sessionKey", session.getKey());

        try {
            return (MemberConnectionLog) query.getSingleResult();
        } catch (NoResultException nre) {
            return null;
        }

    }

    @SuppressWarnings("unchecked")
    @Override
    public Date getLastLoginFor(Member member) {

        String queryStr = "from " + MemberConnectionLogImpl.class.getSimpleName()
                + " l where l.member.id=:member_id ORDER BY l.loginTime DESC";
        Query query = createQuery(queryStr);
        query.setParameter("member_id", member.getId());
        query.setMaxResults(2);

        List<MemberConnectionLog> logs;
        try {
            logs = query.getResultList();
        } catch (NoResultException nre) {
            return null;
        }

        for (MemberConnectionLog log : logs) {
            if (log.getLogoutDate() != null) {
                // The current one does not have logout date
                return log.getLoginDate();
            }
        }

        return null;

    }

    @Override
    public int getNumberOfConnectionFor(Member member) {

        String queryStr = "SELECT COUNT(l.id) FROM " + MemberConnectionLogImpl.class.getSimpleName()
                + " l where l.member.id=:member_id";
        Query query = createQuery(queryStr);
        query.setParameter("member_id", member.getId());
        return (Integer) query.getSingleResult();

    }

    @Override
    public boolean passwordVerify(Member member, String hash) throws CoreException {
        if (member != null && hash != null) {
            return hash.equals(member.getPassword());
        }
        return false;
    }

    @SuppressWarnings("unchecked")
    @Override
    public float getTotalCurrentBetAmountFor(Member member) {

        float total = 0;

        final String queryStr = "from " + KupMemberBetImpl.class.getSimpleName()
                + " b where b.member.id=:member_id AND b.kup.status < 5 AND b.kup.status >= 0";
        final Query query = createQuery(queryStr);
        query.setParameter("member_id", member.getId());

        List<KupMemberBet> currentBets;
        try {
            currentBets = query.getResultList();
        } catch (NoResultException nre) {
            return total;
        }

        for (KupMemberBet bet : currentBets) {
            total += bet.getKup().getStake();
        }

        return total;
    }

    @Override
    public boolean mustMemberAcceptPolicy(Member member) {
        final String latestStr = (String) Configuration.getProperties().get("betkup.policy.latest");
        final SimpleDateFormat sf = new SimpleDateFormat("yyyyMMdd");
        Date latest = null;
        try {
            latest = sf.parse(latestStr);
        } catch (ParseException e) {
            if (log.isDebugEnabled()) {
                e.printStackTrace();
            }
            log.error("An error occured trying to parse latest policy date." + " Check sofun.properties");
            return false;
        }
        final Date memberLatest = member.getPolicyAcceptanceDate();
        return memberLatest.compareTo(latest) < 0;
    }

    @Override
    public float getTransferableAmountFor(Member member) {
        float transferable = member.getMemberCredit().getCredit();
        float uncovered = 0;
        for (MemberTransaction bonusTxn : getBonusCreditHistory(member)) {
            float bonusValue = bonusTxn.getAmount();
            float covered = 0;
            for (MemberTransaction betTxn : getDebitHistory(member)) {
                if (MemberTransactionType.BET_DEBIT.equals(betTxn.getLabel())
                        && betTxn.getDate().compareTo(bonusTxn.getDate()) > 0) {
                    covered += betTxn.getAmount();
                }
            }
            float bonusUncovered = bonusValue - covered;
            if (bonusUncovered > 0) {
                uncovered += bonusUncovered;
            }
        }
        return transferable - uncovered;
    }

    @SuppressWarnings("unchecked")
    @Override
    public List<MemberTransaction> getUnAckWinningsTransactionsFor(Member member) {

        String queryStr = "from " + MemberTransactionImpl.class.getSimpleName()
                + " t where t.member.id=:member_id AND t.credit=:credit AND t.type=:type AND t.ack=:ack ORDER BY txn_date DESC";
        Query query = createQuery(queryStr);
        query.setParameter("member_id", member.getId());
        query.setParameter("type", MemberTransactionType.BET_CREDIT);
        query.setParameter("credit", true);
        query.setParameter("ack", false);

        // TMP
        query.setFirstResult(0);
        query.setMaxResults(1);

        try {
            return query.getResultList();
        } catch (NoResultException nre) {
            return new ArrayList<MemberTransaction>();
        }

    }

    @SuppressWarnings("unchecked")
    @Override
    public List<MemberTransaction> getUnAckBonusTransactionFor(Member member) {

        String queryStr = "from " + MemberTransactionImpl.class.getSimpleName()
                + " t where t.member.id=:member_id AND t.bonus=:bonus AND t.ack=:ack ORDER BY txn_date DESC";
        Query query = createQuery(queryStr);
        query.setParameter("member_id", member.getId());
        query.setParameter("bonus", true);
        query.setParameter("ack", false);

        // TMP
        query.setFirstResult(0);
        query.setMaxResults(1);

        try {
            return query.getResultList();
        } catch (NoResultException nre) {
            return new ArrayList<MemberTransaction>();
        }

    }

    @Override
    public MemberTransaction getMemberTransactionById(Member member, long txnId) {

        String queryStr = "from " + MemberTransactionImpl.class.getSimpleName()
                + " t where t.member.id=:member_id and t.id=:id";
        Query query = createQuery(queryStr);
        query.setParameter("member_id", member.getId());
        query.setParameter("id", txnId);

        try {
            return (MemberTransaction) query.getSingleResult();
        } catch (NoResultException nre) {
            return null;
        }

    }

}