Source Code Cross Referenced for FileSystemGroupStore.java in  » Portal » uPortal_rel-2-6-1-GA » org » jasig » portal » groups » filesystem » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Portal » uPortal_rel 2 6 1 GA » org.jasig.portal.groups.filesystem 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /* Copyright 2003 The JA-SIG Collaborative.  All rights reserved.
002:         *  See license distributed with this file and
003:         *  available online at http://www.uportal.org/license.html
004:         */
005:
006:        package org.jasig.portal.groups.filesystem;
007:
008:        import java.io.BufferedReader;
009:        import java.io.File;
010:        import java.io.FileNotFoundException;
011:        import java.io.FileReader;
012:        import java.io.FilenameFilter;
013:        import java.io.IOException;
014:        import java.util.ArrayList;
015:        import java.util.Collection;
016:        import java.util.Collections;
017:        import java.util.HashMap;
018:        import java.util.HashSet;
019:        import java.util.Iterator;
020:        import java.util.List;
021:        import java.util.Map;
022:        import java.util.Set;
023:        import java.util.StringTokenizer;
024:
025:        import org.apache.oro.io.GlobFilenameFilter;
026:        import org.jasig.portal.EntityIdentifier;
027:        import org.jasig.portal.EntityTypes;
028:        import org.jasig.portal.groups.EntityGroupImpl;
029:        import org.jasig.portal.groups.EntityImpl;
030:        import org.jasig.portal.groups.GroupServiceConfiguration;
031:        import org.jasig.portal.groups.GroupsException;
032:        import org.jasig.portal.groups.IEntity;
033:        import org.jasig.portal.groups.IEntityGroup;
034:        import org.jasig.portal.groups.IEntityGroupStore;
035:        import org.jasig.portal.groups.IEntitySearcher;
036:        import org.jasig.portal.groups.IEntityStore;
037:        import org.jasig.portal.groups.IGroupMember;
038:        import org.jasig.portal.services.GroupService;
039:        import org.apache.commons.logging.Log;
040:        import org.apache.commons.logging.LogFactory;
041:
042:        /**
043:         * This class is an <code>IEntityGroupStore</code> that uses the native file
044:         * system for its back end.  It also implements <code>IEntityStore</code> and
045:         * a no-op <code>IEntitySearcher</code>.  You can substitute a functional entity
046:         * searcher by adding it to the group service element for this component in the
047:         * configuration document, <code>compositeGroupServices.xml</code>.
048:         * <p>
049:         * A groups file system looks like this:
050:         * <p><code>
051:         * <hr width="100%">
052:         *  --&nbsp;groups root<br>
053:         * <blockquote>&nbsp;--&nbsp;org.jasig.portal.ChannelDefinition<br>
054:         *     <blockquote>&nbsp;--&nbsp;channel definition file<br>
055:         *                 &nbsp;--&nbsp;channel definition file<br>
056:         *        ...<br>
057:         *     </blockquote>
058:         * &nbsp;--&nbsp;org.jasig.portal.security.IPerson<br>
059:         *     <blockquote>&nbsp;--&nbsp;person directory<br>
060:         *         <blockquote>&nbsp;--&nbsp;person file <br>
061:         *                     &nbsp;--&nbsp;person file <br>
062:         *                     ...<br>
063:         *         </blockquote>
064:         *        &nbsp;--&nbsp;person directory <br>
065:         *     </blockquote>
066:         *      etc.<br>
067:         * </blockquote>
068:         * <hr width="100%">
069:         * </code><p>
070:         * The groups root is a file system directory declared in the group service
071:         * configuration document, where it is an attribute of the filesystem group
072:         * service element.  This directory has sub-directories, each named for the
073:         * underlying entity type that groups in that sub-directory contain.  If a
074:         * service only contains groups of IPersons, the groups root would have 1
075:         * sub-directory named org.jasig.portal.security.IPerson.
076:         * <p>
077:         * A directory named for a type may contain both sub-directories and files.
078:         * The sub-directories represent groups that can contain other groups.  The
079:         * files represent groups that can contain entity as well as group members.
080:         * The files contain keys, one to a line, and look like this:
081:         * <p><code>
082:         * <hr width="100%">
083:         * #&nbsp;this is a comment<br>
084:         * #&nbsp;another comment<br>
085:         * <br>
086:         * key1 Key One<br>
087:         * key2<br>
088:         * group:org$jasig$portal$security$IPerson/someDirectory/someFile<br>
089:         * key3<br>
090:         * &nbsp;# comment <br>
091:         * <hr width="100%">
092:         *</code><p>
093:         * Blank lines and lines that start with the <code>COMMENT</code> String (here
094:         * <code>#</code>) are ignored.  The first token on a non-ignored line is
095:         * assumed to be a group member key.  If the key starts with the
096:         * <code>GROUP_PREFIX</code> (here <code>:group</code>), it is treated as a
097:         * local group key.  Otherwise, it is assumed to be an entity key.  The rest of
098:         * the tokens on the line are ignored.
099:         * <p>
100:         * The file above contains 3 entity keys, <code>key1</code>, <code>key2</code>,
101:         * and <code>key3</code>, and 1 group key,
102:         * <code>org$jasig$portal$security$IPerson/someDirectory/someFile</code>.  It
103:         * represents a group with 3 entity members and 1 group member.  The local key
104:         * of a group is its file path starting at the type name, with the
105:         * <code>FileSystemGroupStore.SUBSTITUTE_PERIOD</code> character substituted
106:         * for the real period character.
107:         * <p>
108:         * The store is not implemented as a singleton, so you can have multiple
109:         * concurrent instances pointing to different groups root directories.
110:         * <p>
111:         *
112:         * @author Dan Ellentuck
113:         * @version $Revision: 36529 $
114:         */
115:        public class FileSystemGroupStore implements  IEntityGroupStore,
116:                IEntityStore, IEntitySearcher {
117:            private static final Log log = LogFactory
118:                    .getLog(FileSystemGroupStore.class);
119:            // File system constants for unix/windows compatibility:
120:            protected static char FORWARD_SLASH = '/';
121:            protected static char BACK_SLASH = '\\';
122:
123:            // Group file constants:
124:            protected static String COMMENT = "#";
125:            protected static String GROUP_PREFIX = "group:";
126:
127:            // The period is legal in filesystem names but could conflict with
128:            // the node separator in the group key.
129:            protected static char PERIOD = '.';
130:            protected static char SUBSTITUTE_PERIOD = '$';
131:            protected boolean useSubstitutePeriod = false;
132:
133:            private static String DEBUG_CLASS_NAME = "FileSystemGroupStore";
134:
135:            // Path to groups root directory.
136:            private String groupsRootPath;
137:
138:            // Either back slash or forward slash.
139:            protected char goodSeparator;
140:            protected char badSeparator;
141:
142:            // Cache of retrieved groups.
143:            private Map cache;
144:
145:            private FilenameFilter fileFilter = new FileFilter();
146:
147:            private Class defaultEntityType;
148:
149:            // Value holder adds last modified timestamp.
150:            private class GroupHolder {
151:                private long lastModified = 0;
152:                private IEntityGroup group;
153:
154:                protected GroupHolder(IEntityGroup g, long lm) {
155:                    this .group = g;
156:                    this .lastModified = lm;
157:                }
158:
159:                protected IEntityGroup getGroup() {
160:                    return group;
161:                }
162:
163:                protected long getLastModified() {
164:                    return lastModified;
165:                }
166:            }
167:
168:            private class FileFilter implements  FilenameFilter {
169:                /**
170:                 * Tests if a specified file should be included in a file list.
171:                 *
172:                 * @param   dir    the directory in which the file was found.
173:                 * @param   name   the name of the file.
174:                 * @return  <code>true</code> if and only if the name should be
175:                 * included in the file list; <code>false</code> otherwise.
176:                 */
177:                public boolean accept(File dir, String name) {
178:                    return (!name.startsWith("#")) && (!name.startsWith("%"))
179:                            && (!name.startsWith(".")) && (!name.endsWith("~"))
180:                            && (!name.endsWith(".tmp"))
181:                            && (!name.endsWith(".temp"))
182:                            && (!name.endsWith(".txt"));
183:                }
184:            }
185:
186:            /**
187:             * FileSystemGroupStore constructor.
188:             */
189:            public FileSystemGroupStore() {
190:                this (null);
191:            }
192:
193:            /**
194:             * FileSystemGroupStore constructor.
195:             */
196:            public FileSystemGroupStore(GroupServiceConfiguration cfg) {
197:                super ();
198:                initialize(cfg);
199:            }
200:
201:            /**
202:             * @return GroupHolder
203:             */
204:            protected GroupHolder cacheGet(String key) {
205:                return (GroupHolder) getCache().get(key);
206:            }
207:
208:            /**
209:             *
210:             */
211:            protected void cachePut(String key, Object val) {
212:                getCache().put(key, val);
213:            }
214:
215:            /**
216:             *
217:             */
218:            protected String conformSeparatorChars(String s) {
219:                return s.replace(getBadSeparator(), getGoodSeparator());
220:            }
221:
222:            /**
223:             * Delete this <code>IEntityGroup</code> from the data store.  We assume that
224:             * groups will be deleted via the file system, not the group service.
225:             * @param group org.jasig.portal.groups.IEntityGroup
226:             */
227:            public void delete(org.jasig.portal.groups.IEntityGroup group)
228:                    throws GroupsException {
229:                throw new UnsupportedOperationException(
230:                        "FileSystemGroupStore.delete() not supported");
231:            }
232:
233:            /**
234:             * Returns an instance of the <code>IEntityGroup</code> from the data store.
235:             * @return org.jasig.portal.groups.IEntityGroup
236:             * @param file java.io.File
237:             */
238:            private IEntityGroup find(File file) throws GroupsException {
239:                return find(getKeyFromFile(file));
240:            }
241:
242:            /**
243:             * Returns an instance of the <code>IEntityGroup</code> from the data store.
244:             * @return org.jasig.portal.groups.IEntityGroup
245:             * @param key java.lang.String
246:             */
247:            public IEntityGroup find(String key) throws GroupsException {
248:                if (log.isDebugEnabled()) {
249:                    log.debug(DEBUG_CLASS_NAME + ".find(): group key: " + key);
250:                }
251:
252:                String path = getFilePathFromKey(key);
253:                File f = new File(path);
254:
255:                GroupHolder groupHolder = cacheGet(key);
256:
257:                if (groupHolder == null
258:                        || (groupHolder.getLastModified() != f.lastModified())) {
259:                    if (log.isDebugEnabled()) {
260:                        log
261:                                .debug(DEBUG_CLASS_NAME
262:                                        + ".find(): retrieving group from file system for "
263:                                        + path);
264:                    }
265:
266:                    if (!f.exists()) {
267:                        if (log.isDebugEnabled()) {
268:                            log.debug(DEBUG_CLASS_NAME
269:                                    + ".find(): file does not exist: " + path);
270:                        }
271:                        return null;
272:                    }
273:
274:                    IEntityGroup group = newInstance(f);
275:                    groupHolder = new GroupHolder(group, f.lastModified());
276:                    cachePut(key, groupHolder);
277:                }
278:                return groupHolder.getGroup();
279:            }
280:
281:            /**
282:             * Returns an <code>Iterator</code> over the <code>Collection</code> of
283:             * <code>IEntityGroups</code> that the <code>IEntity</code> belongs to.
284:             * @return java.util.Iterator
285:             * @param ent org.jasig.portal.groups.IEntityGroup
286:             */
287:            protected Iterator findContainingGroups(IEntity ent)
288:                    throws GroupsException {
289:                if (log.isDebugEnabled())
290:                    log.debug(DEBUG_CLASS_NAME
291:                            + ".findContainingGroups(): for " + ent);
292:
293:                List groups = new ArrayList();
294:                File root = getFileRoot(ent.getType());
295:                if (root != null) {
296:                    File[] files = getAllFilesBelow(root);
297:
298:                    try {
299:                        for (int i = 0; i < files.length; i++) {
300:                            Collection ids = getEntityIdsFromFile(files[i]);
301:                            if (ids.contains(ent.getKey())) {
302:                                groups.add(find(files[i]));
303:                            }
304:                        }
305:                    } catch (IOException ex) {
306:                        throw new GroupsException(
307:                                "Problem reading group files", ex);
308:                    }
309:                }
310:
311:                return groups.iterator();
312:            }
313:
314:            /**
315:             * Returns an <code>Iterator</code> over the <code>Collection</code> of
316:             * <code>IEntityGroups</code> that the <code>IGroupMember</code> belongs to.
317:             * @return java.util.Iterator
318:             * @param group org.jasig.portal.groups.IEntityGroup
319:             */
320:            protected Iterator findContainingGroups(IEntityGroup group)
321:                    throws GroupsException {
322:                if (log.isDebugEnabled())
323:                    log.debug(DEBUG_CLASS_NAME
324:                            + ".findContainingGroups(): for " + group);
325:
326:                List groups = new ArrayList();
327:                {
328:                    String typeName = group.getLeafType().getName();
329:                    File parent = getFile(group).getParentFile();
330:                    if (!parent.getName().equals(typeName)) {
331:                        groups.add(find(parent));
332:                    }
333:
334:                    File root = getFileRoot(group.getLeafType());
335:                    File[] files = getAllFilesBelow(root);
336:                    try {
337:                        for (int i = 0; i < files.length; i++) {
338:                            Collection ids = getGroupIdsFromFile(files[i]);
339:                            if (ids.contains(group.getLocalKey())) {
340:                                groups.add(find(files[i]));
341:                            }
342:                        }
343:                    } catch (IOException ex) {
344:                        throw new GroupsException(
345:                                "Problem reading group files", ex);
346:                    }
347:                }
348:                return groups.iterator();
349:            }
350:
351:            /**
352:             * Returns an <code>Iterator</code> over the <code>Collection</code> of
353:             * <code>IEntityGroups</code> that the <code>IGroupMember</code> belongs to.
354:             * @return java.util.Iterator
355:             * @param gm org.jasig.portal.groups.IEntityGroup
356:             */
357:            public Iterator findContainingGroups(IGroupMember gm)
358:                    throws GroupsException {
359:                if (gm.isGroup()) {
360:                    IEntityGroup group = (IEntityGroup) gm;
361:                    return findContainingGroups(group);
362:                } else {
363:                    IEntity ent = (IEntity) gm;
364:                    return findContainingGroups(ent);
365:                }
366:            }
367:
368:            /**
369:             * Returns an <code>Iterator</code> over the <code>Collection</code> of
370:             * <code>IEntities</code> that are members of this <code>IEntityGroup</code>.
371:             * @return java.util.Iterator
372:             * @param group org.jasig.portal.groups.IEntityGroup
373:             */
374:            public java.util.Iterator findEntitiesForGroup(IEntityGroup group)
375:                    throws GroupsException {
376:                if (log.isDebugEnabled())
377:                    log
378:                            .debug(DEBUG_CLASS_NAME
379:                                    + ".findEntitiesForGroup(): retrieving entities for group "
380:                                    + group);
381:
382:                Collection entities = null;
383:                File f = getFile(group);
384:                if (f.isDirectory()) {
385:                    entities = Collections.EMPTY_LIST;
386:                } else {
387:                    entities = getEntitiesFromFile(f);
388:                }
389:
390:                return entities.iterator();
391:            }
392:
393:            /**
394:             * Returns an instance of the <code>ILockableEntityGroup</code> from the data store.
395:             * @return org.jasig.portal.groups.IEntityGroup
396:             * @param key java.lang.String
397:             */
398:            public org.jasig.portal.groups.ILockableEntityGroup findLockable(
399:                    String key) throws GroupsException {
400:                throw new UnsupportedOperationException(DEBUG_CLASS_NAME
401:                        + ".findLockable() not supported");
402:            }
403:
404:            /**
405:             * Returns a <code>String[]</code> containing the keys of  <code>IEntityGroups</code>
406:             * that are members of this <code>IEntityGroup</code>.  In a composite group
407:             * system, a group may contain a member group from a different service.  This is
408:             * called a foreign membership, and is only possible in an internally-managed
409:             * service.  A group store in such a service can return the key of a foreign member
410:             * group, but not the group itself, which can only be returned by its local store.
411:             *
412:             * @return String[]
413:             * @param group org.jasig.portal.groups.IEntityGroup
414:             */
415:            public java.lang.String[] findMemberGroupKeys(IEntityGroup group)
416:                    throws GroupsException {
417:                String[] keys;
418:                File f = getFile(group);
419:                if (f.isDirectory()) {
420:                    File[] files = f.listFiles();
421:                    keys = new String[files.length];
422:                    for (int i = 0; i < files.length; i++) {
423:                        keys[i] = getKeyFromFile(files[i]);
424:                    }
425:                } else {
426:                    try {
427:                        Collection groupKeys = getGroupIdsFromFile(f);
428:                        keys = (String[]) groupKeys
429:                                .toArray(new String[groupKeys.size()]);
430:                    } catch (IOException ex) {
431:                        throw new GroupsException(DEBUG_CLASS_NAME
432:                                + ".findMemberGroupKeys(): "
433:                                + "problem finding group members", ex);
434:                    }
435:                }
436:                return keys;
437:            }
438:
439:            /**
440:             * Returns an <code>Iterator</code> over the <code>Collection</code> of
441:             * <code>IEntityGroups</code> that are members of this <code>IEntityGroup</code>.
442:             * @return java.util.Iterator
443:             * @param group org.jasig.portal.groups.IEntityGroup
444:             */
445:            public java.util.Iterator findMemberGroups(IEntityGroup group)
446:                    throws GroupsException {
447:                String[] keys = findMemberGroupKeys(group); // No foreign groups here.
448:                List groups = new ArrayList(keys.length);
449:                for (int i = 0; i < keys.length; i++) {
450:                    groups.add(find(keys[i]));
451:                }
452:                return groups.iterator();
453:            }
454:
455:            /**
456:             * Recursive search of directories underneath dir for files that match filter.
457:             * @return java.util.Set
458:             */
459:            public Set getAllDirectoriesBelow(File dir) {
460:                Set allDirectories = new HashSet();
461:                if (dir.isDirectory()) {
462:                    primGetAllDirectoriesBelow(dir, allDirectories);
463:                }
464:                return allDirectories;
465:            }
466:
467:            /**
468:             * Recursive search of directories underneath dir for files that match filter.
469:             */
470:            public File[] getAllFilesBelow(File dir) {
471:                Set allFiles = new HashSet();
472:                if (dir.isDirectory()) {
473:                    primGetAllFilesBelow(dir, allFiles);
474:                }
475:                return (File[]) allFiles.toArray(new File[allFiles.size()]);
476:            }
477:
478:            /**
479:             * Returns the filesystem separator character NOT in use.
480:             * @return char
481:             */
482:            protected char getBadSeparator() {
483:                return badSeparator;
484:            }
485:
486:            /**
487:             * @return java.util.Map
488:             */
489:            protected java.util.Map getCache() {
490:                return cache;
491:            }
492:
493:            /**
494:             * Returns a Class representing the default entity type.
495:             * @return Class
496:             */
497:            protected Class getDefaultEntityType() {
498:                return defaultEntityType;
499:            }
500:
501:            /**
502:             * @param idFile java.io.File - a file of ids.
503:             * @return entities Collection.
504:             */
505:            protected Collection getEntitiesFromFile(File idFile)
506:                    throws GroupsException {
507:                if (log.isDebugEnabled())
508:                    log.debug(DEBUG_CLASS_NAME + "getEntitiesFromFile(): for "
509:                            + idFile.getPath());
510:
511:                Collection ids = null;
512:                Class type = getEntityType(idFile);
513:                if (EntityTypes.getEntityTypeID(type) == null) {
514:                    throw new GroupsException("Invalid entity type: " + type);
515:                }
516:                try {
517:                    ids = getEntityIdsFromFile(idFile);
518:                } catch (Exception ex) {
519:                    throw new GroupsException(
520:                            "Problem retrieving keys from file", ex);
521:                }
522:
523:                Collection entities = new ArrayList(ids.size());
524:
525:                for (Iterator itr = ids.iterator(); itr.hasNext();) {
526:                    String key = (String) itr.next();
527:                    entities.add(GroupService.getEntity(key, type));
528:                }
529:
530:                if (log.isDebugEnabled())
531:                    log.debug(DEBUG_CLASS_NAME
532:                            + "getEntitiesFromFile(): Retrieved "
533:                            + entities.size() + " entities");
534:
535:                return entities;
536:            }
537:
538:            /**
539:             * @param idFile java.io.File - a file of ids.
540:             * @return String[] ids.
541:             */
542:            protected Collection getEntityIdsFromFile(File idFile)
543:                    throws IOException, FileNotFoundException {
544:                if (log.isDebugEnabled())
545:                    log.debug(DEBUG_CLASS_NAME
546:                            + "getEntityIdsFromFile(): Reading "
547:                            + idFile.getPath());
548:
549:                Collection ids = getIdsFromFile(idFile, false);
550:
551:                if (log.isDebugEnabled())
552:                    log.debug(DEBUG_CLASS_NAME
553:                            + "getEntityIdsFromFile(): Retrieved " + ids.size()
554:                            + " IDs");
555:
556:                return ids;
557:            }
558:
559:            /**
560:             * @param f File
561:             * @return java.lang.Class
562:             * The Class is the first node of the full path name.
563:             */
564:            protected Class getEntityType(File f) {
565:                String path = f.getPath();
566:                String afterRootPath = null;
567:                Class type = null;
568:                if (path.startsWith(getGroupsRootPath())) {
569:                    afterRootPath = path
570:                            .substring(getGroupsRootPath().length());
571:                    int end = afterRootPath.indexOf(File.separatorChar);
572:                    String typeName = afterRootPath.substring(0, end);
573:
574:                    try {
575:                        type = Class.forName(typeName);
576:                    } catch (ClassNotFoundException cnfe) {
577:                    }
578:                }
579:                return type;
580:            }
581:
582:            /**
583:             * @param group IEntityGroup.
584:             * @return File
585:             */
586:            protected File getFile(IEntityGroup group) {
587:                String key = getFilePathFromKey(group.getLocalKey());
588:                return new File(key);
589:            }
590:
591:            /**
592:             *
593:             */
594:            protected String getFilePathFromKey(String key) {
595:                if (log.isDebugEnabled())
596:                    log.debug(DEBUG_CLASS_NAME
597:                            + ".getFilePathFromKey(): for key: " + key);
598:
599:                String groupKey = useSubstitutePeriod ? key.replace(
600:                        SUBSTITUTE_PERIOD, PERIOD) : key;
601:
602:                String fullKey = getGroupsRootPath() + groupKey;
603:
604:                if (log.isDebugEnabled())
605:                    log.debug(DEBUG_CLASS_NAME
606:                            + ".getFilePathFromKey(): full key: " + fullKey);
607:
608:                return conformSeparatorChars(fullKey);
609:            }
610:
611:            /**
612:             * Returns a File that is the root for groups of the given type.
613:             */
614:            protected File getFileRoot(Class type) {
615:                String path = getGroupsRootPath() + type.getName();
616:                File f = new File(path);
617:                return (f.exists()) ? f : null;
618:            }
619:
620:            /**
621:             * Returns the filesystem separator character in use.
622:             * @return char
623:             */
624:            protected char getGoodSeparator() {
625:                return goodSeparator;
626:            }
627:
628:            /**
629:             * @param idFile java.io.File - a file of ids.
630:             * @return String[] ids.
631:             */
632:            protected Collection getGroupIdsFromFile(File idFile)
633:                    throws IOException, FileNotFoundException {
634:                if (log.isDebugEnabled())
635:                    log.debug(DEBUG_CLASS_NAME
636:                            + "getGroupIdsFromFile(): Reading "
637:                            + idFile.getPath());
638:
639:                Collection ids = getIdsFromFile(idFile, true);
640:
641:                if (log.isDebugEnabled())
642:                    log.debug(DEBUG_CLASS_NAME
643:                            + "getGroupIdsFromFile(): Retrieved " + ids.size()
644:                            + " IDs");
645:
646:                return ids;
647:            }
648:
649:            /**
650:             * @return java.lang.String
651:             */
652:            public java.lang.String getGroupsRootPath() {
653:                return groupsRootPath;
654:            }
655:
656:            /**
657:             * @param idFile java.io.File - a file of ids.
658:             * @return String[] ids.
659:             */
660:            protected Collection getIdsFromFile(File idFile, boolean groupIds)
661:                    throws IOException, FileNotFoundException {
662:                Collection ids = new HashSet();
663:                BufferedReader br = new BufferedReader(new FileReader(idFile));
664:                String line, tok;
665:
666:                line = br.readLine();
667:                while (line != null) {
668:                    line = line.trim();
669:                    if (!line.startsWith(COMMENT) && (line.length() > 0)) {
670:                        StringTokenizer st = new StringTokenizer(line);
671:                        tok = st.nextToken();
672:                        if (tok != null) {
673:                            if (tok.startsWith(GROUP_PREFIX)) {
674:                                if (groupIds) {
675:                                    ids.add(tok
676:                                            .substring(GROUP_PREFIX.length()));
677:                                }
678:                            } else {
679:                                if (!groupIds) {
680:                                    ids.add(tok);
681:                                }
682:                            }
683:                        }
684:                    }
685:                    line = br.readLine();
686:                }
687:                br.close();
688:
689:                return ids;
690:            }
691:
692:            /**
693:             *
694:             */
695:            protected String getKeyFromFile(File f) {
696:                String key = null;
697:                if (f.getPath().startsWith(getGroupsRootPath())) {
698:                    key = f.getPath().substring(getGroupsRootPath().length());
699:
700:                    if (useSubstitutePeriod) {
701:                        key = key.replace(PERIOD, SUBSTITUTE_PERIOD);
702:                    }
703:                }
704:                return key;
705:            }
706:
707:            /**
708:             *
709:             */
710:            protected void initialize(GroupServiceConfiguration cfg) {
711:                cache = Collections.synchronizedMap(new HashMap());
712:
713:                goodSeparator = File.separatorChar;
714:                badSeparator = (goodSeparator == FORWARD_SLASH) ? BACK_SLASH
715:                        : FORWARD_SLASH;
716:
717:                defaultEntityType = org.jasig.portal.security.IPerson.class;
718:                GroupServiceConfiguration config = cfg;
719:                if (config == null) {
720:                    try {
721:                        config = GroupServiceConfiguration.getConfiguration();
722:                    } catch (Exception ex) {
723:                        throw new RuntimeException(ex);
724:                    }
725:                }
726:
727:                String sep = config.getNodeSeparator();
728:                if (sep != null) {
729:                    String period = String.valueOf(PERIOD);
730:                    useSubstitutePeriod = sep.equals(period);
731:                }
732:            }
733:
734:            /**
735:             * @return org.jasig.portal.groups.IEntityGroup
736:             */
737:            private IEntityGroup newInstance(File f) throws GroupsException {
738:                String key = getKeyFromFile(f);
739:                String name = f.getName();
740:                Class cl = getEntityType(f);
741:                return newInstance(key, cl, name);
742:            }
743:
744:            /**
745:             * @return org.jasig.portal.groups.IEntityGroup
746:             * We assume that new groups will be created updated via the file system,
747:             * not the group service.
748:             */
749:            public IEntityGroup newInstance(Class entityType)
750:                    throws GroupsException {
751:                throw new UnsupportedOperationException(DEBUG_CLASS_NAME
752:                        + ".newInstance(Class cl) not supported");
753:            }
754:
755:            public IEntity newInstance(String key) throws GroupsException {
756:                return newInstance(key, getDefaultEntityType());
757:            }
758:
759:            public IEntity newInstance(String key, Class type)
760:                    throws GroupsException {
761:                if (org.jasig.portal.EntityTypes.getEntityTypeID(type) == null) {
762:                    throw new GroupsException("Invalid group type: " + type);
763:                }
764:                return new EntityImpl(key, type);
765:            }
766:
767:            /**
768:             * @return org.jasig.portal.groups.IEntityGroup
769:             */
770:            private IEntityGroup newInstance(String newKey, Class newType,
771:                    String newName) throws GroupsException {
772:                EntityGroupImpl egi = new EntityGroupImpl(newKey, newType);
773:                egi.primSetName(newName);
774:                return egi;
775:            }
776:
777:            /**
778:             * Returns all directories under dir.
779:             */
780:            private void primGetAllDirectoriesBelow(File dir, Set allDirectories) {
781:                File[] files = dir.listFiles(fileFilter);
782:                for (int i = 0; i < files.length; i++) {
783:                    if (files[i].isDirectory()) {
784:                        primGetAllDirectoriesBelow(files[i], allDirectories);
785:                        allDirectories.add(files[i]);
786:                    }
787:                }
788:            }
789:
790:            /**
791:             * Returns all files (not directories) underneath dir.
792:             */
793:            private void primGetAllFilesBelow(File dir, Set allFiles) {
794:                File[] files = dir.listFiles(fileFilter);
795:                for (int i = 0; i < files.length; i++) {
796:                    if (files[i].isDirectory()) {
797:                        primGetAllFilesBelow(files[i], allFiles);
798:                    } else {
799:                        allFiles.add(files[i]);
800:                    }
801:                }
802:            }
803:
804:            /**
805:             * Find EntityIdentifiers for entities whose name matches the query string
806:             * according to the specified method and is of the specified type
807:             */
808:            public EntityIdentifier[] searchForEntities(String query,
809:                    int method, Class type) throws GroupsException {
810:                return new EntityIdentifier[0];
811:            }
812:
813:            /**
814:             * Returns an EntityIdentifier[] of groups of the given leaf type whose names
815:             * match the query string according to the search method.
816:             *
817:             * @param query String the string used to match group names.
818:             * @param searchMethod see org.jasig.portal.groups.IGroupConstants.
819:             * @param leafType the leaf type of the groups we are searching for.
820:             * @return EntityIdentifier[]
821:             */
822:            public EntityIdentifier[] searchForGroups(String query,
823:                    int searchMethod, Class leafType) throws GroupsException {
824:                List ids = new ArrayList();
825:                File baseDir = getFileRoot(leafType);
826:
827:                if (log.isDebugEnabled())
828:                    log
829:                            .debug(DEBUG_CLASS_NAME + "searchForGroups(): "
830:                                    + query + " method: " + searchMethod
831:                                    + " type: " + leafType);
832:
833:                if (baseDir != null) {
834:                    String nameFilter = null;
835:
836:                    switch (searchMethod) {
837:                    case IS:
838:                        nameFilter = query;
839:                        break;
840:                    case STARTS_WITH:
841:                        nameFilter = query + "*";
842:                        break;
843:                    case ENDS_WITH:
844:                        nameFilter = "*" + query;
845:                        break;
846:                    case CONTAINS:
847:                        nameFilter = "*" + query + "*";
848:                        break;
849:                    default:
850:                        throw new GroupsException(DEBUG_CLASS_NAME
851:                                + ".searchForGroups(): Unknown search method: "
852:                                + searchMethod);
853:                    }
854:
855:                    FilenameFilter filter = new GlobFilenameFilter(nameFilter);
856:                    Set allDirs = getAllDirectoriesBelow(baseDir);
857:                    allDirs.add(baseDir);
858:
859:                    for (Iterator itr = allDirs.iterator(); itr.hasNext();) {
860:                        File[] files = ((File) itr.next()).listFiles(filter);
861:                        for (int filesIdx = 0; filesIdx < files.length; filesIdx++) {
862:                            String key = getKeyFromFile(files[filesIdx]);
863:                            EntityIdentifier ei = new EntityIdentifier(key,
864:                                    EntityTypes.GROUP_ENTITY_TYPE);
865:                            ids.add(ei);
866:                        }
867:                    }
868:                }
869:
870:                if (log.isDebugEnabled())
871:                    log.debug(DEBUG_CLASS_NAME + ".searchForGroups(): found "
872:                            + ids.size() + " files.");
873:
874:                return (EntityIdentifier[]) ids
875:                        .toArray(new EntityIdentifier[ids.size()]);
876:            }
877:
878:            /**
879:             * @param newCache java.util.Map
880:             */
881:            protected void setCache(java.util.Map newCache) {
882:                cache = newCache;
883:            }
884:
885:            /**
886:             * @param newGroupsRootPath java.lang.String
887:             */
888:            protected void setGroupsRootPath(java.lang.String newGroupsRootPath) {
889:                groupsRootPath = conformSeparatorChars(newGroupsRootPath)
890:                        + getGoodSeparator();
891:            }
892:
893:            /**
894:             * Adds or updates the <code>IEntityGroup</code> AND ITS MEMBERSHIPS to the
895:             * data store, as appropriate.  We assume that groups will be updated via the
896:             * file system, not the group service.
897:             * @param group org.jasig.portal.groups.IEntityGroup
898:             */
899:            public void update(org.jasig.portal.groups.IEntityGroup group)
900:                    throws GroupsException {
901:                throw new UnsupportedOperationException(DEBUG_CLASS_NAME
902:                        + ".update() not supported");
903:            }
904:
905:            /**
906:             * Commits the group memberships of the <code>IEntityGroup</code> to
907:             * the data store.  We assume that groups will be updated via the
908:             * file system, not the group service.
909:             * @param group org.jasig.portal.groups.IEntityGroup
910:             */
911:            public void updateMembers(org.jasig.portal.groups.IEntityGroup group)
912:                    throws GroupsException {
913:                throw new UnsupportedOperationException(DEBUG_CLASS_NAME
914:                        + ".updateMembers() not supported");
915:            }
916:
917:            /**
918:             * Answers if <code>group</code> contains <code>member</code>.
919:             * @return boolean
920:             * @param group org.jasig.portal.groups.IEntityGroup
921:             * @param member org.jasig.portal.groups.IGroupMember
922:             */
923:            public boolean contains(IEntityGroup group, IGroupMember member)
924:                    throws GroupsException {
925:                File f = getFile(group);
926:                return (f.isDirectory()) ? directoryContains(f, member)
927:                        : fileContains(f, member);
928:            }
929:
930:            /**
931:             * Answers if <code>file</code> contains <code>member</code>.  
932:             * @param file
933:             * @param member
934:             * @return boolean
935:             */
936:            private boolean fileContains(File file, IGroupMember member)
937:                    throws GroupsException {
938:                Collection ids = null;
939:                try {
940:                    ids = (member.isEntity()) ? getEntityIdsFromFile(file)
941:                            : getGroupIdsFromFile(file);
942:                } catch (Exception ex) {
943:                    throw new GroupsException("Error retrieving ids from file",
944:                            ex);
945:                }
946:                return ids.contains(member.getKey());
947:            }
948:
949:            /**
950:             * Answers if <code>directory</code> contains <code>member</code>.  A 
951:             * directory can only contain (other) groups.  
952:             * @param directory java.io.File
953:             * @param member
954:             * @return boolean
955:             */
956:            private boolean directoryContains(File directory,
957:                    IGroupMember member) {
958:                boolean found = false;
959:                if (member.isGroup()) {
960:                    File memberFile = getFile((IEntityGroup) member);
961:                    File[] files = directory.listFiles();
962:                    for (int i = 0; i < files.length & !found; i++) {
963:                        found = files[i].equals(memberFile);
964:                    }
965:                }
966:                return found;
967:            }
968:
969:            /**
970:             * Answers if <code>group</code> contains a member group named 
971:             * <code>name</code>.
972:             * @return boolean
973:             * @param group org.jasig.portal.groups.IEntityGroup
974:             * @param name java.lang.String
975:             */
976:            public boolean containsGroupNamed(IEntityGroup group, String name)
977:                    throws GroupsException {
978:                boolean found = false;
979:                Iterator itr = findMemberGroups(group);
980:                while (itr.hasNext() && !found) {
981:                    String otherName = ((IEntityGroup) itr.next()).getName();
982:                    found = otherName != null && otherName.equals(name);
983:                }
984:                return found;
985:            }
986:
987:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.