1 package com.atlassian.user.impl.hibernate;
2
3 import com.atlassian.user.*;
4 import com.atlassian.user.impl.DuplicateEntityException;
5 import com.atlassian.user.impl.RepositoryException;
6 import com.atlassian.user.impl.hibernate.repository.HibernateRepository;
7 import com.atlassian.user.repository.RepositoryIdentifier;
8 import com.atlassian.user.search.page.DefaultPager;
9 import com.atlassian.user.search.page.Pager;
10 import com.atlassian.user.search.page.PagerFactory;
11 import com.atlassian.user.util.Assert;
12 import net.sf.hibernate.HibernateException;
13 import net.sf.hibernate.ObjectDeletedException;
14 import net.sf.hibernate.Query;
15 import net.sf.hibernate.Session;
16 import org.springframework.dao.DataAccessException;
17 import org.springframework.orm.hibernate.HibernateCallback;
18 import org.springframework.orm.hibernate.HibernateTemplate;
19 import org.springframework.orm.hibernate.SessionFactoryUtils;
20 import org.springframework.orm.hibernate.support.HibernateDaoSupport;
21
22 import java.util.*;
23
24
25
26
27 public class HibernateGroupManager extends HibernateDaoSupport implements GroupManager
28 {
29 public static final String GROUPNAME_FIELD = "groupname";
30 public static final String GROUPID_FIELD = "groupid";
31 public static final String ENTITYID_FIELD = "entityid";
32 public static final String EXTERNAL_ENTITY_NAME_FIELD = "externalEntityName";
33
34 private final RepositoryIdentifier identifier;
35 protected final HibernateRepository repository;
36 protected final UserManager userManager;
37 protected final ExternalEntityDAO externalEntityDao;
38
39 private static final boolean USE_EXPERIMENTAL_MAPPINGS = Boolean.getBoolean("com.atlassian.user.experimentalMapping");
40
41 public HibernateGroupManager(RepositoryIdentifier identifier, HibernateRepository repository, UserManager userManager, ExternalEntityDAO externalEntityDao)
42 {
43 this.identifier = identifier;
44 this.repository = repository;
45 this.userManager = userManager;
46 setSessionFactory(repository.getSessionFactory());
47 this.externalEntityDao = externalEntityDao;
48 }
49
50 public Pager<Group> getGroups() throws EntityException
51 {
52 List<Group> result;
53
54 try
55 {
56 result = getGroupsFromHibernate();
57 }
58 catch (DataAccessException e)
59 {
60 throw new RepositoryException(e);
61 }
62
63 if (result == null)
64 return DefaultPager.emptyPager();
65
66 return new DefaultPager<Group>(result);
67 }
68
69 public List<Group> getWritableGroups()
70 {
71 return getGroupsFromHibernate();
72 }
73
74 public Pager<Group> getGroups(User user) throws EntityException
75 {
76 Collection<Group> groups = getAllGroupsForUser(user);
77 return new DefaultPager<Group>(groups);
78 }
79
80 protected Collection<Group> getAllGroupsForUser(User user) throws RepositoryException
81 {
82 Assert.notNull(user, "User must not be null");
83
84 if (isUserExternal(user))
85 return getGroupsForExternalEntity(getCorrespondingExternalEntity(user));
86
87 return getGroupsForLocalUser(user);
88 }
89
90
91
92
93 protected boolean isUserExternal(User user)
94 {
95 return !(user instanceof DefaultHibernateUser);
96 }
97
98 private List<Group> getGroupsForLocalUser(User user) throws RepositoryException
99 {
100 Assert.notNull(user, "User must not be null");
101 Assert.isInstanceOf(DefaultHibernateUser.class, user);
102
103 if (isUserExternal(user))
104 return Collections.emptyList();
105
106 return getLocalUserGroupsFromHibernate((DefaultHibernateUser) user);
107 }
108
109 private List<Group> getGroupsForExternalEntity(final ExternalEntity externalEntity) throws RepositoryException
110 {
111 if (externalEntity == null)
112 throw new IllegalArgumentException("Input (externalEntity) is null.");
113
114 return getExternalUserGroupsFromHibernate(externalEntity);
115 }
116
117
118
119
120 public Pager<String> getMemberNames(Group group) throws EntityException
121 {
122 if (group == null)
123 throw new IllegalArgumentException("Group cannot be null.");
124 if (!isHandledGroup(group))
125 throw new IllegalArgumentException("Group passed to HibernateGroupManager must be of type 'DefaultHibernateGroup'");
126
127
128
129
130
131
132 return PagerFactory.getPager(getExternalMemberNames(group), getLocalMemberNames(group));
133 }
134
135 protected void validateGroup(Group group)
136 {
137 if (group == null)
138 throw new IllegalArgumentException("Input (group) is null.");
139 }
140
141 public Pager<String> getLocalMemberNames(Group group) throws EntityException
142 {
143 validateGroup(group);
144 return new DefaultPager<String>(getLocalMemberNamesFromHibernate((DefaultHibernateGroup) group));
145 }
146
147 public Pager<User> getLocalMembers(Group group) throws RepositoryException
148 {
149 if (group == null)
150 throw new IllegalArgumentException("Input (group) is null.");
151 else if (!isHandledGroup(group))
152 return DefaultPager.emptyPager();
153
154 DefaultHibernateGroup defGroup = (DefaultHibernateGroup) group;
155 return new DefaultPager<User>(new ArrayList<User>(defGroup.getLocalMembers()));
156 }
157
158 private boolean isHandledGroup(Group group)
159 {
160 return (group instanceof DefaultHibernateGroup);
161 }
162
163 public Pager<String> getExternalMemberNames(Group group) throws EntityException
164 {
165 if (group == null)
166 throw new IllegalArgumentException("Input (group) is null.");
167 else if (!isHandledGroup(group))
168 return DefaultPager.emptyPager();
169
170 final DefaultHibernateGroup defGroup = (DefaultHibernateGroup) group;
171
172 return new DefaultPager<String>(getExternalMemberNamesFromHibernate(defGroup));
173 }
174
175 public DefaultHibernateGroup getGroup(Group group) throws EntityException
176 {
177
178 if (group instanceof DefaultHibernateGroup)
179 {
180
181 try
182 {
183 return (DefaultHibernateGroup) getSession().get(DefaultHibernateGroup.class, ((DefaultHibernateGroup) group).getId());
184 }
185 catch (ObjectDeletedException e)
186 {
187 return null;
188 }
189 catch (HibernateException e)
190 {
191 throw new EntityException(e);
192 }
193 }
194 else
195 {
196 return getGroup(group.getName());
197 }
198
199 }
200
201
202 public DefaultHibernateGroup getGroup(final String groupname) throws EntityException
203 {
204 if (groupname == null)
205 throw new IllegalArgumentException("Input (groupname) is null.");
206
207 List result;
208 DefaultHibernateGroup foundGroup = null;
209
210 try
211 {
212 result = getHibernateTemplate().executeFind(new HibernateCallback()
213 {
214 public Object doInHibernate(Session session) throws HibernateException
215 {
216 Query queryObject = session.getNamedQuery("atluser.group_find");
217 SessionFactoryUtils.applyTransactionTimeout(queryObject, getSessionFactory());
218
219 if (groupname != null)
220 queryObject.setParameter(GROUPNAME_FIELD, groupname);
221
222 return queryObject.list();
223 }
224 });
225 }
226 catch (DataAccessException e)
227 {
228 throw new RepositoryException(e);
229 }
230
231 try
232 {
233 foundGroup = (DefaultHibernateGroup) result.get(0);
234 }
235 catch (Exception e)
236 {
237 return foundGroup;
238 }
239
240 return foundGroup;
241 }
242
243 public Group createGroup(String groupname) throws EntityException
244 {
245 if (groupname == null)
246 throw new IllegalArgumentException("Input (groupname) is null.");
247
248 Group group = getGroup(groupname);
249
250 if (group == null)
251 {
252 group = new DefaultHibernateGroup(groupname);
253 getHibernateTemplate().save(group);
254 }
255 else
256 throw new DuplicateEntityException("Group [" + groupname + "] already exists in this repository (" +
257 identifier.getName() + ")");
258
259 return group;
260 }
261
262
263
264
265
266
267
268 public void removeGroup(Group group) throws EntityException
269 {
270 Group groupInSession = getGroupInSession(group);
271
272 DefaultHibernateGroup dGroup = (DefaultHibernateGroup) groupInSession;
273 dGroup.setExternalMembers(null);
274 dGroup.setLocalMembers(null);
275
276 getHibernateTemplate().delete(groupInSession);
277 }
278
279 public void addMembership(Group group, User user) throws EntityException
280 {
281 validateGroupAndUser(group, user);
282
283 DefaultHibernateGroup dGroup = getGroupInSession(group);
284
285 if (isUserExternal(user))
286 {
287 addExternalUserMembership(user, dGroup);
288 }
289 else
290 {
291 addLocalUserMembership(user, dGroup);
292 }
293
294 getHibernateTemplate().saveOrUpdate(dGroup);
295 }
296
297 private void addLocalUserMembership(User user, DefaultHibernateGroup dGroup)
298 {
299 if (USE_EXPERIMENTAL_MAPPINGS)
300 {
301 DefaultHibernateUser huser = (DefaultHibernateUser) user;
302 huser.getGroups().add(dGroup);
303 getHibernateTemplate().saveOrUpdate(user);
304 }
305 else
306 {
307 if (dGroup.getLocalMembers() == null)
308 dGroup.setLocalMembers(new HashSet<User>());
309
310 dGroup.getLocalMembers().add(user);
311 }
312 }
313
314 private void addExternalUserMembership(User user, DefaultHibernateGroup dGroup)
315 throws RepositoryException
316 {
317 if (dGroup.getExternalMembers() == null)
318 dGroup.setExternalMembers(new HashSet<ExternalEntity>());
319
320 dGroup.getExternalMembers().add(getCorrespondingExternalEntity(user));
321 }
322
323 protected ExternalEntity getCorrespondingExternalEntity(final User user) throws RepositoryException
324 {
325 if (user == null)
326 throw new IllegalArgumentException("Input (user) is null.");
327
328 ExternalEntity result = externalEntityDao.getExternalEntity(user.getName());
329
330 if (result == null)
331 return externalEntityDao.createExternalEntity(user.getName());
332 else
333 return result;
334 }
335
336 public boolean hasMembership(Group group, User user) throws EntityException
337 {
338 if (group==null || getGroup(group) == null)
339 return false;
340
341 validateGroupAndUser(group, user);
342
343 final DefaultHibernateGroup defGroup = getGroupInSession(group);
344
345 if (isUserExternal(user))
346 {
347 return hasExternalMembership(defGroup, user);
348 }
349 else
350 {
351 return hasLocalMembership(defGroup, (DefaultHibernateUser) user);
352 }
353 }
354
355 protected void validateGroupAndUser(Group group, User user) throws EntityException
356 {
357 if (group == null)
358 throw new IllegalArgumentException("Can't add membership for null group");
359
360 if (getGroup(group) == null)
361 throw new IllegalArgumentException("Group unknown: [" + group + "] in [" + identifier.getKey() + "]");
362
363 if (user == null)
364 throw new IllegalArgumentException("User unknown: [" + user + "] in [" + identifier.getKey() + "]");
365
366 if (!isHandledGroup(group))
367 throw new IllegalArgumentException("Group is not a Hibernate entity [" + group.getClass().getName());
368 }
369
370 protected boolean hasExternalMembership(DefaultHibernateGroup defGroup, User user) throws EntityException
371 {
372 ExternalEntity entity = getCorrespondingExternalEntity(user);
373
374 return defGroup.getExternalMembers().contains(entity);
375 }
376
377 protected boolean hasLocalMembership(DefaultHibernateGroup defGroup, DefaultHibernateUser defUser) throws EntityException
378 {
379 Collection usersGroups = getAllGroupsForUser(defUser);
380
381 return (usersGroups != null && usersGroups.contains(defGroup));
382 }
383
384 public void removeMembership(Group group, User user) throws EntityException
385 {
386 validateGroupAndUser(group, user);
387
388 Group groupInSession = getGroupInSession(group);
389
390 DefaultHibernateGroup hibernateGroup = (DefaultHibernateGroup) groupInSession;
391
392 HibernateTemplate hibernateTemplate = getHibernateTemplate();
393 if (isUserExternal(user))
394 {
395 ExternalEntity extUser = getCorrespondingExternalEntity(user);
396
397
398 hibernateGroup.getExternalMembers().remove(extUser);
399
400 }
401 else
402 {
403
404 hibernateGroup.getLocalMembers().remove(user);
405
406 }
407
408 hibernateTemplate.saveOrUpdate(groupInSession);
409 hibernateTemplate.flush();
410 }
411
412 public boolean isReadOnly(Group group) throws EntityException
413 {
414 return (getGroup(group) == null);
415 }
416
417 public boolean supportsExternalMembership() throws EntityException
418 {
419 return true;
420 }
421
422
423
424
425 public RepositoryIdentifier getIdentifier()
426 {
427 return identifier;
428 }
429
430 public RepositoryIdentifier getRepository(Entity entity) throws EntityException
431 {
432 if (getGroup(entity.getName()) != null)
433 return identifier;
434
435 return null;
436 }
437
438
439
440
441
442 public boolean isCreative()
443 {
444 return true;
445 }
446
447
448
449
450
451 private DefaultHibernateGroup getGroupInSession(Group group)
452 throws EntityException
453 {
454 if (group == null)
455 throw new IllegalArgumentException("Input (group) is null.");
456 else if (!isHandledGroup(group))
457 throw new IllegalArgumentException("Group is not a Hibernate entity [" + group.getClass().getName());
458
459 return getGroup(group);
460 }
461
462 @SuppressWarnings("unchecked")
463 private List<Group> getGroupsFromHibernate()
464 {
465 return getHibernateTemplate().executeFind(new HibernateCallback()
466 {
467 public Object doInHibernate(Session session) throws HibernateException
468 {
469 Query queryObject = session.getNamedQuery("atluser.group_findAll");
470 SessionFactoryUtils.applyTransactionTimeout(queryObject, getSessionFactory());
471 return queryObject.list();
472 }
473 });
474 }
475
476
477 @SuppressWarnings("unchecked")
478 private List<Group> getLocalUserGroupsFromHibernate(final DefaultHibernateUser defUser) throws RepositoryException
479 {
480 try
481 {
482 return getHibernateTemplate().executeFind(new HibernateCallback()
483 {
484 public Object doInHibernate(Session session) throws HibernateException
485 {
486 Query queryObject = session.getNamedQuery("atluser.group_getGroupsForUser");
487 SessionFactoryUtils.applyTransactionTimeout(queryObject, getSessionFactory());
488 queryObject.setLong(ENTITYID_FIELD, defUser.getId());
489
490 return queryObject.list();
491 }
492 });
493 }
494 catch (DataAccessException e)
495 {
496 throw new RepositoryException(e);
497 }
498 }
499
500 @SuppressWarnings("unchecked")
501 private List<Group> getExternalUserGroupsFromHibernate(final ExternalEntity externalEntity) throws RepositoryException
502 {
503 try
504 {
505 return getHibernateTemplate().executeFind(new HibernateCallback()
506 {
507 public Object doInHibernate(Session session) throws HibernateException
508 {
509 Query queryObject = session.getNamedQuery("atluser.group_getGroupsForExternalEntity");
510 SessionFactoryUtils.applyTransactionTimeout(queryObject, getSessionFactory());
511
512 if (externalEntity != null)
513 queryObject.setLong(ENTITYID_FIELD, externalEntity.getId());
514
515 return queryObject.list();
516 }
517 });
518 }
519 catch (DataAccessException e)
520 {
521 throw new RepositoryException(e);
522 }
523 }
524
525 @SuppressWarnings("unchecked")
526 private List<String> getLocalMemberNamesFromHibernate(final DefaultHibernateGroup defGroup) throws RepositoryException
527 {
528 try
529 {
530 return getHibernateTemplate().executeFind(new HibernateCallback()
531 {
532 public Object doInHibernate(Session session) throws HibernateException
533 {
534 Query queryObject = session.getNamedQuery("atluser.group_getLocalMemberNames");
535 SessionFactoryUtils.applyTransactionTimeout(queryObject, getSessionFactory());
536
537 if (defGroup != null)
538 queryObject.setLong(GROUPID_FIELD, defGroup.getId());
539
540 return queryObject.list();
541 }
542 });
543 }
544 catch (DataAccessException e)
545 {
546 throw new RepositoryException(e);
547 }
548 }
549
550 @SuppressWarnings("unchecked")
551 private List<String> getExternalMemberNamesFromHibernate(final DefaultHibernateGroup defGroup)
552 throws RepositoryException
553 {
554 List result;
555 try
556 {
557 result = getHibernateTemplate().executeFind(new HibernateCallback()
558 {
559 public Object doInHibernate(Session session) throws HibernateException
560 {
561 Query queryObject = session.getNamedQuery("atluser.group_getExternalMemberNames");
562 SessionFactoryUtils.applyTransactionTimeout(queryObject, getSessionFactory());
563
564 if (defGroup != null)
565 queryObject.setLong(GROUPID_FIELD, defGroup.getId());
566
567 return queryObject.list();
568 }
569 });
570 }
571 catch (DataAccessException e)
572 {
573 throw new RepositoryException(e);
574 }
575 return result;
576 }
577 }