Package org.jasig.portal.groups.filesystem

Source Code of org.jasig.portal.groups.filesystem.FileSystemGroupStore$GroupHolder

/* Copyright 2003 The JA-SIG Collaborative.  All rights reserved.
*  See license distributed with this file and
*  available online at http://www.uportal.org/license.html
*/

package org.jasig.portal.groups.filesystem;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FilenameFilter;
import java.io.IOException;
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.Set;
import java.util.StringTokenizer;

import org.apache.oro.io.GlobFilenameFilter;
import org.jasig.portal.EntityIdentifier;
import org.jasig.portal.EntityTypes;
import org.jasig.portal.groups.EntityGroupImpl;
import org.jasig.portal.groups.EntityImpl;
import org.jasig.portal.groups.GroupServiceConfiguration;
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.services.GroupService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
* This class is an <code>IEntityGroupStore</code> that uses the native file
* system for its back end.  It also implements <code>IEntityStore</code> and
* a no-op <code>IEntitySearcher</code>.  You can substitute a functional entity
* searcher by adding it to the group service element for this component in the
* configuration document, <code>compositeGroupServices.xml</code>.
* <p>
* A groups file system looks like this:
* <p><code>
* <hr width="100%">
*  --&nbsp;groups root<br>
* <blockquote>&nbsp;--&nbsp;org.jasig.portal.ChannelDefinition<br>
*     <blockquote>&nbsp;--&nbsp;channel definition file<br>
*                 &nbsp;--&nbsp;channel definition file<br>
*        ...<br>
*     </blockquote>
* &nbsp;--&nbsp;org.jasig.portal.security.IPerson<br>
*     <blockquote>&nbsp;--&nbsp;person directory<br>
*         <blockquote>&nbsp;--&nbsp;person file <br>
*                     &nbsp;--&nbsp;person file <br>
*                     ...<br>
*         </blockquote>
*        &nbsp;--&nbsp;person directory <br>
*     </blockquote>
*      etc.<br>
* </blockquote>
* <hr width="100%">
* </code><p>
* The groups root is a file system directory declared in the group service
* configuration document, where it is an attribute of the filesystem group
* service element.  This directory has sub-directories, each named for the
* underlying entity type that groups in that sub-directory contain.  If a
* service only contains groups of IPersons, the groups root would have 1
* sub-directory named org.jasig.portal.security.IPerson.
* <p>
* A directory named for a type may contain both sub-directories and files.
* The sub-directories represent groups that can contain other groups.  The
* files represent groups that can contain entity as well as group members.
* The files contain keys, one to a line, and look like this:
* <p><code>
* <hr width="100%">
* #&nbsp;this is a comment<br>
* #&nbsp;another comment<br>
* <br>
* key1 Key One<br>
* key2<br>
* group:org$jasig$portal$security$IPerson/someDirectory/someFile<br>
* key3<br>
* &nbsp;# comment <br>
* <hr width="100%">
*</code><p>
* Blank lines and lines that start with the <code>COMMENT</code> String (here
* <code>#</code>) are ignored.  The first token on a non-ignored line is
* assumed to be a group member key.  If the key starts with the
* <code>GROUP_PREFIX</code> (here <code>:group</code>), it is treated as a
* local group key.  Otherwise, it is assumed to be an entity key.  The rest of
* the tokens on the line are ignored.
* <p>
* The file above contains 3 entity keys, <code>key1</code>, <code>key2</code>,
* and <code>key3</code>, and 1 group key,
* <code>org$jasig$portal$security$IPerson/someDirectory/someFile</code>.  It
* represents a group with 3 entity members and 1 group member.  The local key
* of a group is its file path starting at the type name, with the
* <code>FileSystemGroupStore.SUBSTITUTE_PERIOD</code> character substituted
* for the real period character.
* <p>
* The store is not implemented as a singleton, so you can have multiple
* concurrent instances pointing to different groups root directories.
* <p>
*
* @author Dan Ellentuck
* @version $Revision: 1.17 $
*/
public class FileSystemGroupStore implements IEntityGroupStore, IEntityStore,
IEntitySearcher
{
    private static final Log log = LogFactory.getLog(FileSystemGroupStore.class);
    // File system constants for unix/windows compatibility:
    protected static char FORWARD_SLASH = '/';
    protected static char BACK_SLASH = '\\';

    // Group file constants:
    protected static String COMMENT = "#";
    protected static String GROUP_PREFIX = "group:";

    // The period is legal in filesystem names but could conflict with
    // the node separator in the group key.
    protected static char PERIOD = '.';
    protected static char SUBSTITUTE_PERIOD = '$';
    protected boolean useSubstitutePeriod = false;

    private static String DEBUG_CLASS_NAME = "FileSystemGroupStore";

    // Path to groups root directory.
    private String groupsRootPath;

    // Either back slash or forward slash.
    protected char goodSeparator;
    protected char badSeparator;

    // Cache of retrieved groups.
    private Map cache;

    private Class defaultEntityType;

    // Value holder adds last modified timestamp.
    private class GroupHolder {
        private long lastModified = 0;
        private IEntityGroup group;
        protected GroupHolder (IEntityGroup g, long lm) {
            this.group = g;
            this.lastModified = lm;
        }
        protected IEntityGroup getGroup () {
            return group;
        }
        protected long getLastModified() {
            return  lastModified;
        }
    }

/**
* FileSystemGroupStore constructor.
*/
public FileSystemGroupStore() {
    this(null);
}
/**
* FileSystemGroupStore constructor.
*/
public FileSystemGroupStore(GroupServiceConfiguration cfg) {
    super();
    initialize(cfg);
}
/**
* @return GroupHolder
*/
protected GroupHolder cacheGet(String key)
{
    return (GroupHolder) getCache().get(key);
}
/**
*
*/
protected void cachePut(String key, Object val)
{
    getCache().put(key, val);
}
/**
*
*/
protected String conformSeparatorChars(String s)
{
    return s.replace(getBadSeparator(), getGoodSeparator());
}
/**
* Delete this <code>IEntityGroup</code> from the data store.  We assume that
* groups will be deleted via the file system, not the group service.
* @param group org.jasig.portal.groups.IEntityGroup
*/
public void delete(org.jasig.portal.groups.IEntityGroup group) throws GroupsException
{
    throw new UnsupportedOperationException("FileSystemGroupStore.delete() not supported");
}
/**
* Returns an instance of the <code>IEntityGroup</code> from the data store.
* @return org.jasig.portal.groups.IEntityGroup
* @param file java.io.File
*/
private IEntityGroup find(File file) throws GroupsException
{
    return find(getKeyFromFile(file));
}
/**
* Returns an instance of the <code>IEntityGroup</code> from the data store.
* @return org.jasig.portal.groups.IEntityGroup
* @param key java.lang.String
*/
public IEntityGroup find(String key) throws GroupsException
{
    if (log.isDebugEnabled())
        log.debug(
                DEBUG_CLASS_NAME + ".find(): group key: " + key);

    String path = getFilePathFromKey(key);
    File f = new File(path);
    if ( ! f.exists() )
        { return null; }

    GroupHolder groupHolder = cacheGet(key);

    if ( groupHolder == null || (groupHolder.getLastModified() != f.lastModified()) )
    {
        if (log.isDebugEnabled())
            log.debug(
                    DEBUG_CLASS_NAME + ".find(): retrieving group from file system for " + path);

        IEntityGroup group = newInstance(f);
        groupHolder = new GroupHolder(group, f.lastModified()) ;
        cachePut(key, groupHolder);
    }
    return groupHolder.getGroup();
}
/**
* Returns an <code>Iterator</code> over the <code>Collection</code> of
* <code>IEntityGroups</code> that the <code>IEntity</code> belongs to.
* @return java.util.Iterator
* @param ent org.jasig.portal.groups.IEntityGroup
*/
protected Iterator findContainingGroups(IEntity ent) throws GroupsException
{
    if (log.isDebugEnabled())
        log.debug(
                DEBUG_CLASS_NAME + ".findContainingGroups(): for " + ent);

    List groups = new ArrayList();
    File root = getFileRoot(ent.getType());
    if ( root != null )
    {
        File[] files = getAllFilesBelow(root);

       try
        {
            for (int i=0; i<files.length; i++)
            {
                Collection ids = getEntityIdsFromFile(files[i]);
                if ( ids.contains(ent.getKey()) )
                    { groups.add(find(files[i])); }
            }
        }
        catch (IOException ex)
            { throw new GroupsException("Problem reading group files", ex); }
    }

    return groups.iterator();
}
/**
* Returns an <code>Iterator</code> over the <code>Collection</code> of
* <code>IEntityGroups</code> that the <code>IGroupMember</code> belongs to.
* @return java.util.Iterator
* @param group org.jasig.portal.groups.IEntityGroup
*/
protected Iterator findContainingGroups(IEntityGroup group) throws GroupsException
{
    if (log.isDebugEnabled())
        log.debug(
                DEBUG_CLASS_NAME + ".findContainingGroups(): for " + group);

    List groups = new ArrayList();
    {
        String typeName = group.getLeafType().getName();
        File parent = getFile(group).getParentFile();
        if ( ! parent.getName().equals(typeName) )
            { groups.add(find(parent)); }

        File root = getFileRoot(group.getLeafType());
        File[] files = getAllFilesBelow(root);
        try
        {
            for (int i=0; i<files.length; i++)
            {
                Collection ids = getGroupIdsFromFile(files[i]);
                if ( ids.contains(group.getLocalKey()) )
                    { groups.add(find(files[i])); }
            }
        }
        catch (IOException ex)
            { throw new GroupsException("Problem reading group files", ex); }
    }
    return groups.iterator();
}
/**
* Returns an <code>Iterator</code> over the <code>Collection</code> of
* <code>IEntityGroups</code> that the <code>IGroupMember</code> belongs to.
* @return java.util.Iterator
* @param gm org.jasig.portal.groups.IEntityGroup
*/
public Iterator findContainingGroups(IGroupMember gm) throws GroupsException
{
    if ( gm.isGroup() )
    {
        IEntityGroup group = (IEntityGroup) gm;
        return findContainingGroups(group);
    }
    else
    {
        IEntity ent = (IEntity) gm;
        return findContainingGroups(ent);
    }
}
/**
* Returns an <code>Iterator</code> over the <code>Collection</code> of
* <code>IEntities</code> that are members of this <code>IEntityGroup</code>.
* @return java.util.Iterator
* @param group org.jasig.portal.groups.IEntityGroup
*/
public java.util.Iterator findEntitiesForGroup(IEntityGroup group) throws GroupsException
{
    if (log.isDebugEnabled())
        log.debug(
                DEBUG_CLASS_NAME + ".findEntitiesForGroup(): retrieving entities for group " + group);

    Collection entities = null;
    File f = getFile(group);
    if ( f.isDirectory() )
        { entities = Collections.EMPTY_LIST; }
    else
        { entities = getEntitiesFromFile(f); }

    return entities.iterator();
}
/**
* Returns an instance of the <code>ILockableEntityGroup</code> from the data store.
* @return org.jasig.portal.groups.IEntityGroup
* @param key java.lang.String
*/
public org.jasig.portal.groups.ILockableEntityGroup findLockable(String key)
throws GroupsException
{
    throw new UnsupportedOperationException(DEBUG_CLASS_NAME + ".findLockable() not supported");
}
/**
* Returns a <code>String[]</code> containing the keys of  <code>IEntityGroups</code>
* that are members of this <code>IEntityGroup</code>.  In a composite group
* system, a group may contain a member group from a different service.  This is
* called a foreign membership, and is only possible in an internally-managed
* service.  A group store in such a service can return the key of a foreign member
* group, but not the group itself, which can only be returned by its local store.
*
* @return String[]
* @param group org.jasig.portal.groups.IEntityGroup
*/
public java.lang.String[] findMemberGroupKeys(IEntityGroup group) throws GroupsException
{
    String[] keys;
    File f = getFile(group);
    if ( f.isDirectory() )
    {
        File[] files = f.listFiles();
        keys = new String[files.length];
        for (int i=0; i<files.length; i++)
            { keys[i] = getKeyFromFile(files[i]); }
    }
    else
    {
        try
        {
            Collection groupKeys = getGroupIdsFromFile(f);
            keys = (String[])groupKeys.toArray(new String[groupKeys.size()]);
        }
        catch (IOException ex)
            { throw new GroupsException(DEBUG_CLASS_NAME + ".findMemberGroupKeys(): " +
                 "problem finding group members", ex); }
    }
    return keys;
}
/**
* Returns an <code>Iterator</code> over the <code>Collection</code> of
* <code>IEntityGroups</code> that are members of this <code>IEntityGroup</code>.
* @return java.util.Iterator
* @param group org.jasig.portal.groups.IEntityGroup
*/
public java.util.Iterator findMemberGroups(IEntityGroup group) throws GroupsException
{
    String[] keys = findMemberGroupKeys(group)// No foreign groups here.
    List groups = new ArrayList(keys.length);
    for (int i=0; i<keys.length; i++)
        { groups.add(find(keys[i])); }
    return groups.iterator();
}
/**
* Recursive search of directories underneath dir for files that match filter.
* @return java.util.Set
*/
public Set getAllDirectoriesBelow(File dir)
{
    Set allDirectories = new HashSet();
    if ( dir.isDirectory() )
        { primGetAllDirectoriesBelow(dir, allDirectories); }
    return allDirectories;
}
/**
* Recursive search of directories underneath dir for files that match filter.
*/
public File[] getAllFilesBelow(File dir)
{
    Set allFiles = new HashSet();
    if ( dir.isDirectory() )
        { primGetAllFilesBelow(dir, allFiles); }
    return (File[]) allFiles.toArray(new File[allFiles.size()]);
}
/**
* Returns the filesystem separator character NOT in use.
* @return char
*/
protected char getBadSeparator() {
    return badSeparator;
}
/**
* @return java.util.Map
*/
protected java.util.Map getCache()
{
    return cache;
}
/**
* Returns a Class representing the default entity type.
* @return Class
*/
protected Class getDefaultEntityType() {
    return defaultEntityType;
}
/**
* @param idFile java.io.File - a file of ids.
* @return entities Collection.
*/
protected Collection getEntitiesFromFile(File idFile) throws GroupsException
{
    if (log.isDebugEnabled())
        log.debug(
                DEBUG_CLASS_NAME + "getEntitiesFromFile(): for " + idFile.getPath());

    Collection ids = null;
    Class type = getEntityType(idFile);
    if ( EntityTypes.getEntityTypeID(type) == null )
        { throw new GroupsException("Invalid entity type: " + type); }
    try
        { ids = getEntityIdsFromFile(idFile); }
    catch (Exception ex)
        { throw new GroupsException("Problem retrieving keys from file", ex); }

    Collection entities = new ArrayList(ids.size());

    for ( Iterator itr=ids.iterator(); itr.hasNext(); )
    {
        String key = (String) itr.next();
        entities.add(GroupService.getEntity(key, type));
    }

    if (log.isDebugEnabled())
        log.debug(
                DEBUG_CLASS_NAME + "getEntitiesFromFile(): Retrieved " + entities.size() + " entities");

    return entities;
}
/**
* @param idFile java.io.File - a file of ids.
* @return String[] ids.
*/
protected Collection getEntityIdsFromFile(File idFile) throws IOException, FileNotFoundException
{
    if (log.isDebugEnabled())
        log.debug(
                DEBUG_CLASS_NAME + "getEntityIdsFromFile(): Reading " + idFile.getPath());

    Collection ids = getIdsFromFile(idFile, false);

    if (log.isDebugEnabled())
        log.debug(
                DEBUG_CLASS_NAME + "getEntityIdsFromFile(): Retrieved " + ids.size() + " IDs");

    return ids;
}
/**
* @param f File
* @return java.lang.Class
* The Class is the first node of the full path name.
*/
protected Class getEntityType(File f)
{
    String path = f.getPath();
    String afterRootPath = null;
    Class type = null;
    if ( path.startsWith(getGroupsRootPath()) )
    {
        afterRootPath = path.substring(getGroupsRootPath().length());
        int end = afterRootPath.indexOf(File.separatorChar);
        String typeName = afterRootPath.substring(0,end);

        try
            { type = Class.forName(typeName); }
        catch (ClassNotFoundException cnfe) {}
    }
    return type;
}
/**
* @param group IEntityGroup.
* @return File
*/
protected File getFile(IEntityGroup group)
{
    String key = getFilePathFromKey(group.getLocalKey());
    return new File(key);
}
/**
*
*/
protected String getFilePathFromKey(String key)
{
    if (log.isDebugEnabled())
        log.debug(
                DEBUG_CLASS_NAME + ".getFilePathFromKey(): for key: " + key);
       
    String groupKey = useSubstitutePeriod
      ? key.replace(SUBSTITUTE_PERIOD, PERIOD)
      : key;

    String fullKey = getGroupsRootPath() + groupKey;

    if (log.isDebugEnabled())
        log.debug(
                DEBUG_CLASS_NAME + ".getFilePathFromKey(): full key: " + fullKey);

    return conformSeparatorChars(fullKey);
}
/**
* Returns a File that is the root for groups of the given type.
*/
protected File getFileRoot(Class type)
{
    String path = getGroupsRootPath() + type.getName();
    File f = new File(path);
    return ( f.exists() ) ? f : null;
}
/**
* Returns the filesystem separator character in use.
* @return char
*/
protected char getGoodSeparator() {
    return goodSeparator;
}
/**
* @param idFile java.io.File - a file of ids.
* @return String[] ids.
*/
protected Collection getGroupIdsFromFile(File idFile) throws IOException, FileNotFoundException
{
    if (log.isDebugEnabled())
        log.debug(
                DEBUG_CLASS_NAME + "getGroupIdsFromFile(): Reading " + idFile.getPath());

    Collection ids = getIdsFromFile(idFile, true);

    if (log.isDebugEnabled())
        log.debug(
                DEBUG_CLASS_NAME + "getGroupIdsFromFile(): Retrieved " + ids.size() + " IDs");

    return ids;
}
/**
* @return java.lang.String
*/
public java.lang.String getGroupsRootPath() {
    return groupsRootPath;
}
/**
* @param idFile java.io.File - a file of ids.
* @return String[] ids.
*/
protected Collection getIdsFromFile(File idFile, boolean groupIds)
throws IOException, FileNotFoundException
{
    Collection ids = new HashSet();
    BufferedReader br = new BufferedReader(new FileReader(idFile));
    String line, tok;

    line = br.readLine();
    while(line != null)
    {
        line = line.trim();
        if ( ! line.startsWith(COMMENT) && (line.length() > 0) )
        {
            StringTokenizer st = new StringTokenizer(line);
            tok = st.nextToken();
            if ( tok != null )
            {
                if ( tok.startsWith(GROUP_PREFIX) )
                {
                    if ( groupIds )
                        { ids.add(tok.substring(GROUP_PREFIX.length())); }
                }
                else
                {
                    if ( ! groupIds )
                        { ids.add(tok); }
                }
            }
        }
        line = br.readLine();
    }
    br.close();

    return ids;
}
/**
*
*/
protected String getKeyFromFile(File f)
{
    String key = null;
    if ( f.getPath().startsWith(getGroupsRootPath()) )
    {
        key = f.getPath().substring(getGroupsRootPath().length());
       
        if ( useSubstitutePeriod )
            {  key = key.replace(PERIOD, SUBSTITUTE_PERIOD); }
    }
    return key;
}
/**
*
*/
protected void initialize(GroupServiceConfiguration cfg)
{
    cache = Collections.synchronizedMap(new HashMap());

    goodSeparator = File.separatorChar;
    badSeparator = ( goodSeparator == FORWARD_SLASH ) ? BACK_SLASH : FORWARD_SLASH;

    defaultEntityType = org.jasig.portal.security.IPerson.class;
    GroupServiceConfiguration config = cfg;
    if ( config == null )
    {
        try
            { config = GroupServiceConfiguration.getConfiguration(); }
        catch (Exception ex)
            { throw new RuntimeException(ex); }
    }

    String sep = config.getNodeSeparator();
    if (sep != null)
    {
        String period = String.valueOf(PERIOD);
        useSubstitutePeriod = sep.equals(period);
    }
}
/**
* @return org.jasig.portal.groups.IEntityGroup
*/
private IEntityGroup newInstance (File f) throws GroupsException
{
    String key = getKeyFromFile(f);
    String name = f.getName();
    Class cl = getEntityType(f);
    return newInstance(key, cl, name);
}
/**
* @return org.jasig.portal.groups.IEntityGroup
* We assume that new groups will be created updated via the file system,
* not the group service.
*/
public IEntityGroup newInstance(Class entityType) throws GroupsException
{
    throw new UnsupportedOperationException(DEBUG_CLASS_NAME +
      ".newInstance(Class cl) not supported");
}
public IEntity newInstance(String key) throws GroupsException
{
    return newInstance(key, getDefaultEntityType());
}
public IEntity newInstance(String key, Class type) throws GroupsException
{
    if ( org.jasig.portal.EntityTypes.getEntityTypeID(type) == null )
        { throw new GroupsException("Invalid group type: " + type); }
    return new EntityImpl(key, type);
}
/**
* @return org.jasig.portal.groups.IEntityGroup
*/
private IEntityGroup newInstance (String newKey, Class newType, String newName)
throws GroupsException
{
    EntityGroupImpl egi = new EntityGroupImpl(newKey, newType);
    egi.primSetName(newName);
    return egi;
}
/**
* Returns all directories under dir.
*/
private void primGetAllDirectoriesBelow(File dir, Set allDirectories)
{
    File[] files = dir.listFiles();
    for(int i=0; i<files.length; i++)
    {
        if ( files[i].isDirectory() )
        {
            primGetAllDirectoriesBelow(files[i], allDirectories);
            allDirectories.add(files[i]);
        }
    }
}
/**
* Returns all files (not directories) underneath dir.
*/
private void primGetAllFilesBelow(File dir, Set allFiles)
{
    File[] files = dir.listFiles();
    for(int i=0; i<files.length; i++)
    {
        if ( files[i].isDirectory() )
            { primGetAllFilesBelow(files[i], allFiles); }
        else
            { allFiles.add(files[i]); }
    }
}
/**
* Find EntityIdentifiers for entities whose name matches the query string
* according to the specified method and is of the specified type
*/
public EntityIdentifier[] searchForEntities(String query, int method, Class type)
throws GroupsException
{
    return new EntityIdentifier[0];
}
/**
* Returns an EntityIdentifier[] of groups of the given leaf type whose names
* match the query string according to the search method.
*
* @param query String the string used to match group names.
* @param searchMethod see org.jasig.portal.groups.IGroupConstants.
* @param leafType the leaf type of the groups we are searching for.
* @return EntityIdentifier[]
*/
public EntityIdentifier[] searchForGroups(String query, int searchMethod, Class leafType)
throws GroupsException
{
    List ids = new ArrayList();
    File baseDir = getFileRoot(leafType);

    if (log.isDebugEnabled())
        log.debug(
                DEBUG_CLASS_NAME + "searchForGroups(): " + query + " method: " +
                searchMethod + " type: " + leafType);

    if ( baseDir != null )
    {
        String nameFilter = null;

        switch (searchMethod)
        {
          case IS:
            nameFilter = query;
            break;
          case STARTS_WITH:
            nameFilter = query+"*";
            break;
          case ENDS_WITH:
           nameFilter = "*"+query;
           break;
          case CONTAINS:
            nameFilter = "*"+query+"*";
            break;
          default:
            throw new GroupsException(DEBUG_CLASS_NAME +
                ".searchForGroups(): Unknown search method: " + searchMethod);
        }

        FilenameFilter filter = new GlobFilenameFilter(nameFilter);
        Set allDirs = getAllDirectoriesBelow(baseDir);
        allDirs.add(baseDir);

        for (Iterator itr = allDirs.iterator(); itr.hasNext(); )
        {
            File[] files = ((File)itr.next()).listFiles(filter);
            for ( int filesIdx=0; filesIdx<files.length; filesIdx++ )
            {
                String key = getKeyFromFile(files[filesIdx]);
                EntityIdentifier ei = new EntityIdentifier(key, EntityTypes.GROUP_ENTITY_TYPE);
                ids.add(ei);
            }
        }
    }

    if (log.isDebugEnabled())
        log.debug(DEBUG_CLASS_NAME +
                ".searchForGroups(): found " + ids.size() + " files.");

    return (EntityIdentifier[]) ids.toArray(new EntityIdentifier[ids.size()]);
}
/**
* @param newCache java.util.Map
*/
protected void setCache(java.util.Map newCache) {
    cache = newCache;
}
/**
* @param newGroupsRootPath java.lang.String
*/
protected void setGroupsRootPath(java.lang.String newGroupsRootPath) {
    groupsRootPath = conformSeparatorChars(newGroupsRootPath) + getGoodSeparator();
}
/**
* Adds or updates the <code>IEntityGroup</code> AND ITS MEMBERSHIPS to the
* data store, as appropriate.  We assume that groups will be updated via the
* file system, not the group service.
* @param group org.jasig.portal.groups.IEntityGroup
*/
public void update(org.jasig.portal.groups.IEntityGroup group) throws GroupsException
{
    throw new UnsupportedOperationException(DEBUG_CLASS_NAME + ".update() not supported");
}
/**
* Commits the group memberships of the <code>IEntityGroup</code> to
* the data store.  We assume that groups will be updated via the
* file system, not the group service.
* @param group org.jasig.portal.groups.IEntityGroup
*/
public void updateMembers(org.jasig.portal.groups.IEntityGroup group)
throws GroupsException
{
    throw new UnsupportedOperationException(DEBUG_CLASS_NAME + ".updateMembers() not supported");
}
/**
* Answers if <code>group</code> contains <code>member</code>.
* @return boolean
* @param group org.jasig.portal.groups.IEntityGroup
* @param member org.jasig.portal.groups.IGroupMember
*/
public boolean contains(IEntityGroup group, IGroupMember member)
throws GroupsException
{
    boolean contains = false;
    File f = getFile(group);
    if ( f.exists() )
    {
        contains = ( f.isDirectory() )
          ? directoryContains(f, member)
          : fileContains(f, member);
    }
    return contains;
}
/**
* Answers if <code>file</code> contains <code>member</code>
* @param file
* @param member
* @return boolean
*/
private boolean fileContains(File file, IGroupMember member)
throws GroupsException
{
    Collection ids=null;
    try
    {
        ids = ( member.isEntity() )
          ? getEntityIdsFromFile(file)
          : getGroupIdsFromFile(file);
    }
    catch (Exception ex)
    {
        throw new GroupsException("Error retrieving ids from file", ex);
    }
    return ids.contains(member.getKey());
}

/**
* Answers if <code>directory</code> contains <code>member</code>.  A
* directory can only contain (other) groups. 
* @param directory java.io.File
* @param member
* @return boolean
*/
private boolean directoryContains(File directory, IGroupMember member)
{
    boolean found=false;
    if ( member.isGroup() )
    {
        File memberFile = getFile((IEntityGroup)member);
        File[] files = directory.listFiles();
        for (int i=0; i<files.length & ! found; i++)
            { found = files[i].equals(memberFile); }
    }
    return found;
}
/**
* Answers if <code>group</code> contains a member group named
* <code>name</code>.
* @return boolean
* @param group org.jasig.portal.groups.IEntityGroup
* @param name java.lang.String
*/
public boolean containsGroupNamed(IEntityGroup group, String name)
throws GroupsException
{
    boolean found = false;
    Iterator itr = findMemberGroups(group);
    while ( itr.hasNext() && ! found )
    {
        String otherName = ((IEntityGroup)itr.next()).getName();
        found = otherName != null && otherName.equals(name);
    }
    return found;
}

}
TOP

Related Classes of org.jasig.portal.groups.filesystem.FileSystemGroupStore$GroupHolder

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.