KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > dspace > eperson > Group


1 /*
2  * Group.java
3  *
4  * Version: $Revision: 1.31 $
5  *
6  * Date: $Date: 2006/11/22 17:41:52 $
7  *
8  * Copyright (c) 2002-2005, Hewlett-Packard Company and Massachusetts
9  * Institute of Technology. All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions are
13  * met:
14  *
15  * - Redistributions of source code must retain the above copyright
16  * notice, this list of conditions and the following disclaimer.
17  *
18  * - Redistributions in binary form must reproduce the above copyright
19  * notice, this list of conditions and the following disclaimer in the
20  * documentation and/or other materials provided with the distribution.
21  *
22  * - Neither the name of the Hewlett-Packard Company nor the name of the
23  * Massachusetts Institute of Technology nor the names of their
24  * contributors may be used to endorse or promote products derived from
25  * this software without specific prior written permission.
26  *
27  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
30  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
32  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
33  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
34  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
35  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
36  * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
37  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
38  * DAMAGE.
39  */

40 package org.dspace.eperson;
41
42 import java.sql.SQLException JavaDoc;
43 import java.util.ArrayList JavaDoc;
44 import java.util.HashMap JavaDoc;
45 import java.util.HashSet JavaDoc;
46 import java.util.Iterator JavaDoc;
47 import java.util.List JavaDoc;
48 import java.util.Map JavaDoc;
49 import java.util.Set JavaDoc;
50
51 import org.apache.log4j.Logger;
52 import org.dspace.authorize.AuthorizeException;
53 import org.dspace.authorize.AuthorizeManager;
54 import org.dspace.content.DSpaceObject;
55 import org.dspace.core.ConfigurationManager;
56 import org.dspace.core.Constants;
57 import org.dspace.core.Context;
58 import org.dspace.core.LogManager;
59 import org.dspace.storage.rdbms.DatabaseManager;
60 import org.dspace.storage.rdbms.TableRow;
61 import org.dspace.storage.rdbms.TableRowIterator;
62
63 /**
64  * Class representing a group of e-people.
65  *
66  * @author David Stuve
67  * @version $Revision: 1.31 $
68  */

