1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.krms.impl.repository;
17
18 import java.util.ArrayList;
19 import java.util.Collection;
20 import java.util.Collections;
21 import java.util.HashMap;
22 import java.util.HashSet;
23 import java.util.List;
24 import java.util.Map;
25 import java.util.Map.Entry;
26 import java.util.Set;
27
28 import org.apache.commons.lang.StringUtils;
29 import org.kuali.rice.core.api.CoreApiServiceLocator;
30 import org.kuali.rice.core.api.criteria.CriteriaLookupService;
31 import org.kuali.rice.core.api.criteria.GenericQueryResults;
32 import org.kuali.rice.core.api.criteria.Predicate;
33 import org.kuali.rice.core.api.criteria.QueryByCriteria;
34 import org.kuali.rice.core.api.exception.RiceIllegalArgumentException;
35 import org.kuali.rice.core.api.exception.RiceIllegalStateException;
36 import org.kuali.rice.core.api.mo.ModelObjectUtils;
37 import org.kuali.rice.core.impl.services.CoreImplServiceLocator;
38 import org.kuali.rice.coreservice.api.CoreServiceApiServiceLocator;
39 import org.kuali.rice.coreservice.framework.CoreFrameworkServiceLocator;
40 import org.kuali.rice.krad.service.BusinessObjectService;
41 import org.kuali.rice.krad.service.KRADServiceLocator;
42 import org.kuali.rice.krad.service.SequenceAccessorService;
43 import org.kuali.rice.krms.api.repository.agenda.AgendaDefinition;
44 import org.kuali.rice.krms.api.repository.agenda.AgendaItemDefinition;
45 import org.kuali.rice.krms.api.repository.type.KrmsAttributeDefinition;
46 import org.kuali.rice.krms.impl.util.KrmsImplConstants.PropertyNames;
47 import org.springframework.util.CollectionUtils;
48
49 import static org.kuali.rice.core.api.criteria.PredicateFactory.in;
50
51
52
53
54
55
56
57
58 public final class AgendaBoServiceImpl implements AgendaBoService {
59
60
61
62 private BusinessObjectService businessObjectService;
63 private CriteriaLookupService criteriaLookupService;
64 private KrmsAttributeDefinitionService attributeDefinitionService;
65 private SequenceAccessorService sequenceAccessorService;
66
67
68 private static final ModelObjectUtils.Transformer<AgendaItemBo, AgendaItemDefinition> toAgendaItemDefinition =
69 new ModelObjectUtils.Transformer<AgendaItemBo, AgendaItemDefinition>() {
70 public AgendaItemDefinition transform(AgendaItemBo input) {
71 return AgendaItemBo.to(input);
72 };
73 };
74
75
76 private static final ModelObjectUtils.Transformer<AgendaBo, AgendaDefinition> toAgendaDefinition =
77 new ModelObjectUtils.Transformer<AgendaBo, AgendaDefinition>() {
78 public AgendaDefinition transform(AgendaBo input) {
79 return AgendaBo.to(input);
80 };
81 };
82
83
84
85
86
87 @Override
88 public AgendaDefinition createAgenda(AgendaDefinition agenda) {
89 if (agenda == null){
90 throw new RiceIllegalArgumentException("agenda is null");
91 }
92 final String nameKey = agenda.getName();
93 final String contextId = agenda.getContextId();
94 final AgendaDefinition existing = getAgendaByNameAndContextId(nameKey, contextId);
95 if (existing != null){
96 throw new IllegalStateException("the agenda to create already exists: " + agenda);
97 }
98
99 AgendaBo agendaBo = from(agenda);
100 businessObjectService.save(agendaBo);
101 return to(agendaBo);
102 }
103
104
105
106
107 @Override
108 public void updateAgenda(AgendaDefinition agenda) {
109 if (agenda == null){
110 throw new RiceIllegalArgumentException("agenda is null");
111 }
112
113
114 final String agendaIdKey = agenda.getId();
115 final AgendaBo existing = businessObjectService.findBySinglePrimaryKey(AgendaBo.class, agendaIdKey);
116 if (existing == null) {
117 throw new IllegalStateException("the agenda does not exist: " + agenda);
118 }
119 final AgendaDefinition toUpdate;
120 if (existing.getId().equals(agenda.getId())) {
121 toUpdate = agenda;
122 } else {
123
124 final AgendaDefinition.Builder builder = AgendaDefinition.Builder.create(agenda);
125 builder.setId(existing.getId());
126 toUpdate = builder.build();
127 }
128
129
130 AgendaBo boToUpdate = from(toUpdate);
131
132
133 Map<String,String> fields = new HashMap<String,String>(1);
134 fields.put(PropertyNames.Agenda.AGENDA_ID, toUpdate.getId());
135 businessObjectService.deleteMatching(AgendaAttributeBo.class, fields);
136
137
138 businessObjectService.save(boToUpdate);
139 }
140
141 @Override
142 public void deleteAgenda(String agendaId) {
143 if (agendaId == null){ throw new RiceIllegalArgumentException("agendaId is null"); }
144 final AgendaDefinition existing = getAgendaByAgendaId(agendaId);
145 if (existing == null){ throw new IllegalStateException("the Agenda to delete does not exists: " + agendaId);}
146 businessObjectService.delete(from(existing));
147 }
148
149
150
151
152 @Override
153 public AgendaDefinition getAgendaByAgendaId(String agendaId) {
154 if (StringUtils.isBlank(agendaId)){
155 throw new RiceIllegalArgumentException("agenda id is null");
156 }
157 AgendaBo bo = businessObjectService.findBySinglePrimaryKey(AgendaBo.class, agendaId);
158 return to(bo);
159 }
160
161
162
163
164 @Override
165 public AgendaDefinition getAgendaByNameAndContextId(String name, String contextId) {
166 if (StringUtils.isBlank(name)) {
167 throw new RiceIllegalArgumentException("name is blank");
168 }
169 if (StringUtils.isBlank(contextId)) {
170 throw new RiceIllegalArgumentException("contextId is blank");
171 }
172
173 final Map<String, Object> map = new HashMap<String, Object>();
174 map.put("name", name);
175 map.put("contextId", contextId);
176
177 AgendaBo myAgenda = businessObjectService.findByPrimaryKey(AgendaBo.class, Collections.unmodifiableMap(map));
178 return to(myAgenda);
179 }
180
181
182
183
184 @Override
185 public List<AgendaDefinition> getAgendasByContextId(String contextId) {
186 if (StringUtils.isBlank(contextId)){
187 throw new RiceIllegalArgumentException("context ID is null or blank");
188 }
189 final Map<String, Object> map = new HashMap<String, Object>();
190 map.put("contextId", contextId);
191 List<AgendaBo> bos = (List<AgendaBo>) businessObjectService.findMatching(AgendaBo.class, map);
192 return convertAgendaBosToImmutables(bos);
193 }
194
195
196
197
198 @Override
199 public AgendaItemDefinition createAgendaItem(AgendaItemDefinition agendaItem) {
200 if (agendaItem == null){
201 throw new RiceIllegalArgumentException("agendaItem is null");
202 }
203 if (agendaItem.getId() != null){
204 final AgendaDefinition existing = getAgendaByAgendaId(agendaItem.getId());
205 if (existing != null){
206 throw new IllegalStateException("the agendaItem to create already exists: " + agendaItem);
207 }
208 }
209
210 AgendaItemBo bo = AgendaItemBo.from(agendaItem);
211 businessObjectService.save(bo);
212 return AgendaItemBo.to(bo);
213 }
214
215
216
217
218 @Override
219 public void updateAgendaItem(AgendaItemDefinition agendaItem) {
220 if (agendaItem == null){
221 throw new RiceIllegalArgumentException("agendaItem is null");
222 }
223 final String agendaItemIdKey = agendaItem.getId();
224 final AgendaItemDefinition existing = getAgendaItemById(agendaItemIdKey);
225 if (existing == null) {
226 throw new IllegalStateException("the agenda item does not exist: " + agendaItem);
227 }
228 final AgendaItemDefinition toUpdate;
229 if (existing.getId().equals(agendaItem.getId())) {
230 toUpdate = agendaItem;
231 } else {
232 final AgendaItemDefinition.Builder builder = AgendaItemDefinition.Builder.create(agendaItem);
233 builder.setId(existing.getId());
234 toUpdate = builder.build();
235 }
236
237 businessObjectService.save(AgendaItemBo.from(toUpdate));
238 }
239
240
241
242
243 @Override
244 public void addAgendaItem(AgendaItemDefinition agendaItem, String parentId, Boolean position) {
245 if (agendaItem == null){
246 throw new RiceIllegalArgumentException("agendaItem is null");
247 }
248 AgendaItemDefinition parent = null;
249 if (parentId != null){
250 parent = getAgendaItemById(parentId);
251 if (parent == null){
252 throw new IllegalStateException("parent agendaItem does not exist in repository. parentId = " + parentId);
253 }
254 }
255
256 final AgendaItemDefinition toCreate;
257 if (agendaItem.getId() == null) {
258 SequenceAccessorService sas = getSequenceAccessorService();
259 final AgendaItemDefinition.Builder builder = AgendaItemDefinition.Builder.create(agendaItem);
260 final String newId =sas.getNextAvailableSequenceNumber(
261 "KRMS_AGENDA_ITM_S", AgendaItemBo.class).toString();
262 builder.setId(newId);
263 toCreate = builder.build();
264 } else {
265 toCreate = agendaItem;
266 }
267 createAgendaItem(toCreate);
268
269
270 if (parentId != null) {
271 final AgendaItemDefinition.Builder builder = AgendaItemDefinition.Builder.create(parent);
272 if (position == null){
273 builder.setAlwaysId( toCreate.getId() );
274 } else if (position.booleanValue()){
275 builder.setWhenTrueId( toCreate.getId() );
276 } else if (!position.booleanValue()){
277 builder.setWhenFalseId( toCreate.getId() );
278 }
279 final AgendaItemDefinition parentToUpdate = builder.build();
280 updateAgendaItem( parentToUpdate );
281 }
282 }
283
284
285
286
287 @Override
288 public AgendaItemDefinition getAgendaItemById(String id) {
289 if (StringUtils.isBlank(id)){
290 throw new RiceIllegalArgumentException("agenda item id is null or blank");
291 }
292 AgendaItemBo bo = businessObjectService.findBySinglePrimaryKey(AgendaItemBo.class, id);
293 return AgendaItemBo.to(bo);
294 }
295
296 @Override
297 public List<AgendaItemDefinition> getAgendaItemsByAgendaId(String agendaId) {
298 if (StringUtils.isBlank(agendaId)){
299 throw new RiceIllegalArgumentException("agenda id is null or null");
300 }
301 List<AgendaItemDefinition> results = null;
302
303 Collection<AgendaItemBo> bos = businessObjectService.findMatching(AgendaItemBo.class, Collections.singletonMap("agendaId", agendaId));
304
305 if (CollectionUtils.isEmpty(bos)) {
306 results = Collections.emptyList();
307 } else {
308 results = Collections.unmodifiableList(ModelObjectUtils.transform(bos, toAgendaItemDefinition));
309 }
310
311 return results;
312 }
313
314 @Override
315 public List<AgendaDefinition> getAgendasByType(String typeId) throws RiceIllegalArgumentException {
316 if (StringUtils.isBlank(typeId)){
317 throw new RiceIllegalArgumentException("type ID is null or blank");
318 }
319 final Map<String, Object> map = new HashMap<String, Object>();
320 map.put("typeId", typeId);
321 List<AgendaBo> bos = (List<AgendaBo>) businessObjectService.findMatching(AgendaBo.class, map);
322 return convertAgendaBosToImmutables(bos);
323 }
324
325 @Override
326 public List<AgendaDefinition> getAgendasByTypeAndContext(String typeId,
327 String contextId) throws RiceIllegalArgumentException {
328 if (StringUtils.isBlank(typeId)){
329 throw new RiceIllegalArgumentException("type ID is null or blank");
330 }
331 if (StringUtils.isBlank(contextId)){
332 throw new RiceIllegalArgumentException("context ID is null or blank");
333 }
334 final Map<String, Object> map = new HashMap<String, Object>();
335 map.put("typeId", typeId);
336 map.put("contextId", contextId);
337 Collection<AgendaBo> bos = businessObjectService.findMatching(AgendaBo.class, map);
338 return convertAgendaBosToImmutables(bos);
339 }
340
341 @Override
342 public List<AgendaItemDefinition> getAgendaItemsByType(String typeId) throws RiceIllegalArgumentException {
343 return findAgendaItemsForAgendas(getAgendasByType(typeId));
344 }
345
346 @Override
347 public List<AgendaItemDefinition> getAgendaItemsByContext(String contextId) throws RiceIllegalArgumentException {
348 return findAgendaItemsForAgendas(getAgendasByContextId(contextId));
349 }
350
351 @Override
352 public List<AgendaItemDefinition> getAgendaItemsByTypeAndContext(String typeId,
353 String contextId) throws RiceIllegalArgumentException {
354 return findAgendaItemsForAgendas(getAgendasByTypeAndContext(typeId, contextId));
355 }
356
357 @Override
358 public void deleteAgendaItem(String agendaItemId) throws RiceIllegalArgumentException {
359 if (StringUtils.isBlank(agendaItemId)) {
360 throw new RiceIllegalArgumentException("agendaItemId must not be blank or null");
361 }
362
363 businessObjectService.deleteMatching(AgendaItemBo.class, Collections.singletonMap("id", agendaItemId));
364 }
365
366 private List<AgendaItemDefinition> findAgendaItemsForAgendas(List<AgendaDefinition> agendaDefinitions) {
367 List<AgendaItemDefinition> results = null;
368
369 if (!CollectionUtils.isEmpty(agendaDefinitions)) {
370 List<AgendaItemBo> boResults = new ArrayList<AgendaItemBo>(agendaDefinitions.size());
371
372 List<String> agendaIds = new ArrayList<String>(20);
373 for (AgendaDefinition agendaDefinition : agendaDefinitions) {
374 agendaIds.add(agendaDefinition.getId());
375
376 if (agendaIds.size() == 20) {
377
378
379 Predicate predicate = in("agendaId", agendaIds.toArray());
380 QueryByCriteria criteria = QueryByCriteria.Builder.fromPredicates(predicate);
381 GenericQueryResults<AgendaItemBo> batch = criteriaLookupService.lookup(AgendaItemBo.class, criteria);
382
383 boResults.addAll(batch.getResults());
384
385
386 agendaIds.clear();
387 }
388 }
389
390 if (agendaIds.size() > 0) {
391 Predicate predicate = in("agendaId", agendaIds.toArray());
392 QueryByCriteria criteria = QueryByCriteria.Builder.fromPredicates(predicate);
393 GenericQueryResults<AgendaItemBo> batch = criteriaLookupService.lookup(AgendaItemBo.class, criteria);
394
395 boResults.addAll(batch.getResults());
396 }
397
398 results = Collections.unmodifiableList(ModelObjectUtils.transform(boResults, toAgendaItemDefinition));
399 } else {
400 results = Collections.emptyList();
401 }
402
403 return results;
404 }
405
406 public CriteriaLookupService getCriteriaLookupService() {
407 if (criteriaLookupService == null) {
408 criteriaLookupService = KrmsRepositoryServiceLocator.getCriteriaLookupService();
409 }
410 return criteriaLookupService;
411 }
412
413 public void setCriteriaLookupService(CriteriaLookupService criteriaLookupService) {
414 this.criteriaLookupService = criteriaLookupService;
415 }
416
417
418
419
420
421
422 public void setBusinessObjectService(final BusinessObjectService businessObjectService) {
423 this.businessObjectService = businessObjectService;
424 }
425
426 protected BusinessObjectService getBusinessObjectService() {
427 if ( businessObjectService == null ) {
428 businessObjectService = KRADServiceLocator.getBusinessObjectService();
429 }
430 return businessObjectService;
431 }
432
433
434
435
436
437
438 public void setSequenceAccessorService(final SequenceAccessorService sequenceAccessorService) {
439 this.sequenceAccessorService = sequenceAccessorService;
440 }
441
442 protected SequenceAccessorService getSequenceAccessorService() {
443 if ( sequenceAccessorService == null ) {
444 sequenceAccessorService = KRADServiceLocator.getSequenceAccessorService();
445 }
446 return sequenceAccessorService;
447 }
448
449 protected KrmsAttributeDefinitionService getAttributeDefinitionService() {
450 if (attributeDefinitionService == null) {
451 attributeDefinitionService = KrmsRepositoryServiceLocator.getKrmsAttributeDefinitionService();
452 }
453 return attributeDefinitionService;
454 }
455
456 public void setAttributeDefinitionService(KrmsAttributeDefinitionService attributeDefinitionService) {
457 this.attributeDefinitionService = attributeDefinitionService;
458 }
459
460
461
462
463
464
465
466 public List<AgendaDefinition> convertAgendaBosToImmutables(final Collection<AgendaBo> agendaBos) {
467 if (CollectionUtils.isEmpty(agendaBos)) {
468 return Collections.emptyList();
469 }
470 return Collections.unmodifiableList(ModelObjectUtils.transform(agendaBos, toAgendaDefinition));
471 }
472
473
474
475
476
477
478 @Override
479 public AgendaDefinition to(AgendaBo bo) {
480 if (bo == null) { return null; }
481 return org.kuali.rice.krms.api.repository.agenda.AgendaDefinition.Builder.create(bo).build();
482 }
483
484
485
486
487
488
489
490 @Override
491 public AgendaBo from(AgendaDefinition im) {
492 if (im == null) { return null; }
493
494 AgendaBo bo = new AgendaBo();
495 bo.setId(im.getId());
496 bo.setName( im.getName() );
497 bo.setTypeId( im.getTypeId() );
498 bo.setContextId( im.getContextId() );
499 bo.setFirstItemId( im.getFirstItemId() );
500 bo.setVersionNumber( im.getVersionNumber() );
501 Set<AgendaAttributeBo> attributes = buildAgendaAttributeBo(im);
502
503 bo.setAttributeBos(attributes);
504
505 return bo;
506 }
507
508 private Set<AgendaAttributeBo> buildAgendaAttributeBo(AgendaDefinition im) {
509 Set<AgendaAttributeBo> attributes = new HashSet<AgendaAttributeBo>();
510
511
512 Map<String, KrmsAttributeDefinition> attributeDefinitionMap = new HashMap<String, KrmsAttributeDefinition>();
513
514 List<KrmsAttributeDefinition> attributeDefinitions =
515 getAttributeDefinitionService().findAttributeDefinitionsByType(im.getTypeId());
516
517 for (KrmsAttributeDefinition attributeDefinition : attributeDefinitions) {
518 attributeDefinitionMap.put(attributeDefinition.getName(), attributeDefinition);
519 }
520
521
522 for (Entry<String,String> entry : im.getAttributes().entrySet()){
523 KrmsAttributeDefinition attrDef = attributeDefinitionMap.get(entry.getKey());
524
525 if (attrDef != null) {
526 AgendaAttributeBo attributeBo = new AgendaAttributeBo();
527 attributeBo.setAgendaId( im.getId() );
528 attributeBo.setAttributeDefinitionId(attrDef.getId());
529 attributeBo.setValue(entry.getValue());
530 attributeBo.setAttributeDefinition(KrmsAttributeDefinitionBo.from(attrDef));
531 attributes.add( attributeBo );
532 } else {
533 throw new RiceIllegalStateException("there is no attribute definition with the name '" +
534 entry.getKey() + "' that is valid for the agenda type with id = '" + im.getTypeId() +"'");
535 }
536 }
537 return attributes;
538 }
539
540 }