gt: 	protected List<Role> findRootRoles() throws DotDataException {
context: /**
   *
   */
  package com.dotmarketing.business;
  
  import java.lang.reflect.InvocationTargetException;
  import java.text.SimpleDateFormat;
  import java.util.ArrayList;
  import java.util.HashSet;
  import java.util.LinkedList;
  import java.util.List;
  import java.util.Map;
  import java.util.Queue;
  import java.util.Set;
  
  import com.dotcms.repackage.org.apache.commons.beanutils.BeanUtils;
  
  import com.dotmarketing.business.RoleCache.UserRoleCacheHelper;
  import com.dotmarketing.common.db.DotConnect;
  import com.dotmarketing.db.DbConnectionFactory;
  import com.dotmarketing.db.HibernateUtil;
  import com.dotmarketing.exception.DotDataException;
  import com.dotmarketing.util.AdminLogger;
  import com.dotmarketing.util.InodeUtils;
  import com.dotmarketing.util.Logger;
  import com.dotmarketing.util.UUIDGenerator;
  import com.dotmarketing.util.UtilMethods;
  import com.dotmarketing.util.VelocityUtil;
  import com.liferay.portal.model.User;
  
  /**
   * @author Jason Tesser
   *
   */
  public class RoleFactoryImpl extends RoleFactory {
  
  	private RoleCache rc = CacheLocator.getCmsRoleCache();
  
  	@Override
  	protected List<Role> findAllAssignableRoles(boolean showSystemRoles) throws DotDataException {
  		HibernateUtil hu = new HibernateUtil(Role.class);
  		String query = "from com.dotmarketing.business.Role where edit_permissions = ?";
  		if(!showSystemRoles){
  			query = query + " and system = ?";
  		}
  
  		hu.setQuery(query);
  		hu.setParam(true);
  		if(!showSystemRoles){
  			hu.setParam(false);
  		}
  		return hu.list();
  	}
  
  	@Override
  	protected Role getRoleById(String roleId) throws DotDataException {
  		return getRoleById(roleId, true);
  	}
  
  	protected Role getRoleById(String roleId, boolean translateFQN) throws DotDataException {
  		Role r = null;
  		r = rc.get(roleId);
  		if(r == null){
  			HibernateUtil hu = new HibernateUtil(Role.class);
  			hu.setQuery("from com.dotmarketing.business.Role where id = ?");
  			hu.setParam(roleId);
  			r = (Role)hu.load();
  			if(r == null)
  				return null;
  			rc.add(r);
  			try {
  				if(r != null && InodeUtils.isSet(r.getId())){
  					List<Role> roles = new ArrayList<Role>();
  					roles.add(r);
  					populatChildrenForRoles(roles);
  					if(translateFQN) {
  						for (Role role : roles) {
  							translateFQNFromDB(role);
  						}
  					}
  					r = roles.get(0);
  				}else{
  					return null;
  				}
  			} catch (Exception e) {
  				Logger.error(this, e.getMessage(), e);
  				throw new DotDataException(e.getMessage(), e);
  			}
  			rc.add(r);
  			HibernateUtil.evict(r);
  		}
  		return r;
  	}
  
  	@Override
  	protected List<Role> loadRolesForUser(String userId, boolean includeImplicitRoles) throws DotDataException {
  		try {
  			List<Role> roles = new ArrayList<Role>();
  			List<UserRoleCacheHelper> helpers = rc.getRoleIdsForUser(userId);
  			if(helpers != null){
  				for (UserRoleCacheHelper h : helpers) {
  					if(includeImplicitRoles || !h.isInherited()){
  						Role r = getRoleById(h.getRoleId());
  						if(r != null){
  							roles.add(r);
  						}
  					}
  				}
  			}else{
  				helpers = new ArrayList<RoleCache.UserRoleCacheHelper>();
  				LinkedList<Role> rolesToProcess = new LinkedList<Role>();
  				Set<String> rids = new HashSet<String>();
  				DotConnect dc = new DotConnect();
  				dc.setSQL("select distinct role_id from users_cms_roles where users_cms_roles.user_id  = ?");
  				dc.addParam(userId);
  				List<Map<String,Object>> rows = dc.loadObjectResults();
  				for (Map<String, Object> map : rows) {
  					Role r = null;
  					try{
  						r = getRoleById(map.get("role_id").toString());
  					}catch (Exception e) {
  						Logger.error(this, e.getMessage() + " While loading the user with id " + userId == null? "not passed in":userId + " Unable to load role with roleid " + map.get("role_id").toString() == null? "null":map.get("role_id").toString(), e);
  					}
  					rids.add(r.getId());
  					rolesToProcess.add(r);
  				}
  
  				if(APILocator.getUserAPI().getAnonymousUser().getUserId().equals(userId)
  						&& !rolesToProcess.contains(APILocator.getRoleAPI().loadCMSAnonymousRole())){
  					rolesToProcess.add(APILocator.getRoleAPI().loadCMSAnonymousRole());
  				}
  				while(!rolesToProcess.isEmpty()) {
  					Role r = rolesToProcess.poll();
  					if(r ==null) continue;
  					UserRoleCacheHelper h = new UserRoleCacheHelper(r.getId(),rids.contains(r.getId())?false:true);
  					helpers.add(h);
  					if(includeImplicitRoles || rids.contains(r.getId())){
  						roles.add(r);
  					}
  					if(r.getRoleChildren() != null && includeImplicitRoles)
  						for(String roleId: r.getRoleChildren()) {
  							rolesToProcess.add(getRoleById(roleId));
  						}
  				}
  				rc.addRoleListForUser(helpers, userId);
  			}
  
  			return roles;
  		} catch (Exception e) {
  			Logger.error(this,e.getMessage() + " Unable to load the user roles for user " + userId == null? "not passed in":userId, e);
  			throw new DotDataException(e.getMessage() + " Unable to load the user roles for user " + userId == null? "not passed in":userId, e);
  		}
  	}
  
  
  	@Override
  	protected List<Role> getRolesByName(String filter, int start, int limit) throws DotDataException {
  		if(filter==null) return new ArrayList<Role>();
  
  		filter = "%" + filter.toLowerCase() + "%";
  		return getRolesByNameFiltered(filter, start, limit);
  	}
  
  
  	@Override
  	protected List<Role> getRolesByNameFiltered(String filter, int start, int limit) throws DotDataException {
  		HibernateUtil hu = new HibernateUtil(Role.class);
  		hu.setQuery("from " + Role.class.getName() + " where lower(role_name) like ? order by role_name");
  		if(filter ==null)filter ="";
  		filter = filter.toLowerCase();
  		hu.setParam(filter);
  		hu.setFirstResult(start);
  		hu.setMaxResults(limit);
  		List<Role> roles = (List<Role>)hu.list();
  		try {
  			populatChildrenForRoles(roles);
  			for (Role role : roles) {
  				HibernateUtil.evict(role);
  				translateFQNFromDB(role);
  			}
  		} catch (Exception e) {
  			Logger.error(this, e.getMessage(), e);
  			throw new DotDataException(e.getMessage(), e);
  		}
  		if(roles != null){
  			for (Role role : roles) {
  				rc.add(role);
  			}
  		}
  		return roles;
  	}
  
  	@Override
  	protected Role findRoleByName(String rolename, Role parent) throws DotDataException {
  		HibernateUtil hu = new HibernateUtil(Role.class);
  		if(parent == null){
  			hu.setQuery("from " + Role.class.getName() + " as r where r.name = ? and r.parent = r.id");
  		}else{
  			hu.setQuery("from " + Role.class.getName() + " as r where r.name = ? and r.parent = ? and r.parent <> r.id");
  		}
  		hu.setParam(rolename);
  		if(parent != null){
  			hu.setParam(parent.getId());
  		}
  		List<Role> roles = (List<Role>)hu.list();
  		try {
  			populatChildrenForRoles(roles);
  			for (Role role : roles) {
  				translateFQNFromDB(role);
  			}
  		} catch (Exception e) {
  			Logger.error(this, e.getMessage(), e);
  			throw new DotDataException(e.getMessage(), e);
  		}
  		if(roles != null){
  			for (Role role : roles) {
  				HibernateUtil.evict(role);
  				rc.add(role);
  			}
  		}
  		Role role = null;
  		if(roles != null && roles.size()>0){
  			role = roles.get(0);
  			if(roles.size()>1){
  				Logger.error(this, "Found more then one role with the same name : " + rolename != null ? rolename : "");
  			}
  		}
  		return role;
  	}
  
  	@Override
  	protected void addRoleToUser(Role role, User user) throws DotDataException {
  		UsersRoles ur = new UsersRoles();
  		ur.setRoleId(role.getId());
  		ur.setUserId(user.getUserId());
  		HibernateUtil.save(ur);
  		rc.remove(user.getUserId());
  	}
  
  	@Override
  	protected void removeRoleFromUser(Role role, User user)	throws DotDataException {
  		DotConnect dc = new DotConnect();
  		dc.setSQL("delete from users_cms_roles where user_id = ? and role_id = ?");
  		dc.addParam(user.getUserId());
  		dc.addParam(role.getId());
  		dc.loadResult();
  		rc.remove(user.getUserId());
  	}
  
  	@Override
  	protected Role save(Role role) throws DotDataException {
  //		role.setRoleKey(UUIDGenerator.generateUuid());
  		HibernateUtil hu = new HibernateUtil(Role.class);
  
  		Role r = null;
  		if(InodeUtils.isSet(role.getId())) {
  			hu.setQuery("from com.dotmarketing.business.Role where id = ?");
  			hu.setParam(role.getId());
  			r = (Role)hu.load();
  			rc.remove(r.getId());
  			if(UtilMethods.isSet(r.getParent())) {
  				rc.remove(r.getParent());
  			}
  			try {
  				BeanUtils.copyProperties(r, role);
  			} catch (IllegalAccessException e) {
  				Logger.error(this, "Error populating role to save", e);
  				throw new DotDataException("Error populating role to save", e);
  			} catch (InvocationTargetException e) {
  				Logger.error(this, "Error populating role to save", e);
  				throw new DotDataException("Error populating role to save", e);
  			}
  		} else {
  
  			r = role;
  			if(DbConnectionFactory.isMsSql()){
  				String roleKey= VelocityUtil.convertToVelocityVariable(r.getName());
  				DotConnect dc = new DotConnect();
  				dc.setSQL("select count(*) as total from cms_role where role_key =?");
  				dc.addParam(roleKey);
  				int total= dc.getInt("total");
  				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd H:mm:ss.S");
  				String date= sdf.format(new java.util.Date());
  				if(total>0){
  
  					roleKey= UtilMethods.toCamelCase(r.getName())+date;
  				}
  				r.setRoleKey(roleKey);
  				r.setFQN(UUIDGenerator.generateUuid());
  			}
  			HibernateUtil.save(r);
  		}
  
  		//We need to update the role FQN and well as the role children, grand-children, etc as well
  		List<Role> rolesToUpdate = new ArrayList<Role>();
  		Queue<String> roleIdsToProcess = new LinkedList<String>();
  		roleIdsToProcess.add(r.getId());
  		while(roleIdsToProcess.size()>0) {
  			String parentId = roleIdsToProcess.poll();
  			hu = new HibernateUtil(Role.class);
  			hu.setQuery("from com.dotmarketing.business.Role where id = ?");
  			hu.setParam(parentId);
  			Role parentRole = (Role)hu.load();
  			rolesToUpdate.add(parentRole);
  			List<Role> toPopulate = new ArrayList<Role>();
  			toPopulate.add(parentRole);
  			try {
  				populatChildrenForRoles(toPopulate);
  			} catch (Exception e) {
  				throw new DotDataException(e.getMessage(), e);
  			}
  			if(parentRole.getRoleChildren() != null)
  				roleIdsToProcess.addAll(parentRole.getRoleChildren());
  		}
  
  		for(Role roleToUpdate : rolesToUpdate) {
  			setFQNForDB(roleToUpdate);
  			HibernateUtil.save(roleToUpdate);
  		}
  
  		translateFQNFromDB(r);
  
  		if(r.getParent() != null){
  			rc.remove(r.getParent());
  			Role parent = getRoleById(r.getParent());
  			rc.remove(parent.getRoleKey());
  		}
  
  		List<Role> singleRole = new ArrayList<Role>();
  		singleRole.add(r);
  		try {
  			populatChildrenForRoles(singleRole);
  		} catch (Exception e) {
  			Logger.error(this, "Error populating role children", e);
  			throw new DotDataException("Error populating role children", e);
  		}
  		if(r.getParent().equals(r.getId())){
  			rc.clearRootRoleCache();
  		}
  		rc.add(r);
  		HibernateUtil.evict(r);
  		AdminLogger.log(RoleFactoryImpl.class, "save", "Role saved Id :"+r.getId());
  
  		return r;
  	}
  
  	@Override
  	protected void delete(Role role) throws DotDataException {
  
  		DotConnect dc = new DotConnect();
  		dc.setSQL("delete from users_cms_roles where role_id = ?");
  		dc.addParam(role.getId());
  		dc.loadResult();
  		HibernateUtil hu = new HibernateUtil(Role.class);
  		hu.setQuery("from com.dotmarketing.business.Role where id = ?");
  		hu.setParam(role.getId());
  		Role r = (Role)hu.load();
  
  		HibernateUtil.delete(r);
  		if(r.getParent().equals(r.getId())){
  			rc.clearRootRoleCache();
  		}
  
  		rc.clearRoleCache();
  
  		AdminLogger.log(RoleFactoryImpl.class, "delete", "Role deleted Id :"+r.getId());
  
  	}
  
  	@Override
  