/* * Copyright 2000-2013 Enonic AS * http://www.enonic.com/license */ package com.enonic.cms.store.dao; import com.enonic.cms.core.security.group.GroupEntity; import com.enonic.cms.core.security.group.GroupKey; import com.enonic.cms.core.security.group.GroupSpecification; import com.enonic.cms.core.security.group.GroupType; import com.enonic.cms.core.security.userstore.UserStoreKey; import com.enonic.cms.framework.hibernate.support.SelectBuilder; import com.enonic.cms.store.support.EntityPageList; import org.hibernate.Criteria; import org.hibernate.HibernateException; import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.criterion.MatchMode; import org.hibernate.criterion.Order; import org.hibernate.criterion.Restrictions; import org.springframework.orm.hibernate3.HibernateCallback; import org.springframework.stereotype.Repository; import org.springframework.util.Assert; import java.sql.SQLException; import java.util.ArrayList; import java.util.Collection; import java.util.List; @Repository("groupDao") public final class GroupEntityDao extends AbstractBaseEntityDao<GroupEntity> implements GroupDao { private final static GroupType[] GLOBAL_GROUP_TYPES = new GroupType[]{GroupType.ANONYMOUS, GroupType.CONTRIBUTORS, GroupType.ADMINS, GroupType.GLOBAL_GROUP, GroupType.DEVELOPERS, GroupType.EXPERT_CONTRIBUTORS}; private boolean initializedCacheKeys = false; private transient GroupKey cachedEnterpriseAdminGroupKey; private transient GroupKey cachedAdministratorGroupKey; private transient GroupKey cachedDeveloperGroupKey; private transient GroupKey cachedExpertContributorGroupKey; private transient GroupKey cachedContributorGroupKey; private transient GroupKey cachedAnonymousGroupKey; public void invalidateCachedKeys() { initializedCacheKeys = false; } private void initalizeCacheKeys() { if ( initializedCacheKeys ) { return; } // Enterprise Administrator GroupSpecification enterpriseAdminSpec = new GroupSpecification(); enterpriseAdminSpec.setType( GroupType.ENTERPRISE_ADMINS ); GroupEntity enterpriseAdministrator = findSingleBySpecification( enterpriseAdminSpec ); if ( enterpriseAdministrator == null ) { throw new IllegalStateException( "Built-in Enterprise Administrator group does not exist" ); } cachedEnterpriseAdminGroupKey = enterpriseAdministrator.getGroupKey(); // Administrator GroupSpecification administratorSpec = new GroupSpecification(); administratorSpec.setType( GroupType.ADMINS ); GroupEntity administrator = findSingleBySpecification( administratorSpec ); if ( administrator == null ) { throw new IllegalStateException( "Built-in Administrator group does not exist" ); } cachedAdministratorGroupKey = administrator.getGroupKey(); // Developer GroupSpecification developerSpec = new GroupSpecification(); developerSpec.setType( GroupType.DEVELOPERS ); GroupEntity developer = findSingleBySpecification( developerSpec ); if ( developer == null ) { throw new IllegalStateException( "Built-in Developer group does not exist" ); } cachedDeveloperGroupKey = developer.getGroupKey(); // Expert Contributor GroupSpecification expertContributorSpec = new GroupSpecification(); expertContributorSpec.setType( GroupType.EXPERT_CONTRIBUTORS ); GroupEntity expertContributor = findSingleBySpecification( expertContributorSpec ); if ( expertContributor == null ) { throw new IllegalStateException( "Built-in Expert Contributor group does not exist" ); } cachedExpertContributorGroupKey = expertContributor.getGroupKey(); // Contributor GroupSpecification contributorSpec = new GroupSpecification(); contributorSpec.setType( GroupType.CONTRIBUTORS ); GroupEntity contributor = findSingleBySpecification( contributorSpec ); if ( contributor == null ) { throw new IllegalStateException( "Built-in Contributor group does not exist" ); } cachedContributorGroupKey = contributor.getGroupKey(); // Anonymous / Everyone GroupSpecification anonymousSpec = new GroupSpecification(); anonymousSpec.setType( GroupType.ANONYMOUS ); GroupEntity anonymous = findSingleBySpecification( anonymousSpec ); if ( anonymous == null ) { throw new IllegalStateException( "Built-in Anonymous group does not exist" ); } cachedAnonymousGroupKey = anonymous.getGroupKey(); initializedCacheKeys = true; } public GroupEntity find( String groupKey ) { return findByKey( new GroupKey( groupKey ) ); } public GroupEntity findByKey( GroupKey groupKey ) { return get( GroupEntity.class, groupKey ); } public Collection<GroupEntity> findAll( boolean includeDeleted ) { return findByNamedQuery( GroupEntity.class, "GroupEntity.findAll", "deleted", includeDeleted ? 1 : 0 ); } public GroupEntity findSingleBySpecification( GroupSpecification spec ) { List<GroupEntity> list = findBySpecification( spec ); if ( list.isEmpty() ) { return null; } if ( list.size() > 1 ) { throw new IllegalArgumentException( "Expected a single row" ); } return list.get( 0 ); } public GroupEntity findBuiltInEnterpriseAdministrator() { initalizeCacheKeys(); return findByKey( cachedEnterpriseAdminGroupKey ); } public GroupEntity findBuiltInUserStoreAdministrator( UserStoreKey userStoreKey ) { GroupSpecification userStoreAdminSpec = new GroupSpecification(); userStoreAdminSpec.setUserStoreKey( userStoreKey ); userStoreAdminSpec.setType( GroupType.USERSTORE_ADMINS ); return findSingleBySpecification( userStoreAdminSpec ); } public GroupEntity findBuiltInAuthenticatedUsers( UserStoreKey userStoreKey ) { Assert.notNull( userStoreKey, "userStoreKey cannot be null" ); GroupSpecification userStoreAdminSpec = new GroupSpecification(); userStoreAdminSpec.setUserStoreKey( userStoreKey ); userStoreAdminSpec.setType( GroupType.AUTHENTICATED_USERS ); return findSingleBySpecification( userStoreAdminSpec ); } public GroupEntity findBuiltInAdministrator() { initalizeCacheKeys(); return findByKey( cachedAdministratorGroupKey ); } public GroupEntity findBuiltInDeveloper() { initalizeCacheKeys(); return findByKey( cachedDeveloperGroupKey ); } public GroupEntity findBuiltInExpertContributor() { initalizeCacheKeys(); return findByKey( cachedExpertContributorGroupKey ); } public GroupEntity findBuiltInContributor() { initalizeCacheKeys(); return findByKey( cachedContributorGroupKey ); } public GroupEntity findBuiltInAnonymous() { initalizeCacheKeys(); return findByKey( cachedAnonymousGroupKey ); } public List<GroupEntity> findBySpecification( GroupSpecification spec ) { String hqlQuery = createHqlQuery( spec ); Query compiled = getHibernateTemplate().getSessionFactory().getCurrentSession().createQuery( hqlQuery ); compiled.setCacheable( true ); if ( spec.getKey() != null ) { compiled.setString( "key", spec.getKey().toString() ); } if ( spec.getName() != null ) { compiled.setString( "name", spec.getName() ); } if ( spec.getSyncValue() != null ) { compiled.setString( "syncValue", spec.getSyncValue() ); } if ( spec.getUserStoreKey() != null ) { compiled.setInteger( "userStoreKey", spec.getUserStoreKey().toInt() ); } if ( spec.getType() != null ) { compiled.setInteger( "type", spec.getType().toInteger() ); } return compiled.list(); } public Collection<GroupEntity> findByUserstore( UserStoreKey userStoreKey, boolean includeDeleted ) { return findByNamedQuery( GroupEntity.class, "GroupEntity.findByUserStore", new String[]{"userStoreKey", "deleted"}, new Object[]{userStoreKey.toInt(), includeDeleted ? 1 : 0} ); } public GroupEntity findByUserStoreKeyAndSyncValue( UserStoreKey userStoreKey, String syncValue, boolean includeDeleted ) { return findSingleByNamedQuery( GroupEntity.class, "GroupEntity.findByUserStoreAndSyncValue", new String[]{"userStoreKey", "syncValue", "deleted"}, new Object[]{userStoreKey.toInt(), syncValue, includeDeleted ? 1 : 0} ); } public List<GroupEntity> findByUserStoreKeyAndGroupname( UserStoreKey userStoreKey, String groupName, boolean includeDeleted ) { return findByNamedQuery( GroupEntity.class, "GroupEntity.findByQualifiedGroupname", new String[]{"userStoreKey", "name", "deleted"}, new Object[]{userStoreKey.toInt(), groupName, includeDeleted ? 1 : 0} ); } public GroupEntity findSingleUndeletedByUserStoreKeyAndGroupname( UserStoreKey userStoreKey, String groupName ) { return findSingleByNamedQuery( GroupEntity.class, "GroupEntity.findByQualifiedGroupname", new String[]{"userStoreKey", "name", "deleted"}, new Object[]{userStoreKey.toInt(), groupName, 0} ); } public GroupEntity findSingleByGroupType( GroupType groupType ) { if ( !groupType.isOnlyOneGroupOccurance() ) { throw new IllegalArgumentException( "Given group type can have more than one group in the system" ); } return findSingleByNamedQuery( GroupEntity.class, "GroupEntity.findByGroupType", "groupType", groupType.toInteger() ); } public GroupEntity findSingleByGroupTypeAndUserStore( GroupType groupType, UserStoreKey userStoreKey ) { return findSingleByNamedQuery( GroupEntity.class, "GroupEntity.findByGroupTypeAndUserStore", new String[]{"groupType", "userStoreKey"}, new Object[]{groupType.toInteger(), userStoreKey.toInt()} ); } public GroupEntity findGlobalGroupByName( final String name, final boolean includeDeleted ) { return executeSingleResult( GroupEntity.class, new HibernateCallback() { public Object doInHibernate( Session session ) throws HibernateException, SQLException { Criteria crit = session.createCriteria( GroupEntity.class ).setCacheable( true ); crit.add( Restrictions.eq( "name", name ) ); crit.add( Restrictions.in( "type", GroupType.getIntegerValues( GLOBAL_GROUP_TYPES ) ) ); if ( !includeDeleted ) { crit.add( Restrictions.eq( "deleted", 0 ) ); } List list = crit.list(); if ( list.size() == 0 ) { return null; } // we return first one if found return list.get( 0 ); } } ); } @SuppressWarnings({"unchecked"}) public List<GroupEntity> findByQuery( final GroupQuery spec ) { return (List<GroupEntity>) getHibernateTemplate().execute( new HibernateCallback() { public Object doInHibernate( Session session ) throws HibernateException, SQLException { Criteria crit = session.createCriteria( GroupEntity.class ).setCacheable( true ); if ( spec.getUserStoreKey() != null ) { crit.add( Restrictions.eq( "userStore.key", spec.getUserStoreKey().toInt() ) ); } else if ( spec.isGlobalOnly() ) { crit.add( Restrictions.isNull( "userStore.key" ) ); } if ( !spec.isIncludeDeleted() ) { crit.add( Restrictions.eq( "deleted", 0 ) ); } if ( spec.getQuery() != null && spec.getQuery().length() > 0 ) { crit.add( Restrictions.ilike( "name", spec.getQuery(), MatchMode.ANYWHERE ) ); } if ( spec.getOrderBy() != null && !spec.getOrderBy().equals( "" ) ) { if ( spec.isOrderAscending() ) { crit.addOrder( Order.asc( spec.getOrderBy() ).ignoreCase() ); } else { crit.addOrder( Order.desc( spec.getOrderBy() ).ignoreCase() ); } } if ( spec.getGroupTypes() != null ) { Collection<GroupType> gt = new ArrayList<GroupType>( spec.getGroupTypes() ); if ( spec.isIncludeBuiltInGroups() ) { if ( !spec.isIncludeAnonymousGroups() ) { gt.remove( GroupType.ANONYMOUS ); } } else { gt.removeAll( GroupType.getBuiltInTypes() ); } if ( spec.isIncludeUserGroups() ) { gt.add( GroupType.USER ); } crit.add( Restrictions.in( "type", GroupType.getIntegerValues( gt ) ) ); } else { Collection<GroupType> notGroupType = new ArrayList<GroupType>(); if ( !spec.isIncludeBuiltInGroups() ) { notGroupType.addAll( GroupType.getBuiltInTypes() ); if ( spec.isIncludeAnonymousGroups() ) { notGroupType.remove( GroupType.ANONYMOUS ); } } if ( !spec.isIncludeUserGroups() ) { notGroupType.add( GroupType.USER ); } if ( !spec.isIncludeAnonymousGroups() && !notGroupType.contains( GroupType.ANONYMOUS ) ) { notGroupType.add( GroupType.ANONYMOUS ); } crit.add( Restrictions.not( Restrictions.in( "type", GroupType.getIntegerValues( notGroupType ) ) ) ); } crit.setFirstResult( spec.getIndex() ); List list = crit.list(); if ( spec.getCount() == null ) { return list; } else { return list.subList( 0, Math.min( spec.getCount(), list.size() ) ); } } } ); } private String createHqlQuery( final GroupSpecification spec ) { final SelectBuilder hqlQuery = new SelectBuilder( 0 ); hqlQuery.addFromTable( GroupEntity.class.getName(), "g", SelectBuilder.NO_JOIN, null ); if ( spec.getDeletedState() != null ) { if ( spec.getDeletedState() == GroupSpecification.DeletedState.DELETED ) { hqlQuery.addFilter( "AND", "g.deleted = 1" ); } if ( spec.getDeletedState() == GroupSpecification.DeletedState.NOT_DELETED ) { hqlQuery.addFilter( "AND", "g.deleted = 0" ); } } if ( spec.getUserStoreKey() != null ) { hqlQuery.addFilter( "AND", "g.userStore.key = :userStoreKey" ); } if ( spec.getName() != null ) { hqlQuery.addFilter( "AND", "g.name = :name" ); } if ( spec.getKey() != null ) { hqlQuery.addFilter( "AND", "g.key = :key" ); } if ( spec.getSyncValue() != null ) { hqlQuery.addFilter( "AND", "g.syncValue = :syncValue" ); } if ( spec.getType() != null ) { hqlQuery.addFilter( "AND", "g.type = :type" ); } return hqlQuery.toString(); } public EntityPageList<GroupEntity> findAll( int index, int count ) { return findPageList( GroupEntity.class, "x.deleted = 0", index, count ); } }