69 public class Group extends DSpaceObject
70 {
71     // findAll sortby types
72
public static final int ID = 0; // sort by ID
73

74     public static final int NAME = 1; // sort by NAME (default)
75

76     /** log4j logger */
77     private static Logger log = Logger.getLogger(Group.class);
78
79     /** Our context */
80     private Context myContext;
81
82     /** The row in the table representing this object */
83     private TableRow myRow;
84
85     /** lists of epeople and groups in the group */
86     private List JavaDoc epeople = new ArrayList JavaDoc();
87
88     private List JavaDoc groups = new ArrayList JavaDoc();
89
90     /** lists that need to be written out again */
91     private boolean epeopleChanged = false;
92
93     private boolean groupsChanged = false;
94
95     /** is this just a stub, or is all data loaded? */
96     private boolean isDataLoaded = false;
97
98     /**
99      * Construct a Group from a given context and tablerow
100      *
101      * @param context
102      * @param row
103      */

104     Group(Context context, TableRow row) throws SQLException JavaDoc
105     {
106         myContext = context;
107         myRow = row;
108
109         // Cache ourselves
110
context.cache(this, row.getIntColumn("eperson_group_id"));
111     }
112
113     /**
114      * Populate Group with eperson and group objects
115      *
116      * @param context
117      * @throws SQLException
118      */

119     public void loadData()
120     {
121         // only populate if not already populated
122
if (!isDataLoaded)
123         {
124             // naughty thing to do - swallowing SQL exception and throwing it as
125
// a RuntimeException - a hack to avoid changing the API all over
126
// the place
127
try
128             {
129                 // get epeople objects
130
TableRowIterator tri = DatabaseManager.queryTable(myContext,"eperson",
131                                 "SELECT eperson.* FROM eperson, epersongroup2eperson WHERE " +
132                                 "epersongroup2eperson.eperson_id=eperson.eperson_id AND " +
133                                 "epersongroup2eperson.eperson_group_id= ?",
134                                 myRow.getIntColumn("eperson_group_id"));
135
136                 while (tri.hasNext())
137                 {
138                     TableRow r = (TableRow) tri.next();
139
140                     // First check the cache
141
EPerson fromCache = (EPerson) myContext.fromCache(
142                             EPerson.class, r.getIntColumn("eperson_id"));
143
144                     if (fromCache != null)
145                     {
146                         epeople.add(fromCache);
147                     }
148                     else
149                     {
150                         epeople.add(new EPerson(myContext, r));
151                     }
152                 }
153
154                 tri.close();
155                 
156                 // now get Group objects
157
tri = DatabaseManager.queryTable(myContext,"epersongroup",
158                                 "SELECT epersongroup.* FROM epersongroup, group2group WHERE " +
159                                 "group2group.child_id=epersongroup.eperson_group_id AND "+
160                                 "group2group.parent_id= ? ",
161                                 myRow.getIntColumn("eperson_group_id"));
162
163                 while (tri.hasNext())
164                 {
165                     TableRow r = (TableRow) tri.next();
166
167                     // First check the cache
168
Group fromCache = (Group) myContext.fromCache(Group.class,
169                             r.getIntColumn("eperson_group_id"));
170
171                     if (fromCache != null)
172                     {
173                         groups.add(fromCache);
174                     }
175                     else
176                     {
177                         groups.add(new Group(myContext, r));
178                     }
179                 }
180                 
181                 tri.close();
182
183             }
184             catch (Exception JavaDoc e)
185             {
186                 throw new RuntimeException JavaDoc(e);
187             }
188             isDataLoaded = true;
189         }
190     }
191
192     /**
193      * Create a new group
194      *
195      * @param context
196      * DSpace context object
197      */

198     public static Group create(Context context) throws SQLException JavaDoc,
199             AuthorizeException
200     {
201         // FIXME - authorization?
202
if (!AuthorizeManager.isAdmin(context))
203         {
204             throw new AuthorizeException(
205                     "You must be an admin to create an EPerson Group");
206         }
207
208         // Create a table row
209
TableRow row = DatabaseManager.create(context, "epersongroup");
210
211         Group g = new Group(context, row);
212
213         log.info(LogManager.getHeader(context, "create_group", "group_id="
214                 + g.getID()));
215
216         return g;
217     }
218
219     /**
220      * get the ID of the group object
221      *
222      * @return id
223      */

224     public int getID()
225     {
226         return myRow.getIntColumn("eperson_group_id");
227     }
228
229     /**
230      * get name of group
231      *
232      * @return name
233      */

234     public String JavaDoc getName()
235     {
236         return myRow.getStringColumn("name");
237     }
238
239     /**
240      * set name of group
241      *
242      * @param name
243      * new group name
244      */

245     public void setName(String JavaDoc name)
246     {
247         myRow.setColumn("name", name);
248     }
249
250     /**
251      * add an eperson member
252      *
253      * @param e
254      * eperson
255      */

256     public void addMember(EPerson e)
257     {
258         loadData(); // make sure Group has data loaded
259

260         if (isMember(e))
261         {
262             return;
263         }
264
265         epeople.add(e);
266         epeopleChanged = true;
267     }
268
269     /**
270      * add group to this group
271      *
272      * @param g
273      */

274     public void addMember(Group g)
275     {
276         loadData(); // make sure Group has data loaded
277

278         // don't add if it's already a member
279
if (isMember(g))
280         {
281             return;
282         }
283
284         groups.add(g);
285         groupsChanged = true;
286     }
287
288     /**
289      * remove an eperson from a group
290      *
291      * @param e
292      * eperson
293      */

294     public void removeMember(EPerson e)
295     {
296         loadData(); // make sure Group has data loaded
297

298         if (epeople.remove(e))
299         {
300             epeopleChanged = true;
301         }
302     }
303
304     /**
305      * remove group from this group
306      *
307      * @param g
308      */

309     public void removeMember(Group g)
310     {
311         loadData(); // make sure Group has data loaded
312

313         if (groups.remove(g))
314         {
315             groupsChanged = true;
316         }
317     }
318
319     /**
320      * check to see if an eperson is a member
321      *
322      * @param e
323      * eperson to check membership
324      */

325     public boolean isMember(EPerson e)
326     {
327         // special, group 0 is anonymous
328
if (getID() == 0)
329         {
330             return true;
331         }
332
333         loadData(); // make sure Group has data loaded
334

335         return epeople.contains(e);
336     }
337
338     /**
339      * check to see if group is a member
340      *
341      * @param g
342      * group to check
343      * @return
344      */

345     public boolean isMember(Group g)
346     {
347         loadData(); // make sure Group has data loaded
348

349         return groups.contains(g);
350     }
351
352     /**
353      * fast check to see if an eperson is a member called with eperson id, does
354      * database lookup without instantiating all of the epeople objects and is
355      * thus a static method
356      *
357      * @param c
358      * context
359      * @param groupid
360      * group ID to check
361      */

362     public static boolean isMember(Context c, int groupid) throws SQLException JavaDoc
363     {
364         // special, everyone is member of group 0 (anonymous)
365
if (groupid == 0)
366         {
367             return true;
368         }
369
370         // first, check for membership if it's a special group
371
// (special groups can be set even if person isn't authenticated)
372
if (c.inSpecialGroup(groupid))
373         {
374             return true;
375         }
376
377         EPerson currentuser = c.getCurrentUser();
378
379         // only test for membership if context contains a user
380
if (currentuser != null)
381         {
382             return epersonInGroup(c, groupid, currentuser);
383         }
384
385         // currentuser not set, return FALSE
386
return false;
387     }
388
389     /**
390      * Get all of the groups that an eperson is a member of
391      *
392      * @param c
393      * @param e
394      * @return
395      * @throws SQLException
396      */

397     public static Group[] allMemberGroups(Context c, EPerson e)
398             throws SQLException JavaDoc
399     {
400         List JavaDoc groupList = new ArrayList JavaDoc();
401
402         Set JavaDoc myGroups = allMemberGroupIDs(c, e);
403         // now convert those Integers to Groups
404
Iterator JavaDoc i = myGroups.iterator();
405
406         while (i.hasNext())
407         {
408             groupList.add(Group.find(c, ((Integer JavaDoc) i.next()).intValue()));
409         }
410
411         return (Group[]) groupList.toArray(new Group[0]);
412     }
413
414     /**
415      * get Set of Integers all of the group memberships for an eperson
416      *
417      * @param c
418      * @param e
419      * @return Set of Integer groupIDs
420      * @throws SQLException
421      */

422     public static Set JavaDoc allMemberGroupIDs(Context c, EPerson e)
423             throws SQLException JavaDoc
424     {
425         // two queries - first to get groups eperson is a member of
426
// second query gets parent groups for groups eperson is a member of
427

428         TableRowIterator tri = DatabaseManager.queryTable(c, "epersongroup2eperson",
429                 "SELECT * FROM epersongroup2eperson WHERE eperson_id= ?",
430                  e.getID());
431
432         Set JavaDoc groupIDs = new HashSet JavaDoc();
433
434         while (tri.hasNext())
435         {
436             TableRow row = tri.next();
437
438             int childID = row.getIntColumn("eperson_group_id");
439
440             groupIDs.add(new Integer JavaDoc(childID));
441         }
442         
443         tri.close();
444
445         // Also need to get all "Special Groups" user is a member of!
446
// Otherwise, you're ignoring the user's membership to these groups!
447
Group[] specialGroups = c.getSpecialGroups();
448         for(int j=0; j<specialGroups.length;j++)
449             groupIDs.add(new Integer JavaDoc(specialGroups[j].getID()));
450         
451         // now we have all owning groups, also grab all parents of owning groups
452
// yes, I know this could have been done as one big query and a union,
453
// but doing the Oracle port taught me to keep to simple SQL!
454

455         String JavaDoc groupQuery = "";
456
457         Iterator JavaDoc i = groupIDs.iterator();
458
459         // Build a list of query parameters
460
Object JavaDoc[] parameters = new Object JavaDoc[groupIDs.size()];
461         int idx = 0;
462         while (i.hasNext())
463         {
464             int groupID = ((Integer JavaDoc) i.next()).intValue();
465
466             parameters[idx++] = new Integer JavaDoc(groupID);
467             
468             groupQuery += "child_id= ? ";
469             if (i.hasNext())
470                 groupQuery += " OR ";
471         }
472
473         if ("".equals(groupQuery))
474         {
475             // don't do query, isn't member of any groups
476
return groupIDs;
477         }
478         
479         // was member of at least one group
480
// NOTE: even through the query is built dynamicaly all data is seperated into the
481
// the parameters array.
482
tri = DatabaseManager.queryTable(c, "group2groupcache",
483                 "SELECT * FROM group2groupcache WHERE " + groupQuery,
484                 parameters);
485
486         while (tri.hasNext())
487         {
488             TableRow row = tri.next();
489
490             int parentID = row.getIntColumn("parent_id");
491
492             groupIDs.add(new Integer JavaDoc(parentID));
493         }
494         
495         tri.close();
496
497         return groupIDs;
498     }
499     
500     
501     /**
502      * Get all of the epeople who are a member of the
503      * specified group, or a member of a sub-group of the
504      * specified group, etc.
505      *
506      * @param c
507      * DSpace context
508      * @param g
509      * Group object
510      * @return Array of EPerson objects
511      * @throws SQLException
512      */

513     public static EPerson[] allMembers(Context c, Group g)
514             throws SQLException JavaDoc
515     {
516         List JavaDoc epersonList = new ArrayList JavaDoc();
517
518         Set JavaDoc myEpeople = allMemberIDs(c, g);
519         // now convert those Integers to EPerson objects
520
Iterator JavaDoc i = myEpeople.iterator();
521
522         while (i.hasNext())
523         {
524             epersonList.add(EPerson.find(c, ((Integer JavaDoc) i.next()).intValue()));
525         }
526
527         return (EPerson[]) epersonList.toArray(new EPerson[0]);
528     }
529
530     /**
531      * Get Set of all Integers all of the epeople
532      * members for a group
533      *
534      * @param c
535      * DSpace context
536      * @param g
537      * Group object
538      * @return Set of Integer epersonIDs
539      * @throws SQLException
540      */

541     public static Set JavaDoc allMemberIDs(Context c, Group g)
542             throws SQLException JavaDoc
543     {
544         // two queries - first to get all groups which are a member of this group
545
// second query gets all members of each group in the first query
546
Set JavaDoc epeopleIDs = new HashSet JavaDoc();
547         
548         // Get all groups which are a member of this group
549
TableRowIterator tri = DatabaseManager.queryTable(c, "group2groupcache",
550                 "SELECT * FROM group2groupcache WHERE parent_id= ? ",
551                 g.getID());
552         
553         Set JavaDoc groupIDs = new HashSet JavaDoc();
554
555         while (tri.hasNext())
556         {
557             TableRow row = tri.next();
558
559             int childID = row.getIntColumn("child_id");
560
561             groupIDs.add(new Integer JavaDoc(childID));
562         }
563         
564         tri.close();
565
566         // now we have all the groups (including this one)
567
// it is time to find all the EPeople who belong to those groups
568
// and filter out all duplicates
569

570         Object JavaDoc[] parameters = new Object JavaDoc[groupIDs.size()+1];
571         int idx = 0;
572         Iterator JavaDoc i = groupIDs.iterator();
573
574         // don't forget to add the current group to this query!
575
parameters[idx++] = new Integer JavaDoc(g.getID());
576         String JavaDoc epersonQuery = "eperson_group_id= ? ";
577         if (i.hasNext())
578             epersonQuery += " OR ";
579         
580         while (i.hasNext())
581         {
582             int groupID = ((Integer JavaDoc) i.next()).intValue();
583             parameters[idx++] = new Integer JavaDoc(groupID);
584             
585             epersonQuery += "eperson_group_id= ? ";
586             if (i.hasNext())
587                 epersonQuery += " OR ";
588         }
589
590         //get all the EPerson IDs
591
// Note: even through the query is dynamicaly built all data is seperated
592
// into the parameters array.
593
tri = DatabaseManager.queryTable(c, "epersongroup2eperson",
594                 "SELECT * FROM epersongroup2eperson WHERE " + epersonQuery,
595                 parameters);
596
597         while (tri.hasNext())
598         {
599             TableRow row = tri.next();
600
601             int epersonID = row.getIntColumn("eperson_id");
602    
603             epeopleIDs.add(new Integer JavaDoc(epersonID));
604         }
605         
606         tri.close();
607
608         return epeopleIDs;
609     }
610
611     private static boolean epersonInGroup(Context c, int groupID, EPerson e)
612             throws SQLException JavaDoc
613     {
614         Set JavaDoc groupIDs = Group.allMemberGroupIDs(c, e);
615
616         return groupIDs.contains(new Integer JavaDoc(groupID));
617     }
618
619     /**
620      * find the group by its ID
621      *
622      * @param context
623      * @param id
624      */

625     public static Group find(Context context, int id) throws SQLException JavaDoc
626     {
627         // First check the cache
628
Group fromCache = (Group) context.fromCache(Group.class, id);
629
630         if (fromCache != null)
631         {
632             return fromCache;
633         }
634
635         TableRow row = DatabaseManager.find(context, "epersongroup", id);
636
637         if (row == null)
638         {
639             return null;
640         }
641         else
642         {
643             return new Group(context, row);
644         }
645     }
646
647     /**
648      * Find the group by its name - assumes name is unique
649      *
650      * @param context
651      * @param name
652      *
653      * @return Group
654      */

655     public static Group findByName(Context context, String JavaDoc name)
656             throws SQLException JavaDoc
657     {
658         TableRow row = DatabaseManager.findByUnique(context, "epersongroup",
659                 "name", name);
660
661         if (row == null)
662         {
663             return null;
664         }
665         else
666         {
667             // First check the cache
668
Group fromCache = (Group) context.fromCache(Group.class, row
669                     .getIntColumn("eperson_group_id"));
670
671             if (fromCache != null)
672             {
673                 return fromCache;
674             }
675             else
676             {
677                 return new Group(context, row);
678             }
679         }
680     }
681
682     /**
683      * Finds all groups in the site
684      *
685      * @param context
686      * DSpace context
687      * @param sortField
688      * field to sort by -- Group.ID or Group.NAME
689      *
690      * @return array of all groups in the site
691      */

692     public static Group[] findAll(Context context, int sortField)
693             throws SQLException JavaDoc
694     {
695         String JavaDoc s;
696
697         switch (sortField)
698         {
699         case ID:
700             s = "eperson_group_id";
701
702             break;
703
704         case NAME:
705             s = "name";
706
707             break;
708
709         default:
710             s = "name";
711         }
712
713         // NOTE: The use of 's' in the order by clause can not cause an sql
714
// injection because the string is derived from constant values above.
715
TableRowIterator rows = DatabaseManager.queryTable(
716                 context, "epersongroup",
717                 "SELECT * FROM epersongroup ORDER BY "+s);
718
719         List JavaDoc gRows = rows.toList();
720
721         Group[] groups = new Group[gRows.size()];
722
723         for (int i = 0; i < gRows.size(); i++)
724         {
725             TableRow row = (TableRow) gRows.get(i);
726
727             // First check the cache
728
Group fromCache = (Group) context.fromCache(Group.class, row
729                     .getIntColumn("eperson_group_id"));
730
731             if (fromCache != null)
732             {
733                 groups[i] = fromCache;
734             }
735             else
736             {
737                 groups[i] = new Group(context, row);
738             }
739         }
740
741         return groups;
742     }
743     
744     
745     /**
746      * Find the groups that match the search query across eperson_group_id or name
747      *
748      * @param context
749      * DSpace context
750      * @param query
751      * The search string
752      *
753      * @return array of Group objects
754      */

755     public static Group[] search(Context context, String JavaDoc query)
756             throws SQLException JavaDoc
757     {
758         return search(context, query, -1, -1);
759     }
760     
761     /**
762      * Find the groups that match the search query across eperson_group_id or name
763      *
764      * @param context
765      * DSpace context
766      * @param query
767      * The search string
768      * @param offset
769      * Inclusive offset
770      * @param limit
771      * Maximum number of matches returned
772      *
773      * @return array of Group objects
774      */

775     public static Group[] search(Context context, String JavaDoc query, int offset, int limit)
776             throws SQLException JavaDoc
777     {
778         String JavaDoc params = "%"+query.toLowerCase()+"%";
779         String JavaDoc dbquery = "SELECT * FROM epersongroup WHERE name ILIKE ? OR eperson_group_id = ? ORDER BY name ASC ";
780         
781         if (offset >= 0 && limit > 0) {
782             dbquery += "LIMIT " + limit + " OFFSET " + offset;
783         }
784         
785         // When checking against the eperson-id, make sure the query can be made into a number
786
Integer JavaDoc int_param;
787         try {
788             int_param = Integer.valueOf(query);
789         }
790         catch (NumberFormatException JavaDoc e) {
791             int_param = new Integer JavaDoc(-1);
792         }
793         
794         TableRowIterator rows =
795             DatabaseManager.query(context, dbquery, new Object JavaDoc[]{params, int_param});
796         
797         List JavaDoc groupRows = rows.toList();
798         Group[] groups = new Group[groupRows.size()];
799         
800         for (int i = 0; i < groupRows.size(); i++)
801         {
802             TableRow row = (TableRow) groupRows.get(i);
803     
804             // First check the cache
805
Group fromCache = (Group) context.fromCache(Group.class, row
806                     .getIntColumn("eperson_group_id"));
807     
808             if (fromCache != null)
809             {
810                 groups[i] = fromCache;
811             }
812             else
813             {
814                 groups[i] = new Group(context, row);
815             }
816         }
817         return groups;
818     }
819
820     /**
821      * Returns the total number of groups returned by a specific query, without the overhead
822      * of creating the Group objects to store the results.
823      *
824      * @param context
825      * DSpace context
826      * @param query
827      * The search string
828      *
829      * @return the number of groups mathching the query
830      */

831     public static int searchResultCount(Context context, String JavaDoc query)
832         throws SQLException JavaDoc
833     {
834         String JavaDoc params = "%"+query.toLowerCase()+"%";
835         String JavaDoc dbquery = "SELECT count(*) as count FROM epersongroup WHERE name ILIKE ? OR eperson_group_id = ? ";
836         
837         // When checking against the eperson-id, make sure the query can be made into a number
838
Integer JavaDoc int_param;
839         try {
840             int_param = Integer.valueOf(query);
841         }
842         catch (NumberFormatException JavaDoc e) {
843             int_param = new Integer JavaDoc(-1);
844         }
845         
846         // Get all the epeople that match the query
847
TableRow row = DatabaseManager.querySingle(context, dbquery, new Object JavaDoc[] {params, int_param});
848         
849         // use getIntColumn for Oracle count data
850
Long JavaDoc count;
851         if ("oracle".equals(ConfigurationManager.getProperty("db.name")))
852         {
853             count = new Long JavaDoc(row.getIntColumn("count"));
854         }
855         else //getLongColumn works for postgres
856
{
857             count = new Long JavaDoc(row.getLongColumn("count"));
858         }
859
860         return count.intValue();
861     }
862     
863     
864     /**
865      * Delete a group
866      *
867      */

868     public void delete() throws SQLException JavaDoc
869     {
870         // FIXME: authorizations
871
// Remove from cache
872
myContext.removeCached(this, getID());
873
874         // Remove any ResourcePolicies that reference this group
875
AuthorizeManager.removeGroupPolicies(myContext, getID());
876
877         // Remove any group memberships first
878
DatabaseManager.updateQuery(myContext,
879                 "DELETE FROM EPersonGroup2EPerson WHERE eperson_group_id= ? ",
880                 getID());
881
882         // remove any group2groupcache entries
883
DatabaseManager.updateQuery(myContext,
884                 "DELETE FROM group2groupcache WHERE parent_id= ? OR child_id= ? ",
885                 getID(),getID());
886
887         // Now remove any group2group assignments
888
DatabaseManager.updateQuery(myContext,
889                 "DELETE FROM group2group WHERE parent_id= ? OR child_id= ? ",
890                 getID(),getID());
891
892         // don't forget the new table
893
deleteEpersonGroup2WorkspaceItem();
894
895         // Remove ourself
896
DatabaseManager.delete(myContext, myRow);
897
898         epeople.clear();
899
900         log.info(LogManager.getHeader(myContext, "delete_group", "group_id="
901                 + getID()));
902     }
903
904     /**
905      * @throws SQLException
906      */

907     private void deleteEpersonGroup2WorkspaceItem() throws SQLException JavaDoc
908     {
909         DatabaseManager.updateQuery(myContext,
910                 "DELETE FROM EPersonGroup2WorkspaceItem WHERE eperson_group_id= ? ",
911                 getID());
912     }
913
914     /**
915      * Return EPerson members of a Group
916      */

917     public EPerson[] getMembers()
918     {
919         loadData(); // make sure all data is loaded
920

921         EPerson[] myArray = new EPerson[epeople.size()];
922         myArray = (EPerson[]) epeople.toArray(myArray);
923
924         return myArray;
925     }
926    
927     /**
928      * Return Group members of a Group
929      *
930      * @return
931      */

932     public Group[] getMemberGroups()
933     {
934         loadData(); // make sure all data is loaded
935

936         Group[] myArray = new Group[groups.size()];
937         myArray = (Group[]) groups.toArray(myArray);
938
939         return myArray;
940     }
941     
942     /**
943      * Return true if group has no members
944      */

945     public boolean isEmpty()
946     {
947         loadData(); // make sure all data is loaded
948

949         if ((epeople.size() == 0) && (groups.size() == 0))
950         {
951             return true;
952         }
953         else
954         {
955             return false;
956         }
957     }
958
959     /**
960      * Update the group - writing out group object and EPerson list if necessary
961      */

962     public void update() throws SQLException JavaDoc, AuthorizeException
963     {
964         // FIXME: Check authorisation
965
DatabaseManager.update(myContext, myRow);
966
967         // Redo eperson mappings if they've changed
968
if (epeopleChanged)
969         {
970             // Remove any existing mappings
971
DatabaseManager.updateQuery(myContext,
972                     "delete from epersongroup2eperson where eperson_group_id= ? ",
973                     getID());
974
975             // Add new mappings
976
Iterator JavaDoc i = epeople.iterator();
977
978             while (i.hasNext())
979             {
980                 EPerson e = (EPerson) i.next();
981
982                 TableRow mappingRow = DatabaseManager.create(myContext,
983                         "epersongroup2eperson");
984                 mappingRow.setColumn("eperson_id", e.getID());
985                 mappingRow.setColumn("eperson_group_id", getID());
986                 DatabaseManager.update(myContext, mappingRow);
987             }
988
989             epeopleChanged = false;
990         }
991
992         // Redo Group mappings if they've changed
993
if (groupsChanged)
994         {
995             // Remove any existing mappings
996
DatabaseManager.updateQuery(myContext,
997                     "delete from group2group where parent_id= ? ",
998                     getID());
999
1000            // Add new mappings
1001
Iterator JavaDoc i = groups.iterator();
1002
1003            while (i.hasNext())
1004            {
1005                Group g = (Group) i.next();
1006
1007                TableRow mappingRow = DatabaseManager.create(myContext,
1008                        "group2group");
1009                mappingRow.setColumn("parent_id", getID());
1010                mappingRow.setColumn("child_id", g.getID());
1011                DatabaseManager.update(myContext, mappingRow);
1012            }
1013
1014            // groups changed, now change group cache
1015
rethinkGroupCache();
1016
1017            groupsChanged = false;
1018        }
1019
1020        log.info(LogManager.getHeader(myContext, "update_group", "group_id="
1021                + getID()));
1022    }
1023
1024    /**
1025     * Return <code>true</code> if <code>other</code> is the same Group as
1026     * this object, <code>false</code> otherwise
1027     *
1028     * @param other
1029     * object to compare to
1030     *
1031     * @return <code>true</code> if object passed in represents the same group
1032     * as this object
1033     */

1034    public boolean equals(Object JavaDoc other)
1035    {
1036        if (!(other instanceof Group))
1037        {
1038            return false;
1039        }
1040
1041        return (getID() == ((Group) other).getID());
1042    }
1043
1044    public int getType()
1045    {
1046        return Constants.GROUP;
1047    }
1048
1049    public String JavaDoc getHandle()
1050    {
1051        return null;
1052    }
1053
1054    /**
1055     * Regenerate the group cache AKA the group2groupcache table in the database -
1056     * meant to be called when a group is added or removed from another group
1057     *
1058     */

1059    private void rethinkGroupCache() throws SQLException JavaDoc
1060    {
1061        // read in the group2group table
1062
TableRowIterator tri = DatabaseManager.queryTable(myContext, "group2group",
1063                "SELECT * FROM group2group");
1064
1065        Map JavaDoc parents = new HashMap JavaDoc();
1066
1067        while (tri.hasNext())
1068        {
1069            TableRow row = (TableRow) tri.next();
1070
1071            Integer JavaDoc parentID = new Integer JavaDoc(row.getIntColumn("parent_id"));
1072            Integer JavaDoc childID = new Integer JavaDoc(row.getIntColumn("child_id"));
1073
1074            // if parent doesn't have an entry, create one
1075
if (!parents.containsKey(parentID))
1076            {
1077                Set JavaDoc children = new HashSet JavaDoc();
1078
1079                // add child id to the list
1080
children.add(childID);
1081                parents.put(parentID, children);
1082            }
1083            else
1084            {
1085                // parent has an entry, now add the child to the parent's record
1086
// of children
1087
Set JavaDoc children = (Set JavaDoc) parents.get(parentID);
1088                children.add(childID);
1089            }
1090        }
1091        
1092        tri.close();
1093
1094        // now parents is a hash of all of the IDs of groups that are parents
1095
// and each hash entry is a hash of all of the IDs of children of those
1096
// parent groups
1097
// so now to establish all parent,child relationships we can iterate
1098
// through the parents hash
1099

1100        Iterator JavaDoc i = parents.keySet().iterator();
1101
1102        while (i.hasNext())
1103        {
1104            Integer JavaDoc parentID = (Integer JavaDoc) i.next();
1105
1106            Set JavaDoc myChildren = getChildren(parents, parentID);
1107
1108            Iterator JavaDoc j = myChildren.iterator();
1109
1110            while (j.hasNext())
1111            {
1112                // child of a parent
1113
Integer JavaDoc childID = (Integer JavaDoc) j.next();
1114
1115                ((Set JavaDoc) parents.get(parentID)).add(childID);
1116            }
1117        }
1118
1119        // empty out group2groupcache table
1120
DatabaseManager.updateQuery(myContext,
1121                "DELETE FROM group2groupcache WHERE id >= 0");
1122
1123        // write out new one
1124
Iterator JavaDoc pi = parents.keySet().iterator(); // parent iterator
1125

1126        while (pi.hasNext())
1127        {
1128            Integer JavaDoc parent = (Integer JavaDoc) pi.next();
1129
1130            Set JavaDoc children = (Set JavaDoc) parents.get(parent);
1131            Iterator JavaDoc ci = children.iterator(); // child iterator
1132

1133            while (ci.hasNext())
1134            {
1135                Integer JavaDoc child = (Integer JavaDoc) ci.next();
1136
1137                TableRow row = DatabaseManager.create(myContext,
1138                        "group2groupcache");
1139
1140                int parentID = parent.intValue();
1141                int childID = child.intValue();
1142
1143                row.setColumn("parent_id", parentID);
1144                row.setColumn("child_id", childID);
1145
1146                DatabaseManager.update(myContext, row);
1147            }
1148        }
1149    }
1150
1151    /**
1152     * Used recursively to generate a map of ALL of the children of the given
1153     * parent
1154     *
1155     * @param parents
1156     * Map of parent,child relationships
1157     * @param parent
1158     * the parent you're interested in
1159     * @return Map whose keys are all of the children of a parent
1160     */

1161    private Set JavaDoc getChildren(Map JavaDoc parents, Integer JavaDoc parent)
1162    {
1163        Set JavaDoc myChildren = new HashSet JavaDoc();
1164
1165        // degenerate case, this parent has no children
1166
if (!parents.containsKey(parent))
1167            return myChildren;
1168
1169        // got this far, so we must have children
1170
Set JavaDoc children = (Set JavaDoc) parents.get(parent);
1171
1172        // now iterate over all of the children
1173
Iterator JavaDoc i = children.iterator();
1174
1175        while (i.hasNext())
1176        {
1177            Integer JavaDoc childID = (Integer JavaDoc) i.next();
1178
1179            // add this child's ID to our return set
1180
myChildren.add(childID);
1181
1182            // and now its children
1183
myChildren.addAll(getChildren(parents, childID));
1184        }
1185
1186        return myChildren;
1187    }
1188}
1189
Popular Tags