Package org.jasig.portal.groups.pags

Source Code of org.jasig.portal.groups.pags.PersonAttributesGroupStore$TestGroup

/**
* Licensed to Jasig under one or more contributor license
* agreements. See the NOTICE file distributed with this work
* for additional information regarding copyright ownership.
* Jasig licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a
* copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package org.jasig.portal.groups.pags;

import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.Vector;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jasig.portal.EntityIdentifier;
import org.jasig.portal.EntityTypes;
import org.jasig.portal.groups.EntityImpl;
import org.jasig.portal.groups.EntityTestingGroupImpl;
import org.jasig.portal.groups.GroupsException;
import org.jasig.portal.groups.IEntity;
import org.jasig.portal.groups.IEntityGroup;
import org.jasig.portal.groups.IEntityGroupStore;
import org.jasig.portal.groups.IEntitySearcher;
import org.jasig.portal.groups.IEntityStore;
import org.jasig.portal.groups.IGroupMember;
import org.jasig.portal.groups.ILockableEntityGroup;
import org.jasig.portal.security.IPerson;
import org.jasig.portal.security.PersonFactory;
import org.jasig.portal.security.provider.RestrictedPerson;
import org.jasig.portal.services.PersonDirectory;
import org.jasig.services.persondir.IPersonAttributeDao;
import org.jasig.services.persondir.IPersonAttributes;

/**
* The Person Attributes Group Store uses attributes stored in the IPerson object to determine
* group membership.  It can use attributes from any data source supported by the PersonDirectory
* service.
*
* @author Al Wold
* @version $Revision: 19776 $
*/
public class PersonAttributesGroupStore implements IEntityGroupStore, IEntityStore, IEntitySearcher {
   private static final Log log = LogFactory.getLog(PersonAttributesGroupStore.class);
   private static final Class<IPerson> IPERSON_CLASS = IPerson.class;
   private static final EntityIdentifier[] EMPTY_SEARCH_RESULTS =
       new EntityIdentifier[0];
   private Properties props;
   private Map groupDefinitions;
   private Map<String, IEntityGroup> groups;
   private Map<String, List> containingGroups;
     
   public PersonAttributesGroupStore() {
      groups = new HashMap<String, IEntityGroup>();
      containingGroups = new HashMap<String, List>();
      try {
         props = new Properties();
         props.load(PersonAttributesGroupStore.class.getResourceAsStream("/properties/groups/pags.properties"));
         IPersonAttributesConfiguration config = getConfig(props.getProperty("org.jasig.portal.groups.pags.PersonAttributesGroupStore.configurationClass"));
         groupDefinitions = config.getConfig();
         initGroups();
      } catch ( Exception e ) {
         throw new RuntimeException("Problem initializing groups", e);
      }
   }
  
