1 package com.atlassian.core.ofbiz.association;
2
3 import com.atlassian.core.ofbiz.CoreFactory;
4 import com.atlassian.core.user.UserUtils;
5 import com.opensymphony.user.EntityNotFoundException;
6 import com.opensymphony.user.User;
7 import org.apache.commons.collections.CollectionUtils;
8 import org.apache.commons.collections.Transformer;
9 import org.apache.log4j.Logger;
10 import org.ofbiz.core.entity.*;
11 import org.ofbiz.core.util.UtilMisc;
12
13 import java.util.*;
14
15 public class DefaultAssociationManager implements AssociationManager
16 {
17 private static final Logger log = Logger.getLogger(DefaultAssociationManager.class);
18 private final GenericDelegator delegator = CoreFactory.getGenericDelegator();
19
20
21
22
23
24
25
26
27 public GenericValue createAssociation(GenericValue source, GenericValue sink, String associationType)
28 throws GenericEntityException
29 {
30 final GenericValue existingAssocation = getAssociation(source, sink, associationType);
31 if (existingAssocation == null)
32 {
33 GenericValue v = delegator.makeValue("NodeAssociation", UtilMisc.toMap(
34 "associationType", associationType,
35 "sourceNodeId", source.getLong("id"),
36 "sourceNodeEntity", source.getEntityName(),
37 "sinkNodeId", sink.getLong("id"),
38 "sinkNodeEntity", sink.getEntityName()));
39 v.create();
40 return v;
41 }
42 return existingAssocation;
43 }
44
45 public GenericValue createAssociation(Long sourceNodeId, String sourceNodeEntity, Long sinkNodeId, String sinkNodeEntity, String associationType)
46 throws GenericEntityException
47 {
48 final GenericValue existingAssocation = getAssociation(sourceNodeId, sourceNodeEntity, sinkNodeId, sinkNodeEntity, associationType);
49 if (existingAssocation == null)
50 {
51 GenericValue v = delegator.makeValue("NodeAssociation", UtilMisc.toMap(
52 "associationType", associationType,
53 "sourceNodeId", sourceNodeId,
54 "sourceNodeEntity", sourceNodeEntity,
55 "sinkNodeId", sinkNodeId,
56 "sinkNodeEntity", sinkNodeEntity));
57 v.create();
58 return v;
59 }
60 return existingAssocation;
61 }
62
63 public GenericValue createAssociation(String userName, Long sinkNodeId, String sinkNodeEntity, String associationType)
64 throws GenericEntityException
65 {
66 final GenericValue existingAssociation = getAssociation(userName, sinkNodeId, sinkNodeEntity, associationType);
67 if (existingAssociation == null)
68 {
69 GenericValue v = delegator.makeValue("UserAssociation", UtilMisc.toMap(
70 "associationType", associationType,
71 "sourceName", userName,
72 "sinkNodeId", sinkNodeId,
73 "sinkNodeEntity", sinkNodeEntity));
74 v.create();
75 v.refresh();
76 return v;
77 }
78 return existingAssociation;
79 }
80
81 public GenericValue createAssociation(User user, GenericValue sink, String associationType)
82 throws GenericEntityException
83 {
84 final GenericValue v = delegator.makeValue("UserAssociation", UtilMisc.toMap(
85 "associationType", associationType,
86 "sourceName", user.getName(),
87 "sinkNodeId", sink.getLong("id"),
88 "sinkNodeEntity", sink.getEntityName()));
89 v.create();
90 v.refresh();
91 return v;
92 }
93
94
95 public void removeAssociation(User user, GenericValue sink, String associationType) throws GenericEntityException
96 {
97 removeAssociation(user.getName(), sink, associationType);
98 }
99
100 public void removeAssociation(String username, GenericValue sink, String associationType) throws GenericEntityException
101 {
102 final Map fields = new HashMap();
103 fields.put("sinkNodeId", sink.getLong("id"));
104 fields.put("sinkNodeEntity", sink.getEntityName());
105 fields.put("sourceName", username);
106 fields.put("associationType", associationType);
107 delegator.removeByPrimaryKey(delegator.makePK("UserAssociation", fields));
108 }
109
110 public void removeAssociation(GenericValue source, GenericValue sink, String associationType)
111 throws GenericEntityException
112 {
113 final Map fields = new HashMap();
114 fields.put("sinkNodeId", sink.getLong("id"));
115 fields.put("sinkNodeEntity", sink.getEntityName());
116 fields.put("sourceNodeId", source.getLong("id"));
117 fields.put("sourceNodeEntity", source.getEntityName());
118 fields.put("associationType", associationType);
119 delegator.removeByPrimaryKey(delegator.makePK("NodeAssociation", fields));
120 }
121
122
123
124
125 public void removeAssociationsFromSource(GenericValue source) throws GenericEntityException
126 {
127 final Map fields = new HashMap();
128 fields.put("sourceNodeId", source.getLong("id"));
129 fields.put("sourceNodeEntity", source.getEntityName());
130 delegator.removeByAnd("NodeAssociation", fields);
131 }
132
133 public void removeAssociationsFromSink(GenericValue sink) throws GenericEntityException
134 {
135 final Map fields = new HashMap();
136 fields.put("sinkNodeId", sink.getLong("id"));
137 fields.put("sinkNodeEntity", sink.getEntityName());
138 delegator.removeByAnd("NodeAssociation", fields);
139 }
140
141
142
143
144 public void removeUserAssociationsFromSink(GenericValue sink) throws GenericEntityException
145 {
146 final Map fields = new HashMap();
147 fields.put("sinkNodeId", sink.getLong("id"));
148 fields.put("sinkNodeEntity", sink.getEntityName());
149 delegator.removeByAnd("UserAssociation", fields);
150 }
151
152
153
154
155 public void removeUserAssociationsFromSink(GenericValue sink, String associationType) throws GenericEntityException
156 {
157 final Map fields = new HashMap();
158 fields.put("sinkNodeId", sink.getLong("id"));
159 fields.put("sinkNodeEntity", sink.getEntityName());
160 fields.put("associationType", associationType);
161 delegator.removeByAnd("UserAssociation", fields);
162 }
163
164
165
166
167
168 public void removeUserAssociationsFromUser(User user) throws GenericEntityException
169 {
170 final Map fields = new HashMap();
171 fields.put("sourceName", user.getName());
172 delegator.removeByAnd("UserAssociation", fields);
173 }
174
175 public void removeUserAssociationsFromUser(final User user, final String associationType)
176 throws GenericEntityException
177 {
178 final Map fields = new HashMap();
179 fields.put("sourceName", user.getName());
180 fields.put("associationType", associationType);
181 delegator.removeByAnd("UserAssociation", fields);
182 }
183
184 public void removeUserAssociationsFromUser(final User user, final String associationType, final String entityName)
185 throws GenericEntityException
186 {
187 final Map fields = new HashMap();
188 fields.put("sourceName", user.getName());
189 fields.put("associationType", associationType);
190 fields.put("sinkNodeEntity", entityName);
191 delegator.removeByAnd("UserAssociation", fields);
192 }
193
194
195
196
197
198
199
200 public void swapAssociation(String sourceEntityName, String associationType, GenericValue fromSink, GenericValue toSink)
201 throws GenericEntityException
202 {
203 final List sources = getSourceFromSink(fromSink, sourceEntityName, associationType, false);
204 swapAssociation(sources, associationType, fromSink, toSink);
205 }
206
207
208
209
210 public void swapAssociation(List entities, String associationType, GenericValue fromSink, GenericValue toSink)
211 throws GenericEntityException
212 {
213 for (Iterator iterator = entities.iterator(); iterator.hasNext();)
214 {
215 GenericValue entity = (GenericValue) iterator.next();
216 CoreFactory.getAssociationManager().createAssociation(entity, toSink, associationType);
217 removeAssociation(entity, fromSink, associationType);
218 }
219 }
220
221 List getAssociations(String associationName, Map fields, boolean useCache, boolean useSequence)
222 throws GenericEntityException
223 {
224 List result;
225 if (useCache)
226 {
227 result = delegator.findByAndCache(associationName, fields);
228 }
229 else
230 {
231 result = delegator.findByAnd(associationName, fields);
232 }
233
234 if (useSequence)
235 {
236 result = EntityUtil.orderBy(result, UtilMisc.toList("sequence"));
237 }
238 return result;
239 }
240
241 public GenericValue getAssociation(GenericValue source, GenericValue sink, String associationType)
242 throws GenericEntityException
243 {
244 return getAssociation(source.getLong("id"), source.getEntityName(), sink.getLong("id"), sink.getEntityName(), associationType);
245 }
246
247 public GenericValue getAssociation(User user, GenericValue sink, String associationType)
248 throws GenericEntityException
249 {
250 if (user == null)
251 {
252 return null;
253 }
254
255 return EntityUtil.getOnly(delegator.findByAnd("UserAssociation", UtilMisc.toMap(
256 "associationType", associationType,
257 "sourceName", user.getName(),
258 "sinkNodeId", sink.getLong("id"),
259 "sinkNodeEntity", sink.getEntityName())));
260 }
261
262
263
264
265 public List getSinkFromSource(GenericValue source, String sinkName, String associationType, boolean useCache)
266 throws GenericEntityException
267 {
268 return getSinkFromSource(source, sinkName, associationType, useCache, false);
269 }
270
271 public List getSinkFromSource(GenericValue source, String sinkName, String associationType, boolean useCache, boolean useSequence)
272 throws GenericEntityException
273 {
274 if (source == null)
275 {
276 throw new IllegalArgumentException("Source GenericValue can not be null.");
277 }
278
279 final List result = getSinkIdsFromSource(source, sinkName, associationType, useCache, useSequence);
280
281 final List outList = new ArrayList(result.size());
282 for (Iterator iterator = result.iterator(); iterator.hasNext();)
283 {
284 GenericValue value = (GenericValue) iterator.next();
285 GenericValue byPrimaryKey;
286 if (useCache)
287 {
288 byPrimaryKey = delegator.findByPrimaryKeyCache(sinkName, UtilMisc.toMap("id", value.getLong("sinkNodeId")));
289 }
290 else
291 {
292 byPrimaryKey = delegator.findByPrimaryKey(sinkName, UtilMisc.toMap("id", value.getLong("sinkNodeId")));
293 }
294
295 if (byPrimaryKey != null)
296 {
297 outList.add(byPrimaryKey);
298 }
299 }
300 return result.isEmpty() ? Collections.EMPTY_LIST : outList;
301 }
302
303 private List getSinkIdsFromSource(GenericValue source, String sinkName, String associationType, boolean useCache, boolean useSequence)
304 throws GenericEntityException
305 {
306 final Map fields = new HashMap();
307 fields.put("sourceNodeId", source.getLong("id"));
308 fields.put("sourceNodeEntity", source.getEntityName());
309 fields.put("associationType", associationType);
310 fields.put("sinkNodeEntity", sinkName);
311 return getAssociations("NodeAssociation", fields, useCache, useSequence);
312 }
313
314
315
316
317 public List getSourceFromSink(GenericValue sink, String sourceName, String associationType, boolean useCache)
318 throws GenericEntityException
319 {
320 return getSourceFromSink(sink, sourceName, associationType, useCache, false);
321 }
322
323
324
325
326 public List getSourceFromSink(GenericValue sink, String sourceName, String associationType, boolean useCache, boolean useSequence)
327 throws GenericEntityException
328 {
329 if (sink == null)
330 {
331 throw new IllegalArgumentException("Sink GenericValue can not be null.");
332 }
333 final List result = getSourceIdsFromSink(sink, associationType, sourceName, useCache, useSequence);
334 final List outList = new ArrayList(result.size());
335 for (Iterator iterator = result.iterator(); iterator.hasNext();)
336 {
337 GenericValue value = (GenericValue) iterator.next();
338 GenericPK pk = delegator.makePK(sourceName, UtilMisc.toMap("id", value.getLong("sourceNodeId")));
339 GenericValue byPrimaryKey;
340 if (useCache)
341 {
342 byPrimaryKey = delegator.findByPrimaryKeyCache(pk);
343 }
344 else
345 {
346 byPrimaryKey = delegator.findByPrimaryKey(pk);
347 }
348
349 if (byPrimaryKey != null)
350 {
351 outList.add(byPrimaryKey);
352 }
353 }
354 return result.isEmpty() ? Collections.EMPTY_LIST : outList;
355 }
356
357 private List getSourceIdsFromSink(GenericValue sink, String associationType, String sourceName, boolean useCache, boolean useSequence)
358 throws GenericEntityException
359 {
360 final Map fields = new HashMap();
361 fields.put("sinkNodeId", sink.getLong("id"));
362 fields.put("sinkNodeEntity", sink.getEntityName());
363 fields.put("associationType", associationType);
364 fields.put("sourceNodeEntity", sourceName);
365 return getAssociations("NodeAssociation", fields, useCache, useSequence);
366 }
367
368
369
370
371 public List getSinkFromUser(User source, String sinkName, String associationType, boolean useCache)
372 throws GenericEntityException
373 {
374 return getSinkFromUser(source, sinkName, associationType, useCache, false);
375 }
376
377 public List
378 throws GenericEntityException
379 {
380 final List result = getAssociationsForUser(source, sinkName, associationType, useCache, false);
381 CollectionUtils.transform(result, new Transformer()
382 {
383 public Object transform(Object input)
384 {
385 return ((GenericValue) input).getLong("sinkNodeId");
386 }
387 });
388 return result;
389 }
390
391
392
393
394 public List getSinkFromUser(User source, String sinkName, String associationType, boolean useCache, boolean useSequence)
395 throws GenericEntityException
396 {
397 final List result = getAssociationsForUser(source, sinkName, associationType, useCache, useSequence);
398
399 final List outList = new ArrayList(result.size());
400 for (Iterator iterator = result.iterator(); iterator.hasNext();)
401 {
402 GenericValue value = (GenericValue) iterator.next();
403 GenericPK pk = delegator.makePK(sinkName, UtilMisc.toMap("id", value.getLong("sinkNodeId")));
404 GenericValue byPrimaryKey;
405 if (useCache)
406 {
407 byPrimaryKey = delegator.findByPrimaryKeyCache(pk);
408 }
409 else
410 {
411 byPrimaryKey = delegator.findByPrimaryKey(pk);
412 }
413
414 if (byPrimaryKey != null)
415 {
416 outList.add(byPrimaryKey);
417 }
418 }
419 return result.isEmpty() ? Collections.EMPTY_LIST : outList;
420 }
421
422 private List getAssociationsForUser(final User source, final String sinkName, final String associationType, final boolean useCache, final boolean useSequence)
423 throws GenericEntityException
424 {
425 if (source == null)
426 {
427 throw new IllegalArgumentException("User can not be null.");
428 }
429 final Map fields = new HashMap();
430 fields.put("sourceName", source.getName());
431 fields.put("associationType", associationType);
432 fields.put("sinkNodeEntity", sinkName);
433 return getAssociations("UserAssociation", fields, useCache, useSequence);
434 }
435
436
437
438
439 public List getUserFromSink(GenericValue sink, String associationType, boolean useCache)
440 throws GenericEntityException, EntityNotFoundException
441 {
442 return getUserFromSink(sink, associationType, useCache, false);
443 }
444
445
446
447
448 public List
449 throws GenericEntityException, EntityNotFoundException
450 {
451 final List
452 final List
453 for (Iterator it = usernames.iterator(); it.hasNext();)
454 {
455 String username = (String) it.next();
456 try
457 {
458 final User user = UserUtils.getUser(username);
459 if (user != null)
460 {
461 users.add(user);
462 }
463 }
464 catch (EntityNotFoundException e)
465 {
466 log.error("Cannot find user with username '" + username + "'.", e);
467 }
468 }
469 return users;
470 }
471
472 public List
473 throws GenericEntityException
474 {
475 if (sink == null)
476 {
477 throw new IllegalArgumentException("Sink GenericValue can not be null.");
478 }
479
480 final Map fields = new HashMap();
481 fields.put("sinkNodeId", sink.getLong("id"));
482 fields.put("sinkNodeEntity", sink.getEntityName());
483 fields.put("associationType", associationType);
484
485 final List results = getAssociations("UserAssociation", fields, useCache, useSequence);
486 if (results.isEmpty())
487 {
488 return Collections.EMPTY_LIST;
489 }
490
491 final List outList = new ArrayList(results.size());
492 for (Iterator it = results.iterator(); it.hasNext();)
493 {
494 outList.add(((GenericValue) it.next()).getString("sourceName"));
495 }
496 return outList;
497 }
498
499 public List getSinkIdsFromSource(GenericValue source, String sinkEntity, String associationType)
500 throws GenericEntityException
501 {
502 List sinks = getSinkIdsFromSource(source, sinkEntity, associationType, false, false);
503
504 if (sinks != null && !sinks.isEmpty())
505 {
506 List sinkIds = new ArrayList();
507 for (Iterator iterator = sinks.iterator(); iterator.hasNext();)
508 {
509 GenericValue sink = (GenericValue) iterator.next();
510 sinkIds.add(sink.getLong("sinkNodeId"));
511 }
512 return sinkIds;
513 }
514
515 return Collections.EMPTY_LIST;
516 }
517
518 public List getSourceIdsFromSink(GenericValue sink, String sourceEntity, String associationType)
519 throws GenericEntityException
520 {
521 List sources = getSourceIdsFromSink(sink, associationType, sourceEntity, false, false);
522
523 if (sources != null && !sources.isEmpty())
524 {
525 List sourceIds = new ArrayList();
526 for (Iterator iterator = sources.iterator(); iterator.hasNext();)
527 {
528 GenericValue source = (GenericValue) iterator.next();
529 sourceIds.add(source.getLong("sourceNodeId"));
530 }
531 return sourceIds;
532 }
533
534 return Collections.EMPTY_LIST;
535 }
536
537 private GenericValue getAssociation(Long sourceNodeId, String sourceNodeEntity, Long sinkNodeId, String sinkNodeEntity, String associationType)
538 throws GenericEntityException
539 {
540 return EntityUtil.getOnly(delegator.findByAnd("NodeAssociation", UtilMisc.toMap("associationType", associationType, "sourceNodeId", sourceNodeId, "sourceNodeEntity", sourceNodeEntity, "sinkNodeId", sinkNodeId, "sinkNodeEntity", sinkNodeEntity)));
541 }
542
543 private GenericValue getAssociation(String sourceName, Long sinkNodeId, String sinkNodeEntity, String associationType)
544 throws GenericEntityException
545 {
546 return EntityUtil.getOnly(delegator.findByAnd("UserAssociation", UtilMisc.toMap("associationType", associationType, "sourceName", sourceName, "sinkNodeId", sinkNodeId, "sinkNodeEntity", sinkNodeEntity)));
547 }
548 }