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