001: /* Copyright 2002 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;
007:
008: import java.util.ArrayList;
009: import java.util.Collection;
010: import java.util.HashMap;
011: import java.util.Iterator;
012: import java.util.List;
013: import java.util.Map;
014:
015: import javax.naming.Name;
016:
017: import org.jasig.portal.EntityIdentifier;
018: import org.jasig.portal.concurrency.CachingException;
019: import org.jasig.portal.concurrency.IEntityLock;
020: import org.jasig.portal.concurrency.LockingException;
021: import org.jasig.portal.services.EntityCachingService;
022: import org.jasig.portal.services.EntityLockService;
023: import org.jasig.portal.services.GroupService;
024: import org.apache.commons.logging.Log;
025: import org.apache.commons.logging.LogFactory;
026:
027: /**
028: * Reference individual, or leaf, group service.
029: *
030: * @author Dan Ellentuck
031: * @version $Revision: 35418 $
032: */
033: public class ReferenceIndividualGroupService extends
034: ReferenceCompositeGroupService implements
035: IIndividualGroupService, ILockableGroupService {
036:
037: private static final Log log = LogFactory
038: .getLog(ReferenceIndividualGroupService.class);
039:
040: // Describes the attributes of this service. See compositeGroupServices.xml.
041: protected ComponentGroupServiceDescriptor serviceDescriptor;
042:
043: protected IEntityGroupStore groupFactory;
044:
045: // Entity searcher
046: protected IEntitySearcher entitySearcher;
047:
048: /**
049: * ReferenceGroupsService constructor.
050: */
051: public ReferenceIndividualGroupService() throws GroupsException {
052: this (new ComponentGroupServiceDescriptor());
053: }
054:
055: /**
056: * ReferenceGroupsService constructor.
057: */
058: public ReferenceIndividualGroupService(
059: ComponentGroupServiceDescriptor svcDescriptor)
060: throws GroupsException {
061: super ();
062: serviceDescriptor = svcDescriptor;
063: initialize();
064: }
065:
066: /**
067: * Answers if <code>IGroupMembers</code> are being cached.
068: */
069: protected boolean cacheInUse() {
070: return getServiceDescriptor().isCachingEnabled();
071: }
072:
073: /**
074: * Removes the <code>IEntityGroup</code> from the cache and the store.
075: * @param group IEntityGroup
076: */
077: public void deleteGroup(IEntityGroup group) throws GroupsException {
078: throwExceptionIfNotInternallyManaged();
079: synchronizeGroupMembersOnDelete(group);
080: getGroupStore().delete(group);
081: if (cacheInUse()) {
082: cacheRemove(group);
083: }
084: }
085:
086: /**
087: * Removes the <code>ILockableEntityGroup</code> from its containing groups.
088: * The <code>finally</code> block tries to release any groups that are still
089: * locked, which can occur if an attempt to remove the group from one of
090: * its containing groups fails and throws a GroupsException. In this event,
091: * we do not try to roll back any successful removes, since that would probably
092: * fail anyway.
093: * @param group ILockableEntityGroup
094: */
095: private void removeDeletedGroupFromContainingGroups(
096: ILockableEntityGroup group) throws GroupsException {
097: Iterator itr;
098: IEntityGroup containingGroup = null;
099: ILockableEntityGroup lockableGroup = null;
100: IEntityLock lock = null;
101: List lockableGroups = new ArrayList();
102: try {
103: String lockOwner = group.getLock().getLockOwner();
104: for (itr = group.getContainingGroups(); itr.hasNext();) {
105: containingGroup = (IEntityGroup) itr.next();
106: lockableGroup = GroupService.findLockableGroup(
107: containingGroup.getKey(), lockOwner);
108: if (lockableGroup != null) {
109: lockableGroups.add(lockableGroup);
110: }
111: }
112: for (itr = lockableGroups.iterator(); itr.hasNext();) {
113: lockableGroup = (ILockableEntityGroup) itr.next();
114: lockableGroup.removeMember(group);
115: lockableGroup.updateMembers();
116: }
117: } catch (GroupsException ge) {
118: throw new GroupsException("Could not remove deleted group "
119: + group.getKey() + " from parent", ge);
120: } finally {
121: for (itr = lockableGroups.iterator(); itr.hasNext();) {
122: lock = ((ILockableEntityGroup) itr.next()).getLock();
123: try {
124: if (lock.isValid()) {
125: lock.release();
126: }
127: } catch (LockingException le) {
128: log.error(
129: "ReferenceIndividualGroupService.removeDeletedGroupFromContainingGroups(): "
130: + "Problem unlocking parent group",
131: le);
132: }
133: }
134: }
135: }
136:
137: /**
138: * Removes the <code>ILockableEntityGroup</code> from the cache and the store,
139: * including both parent and child memberships.
140: * @param group ILockableEntityGroup
141: */
142: public void deleteGroup(ILockableEntityGroup group)
143: throws GroupsException {
144: throwExceptionIfNotInternallyManaged();
145: try {
146: if (group.getLock().isValid()) {
147: removeDeletedGroupFromContainingGroups(group);
148: deleteGroup((IEntityGroup) group);
149: } else {
150: throw new GroupsException("Could not delete group "
151: + group.getKey() + " has invalid lock.");
152: }
153: } catch (LockingException le) {
154: throw new GroupsException("Could not delete group "
155: + group.getKey(), le);
156: } finally {
157: try {
158: group.getLock().release();
159: } catch (LockingException le) {
160: }
161: }
162: }
163:
164: private EntityIdentifier[] filterEntities(
165: EntityIdentifier[] entities, IEntityGroup ancestor)
166: throws GroupsException {
167: ArrayList ar = new ArrayList(entities.length);
168: for (int i = 0; i < entities.length; i++) {
169: IGroupMember gm = this .getGroupMember(entities[i]);
170: if (ancestor.deepContains(gm)) {
171: ar.add(entities[i]);
172: }
173: }
174: return (EntityIdentifier[]) ar.toArray(new EntityIdentifier[0]);
175: }
176:
177: /**
178: * Returns and caches the containing groups for the <code>IGroupMember</code>
179: * @param gm IGroupMember
180: */
181: public Iterator findContainingGroups(IGroupMember gm)
182: throws GroupsException {
183: Collection groups = new ArrayList(10);
184: IEntityGroup group = null;
185: for (Iterator it = getGroupStore().findContainingGroups(gm); it
186: .hasNext();) {
187: group = (IEntityGroup) it.next();
188: group.setLocalGroupService(this );
189: groups.add(group);
190: if (cacheInUse()) {
191: try {
192: if (getGroupFromCache(group.getEntityIdentifier()
193: .getKey()) == null) {
194: cacheAdd(group);
195: }
196: } catch (CachingException ce) {
197: throw new GroupsException(
198: "Problem finding containing groups", ce);
199: }
200: }
201: }
202: return groups.iterator();
203: }
204:
205: /**
206: * Returns a pre-existing <code>IEntityGroup</code> or null if it
207: * does not exist.
208: */
209: public IEntityGroup findGroup(String key) throws GroupsException {
210: return findGroup(newCompositeEntityIdentifier(key));
211: }
212:
213: /**
214: * Returns a pre-existing <code>IEntityGroup</code> or null if it
215: * does not exist.
216: */
217: public IEntityGroup findGroup(CompositeEntityIdentifier ent)
218: throws GroupsException {
219: return (cacheInUse()) ? findGroupWithCache(ent.getKey())
220: : primFindGroup(ent.getLocalKey());
221: }
222:
223: /**
224: * Returns a pre-existing <code>IEntityGroup</code> or null if it
225: * does not exist.
226: */
227: protected IEntityGroup findGroupWithCache(String key)
228: throws GroupsException {
229: return findGroupWithCache(newCompositeEntityIdentifier(key));
230: }
231:
232: /**
233: * Returns a pre-existing <code>IEntityGroup</code> or null if it
234: * does not exist.
235: */
236: protected IEntityGroup findGroupWithCache(
237: CompositeEntityIdentifier ent) throws GroupsException {
238: try {
239: IEntityGroup group = getGroupFromCache(ent.getKey());
240: if (group == null) {
241: group = primFindGroup(ent.getLocalKey());
242: if (group != null) {
243: cacheAdd(group);
244: }
245: }
246: return group;
247: } catch (CachingException ce) {
248: throw new GroupsException("Problem retrieving group "
249: + ent.getKey(), ce);
250: }
251: }
252:
253: /**
254: * Returns a pre-existing <code>ILockableEntityGroup</code> or null if the
255: * group is not found.
256: */
257: public ILockableEntityGroup findGroupWithLock(String key,
258: String owner) throws GroupsException {
259: return findGroupWithLock(key, owner, 0);
260: }
261:
262: /**
263: * Returns a pre-existing <code>ILockableEntityGroup</code> or null if the
264: * group is not found.
265: */
266: public ILockableEntityGroup findGroupWithLock(String key,
267: String owner, int secs) throws GroupsException {
268:
269: throwExceptionIfNotInternallyManaged();
270:
271: Class groupType = org.jasig.portal.EntityTypes.GROUP_ENTITY_TYPE;
272: try {
273: IEntityLock lock = (secs == 0) ? EntityLockService
274: .instance().newWriteLock(groupType, key, owner)
275: : EntityLockService.instance().newWriteLock(
276: groupType, key, owner, secs);
277:
278: ILockableEntityGroup group = groupFactory.findLockable(key);
279: if (group == null) {
280: lock.release();
281: } else {
282: group.setLock(lock);
283: group.setLocalGroupService(this );
284: }
285:
286: return group;
287: } catch (LockingException le) {
288: throw new GroupsException("Problem getting lock for group "
289: + key, le);
290: }
291:
292: }
293:
294: /**
295: * Returns and caches the member groups for the <code>IEntityGroup</code>
296: * @param eg IEntityGroup
297: */
298: protected Iterator findLocalMemberGroups(IEntityGroup eg)
299: throws GroupsException {
300: Collection groups = new ArrayList(10);
301: IEntityGroup group = null;
302: for (Iterator it = getGroupStore().findMemberGroups(eg); it
303: .hasNext();) {
304: group = (IEntityGroup) it.next();
305: group.setLocalGroupService(this );
306: groups.add(group);
307: if (cacheInUse()) {
308: try {
309: if (getGroupFromCache(group.getEntityIdentifier()
310: .getKey()) == null) {
311: cacheAdd(group);
312: }
313: } catch (CachingException ce) {
314: throw new GroupsException(
315: "Problem finding member groups", ce);
316: }
317: }
318: }
319: return groups.iterator();
320: }
321:
322: /**
323: * Finds the <code>IEntities</code> that are members of <code>group</code>.
324: */
325: public Iterator findMemberEntities(IEntityGroup group)
326: throws GroupsException {
327: return getGroupStore().findEntitiesForGroup(group);
328: }
329:
330: /**
331: * Returns member groups for the <code>IEntityGroup</code>. First get the
332: * member groups that are local to this service. Then retrieve the keys of
333: * all of the member groups and ask the GroupService to find the groups
334: * we do not yet have.
335: *
336: * @param eg IEntityGroup
337: */
338: public Iterator findMemberGroups(IEntityGroup eg)
339: throws GroupsException {
340: Map groups = new HashMap();
341: IEntityGroup group = null;
342: for (Iterator itr = findLocalMemberGroups(eg); itr.hasNext();) {
343: group = (IEntityGroup) itr.next();
344: groups.put(group.getKey(), group);
345: }
346:
347: String[] memberGroupKeys = getGroupStore().findMemberGroupKeys(
348: eg);
349: for (int i = 0; i < memberGroupKeys.length; i++) {
350: if (!groups.containsKey(memberGroupKeys[i])) {
351: group = GroupService.findGroup(memberGroupKeys[i]);
352: if (group != null) {
353: groups.put(group.getKey(), group);
354: }
355: }
356: }
357: return groups.values().iterator();
358: }
359:
360: /**
361: * Returns and members for the <code>IEntityGroup</code>.
362: * @param eg IEntityGroup
363: */
364: public Iterator findMembers(IEntityGroup eg) throws GroupsException {
365: Collection members = new ArrayList(10);
366: Iterator it = null;
367:
368: for (it = findMemberGroups(eg); it.hasNext();) {
369: members.add(it.next());
370: }
371: for (it = findMemberEntities(eg); it.hasNext();) {
372: members.add(it.next());
373: }
374:
375: return members.iterator();
376: }
377:
378: /**
379: * Returns an <code>IEntity</code> representing a portal entity. This does
380: * not guarantee that the underlying entity actually exists.
381: */
382: public IEntity getEntity(String key, Class type)
383: throws GroupsException {
384: IEntity ent = primGetEntity(key, type);
385:
386: if (cacheInUse()) {
387: try {
388: IEntity cachedEnt = getEntityFromCache(ent
389: .getEntityIdentifier().getKey());
390: if (cachedEnt == null) {
391: cacheAdd(ent);
392: } else {
393: ent = cachedEnt;
394: }
395: } catch (CachingException ce) {
396: throw new GroupsException(
397: "Problem retrieving group member " + type + "("
398: + key + ")", ce);
399: }
400: }
401: return ent;
402: }
403:
404: /**
405: * Returns an <code>IEntity</code> representing a portal entity. This does
406: * not guarantee that the entity actually exists.
407: */
408: public IEntityStore getEntityFactory() {
409: return entityFactory;
410: }
411:
412: /**
413: * Returns a cached <code>IEntityGroup</code> or null if it has not been cached.
414: */
415: protected IEntityGroup getGroupFromCache(String key)
416: throws CachingException {
417: return (IEntityGroup) EntityCachingService.instance().get(
418: org.jasig.portal.EntityTypes.GROUP_ENTITY_TYPE, key);
419: }
420:
421: /**
422: * Returns an <code>IGroupMember</code> representing either a group or a
423: * portal entity. If the parm <code>type</code> is the group type,
424: * the <code>IGroupMember</code> is an <code>IEntityGroup</code> else it is
425: * an <code>IEntity</code>.
426: */
427: public IGroupMember getGroupMember(String key, Class type)
428: throws GroupsException {
429: IGroupMember gm = null;
430: if (type == org.jasig.portal.EntityTypes.GROUP_ENTITY_TYPE)
431: gm = findGroup(key);
432: else
433: gm = getEntity(key, type);
434: return gm;
435: }
436:
437: /**
438: * Returns an <code>IGroupMember</code> representing either a group or a
439: * portal entity, based on the <code>EntityIdentifier</code>, which
440: * refers to the UNDERLYING entity for the <code>IGroupMember</code>.
441: */
442: public IGroupMember getGroupMember(
443: EntityIdentifier underlyingEntityIdentifier)
444: throws GroupsException {
445: return getGroupMember(underlyingEntityIdentifier.getKey(),
446: underlyingEntityIdentifier.getType());
447: }
448:
449: /**
450: * Returns the implementation of <code>IEntityGroupStore</code> whose class name
451: * was retrieved by the PropertiesManager (see initialize()).
452: */
453: public IEntityGroupStore getGroupStore() throws GroupsException {
454: return groupFactory;
455: }
456:
457: /**
458: *
459: */
460: protected ComponentGroupServiceDescriptor getServiceDescriptor() {
461: return serviceDescriptor;
462: }
463:
464: /**
465: * @exception org.jasig.portal.groups.GroupsException
466: */
467: private void initialize() throws GroupsException {
468: String eMsg = null;
469: String svcName = getServiceDescriptor().getName();
470: if (log.isDebugEnabled())
471: log.debug("Service descriptor attributes: " + svcName);
472:
473: // print service descriptor attributes:
474: for (Iterator i = getServiceDescriptor().keySet().iterator(); i
475: .hasNext();) {
476: String descriptorKey = (String) i.next();
477: Object descriptorValue = getServiceDescriptor().get(
478: descriptorKey);
479: if (descriptorValue != null) {
480: if (log.isDebugEnabled())
481: log.debug(" " + descriptorKey + " : "
482: + descriptorValue);
483: }
484: }
485:
486: String groupStoreFactoryName = getServiceDescriptor()
487: .getGroupStoreFactoryName();
488: String entityStoreFactoryName = getServiceDescriptor()
489: .getEntityStoreFactoryName();
490: String entitySearcherFactoryName = getServiceDescriptor()
491: .getEntitySearcherFactoryName();
492:
493: if (groupStoreFactoryName == null) {
494: if (log.isInfoEnabled()) {
495: log
496: .info("ReferenceGroupService.initialize(): ("
497: + svcName
498: + ") No Group Store factory specified in service descriptor.");
499: }
500: }
501:
502: else {
503: try {
504: IEntityGroupStoreFactory groupStoreFactory = (IEntityGroupStoreFactory) Class
505: .forName(groupStoreFactoryName).newInstance();
506: groupFactory = groupStoreFactory
507: .newGroupStore(getServiceDescriptor());
508: } catch (Exception e) {
509: eMsg = "ReferenceIndividualGroupService.initialize(): Failed to instantiate group store ("
510: + svcName + "): " + e;
511: log.error(eMsg);
512: throw new GroupsException(eMsg);
513: }
514: }
515:
516: if (entityStoreFactoryName == null) {
517: if (log.isInfoEnabled())
518: log
519: .info("ReferenceIndividualGroupService.initialize(): "
520: + "No Entity Store Factory specified in service descriptor ("
521: + svcName + ")");
522: }
523:
524: else {
525: try {
526: IEntityStoreFactory entityStoreFactory = (IEntityStoreFactory) Class
527: .forName(entityStoreFactoryName).newInstance();
528: entityFactory = entityStoreFactory.newEntityStore();
529: } catch (Exception e) {
530: eMsg = "ReferenceIndividualGroupService.initialize(): Failed to instantiate entity store "
531: + e;
532: log.error(eMsg);
533: throw new GroupsException(eMsg);
534: }
535: }
536:
537: if (entitySearcherFactoryName == null) {
538: if (log.isInfoEnabled())
539: log
540: .info("ReferenceIndividualGroupService.initialize(): "
541: + "No Entity Searcher Factory specified in service descriptor.");
542: }
543:
544: else {
545: try {
546: IEntitySearcherFactory entitySearcherFactory = (IEntitySearcherFactory) Class
547: .forName(entitySearcherFactoryName)
548: .newInstance();
549: entitySearcher = entitySearcherFactory
550: .newEntitySearcher();
551: } catch (Exception e) {
552: eMsg = "ReferenceIndividualGroupService.initialize(): Failed to instantiate entity searcher "
553: + e;
554: log.error(eMsg);
555: throw new GroupsException(eMsg);
556: }
557: }
558:
559: }
560:
561: /**
562: * Answers if the group can be updated or deleted in the store.
563: */
564: public boolean isEditable(IEntityGroup group)
565: throws GroupsException {
566: return isInternallyManaged();
567: }
568:
569: /**
570: * Answers if this service is managed by the portal and is therefore
571: * updatable.
572: */
573: protected boolean isInternallyManaged() {
574: return getServiceDescriptor().isInternallyManaged();
575: }
576:
577: /**
578: * Answers if this service is a leaf in the composite; a service that
579: * actually operates on groups.
580: */
581: public boolean isLeafService() {
582: return true;
583: }
584:
585: /**
586: * Answers if this service is updateable by the portal.
587: */
588: public boolean isEditable() {
589: return isInternallyManaged();
590: }
591:
592: /**
593: * Returns a new <code>IEntityGroup</code> for the given Class with an unused
594: * key.
595: */
596: public IEntityGroup newGroup(Class type) throws GroupsException {
597: throwExceptionIfNotInternallyManaged();
598: IEntityGroup group = groupFactory.newInstance(type);
599: group.setLocalGroupService(this );
600: if (cacheInUse()) {
601: cacheAdd(group);
602: }
603: return group;
604: }
605:
606: /**
607: * Returns a pre-existing <code>IEntityGroup</code> or null if it
608: * does not exist.
609: */
610: protected IEntityGroup primFindGroup(String localKey)
611: throws GroupsException {
612: IEntityGroup group = groupFactory.find(localKey);
613: if (group != null) {
614: group.setLocalGroupService(this );
615: }
616: return group;
617: }
618:
619: private EntityIdentifier[] removeDuplicates(
620: EntityIdentifier[] entities) {
621: ArrayList ar = new ArrayList(entities.length);
622: for (int i = 0; i < entities.length; i++) {
623: if (!ar.contains(entities[i])) {
624: ar.add(entities[i]);
625: }
626: }
627: return (EntityIdentifier[]) ar.toArray(new EntityIdentifier[0]);
628: }
629:
630: public EntityIdentifier[] searchForEntities(String query,
631: int method, Class type) throws GroupsException {
632: return removeDuplicates(entitySearcher.searchForEntities(query,
633: method, type));
634: }
635:
636: public EntityIdentifier[] searchForEntities(String query,
637: int method, Class type, IEntityGroup ancestor)
638: throws GroupsException {
639: return filterEntities(searchForEntities(query, method, type),
640: ancestor);
641: }
642:
643: public EntityIdentifier[] searchForGroups(String query, int method,
644: Class leaftype) throws GroupsException {
645: return removeDuplicates(groupFactory.searchForGroups(query,
646: method, leaftype));
647: }
648:
649: public EntityIdentifier[] searchForGroups(String query, int method,
650: Class leaftype, IEntityGroup ancestor)
651: throws GroupsException {
652: return filterEntities(searchForGroups(query, method, leaftype),
653: ancestor);
654: }
655:
656: /**
657: *
658: */
659: protected void throwExceptionIfNotInternallyManaged()
660: throws GroupsException {
661: if (!isInternallyManaged()) {
662: throw new GroupsException("Group Service "
663: + getServiceName() + " is not updatable.");
664: }
665:
666: }
667:
668: /**
669: * Update the store and the updated members.
670: * @param group IEntityGroup
671: */
672: public void updateGroup(IEntityGroup group) throws GroupsException {
673: throwExceptionIfNotInternallyManaged();
674: getGroupStore().update(group);
675: if (cacheInUse()) {
676: cacheUpdate(group);
677: }
678: synchronizeGroupMembersOnUpdate(group);
679: }
680:
681: /**
682: * Updates the <code>ILockableEntityGroup</code> in the cache and the store.
683: * @param group ILockableEntityGroup
684: */
685: public void updateGroup(ILockableEntityGroup group)
686: throws GroupsException {
687: updateGroup(group, false);
688: }
689:
690: /**
691: * Updates the <code>ILockableEntityGroup</code> in the store and removes
692: * it from the cache.
693: * @param group ILockableEntityGroup
694: */
695: public void updateGroup(ILockableEntityGroup group,
696: boolean renewLock) throws GroupsException {
697: throwExceptionIfNotInternallyManaged();
698:
699: try {
700: if (!group.getLock().isValid()) {
701: throw new GroupsException("Could not update group "
702: + group.getKey() + " has invalid lock.");
703: }
704:
705: // updateGroup((IEntityGroup)group);
706: getGroupStore().update(group);
707: if (cacheInUse()) {
708: cacheRemove(group);
709: }
710: synchronizeGroupMembersOnUpdate(group);
711:
712: if (renewLock) {
713: group.getLock().renew();
714: } else {
715: group.getLock().release();
716: }
717:
718: } catch (LockingException le) {
719: throw new GroupsException("Problem updating group "
720: + group.getKey(), le);
721: }
722: }
723:
724: /**
725: * Update the store and the updated members.
726: * @param group IEntityGroup
727: */
728: public void updateGroupMembers(IEntityGroup group)
729: throws GroupsException {
730: throwExceptionIfNotInternallyManaged();
731: getGroupStore().updateMembers(group);
732: if (cacheInUse()) {
733: cacheUpdate(group);
734: }
735: synchronizeGroupMembersOnUpdate(group);
736: }
737:
738: /**
739: * Updates the <code>ILockableEntityGroup</code> in the cache and the store.
740: * @param group ILockableEntityGroup
741: */
742: public void updateGroupMembers(ILockableEntityGroup group)
743: throws GroupsException {
744: updateGroupMembers(group, false);
745: }
746:
747: /**
748: * Updates the <code>ILockableEntityGroup</code> in the store and removes
749: * it from the cache.
750: * @param group ILockableEntityGroup
751: */
752: public void updateGroupMembers(ILockableEntityGroup group,
753: boolean renewLock) throws GroupsException {
754: throwExceptionIfNotInternallyManaged();
755:
756: try {
757: if (!group.getLock().isValid()) {
758: throw new GroupsException("Could not update group "
759: + group.getKey() + " has invalid lock.");
760: }
761:
762: getGroupStore().updateMembers(group);
763: if (cacheInUse()) {
764: cacheRemove(group);
765: }
766: synchronizeGroupMembersOnUpdate(group);
767:
768: if (renewLock) {
769: group.getLock().renew();
770: } else {
771: group.getLock().release();
772: }
773:
774: } catch (LockingException le) {
775: throw new GroupsException("Problem updating group "
776: + group.getKey(), le);
777: }
778: }
779:
780: /**
781: * Returns an <code>IEntity</code> representing a portal entity. This does
782: * not guarantee that the underlying entity actually exists.
783: */
784: protected IEntity primGetEntity(String key, Class type)
785: throws GroupsException {
786: return entityFactory.newInstance(key, type);
787: }
788:
789: /**
790: * Remove the back pointers of the group members of the deleted group. Then
791: * update the cache to invalidate copies on peer servers.
792: *
793: * @param group ILockableEntityGroup
794: */
795: protected void synchronizeGroupMembersOnDelete(IEntityGroup group)
796: throws GroupsException {
797: GroupMemberImpl gmi = null;
798:
799: for (Iterator it = group.getMembers(); it.hasNext();) {
800: gmi = (GroupMemberImpl) it.next();
801: gmi.removeGroup(group);
802: if (cacheInUse()) {
803: cacheUpdate(gmi);
804: }
805: }
806: }
807:
808: /**
809: * Adjust the back pointers of the updated group members to either add or remove
810: * the parent group. Then update the cache to invalidate copies on peer servers.
811: *
812: * @param group ILockableEntityGroup
813: */
814: protected void synchronizeGroupMembersOnUpdate(IEntityGroup group)
815: throws GroupsException {
816: EntityGroupImpl egi = (EntityGroupImpl) group;
817: GroupMemberImpl gmi = null;
818:
819: for (Iterator it = egi.getAddedMembers().values().iterator(); it
820: .hasNext();) {
821: gmi = (GroupMemberImpl) it.next();
822: gmi.addGroup(egi);
823: if (cacheInUse()) {
824: cacheUpdate(gmi);
825: }
826: }
827:
828: for (Iterator it = egi.getRemovedMembers().values().iterator(); it
829: .hasNext();) {
830: gmi = (GroupMemberImpl) it.next();
831: gmi.removeGroup(egi);
832: if (cacheInUse()) {
833: cacheUpdate(gmi);
834: }
835: }
836: }
837:
838: /**
839: * Answers if <code>group</code> contains <code>member</code>.
840: * If the group belongs to another service and the present service is
841: * not editable, simply return false.
842: * @return boolean
843: * @param group org.jasig.portal.groups.IEntityGroup
844: * @param member org.jasig.portal.groups.IGroupMember
845: */
846: public boolean contains(IEntityGroup group, IGroupMember member)
847: throws GroupsException {
848: return (isForeign(member) && !isEditable()) ? false
849: : getGroupStore().contains(group, member);
850: }
851:
852: /**
853: * A foreign member is a group from a different service.
854: * @param member IGroupMember
855: * @return boolean
856: */
857: protected boolean isForeign(IGroupMember member) {
858: if (member.isEntity()) {
859: return false;
860: } else {
861: Name memberSvcName = ((IEntityGroup) member)
862: .getServiceName();
863: return (!getServiceName().equals(memberSvcName));
864: }
865: }
866:
867: }
|