UserClientMappingRepositoryImpl.java

package com.tradecloud.repository.impl;

import com.tradecloud.authentication.Client;
import com.tradecloud.authentication.MultiTenantUtil;
import com.tradecloud.authentication.UserNameClientLookup;
import com.tradecloud.domain.exception.DuplicateEntityException;
import com.tradecloud.repository.UserClientMappingRepository;
import com.tradecloud.repository.base.impl.RepositoryBaseImpl;
import org.apache.log4j.Logger;
import org.hibernate.query.NativeQuery;
import org.hibernate.query.Query;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.List;

/**
 * User Repository.
 * <p>
 * Note the SessionFactory used here is hard coded for the 'tradecloud'
 * database.
 * <p>
 * This is wired directly into the Spring security classes to be used for login.
 * ALso used by our UserService for other user actions.
 */
@Transactional(transactionManager = "authTransactionManager", propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT)
@Repository(value = "userClientMappingRepository")
public class UserClientMappingRepositoryImpl extends RepositoryBaseImpl<UserNameClientLookup, Object> implements UserClientMappingRepository {

    private static final long serialVersionUID = 1L;
    private static final Logger log = Logger.getLogger(UserClientMappingRepositoryImpl.class);

    @Override
    public UserNameClientLookup findByUserName(String username) {
        //log.debug("Username " + username);
        CriteriaBuilder criteriaBuilder = getSession().getCriteriaBuilder();
        CriteriaQuery<UserNameClientLookup> criteriaQuery = criteriaBuilder.createQuery(UserNameClientLookup.class);
        Root<UserNameClientLookup> c = criteriaQuery.from(UserNameClientLookup.class);
        List<Predicate> predicates = new ArrayList();
        predicates.add(criteriaBuilder.equal(c.get("username"), username));

        if (MultiTenantUtil.getActiveUser() != null) {
            predicates.add(criteriaBuilder.equal(c.get("client"), MultiTenantUtil.getClient()));
        }

        criteriaQuery = criteriaQuery.select(c).where(predicates.stream().toArray(Predicate[]::new));
        Query<UserNameClientLookup> q = getSession().createQuery(criteriaQuery);
        List<UserNameClientLookup> list = q.list();

        if (list.size() == 1)
            return list.get(0);

        if (list.size() > 1)
            throw new DuplicateEntityException("Multiple users: " + list.size() + " client mappings found for: " + username +
                    " please provide the correct client.");

        return null;
    }

    @SuppressWarnings("unchecked")
    @Override
    public List<UserNameClientLookup> findAll() {
        CriteriaBuilder criteriaBuilder = getSession().getCriteriaBuilder();
        CriteriaQuery<UserNameClientLookup> criteriaQuery = criteriaBuilder.createQuery(UserNameClientLookup.class);
        Root<UserNameClientLookup> c = criteriaQuery.from(UserNameClientLookup.class);
        Query<UserNameClientLookup> q = getSession().createQuery(criteriaQuery);
        return q.list();
    }

    @Override
    public void save(UserNameClientLookup userClientMapping) {
        getCurrentSessionNoMulti().persist(userClientMapping);
    }

    @Override
    public void update(UserNameClientLookup mapping) {
        getCurrentSessionNoMulti().update(mapping);
    }

    @Override
    public void delete(UserNameClientLookup userClientMapping) {
        getCurrentSessionNoMulti().delete(userClientMapping);
    }

    @Override
    public Client findClientByCode(String clientCode) {
        CriteriaBuilder criteriaBuilder = getSession().getCriteriaBuilder();
        CriteriaQuery<Client> criteriaQuery = criteriaBuilder.createQuery(Client.class);
        Root<Client> c = criteriaQuery.from(Client.class);
        criteriaQuery = criteriaQuery.select(c).where(criteriaBuilder.equal(c.get("code"), clientCode));
        Query<Client> q = getSession().createQuery(criteriaQuery);
        return q.uniqueResult();
    }

    @Override
    public List<Client> findAllClients() {
        CriteriaBuilder criteriaBuilder = getSession().getCriteriaBuilder();
        CriteriaQuery<Client> criteriaQuery = criteriaBuilder.createQuery(Client.class);
        Root<Client> c = criteriaQuery.from(Client.class);
        Query<Client> q = getSession().createQuery(criteriaQuery);
        return q.list();
    }

    @Override
    public List<Client> findAllActiveClients() {
        CriteriaBuilder criteriaBuilder = getSession().getCriteriaBuilder();
        CriteriaQuery<Client> criteriaQuery = criteriaBuilder.createQuery(Client.class);
        Root<Client> c = criteriaQuery.from(Client.class);
        criteriaQuery = criteriaQuery.select(c).where(criteriaBuilder.equal(c.get("active"), true));
        Query<Client> q = getSession().createQuery(criteriaQuery);
        return q.list();
    }

    @Override
    public void updateClient(Client client) {
        getCurrentSessionNoMulti().update(client);
    }

    @Override
    public boolean hasSession() {
        return getSession() != null;
    }

    @Override
    public List<Client> getClientsForUser(String username) {
        String query = "select * from client left join username_client_lookup on client.code = username_client_lookup.client_code " +
                "where username = :username";

        NativeQuery nativeQuery = getSession().createNativeQuery(query, Client.class);
        nativeQuery.setParameter("username", username);

        return nativeQuery.list();
    }

    @Override
    public UserNameClientLookup lookupUserClient(String username, String clientCode) {
        StringBuilder query = new StringBuilder("select * from username_client_lookup where username = :username ");
        if (clientCode != null && !clientCode.equals("icp"))
            query.append("and client_code = :clientCode");

        NativeQuery nativeQuery = getSession().createNativeQuery(query.toString(), UserNameClientLookup.class);
        nativeQuery.setParameter("username", username);
        if (clientCode != null && !clientCode.equals("icp"))
            nativeQuery.setParameter("clientCode", clientCode);

        List list = nativeQuery.list();
        if (list != null && !list.isEmpty())
            return (UserNameClientLookup) list.get(0);

        return null;
    }
}