/*******************************************************************************
 * This file is part of GECAMed.
 * 
 * GECAMed is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License (L-GPL) as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * GECAMed is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License (L-GPL)
 * along with GECAMed.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * GECAMed is Copyrighted by the Centre de Recherche Public Henri Tudor (http://www.tudor.lu)
 * (c) CRP Henri Tudor, Luxembourg, 2008
 *******************************************************************************/
package lu.tudor.santec.gecamed.usermanagement.ejb.session.beans;

import java.util.Collection;

import javax.annotation.Resource;
import javax.annotation.security.RolesAllowed;
import javax.ejb.EJB;
import javax.ejb.FinderException;
import javax.ejb.Remote;
import javax.ejb.SessionContext;
import javax.ejb.Stateless;
import javax.naming.NamingException;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import lu.tudor.santec.gecamed.usermanagement.ejb.entity.beans.GecamedUser;
import lu.tudor.santec.gecamed.usermanagement.ejb.entity.beans.Permission;
import lu.tudor.santec.gecamed.usermanagement.ejb.entity.beans.Role;
import lu.tudor.santec.gecamed.usermanagement.ejb.session.interfaces.LoginInterface;
import lu.tudor.santec.gecamed.usermanagement.ejb.session.interfaces.UserAdminInterface;

import org.jboss.annotation.security.SecurityDomain;

/**
 * This Bean-Class manages the Administration of the different GeCam Users 
 * it provides methods to grand, retrieve rights to a user and add and delete
 * or modify users. Use this class to list, update and create new Users.
 * 
 * @author Johannes Hermen
 * @updated 11.10.2005 Martin Heinemann
 * @updated 15.06.2006 Johannes Hermen
 * 
 * @Version
 *  * <br>$Log: UserAdminBean.java,v $
 *  * <br>Revision 1.14  2010-05-05 12:15:11  hermen
 *  * <br>*** empty log message ***
 *  * <br>
 *  * <br>Revision 1.13  2008-11-26 13:55:11  hermen
 *  * <br>added getGecamedUser(String login)
 *  * <br>
 *  * <br>Revision 1.12  2008-10-08 09:37:44  heinemann
 *  * <br>translations of roles and rights
 *  * <br>
 *  * <br>Revision 1.11  2008-09-25 09:43:10  heinemann
 *  * <br>fixed copyrights
 *  * <br>
 *  * <br>Revision 1.10  2008-01-15 09:30:13  hermen
 *  * <br>updated Javadoc and refactured code
 *  * <br>
 *
 */

@Remote ({UserAdminInterface.class})
@Stateless
@SecurityDomain ("gecamedLoginDS")
public class UserAdminBean implements UserAdminInterface 
{
    //~ Static fields/initializers =============================================

    private static final long serialVersionUID = 1L;
    
    //~ Instance fields ========================================================
    
    @PersistenceContext(unitName ="gecam") 
    protected EntityManager em;
    
    @Resource
    protected SessionContext sessionContext;
    
    @EJB 
    LoginInterface userLogin;

    //~ Constructors ===========================================================

    /**
     * creates a new instance of  UserAdminBean
     */
    public UserAdminBean()
    {
        super();
    }


    /* (non-Javadoc)
	 * @see lu.tudor.santec.gecamed.usermanagement.ejb.session.beans.UserAdminInterface#setUser(lu.tudor.santec.gecamed.usermanagement.ejb.entity.beans.GecamedUser)
	 */
    @RolesAllowed("gecam")
    public GecamedUser saveUser(GecamedUser user)
        throws Exception
    {
        if (this.userLogin.userHasRole (Role.ADMIN) || this.userLogin.getCurrentUser().equals(user))
        		{
        		user = em.merge(user);
        		em.flush();
        		user.setHasChanges(false);
        		}
        return user;
    }

    /* (non-Javadoc)
	 * @see lu.tudor.santec.gecamed.usermanagement.ejb.session.beans.UserAdminInterface#getUser(java.lang.Integer)
	 */
    @RolesAllowed("gecam")
    public GecamedUser getUser(Integer userID)
        throws NamingException, FinderException
    {
        /* =========================================================== */
        if (userID == null) {
            return null;
        }
        /* ------------------------------------------------------------ */
        GecamedUser s = (GecamedUser) em.createNamedQuery(GecamedUser.FIND_USER_BY_ID)
        					.setParameter("id", userID)
        					.getSingleResult();
        /* ------------------------------------------------------------ */
        return s;        
    }
      
    @RolesAllowed("gecam")
    public GecamedUser getUser(String  login)
        throws NamingException, FinderException
    {
        /* =========================================================== */
        if (login == null) {
            return null;
        }
        /* ------------------------------------------------------------ */
        GecamedUser s = (GecamedUser) em.createNamedQuery(GecamedUser.FIND_USERS_BY_LOGIN)
        					.setParameter("login", login)
        					.getSingleResult();
        /* ------------------------------------------------------------ */
        return s;        
    }

    /* (non-Javadoc)
	 * @see lu.tudor.santec.gecamed.usermanagement.ejb.session.beans.UserAdminInterface#getUserList()
	 */
    @SuppressWarnings("unchecked")
	@RolesAllowed("gecam")
    public Collection<GecamedUser> getUserList() throws FinderException
    {
    	return em.createNamedQuery("findAllGecamedUsers").getResultList();
    }
    
    /* (non-Javadoc)
	 * @see lu.tudor.santec.gecamed.usermanagement.ejb.session.beans.UserAdminInterface#deleteUser(java.lang.Integer)
	 */
    @RolesAllowed("gecam")
    public void deleteUser(Integer userID) throws Exception
    {
        // Throw Exception if right not granted
    		if (this.userLogin.userHasRole (Role.ADMIN))
    			{
    			GecamedUser user = em.find(GecamedUser.class, userID);
    			em.remove(user);
    			}

    }


	/* (non-Javadoc)
	 * @see lu.tudor.santec.gecamed.usermanagement.ejb.session.interfaces.UserAdminInterface#getRoles()
	 */
	@SuppressWarnings("unchecked")
	public Collection<Role> getRoles() {
		return em.createNamedQuery("getAllRoles").getResultList();
	}


	/* (non-Javadoc)
	 * @see lu.tudor.santec.gecamed.usermanagement.ejb.session.interfaces.UserAdminInterface#getPermissions()
	 */
	@SuppressWarnings("unchecked")
	public Collection<Permission> getPermissions() {
		return em.createNamedQuery("getAllPermissions").getResultList();
	}

	/* (non-Javadoc)
	 * @see lu.tudor.santec.gecamed.usermanagement.ejb.session.interfaces.UserAdminInterface#getPermissions(java.lang.Integer)
	 */
	@SuppressWarnings("unchecked")
	@RolesAllowed("gecam")
	public Collection<Permission> getPermissions(Integer userId) {
		/* ====================================================== */
		Query q = em.createQuery(
			"SELECT Object(o) FROM Permission o WHERE " +
				"(o.id IN " +
					"(Select permission.id FROM RolePermission WHERE role.id IN " +
			         	"(Select role.id FROM UserRole WHERE user.id = :userid))" +
			    "OR id IN " +
				"(Select permission.id FROM UserPermission WHERE user.id = :userid))");
		q.setParameter("userid", userId);
		
		return q.getResultList();
		/* ====================================================== */
	}
  
}