   private IPersonAttributesConfiguration getConfig(String className) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
      Class configClass = Class.forName(className);
      Object o = configClass.newInstance();
      return (IPersonAttributesConfiguration)o;
   }

   /**
    * Iterates over the groupDefinitions Collection and creates the
    * corresponding groups.  Then, caches parents for each child group.
    */
   private void initGroups() throws GroupsException {
       Iterator<IEntityGroup> i = null;
       Collection<IEntityGroup> groupDefs = groupDefinitions.values();
      
       for ( i=groupDefs.iterator(); i.hasNext(); )
       {
           GroupDefinition groupDef = (GroupDefinition) i.next();
           IEntityGroup group = new EntityTestingGroupImpl(groupDef.getKey(), IPERSON_CLASS);
           group.setName(groupDef.getName());
           group.setDescription(groupDef.getDescription());
           cachePut(group);
       }
       cacheContainingGroupsForGroups();
   }
  

  
   private IPersonTester initializeTester(String tester, String attribute, String value) {
      try {
         Class testerClass = Class.forName(tester);
         Constructor c = testerClass.getConstructor(new Class[]{String.class, String.class});
         Object o = c.newInstance(new Object[]{attribute, value});
         return (IPersonTester)o;
      } catch (Exception e) {
         e.printStackTrace();
         return null;
      }
   }
  
   private IEntityGroup cacheGet(String key) {
        return groups.get(key);
    }
   private void cachePut(IEntityGroup group) {
       groups.put(group.getLocalKey(), group);
   }
  
   public boolean contains(IEntityGroup group, IGroupMember member)
   throws GroupsException
   {
      GroupDefinition groupDef = (GroupDefinition)groupDefinitions.get(group.getLocalKey());
      if (member.isGroup())
      {
         String key = ((IEntityGroup)member).getLocalKey();
         return groupDef.hasMember(key);
      }
      else
      {
         if (member.getEntityType() != IPERSON_CLASS)
             { return false; }
         IPerson person = null;
         try {
             IPersonAttributeDao pa = PersonDirectory.getPersonAttributeDao();
             final IPersonAttributes personAttributes = pa.getPerson(member.getKey());

             RestrictedPerson rp = PersonFactory.createRestrictedPerson();
             if (personAttributes != null) {
                 rp.setAttributes(personAttributes.getAttributes());
             }
            
             person = rp;
         }
         catch (Exception ex) {
             log.error("Exception acquiring attributes for member " + member + " while checking if group " + group + " contains this member.", ex);
             return false;
         }
         return testRecursively(groupDef, person, member);
      }
   }

   public void delete(IEntityGroup group) throws GroupsException {
      throw new UnsupportedOperationException("PersonAttributesGroupStore: Method delete() not supported.");
   }

   public IEntityGroup find(String key) throws GroupsException {
      return groups.get(key);
   }
  
   private void cacheContainingGroupsForGroups() throws GroupsException
   {
       Iterator<IEntityGroup> i = null;
       // Find potential parent groups, those whose GroupDefinitions have members.
       List<IEntityGroup> parentGroupsList = new ArrayList<IEntityGroup>();
       for (i=groupDefinitions.values().iterator(); i.hasNext();)
       {
           GroupDefinition groupDef = (GroupDefinition) i.next();
           if (! groupDef.members.isEmpty())
               { parentGroupsList.add(cacheGet(groupDef.getKey())); }
       }
       IEntityGroup[] parentGroupsArray = parentGroupsList.toArray(new IEntityGroup[parentGroupsList.size()]);
        
       // Check each group for its parents and cache the references.
       for (i=groups.values().iterator(); i.hasNext();)
       {
           IEntityGroup childGroup = i.next();
           parentGroupsList = new ArrayList<IEntityGroup>(5);
           for (int idx=0; idx<parentGroupsArray.length; idx++)
           {
               if ( contains(parentGroupsArray[idx], childGroup) )
                   { parentGroupsList.add(parentGroupsArray[idx]); }
           }
           containingGroups.put(childGroup.getLocalKey(), parentGroupsList);
       }
   }

   private boolean testRecursively(GroupDefinition groupDef, IPerson person,
       IGroupMember member)
   throws GroupsException {
       if ( ! groupDef.contains(person) )
           { return false;}
       else
       {
           IEntityGroup group = cacheGet(groupDef.getKey());
           IEntityGroup parentGroup = null;
           Set<IEntityGroup> allParents = primGetAllContainingGroups(group, new HashSet<IEntityGroup>());
           boolean testPassed = true;
           for (Iterator<IEntityGroup> i=allParents.iterator(); i.hasNext() && testPassed;)
           {
               parentGroup = i.next();
               GroupDefinition parentGroupDef =
                 (GroupDefinition) groupDefinitions.get(parentGroup.getLocalKey());
               testPassed = parentGroupDef.test(person);              
           }
          
           if (!testPassed && log.isWarnEnabled()) {
               StringBuffer sb = new StringBuffer();
               sb.append("PAGS group=").append(group.getKey());
               sb.append(" contained person=").append(member.getKey());
               sb.append(", but the person failed to be contained in ");
               sb.append("ancesters of this group");
               sb.append((parentGroup != null ? " (parentGroup="+parentGroup.getKey()+")" : ""));
               sb.append(". This may indicate a ");
               sb.append("misconfigured PAGS group ");
               sb.append("store. Please check PAGSGroupStoreConfig.xml.");
               log.warn(sb.toString());
           }
           return testPassed;
       }
   }
   private java.util.Set<IEntityGroup> primGetAllContainingGroups(IEntityGroup group, Set<IEntityGroup> s)
   throws GroupsException
   {
       Iterator i = findContainingGroups(group);
       while ( i.hasNext() )
       {
           IEntityGroup parentGroup = (IEntityGroup) i.next();
           s.add(parentGroup);
           primGetAllContainingGroups(parentGroup, s);
       }
       return s;
   }

   public Iterator findContainingGroups(IGroupMember member)
   throws GroupsException
   {
      return (member.isEntity())
        ? findContainingGroupsForEntity((IEntity)member)
        : findContainingGroupsForGroup((IEntityGroup)member);
   }
  
   private Iterator findContainingGroupsForGroup(IEntityGroup group)
   {
       List parents = containingGroups.get(group.getLocalKey());
       return (parents !=null)
         ? parents.iterator()
         : Collections.EMPTY_LIST.iterator();
   }
   private Iterator<IEntityGroup> findContainingGroupsForEntity(IEntity member)
   throws GroupsException {
       List<IEntityGroup> results = new ArrayList<IEntityGroup>();
       for (Iterator<IEntityGroup> i = groups.values().iterator(); i.hasNext(); ) {
          IEntityGroup group = i.next();
          if ( contains(group, member))
              { results.add(group); }
       }
       return results.iterator();
   }

   public Iterator findEntitiesForGroup(IEntityGroup group) throws GroupsException {
      return Collections.EMPTY_LIST.iterator();
   }

   public ILockableEntityGroup findLockable(String key) throws GroupsException {
      throw new UnsupportedOperationException("PersonAttributesGroupStore: Method findLockable() not supported");
   }

   public String[] findMemberGroupKeys(IEntityGroup group) throws GroupsException {
      List<String> keys = new ArrayList<String>();
      GroupDefinition groupDef = (GroupDefinition) groupDefinitions.get(group.getLocalKey());
      if (groupDef != null)
      {
          for (Iterator<String> i = groupDef.members.iterator(); i.hasNext(); )
              { keys.add(i.next()); }
      }
      return keys.toArray(new String[]{});
   }

   public Iterator<IEntityGroup> findMemberGroups(IEntityGroup group) throws GroupsException {
      String[] keys = findMemberGroupKeys(group);
      List<IEntityGroup> results = new ArrayList<IEntityGroup>();
      for (int i = 0; i < keys.length; i++) {
         results.add(cacheGet(keys[i]));
      }
      return results.iterator();
   }

   public IEntityGroup newInstance(Class entityType) throws GroupsException {
      throw new UnsupportedOperationException("PersonAttributesGroupStore: Method newInstance() not supported");
   }

   public EntityIdentifier[] searchForGroups(String query, int method, Class leaftype) throws GroupsException {
      if ( leaftype != IPERSON_CLASS )
          { return EMPTY_SEARCH_RESULTS; }
      List<EntityIdentifier> results = new ArrayList<EntityIdentifier>();
      switch (method) {
         case IS:
            for (Iterator<IEntityGroup> i = groups.values().iterator(); i.hasNext(); ) {
               IEntityGroup g = i.next();
               if (g.getName().equalsIgnoreCase(query)) {
                  results.add(g.getEntityIdentifier());
               }
            }
            break;
         case STARTS_WITH:
            for (Iterator<IEntityGroup> i = groups.values().iterator(); i.hasNext(); ) {
               IEntityGroup g = i.next();
               if (g.getName().toUpperCase().startsWith(query.toUpperCase())) {
                  results.add(g.getEntityIdentifier());
               }
            }
            break;
         case ENDS_WITH:
            for (Iterator<IEntityGroup> i = groups.values().iterator(); i.hasNext(); ) {
               IEntityGroup g = i.next();
               if (g.getName().toUpperCase().endsWith(query.toUpperCase())) {
                  results.add(g.getEntityIdentifier());
              }
            }
            break;
         case CONTAINS:
            for (Iterator<IEntityGroup> i = groups.values().iterator(); i.hasNext(); ) {
               IEntityGroup g = i.next();
               if (g.getName().toUpperCase().indexOf(query.toUpperCase()) != -1) {
                  results.add(g.getEntityIdentifier());
              }
            }
            break;
      }
      return results.toArray(new EntityIdentifier[]{});
   }

   public void update(IEntityGroup group) throws GroupsException {
      throw new UnsupportedOperationException("PersonAttributesGroupStore: Method update() not supported.");
   }

   public void updateMembers(IEntityGroup group) throws GroupsException {
      throw new UnsupportedOperationException("PersonAttributesGroupStore: Method updateMembers() not supported.");
   }
  
   public static class GroupDefinition {
      private String key;
      private String name;
      private String description;
      private List<String> members;
      private List<TestGroup> testGroups;
     
      public GroupDefinition() {
         members = new Vector<String>();
         testGroups = new Vector<TestGroup>();
      }
     
      public void setKey(String key) {
         this.key = key;
      }
      public String getKey() {
         return key;
      }
     
      public void setName(String name) {
         this.name = name;
      }
      public String getName() {
         return name;
      }
     
      public void setDescription(String description) {
         this.description = description;
      }
      public String getDescription() {
         return description;
      }
      public void addMember(String key) {
         members.add(key);
      }
      public boolean hasMember(String key) {
         return members.contains(key);
      }
      public void addTestGroup(TestGroup testGroup) {
         testGroups.add(testGroup);
      }
      public boolean contains(IPerson person) {
         return ( testGroups.isEmpty() ) ? false : test(person);
      }
      public boolean test(IPerson person) {
         if (testGroups.isEmpty())
             return true;
         for (Iterator<TestGroup> i = testGroups.iterator(); i.hasNext(); ) {
            TestGroup testGroup = i.next();
            if (testGroup.test(person)) {
               return true;
            }
         }
         return false;
      }
      public String toString() {
          return "GroupDefinition " + key + " (" + name + ")";
      }
   }
  
   public static class TestGroup {
      private List<IPersonTester> tests;
     
      public TestGroup() {
         tests = new Vector<IPersonTester>();
      }
     
      public void addTest(IPersonTester test) {
         tests.add(test);
      }
     
      public boolean test(IPerson person) {
         for (Iterator<IPersonTester> i = tests.iterator(); i.hasNext(); ) {
            IPersonTester tester = i.next();
            if (!tester.test(person)) {
               return false;
            }
         }
         return true;
      }
   }

   public IEntity newInstance(String key, Class type) throws GroupsException {
      if (EntityTypes.getEntityTypeID(type) == null) {
         throw new GroupsException("Invalid entity type: "+type.getName());
      }
      return new EntityImpl(key, type);
   }

   public IEntity newInstance(String key) throws GroupsException {
      return new EntityImpl(key, null);
   }

   public EntityIdentifier[] searchForEntities(String query, int method, Class type) throws GroupsException {
      return EMPTY_SEARCH_RESULTS;
   }

}
TOP

Related Classes of org.jasig.portal.groups.pags.PersonAttributesGroupStore$TestGroup

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.