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.HashSet;
011: import java.util.Iterator;
012: import java.util.List;
013: import java.util.Map;
014: import java.util.Set;
015:
016: import javax.naming.InvalidNameException;
017: import javax.naming.Name;
018:
019: import org.jasig.portal.EntityIdentifier;
020: import org.jasig.portal.concurrency.CachingException;
021: import org.jasig.portal.services.EntityCachingService;
022: import org.jasig.portal.services.GroupService;
023:
024: /**
025: * @author Dan Ellentuck
026: * @version $Revision: 36539 $
027: */
028: public class ReferenceCompositeGroupService extends
029: ReferenceComponentGroupService implements
030: ICompositeGroupService {
031: // Factory for IEntities:
032: protected IEntityStore entityFactory = null;
033:
034: // See CompositeGroupService.xml:
035: protected IIndividualGroupService defaultService;
036:
037: /**
038: * ReferenceCompositeGroupService constructor comment.
039: */
040: public ReferenceCompositeGroupService() throws GroupsException {
041: super ();
042: // initializeComponentServices();
043: }
044:
045: /**
046: * Returns groups that contain the <code>IGroupMember</code>. Delegates to the
047: * component services, but only after checking that they might actually contain
048: * a membership for this member.
049: * @param gm IGroupMember
050: */
051: public Iterator findContainingGroups(IGroupMember gm)
052: throws GroupsException {
053: Collection allGroups = new ArrayList();
054: IIndividualGroupService service = null;
055:
056: for (Iterator services = getComponentServices().values()
057: .iterator(); services.hasNext();) {
058: service = (IIndividualGroupService) services.next();
059: if (gm.isEntity()
060: || service.isEditable()
061: || getComponentService(((IEntityGroup) gm)
062: .getServiceName()) == service) {
063: {
064: for (Iterator groups = service
065: .findContainingGroups(gm); groups.hasNext();) {
066: allGroups.add((IEntityGroup) groups.next());
067: }
068: }
069: }
070: }
071: return allGroups.iterator();
072: }
073:
074: /**
075: * Returns a pre-existing <code>IEntityGroup</code> or null if the
076: * <code>IGroupMember</code> does not exist.
077: */
078: public IEntityGroup findGroup(String key) throws GroupsException {
079: CompositeEntityIdentifier ent = newCompositeEntityIdentifier(key);
080: IIndividualGroupService service = getComponentService(ent);
081: return (service == null) ? null : service.findGroup(ent);
082: }
083:
084: /**
085: * Returns a pre-existing <code>IEntityGroup</code> or null if the
086: * <code>IGroupMember</code> does not exist.
087: */
088: public ILockableEntityGroup findGroupWithLock(String key,
089: String lockOwner) throws GroupsException {
090: CompositeEntityIdentifier ent = newCompositeEntityIdentifier(key);
091: IIndividualGroupService service = getComponentService(ent);
092: return (service == null) ? null : service.findGroupWithLock(ent
093: .getLocalKey(), lockOwner);
094: }
095:
096: /**
097: * @return IIndividualGroupService
098: */
099: protected IIndividualGroupService getComponentService(
100: Name serviceName) {
101: return (IIndividualGroupService) getComponentServices().get(
102: serviceName);
103: }
104:
105: /**
106: * @return IIndividualGroupService
107: */
108: protected IIndividualGroupService getComponentService(
109: CompositeEntityIdentifier entId) {
110: return getComponentService(entId.getServiceName());
111: }
112:
113: /**
114: * Returns the <code>IIndividualGroupService</code> designated as the default service
115: * in the configuration document.
116: */
117: protected IIndividualGroupService getDefaultService() {
118: return defaultService;
119: }
120:
121: /**
122: * Returns an <code>IEntity</code> representing a portal entity. This does
123: * not guarantee that the entity actually exists.
124: */
125: public IEntity getEntity(String key, Class type)
126: throws GroupsException {
127: return getEntity(key, type, null);
128: }
129:
130: /**
131: * Returns an <code>IEntity</code> representing a portal entity. This does
132: * not guarantee that the entity actually exists.
133: */
134: public IEntity getEntity(String key, Class type, String svcName)
135: throws GroupsException {
136: IIndividualGroupService svc = null;
137: if (svcName == null) {
138: svc = getDefaultService();
139: } else {
140: try {
141: Name n = GroupService.parseServiceName(svcName);
142: svc = getComponentService(n);
143: } catch (InvalidNameException ine) {
144: throw new GroupsException("Invalid service name.");
145: }
146: }
147: return (svc == null) ? null : svc.getEntity(key, type);
148: }
149:
150: /**
151: * Returns an <code>IGroupMember</code> representing either a group or a
152: * portal entity. If the parm <code>type</code> is the group type,
153: * the <code>IGroupMember</code> is an <code>IEntityGroup</code> else it is
154: * an <code>IEntity</code>.
155: */
156: public IGroupMember getGroupMember(String key, Class type)
157: throws GroupsException {
158: IGroupMember gm = null;
159: if (type == org.jasig.portal.EntityTypes.GROUP_ENTITY_TYPE)
160: gm = findGroup(key);
161: else
162: gm = getEntity(key, type);
163: return gm;
164: }
165:
166: /**
167: * Returns an <code>IGroupMember</code> representing either a group or a
168: * portal entity, based on the <code>EntityIdentifier</code>, which refers
169: * to the UNDERLYING entity for the <code>IGroupMember</code>.
170: */
171: public IGroupMember getGroupMember(
172: EntityIdentifier underlyingEntityIdentifier)
173: throws GroupsException {
174: return getGroupMember(underlyingEntityIdentifier.getKey(),
175: underlyingEntityIdentifier.getType());
176: }
177:
178: /**
179: * Assembles the group services composite. Once the leaf services have been
180: * retrieved, they are held in a (one-dimensional) Map. The composite
181: * identity of a service is preserved in its Map key, a javax.naming.Name.
182: * Each node of the Name is the name of a component service, starting with
183: * the service closest to the composite service and ending with the name of
184: * the leaf service. The key is built up layer by layer.
185: *
186: * @exception GroupsException
187: */
188: protected void initializeComponentServices() throws GroupsException {
189: Name leafServiceName = null;
190: try {
191: GroupServiceConfiguration cfg = GroupServiceConfiguration
192: .getConfiguration();
193: List services = cfg.getServiceDescriptors();
194: for (Iterator it = services.iterator(); it.hasNext();) {
195: ComponentGroupServiceDescriptor descriptor = (ComponentGroupServiceDescriptor) it
196: .next();
197: String factoryName = descriptor.getServiceFactoryName();
198: IComponentGroupServiceFactory factory = (IComponentGroupServiceFactory) Class
199: .forName(factoryName).newInstance();
200: IComponentGroupService service = factory
201: .newGroupService(descriptor);
202:
203: // If it's a leaf service, add it to the Map.
204: if (service.isLeafService()) {
205: leafServiceName = GroupService
206: .parseServiceName(descriptor.getName());
207: service.setServiceName(leafServiceName);
208: getComponentServices()
209: .put(leafServiceName, service);
210: }
211:
212: // Otherwise, get its leaf services and for each, push our node onto the service Name
213: // and add the service to the Map.
214: else {
215: Map componentMap = service.getComponentServices();
216: for (Iterator components = componentMap.values()
217: .iterator(); components.hasNext();) {
218: IIndividualGroupService leafService = (IIndividualGroupService) components
219: .next();
220: leafServiceName = leafService.getServiceName();
221: leafServiceName.add(0, descriptor.getName());
222: getComponentServices().put(leafServiceName,
223: leafService);
224: }
225: }
226: }
227:
228: Name defaultServiceName = GroupService.parseServiceName(cfg
229: .getDefaultService());
230: defaultService = (IIndividualGroupService) getComponentService(defaultServiceName);
231:
232: } catch (Exception ex) {
233: throw new GroupsException(
234: "Problem initializing component services", ex);
235: }
236: }
237:
238: /**
239: * Returns a <code>CompositeEntityIdentifier</code> for the group identified
240: * by <code>key</code>.
241: */
242: protected CompositeEntityIdentifier newCompositeEntityIdentifier(
243: String key) throws GroupsException {
244: return new CompositeEntityIdentifier(key,
245: org.jasig.portal.EntityTypes.GROUP_ENTITY_TYPE);
246: }
247:
248: /**
249: * Returns a new <code>IEntityGroup</code> from the named service.
250: */
251: public IEntityGroup newGroup(Class type, Name serviceName)
252: throws GroupsException {
253: return getComponentService(serviceName).newGroup(type);
254: }
255:
256: /**
257: * Returns a pre-existing <code>IEntityGroup</code> or null if the
258: * <code>IGroupMember</code> does not exist.
259: */
260: protected IEntityGroup primFindGroup(String key)
261: throws GroupsException {
262: CompositeEntityIdentifier ent = newCompositeEntityIdentifier(key);
263: IIndividualGroupService service = getComponentService(ent);
264: return (service == null) ? null : service.findGroup(ent);
265: }
266:
267: /**
268: * Find EntityIdentifiers for entities whose name matches the query string
269: * according to the specified method and is of the specified type
270: */
271: public EntityIdentifier[] searchForEntities(String query,
272: int method, Class type) throws GroupsException {
273: Set allIds = new HashSet();
274:
275: for (Iterator services = getComponentServices().values()
276: .iterator(); services.hasNext();) {
277: IIndividualGroupService service = (IIndividualGroupService) services
278: .next();
279: EntityIdentifier[] ids = service.searchForEntities(query,
280: method, type);
281: for (int i = 0; i < ids.length; i++) {
282: allIds.add(ids[i]);
283: }
284: }
285: return (EntityIdentifier[]) allIds
286: .toArray(new EntityIdentifier[allIds.size()]);
287: }
288:
289: /**
290: * Find EntityIdentifiers for entities whose name matches the query string
291: * according to the specified method, is of the specified type and
292: * descends from the specified group
293: */
294: public EntityIdentifier[] searchForEntities(String query,
295: int method, Class type, IEntityGroup ancestor)
296: throws GroupsException {
297: Set allIds = new HashSet();
298:
299: for (Iterator services = getComponentServices().values()
300: .iterator(); services.hasNext();) {
301: IIndividualGroupService service = (IIndividualGroupService) services
302: .next();
303: EntityIdentifier[] ids = service.searchForEntities(query,
304: method, type, ancestor);
305: for (int i = 0; i < ids.length; i++) {
306: allIds.add(ids[i]);
307: }
308: }
309: return (EntityIdentifier[]) allIds
310: .toArray(new EntityIdentifier[allIds.size()]);
311: }
312:
313: /**
314: * Find EntityIdentifiers for groups whose name matches the query string
315: * according to the specified method and matches the provided leaf type
316: */
317: public EntityIdentifier[] searchForGroups(String query, int method,
318: Class leaftype) throws GroupsException {
319: Set allIds = new HashSet();
320:
321: for (Iterator services = getComponentServices().values()
322: .iterator(); services.hasNext();) {
323: IIndividualGroupService service = (IIndividualGroupService) services
324: .next();
325: EntityIdentifier[] ids = service.searchForGroups(query,
326: method, leaftype);
327: for (int i = 0; i < ids.length; i++) {
328: try {
329: CompositeEntityIdentifier cei = new CompositeEntityIdentifier(
330: ids[i].getKey(), ids[i].getType());
331: cei.setServiceName(service.getServiceName());
332: allIds.add(cei);
333: } catch (javax.naming.InvalidNameException ine) {
334: }
335: }
336: }
337: return (EntityIdentifier[]) allIds
338: .toArray(new EntityIdentifier[allIds.size()]);
339: }
340:
341: /**
342: * Find EntityIdentifiers for groups whose name matches the query string
343: * according to the specified method, has the provided leaf type and
344: * descends from the specified group
345: */
346: public EntityIdentifier[] searchForGroups(String query, int method,
347: Class leaftype, IEntityGroup ancestor)
348: throws GroupsException {
349: Set allIds = new HashSet();
350:
351: for (Iterator services = getComponentServices().values()
352: .iterator(); services.hasNext();) {
353: IIndividualGroupService service = (IIndividualGroupService) services
354: .next();
355: EntityIdentifier[] ids = service.searchForGroups(query,
356: method, leaftype, ancestor);
357: for (int i = 0; i < ids.length; i++) {
358: try {
359: CompositeEntityIdentifier cei = new CompositeEntityIdentifier(
360: ids[i].getKey(), ids[i].getType());
361: cei.setServiceName(service.getServiceName());
362: allIds.add(cei);
363: } catch (javax.naming.InvalidNameException ine) {
364: }
365: }
366: }
367: return (EntityIdentifier[]) allIds
368: .toArray(new EntityIdentifier[allIds.size()]);
369: }
370:
371: /**
372: * Insert the method's description here.
373: * Creation date: (10/31/2002 10:58:53 AM)
374: * @param newComponentServices java.util.Map
375: */
376: protected void setComponentServices(
377: java.util.Map newComponentServices) {
378: componentServices = newComponentServices;
379: }
380:
381: /**
382: *
383: */
384: protected void cacheAdd(IGroupMember gm) throws GroupsException {
385: try {
386: EntityCachingService.instance().add(gm);
387: } catch (CachingException ce) {
388: throw new GroupsException("Problem adding group member "
389: + gm.getKey() + " to cache", ce);
390: }
391: }
392:
393: /**
394: *
395: */
396: protected void cacheRemove(IGroupMember gm) throws GroupsException {
397: try {
398: EntityCachingService.instance().remove(
399: gm.getEntityIdentifier());
400: } catch (CachingException ce) {
401: throw new GroupsException("Problem removing group member "
402: + gm.getKey() + " from cache", ce);
403: }
404: }
405:
406: /**
407: *
408: */
409: protected void cacheUpdate(IGroupMember gm) throws GroupsException {
410: try {
411: EntityCachingService.instance().update(gm);
412: } catch (CachingException ce) {
413: throw new GroupsException("Problem updating group member "
414: + gm.getKey() + " in cache", ce);
415: }
416: }
417:
418: /**
419: * Returns a cached <code>IEntity</code> or null if it has not been cached.
420: */
421: protected IEntity getEntityFromCache(String key)
422: throws CachingException {
423: return (IEntity) EntityCachingService.instance().get(
424: org.jasig.portal.EntityTypes.LEAF_ENTITY_TYPE, key);
425: }
426: }
|