1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  package org.kuali.student.r2.lum.lu.service.impl;
16  
17  import org.apache.log4j.Logger;
18  import org.kuali.rice.core.api.criteria.QueryByCriteria;
19  import org.kuali.student.r1.common.dictionary.dto.ObjectStructureDefinition;
20  import org.kuali.student.r1.common.dictionary.service.DictionaryService;
21  import org.kuali.student.r1.common.entity.Amount;
22  import org.kuali.student.r1.common.entity.TimeAmount;
23  import org.kuali.student.r1.common.entity.Version;
24  import org.kuali.student.r1.common.entity.VersionEntity;
25  import org.kuali.student.r2.common.dto.ContextInfo;
26  import org.kuali.student.r2.common.dto.DtoConstants;
27  import org.kuali.student.r2.common.dto.StatusInfo;
28  import org.kuali.student.r2.common.dto.ValidationResultInfo;
29  import org.kuali.student.r2.common.exceptions.*;
30  import org.kuali.student.r2.core.search.dto.*;
31  import org.kuali.student.r2.core.search.service.SearchManager;
32  import org.kuali.student.r2.core.search.service.SearchService;
33  import org.kuali.student.r2.common.validator.Validator;
34  import org.kuali.student.r2.common.validator.ValidatorFactory;
35  import org.kuali.student.r2.core.class1.type.dto.TypeInfo;
36  import org.kuali.student.r2.core.versionmanagement.dto.VersionDisplayInfo;
37  import org.kuali.student.r2.lum.clu.dto.*;
38  import org.kuali.student.r2.lum.clu.service.CluService;
39  import org.kuali.student.r2.lum.lu.dao.LuDao;
40  import org.kuali.student.r2.lum.lu.entity.*;
41  import org.kuali.student.r2.lum.util.constants.CluServiceConstants;
42  import org.springframework.beans.BeanUtils;
43  import org.springframework.transaction.annotation.Transactional;
44  
45  import javax.jws.WebParam;
46  import javax.jws.WebService;
47  import javax.persistence.NoResultException;
48  import java.util.*;
49  import java.util.Map.Entry;
50  
51  @WebService(endpointInterface = "org.kuali.student.r2.lum.clu.service.CluService", serviceName = "CluService", portName = "CluService", targetNamespace = "http://student.kuali.org/wsdl/clu")
52  @Transactional(readOnly=true,noRollbackFor={DoesNotExistException.class},rollbackFor={Throwable.class})
53  public class CluServiceImpl implements CluService {
54  
55      private static final String SEARCH_KEY_DEPENDENCY_ANALYSIS = "lu.search.dependencyAnalysis";
56      private static final String SEARCH_KEY_BROWSE_PROGRAM = "lu.search.browseProgram";
57      private static final String SEARCH_KEY_BROWSE_VARIATIONS = "lu.search.browseVariations";
58      private static final String SEARCH_KEY_RESULT_COMPONENT = "lrc.search.resultComponent";
59      private static final String SEARCH_KEY_PROPOSALS_BY_COURSE_CODE = "lu.search.proposalsByCourseCode";
60      private static final String SEARCH_KEY_BROWSE_VERSIONS = "lu.search.clu.versions";
61      private static final String SEARCH_KEY_LU_RESULT_COMPONENTS = "lu.search.resultComponents";
62      private static final String SEARCH_KEY_CLUSET_SEARCH_GENERIC = "cluset.search.generic";
63      private static final String SEARCH_KEY_CLUSET_SEARCH_GENERICWITHCLUS = "cluset.search.genericWithClus";
64  
65      final Logger logger = Logger.getLogger(CluServiceImpl.class);
66      private LuDao luDao;
67      private ValidatorFactory validatorFactory;
68      private DictionaryService dictionaryServiceDelegate;
69      private SearchService searchDispatcher;
70      private SearchManager searchManager;
71  
72      public void setDictionaryServiceDelegate(
73              DictionaryService dictionaryServiceDelegate) {
74          this.dictionaryServiceDelegate = dictionaryServiceDelegate;
75      }
76  
77      public DictionaryService getDictionaryServiceDelegate() {
78          return dictionaryServiceDelegate;
79      }
80  
81      @Override
82      public List<TypeInfo> getSearchTypes( ContextInfo contextInfo) throws InvalidParameterException, MissingParameterException, OperationFailedException {
83          return searchManager.getSearchTypes(contextInfo);
84      }
85  
86      @Override
87      public TypeInfo getSearchType(@WebParam(name = "searchTypeKey") String searchTypeKey, @WebParam(name = "contextInfo") ContextInfo contextInfo) throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException {
88          checkForMissingParameter(searchTypeKey, "searchTypeKey");
89          return searchManager.getSearchType(searchTypeKey, contextInfo);
90      }
91  
92      public SearchManager getSearchManager() {
93          return searchManager;
94      }
95  
96      public void setSearchManager(SearchManager searchManager) {
97          this.searchManager = searchManager;
98      }
99  
100     
101 
102 
103     @Override
104     public List<TypeInfo> getDeliveryMethodTypes(ContextInfo context)
105             throws OperationFailedException {
106         return CluServiceAssembler.toGenericTypeInfoList(luDao.find(DeliveryMethodType.class));
107     }
108 
109     @Override
110     public TypeInfo getDeliveryMethodType(
111             String deliveryMethodTypeKey, ContextInfo context) throws DoesNotExistException,
112             InvalidParameterException, MissingParameterException,
113             OperationFailedException {
114 
115         checkForMissingParameter(deliveryMethodTypeKey, "deliveryMethodTypeKey");
116         try {
117             return CluServiceAssembler.toGenericTypeInfo(luDao.fetch(
118                     DeliveryMethodType.class, deliveryMethodTypeKey));
119         } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException ex) {
120             throw new DoesNotExistException(deliveryMethodTypeKey, ex);
121         }
122     }
123 
124     @Override
125     public List<TypeInfo> getInstructionalFormatTypes(ContextInfo context)
126             throws OperationFailedException {
127         return CluServiceAssembler.toGenericTypeInfoList(luDao.find(InstructionalFormatType.class));
128     }
129 
130     @Override
131     public TypeInfo getInstructionalFormatType(
132             String instructionalFormatTypeKey, ContextInfo context) throws DoesNotExistException,
133             InvalidParameterException, MissingParameterException,
134             OperationFailedException {
135         checkForMissingParameter(instructionalFormatTypeKey,
136                 "instructionalFormatTypeKey");
137         try {
138             return CluServiceAssembler.toGenericTypeInfo(luDao.fetch(
139                     InstructionalFormatType.class, instructionalFormatTypeKey));
140         } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException ex) {
141             throw new DoesNotExistException(instructionalFormatTypeKey, ex);
142         }
143     }
144 
145     @Override
146     public List<TypeInfo> getLuTypes(ContextInfo context) throws OperationFailedException {
147         return CluServiceAssembler.toGenericTypeInfoList(luDao.find(LuType.class));
148     }
149 
150     @Override
151     public TypeInfo getLuType(String luTypeKey, ContextInfo context) throws DoesNotExistException,
152             InvalidParameterException, MissingParameterException,
153             OperationFailedException {
154         checkForMissingParameter(luTypeKey, "luTypeKey");
155         try {
156             return CluServiceAssembler.toGenericTypeInfo(luDao.fetch(LuType.class,
157                     luTypeKey));
158         } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException ex) {
159             throw new DoesNotExistException(luTypeKey,ex);
160         }
161     }
162 
163     @Override
164     public TypeInfo getLuCodeType(String luCodeTypeKey, ContextInfo context)
165             throws DoesNotExistException, InvalidParameterException,
166             MissingParameterException, OperationFailedException {
167         try {
168             checkForMissingParameter(luCodeTypeKey, "luCodeTypeKey");
169             return CluServiceAssembler.toGenericTypeInfo(luDao.fetch(
170                     LuCodeType.class, luCodeTypeKey));
171         } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException ex) {
172             throw new DoesNotExistException(luCodeTypeKey, ex);
173         }
174     }
175 
176     @Override
177     public List<TypeInfo> getLuCodeTypes(ContextInfo context)
178             throws OperationFailedException {
179         return CluServiceAssembler.toGenericTypeInfoList(luDao.find(LuCodeType.class));
180     }
181 
182     @Override
183     public List<TypeInfo> getCluCluRelationTypes(ContextInfo context)
184             throws OperationFailedException {
185         return CluServiceAssembler.toLuLuRelationTypeInfos(luDao.find(LuLuRelationType.class));
186     }
187 
188     @Override
189     public TypeInfo getLuLuRelationType(String luLuRelationTypeKey, ContextInfo context)
190             throws OperationFailedException, MissingParameterException,
191             DoesNotExistException {
192         checkForMissingParameter(luLuRelationTypeKey, "luLuRelationTypeKey");
193 
194         LuLuRelationType luLuRelationType;
195         try {
196             luLuRelationType = luDao.fetch(LuLuRelationType.class,
197                     luLuRelationTypeKey);
198         } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException ex) {
199             throw new DoesNotExistException(luLuRelationTypeKey, ex);
200         }
201         return CluServiceAssembler.toLuLuRelationTypeInfo(luLuRelationType);
202     }
203 
204     @Override
205     public List<String> getAllowedLuLuRelationTypesForLuType(String luTypeKey,
206                                                              String relatedLuTypeKey, ContextInfo context) throws DoesNotExistException,
207             InvalidParameterException, MissingParameterException,
208             OperationFailedException {
209         checkForMissingParameter(luTypeKey, "luTypeKey");
210         checkForMissingParameter(relatedLuTypeKey, "relatedLuTypeKey");
211 
212         return luDao.getAllowedLuLuRelationTypesForLuType(luTypeKey,
213                 relatedLuTypeKey);
214     }
215 
216     @Override
217     public List<TypeInfo> getLuPublicationTypes(ContextInfo context)
218             throws OperationFailedException {
219         return CluServiceAssembler.toGenericTypeInfoList(luDao.find(LuPublicationType.class));
220     }
221 
222     @Override
223     public TypeInfo getLuPublicationType(
224             String luPublicationTypeKey, ContextInfo context) throws DoesNotExistException,
225             InvalidParameterException, MissingParameterException,
226             OperationFailedException {
227         checkForMissingParameter(luPublicationTypeKey, "luPublicationTypeKey");
228         try {
229             return CluServiceAssembler.toGenericTypeInfo(luDao.fetch(
230                     LuPublicationType.class, luPublicationTypeKey));
231         } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException ex) {
232             throw new DoesNotExistException(luPublicationTypeKey, ex);
233         }
234     }
235 
236     @Override
237     public List<String> getLuPublicationTypesForLuType(String luTypeKey, ContextInfo context)
238             throws DoesNotExistException, InvalidParameterException,
239             MissingParameterException, OperationFailedException {
240         throw new UnsupportedOperationException("getLuPublicationTypesForLuType");
241     }
242 
243     @Override
244     public List<TypeInfo> getCluResultTypes(ContextInfo context)
245             throws OperationFailedException {
246         return CluServiceAssembler.toGenericTypeInfoList(luDao.find(CluResultType.class));
247     }
248 
249     @Override
250     public TypeInfo getCluResultType(String cluResultTypeKey, ContextInfo context)
251             throws DoesNotExistException, InvalidParameterException,
252             MissingParameterException, OperationFailedException {
253         try {
254             return CluServiceAssembler.toGenericTypeInfo(luDao.fetch(
255                     CluResultType.class, cluResultTypeKey));
256         } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException ex) {
257             throw new DoesNotExistException(cluResultTypeKey, ex);
258         }
259     }
260 
261     @Override
262     public List<TypeInfo> getCluResultTypesForLuType(String luTypeKey, ContextInfo context)
263             throws DoesNotExistException, InvalidParameterException,
264             MissingParameterException, OperationFailedException {
265         checkForMissingParameter(luTypeKey, "luTypeKey");
266         return CluServiceAssembler.toGenericTypeInfoList(luDao.getAllowedCluResultTypesForLuType(luTypeKey));
267     }
268 
269     @Override
270     public List<TypeInfo> getResultUsageTypes(ContextInfo context)
271             throws OperationFailedException {
272         return CluServiceAssembler.toGenericTypeInfoList(luDao.find(ResultUsageType.class));
273     }
274 
275     @Override
276     public TypeInfo getResultUsageType(String resultUsageTypeKey, ContextInfo context)
277             throws DoesNotExistException, InvalidParameterException,
278             MissingParameterException, OperationFailedException {
279         checkForMissingParameter(resultUsageTypeKey, "resultUsageTypeKey");
280         try {
281             return CluServiceAssembler.toGenericTypeInfo(luDao.fetch(
282                     ResultUsageType.class, resultUsageTypeKey));
283         } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException ex) {
284             throw new DoesNotExistException(resultUsageTypeKey, ex);
285         }
286     }
287 
288     @Override
289     public List<String> getAllowedResultUsageTypesForLuType(String luTypeKey, ContextInfo context)
290             throws DoesNotExistException, InvalidParameterException,
291             MissingParameterException, OperationFailedException {
292         checkForMissingParameter(luTypeKey, "luTypeKey");
293 
294         return luDao.getAllowedResultUsageTypesForLuType(luTypeKey);
295     }
296 
297     @Override
298     public List<String> getAllowedResultComponentTypesForResultUsageType(
299             String resultUsageTypeKey, ContextInfo context) throws DoesNotExistException,
300             InvalidParameterException, MissingParameterException,
301             OperationFailedException {
302 
303         checkForMissingParameter(resultUsageTypeKey, "resultUsageTypeKey");
304 
305         return luDao.getAllowedResultComponentTypesForResultUsageType(resultUsageTypeKey);
306     }
307 
308     @Override
309     public TypeInfo getCluLoRelationType(
310             String cluLoRelationTypeKey, ContextInfo context) throws DoesNotExistException,
311             InvalidParameterException, MissingParameterException,
312             OperationFailedException {
313         checkForMissingParameter(cluLoRelationTypeKey, "cluLoRelationTypeKey");
314 
315         CluLoRelationType cluLoRelationType;
316         try {
317             cluLoRelationType = luDao.fetch(
318                     CluLoRelationType.class, cluLoRelationTypeKey);
319         } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException ex) {
320             throw new DoesNotExistException(cluLoRelationTypeKey, ex);
321         }
322         return CluServiceAssembler.toGenericTypeInfo(cluLoRelationType);
323     }
324 
325     @Override
326     public List<TypeInfo> getCluLoRelationTypes(ContextInfo context)
327             throws OperationFailedException {
328         return CluServiceAssembler.toGenericTypeInfoList(luDao.find(CluLoRelationType.class));
329     }
330 
331     @Override
332     public List<String> getAllowedCluLoRelationTypesForLuType(String luTypeKey, ContextInfo context)
333             throws DoesNotExistException, InvalidParameterException,
334             MissingParameterException, OperationFailedException {
335 
336         checkForMissingParameter(luTypeKey, luTypeKey);
337 
338         return luDao.getAllowedCluLoRelationTypesForLuType(luTypeKey);
339     }
340 
341     @Override
342     public List<TypeInfo> getCluSetTypes(ContextInfo context)
343             throws OperationFailedException {
344         return CluServiceAssembler.toGenericTypeInfoList(luDao.find(CluSetType.class));
345     }
346 
347     @Override
348     public TypeInfo getCluSetType(String cluSetTypeKey, ContextInfo context)
349             throws DoesNotExistException, InvalidParameterException,
350             MissingParameterException, OperationFailedException {
351         checkForMissingParameter(cluSetTypeKey, "cluSetTypeKey");
352         try {
353             return CluServiceAssembler.toGenericTypeInfo(luDao.fetch(
354                     CluSetType.class, cluSetTypeKey));
355         } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException ex) {
356             throw new DoesNotExistException(cluSetTypeKey, ex);
357         }
358     }
359 
360     
361 
362 
363     
364     @Override
365     public CluInfo getClu(String cluId, ContextInfo context) throws DoesNotExistException,
366             InvalidParameterException, MissingParameterException,
367             OperationFailedException {
368 
369         checkForMissingParameter(cluId, "cluId");
370 
371         Clu clu;
372         try {
373             clu = luDao.fetch(Clu.class, cluId);
374         } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException ex) {
375             throw new DoesNotExistException(cluId, ex);
376         }
377         return CluServiceAssembler.toCluInfo(clu);
378     }
379 
380     @Override
381     public List<CluInfo> getClusByIds(List<String> cluIds, ContextInfo context)
382             throws DoesNotExistException, InvalidParameterException,
383             MissingParameterException, OperationFailedException {
384         checkForMissingParameter(cluIds, "cluIds");
385         checkForEmptyList(cluIds, "cluIds");
386         List<Clu> clus = luDao.getClusByIdList(cluIds);
387         return CluServiceAssembler.toCluInfos(clus);
388     }
389 
390     @Override
391     public List<CluInfo> getClusByLuType(String luTypeKey, String luState, ContextInfo context)
392             throws DoesNotExistException, InvalidParameterException,
393             MissingParameterException, OperationFailedException {
394         checkForMissingParameter(luTypeKey, "luTypeKey");
395         checkForMissingParameter(luState, "lustate");
396         List<Clu> clus = luDao.getClusByLuType(luTypeKey, luState);
397         return CluServiceAssembler.toCluInfos(clus);
398     }
399 
400     @Override
401     public List<String> getCluIdsByLuType(String luTypeKey, String luState, ContextInfo context)
402             throws DoesNotExistException, InvalidParameterException,
403             MissingParameterException, OperationFailedException {
404         checkForMissingParameter(luTypeKey, "luTypeKey");
405         checkForMissingParameter(luState, "luState");
406         List<Clu> clus = luDao.getClusByLuType(luTypeKey, luState);
407         List<String> Ids = new ArrayList<String>(clus.size());
408         for (Clu clu : clus) {
409             Ids.add(clu.getId());
410         }
411         return Ids;
412     }
413 
414     
415     @Override
416     public List<String> getAllowedCluCluRelationTypesByClu(String cluId,
417                                                            String relatedCluId, ContextInfo context) throws DoesNotExistException,
418             InvalidParameterException, MissingParameterException,
419             OperationFailedException {
420         checkForMissingParameter(cluId, "cluId");
421         checkForMissingParameter(relatedCluId, "relatedCluId");
422 
423         return luDao.getAllowedLuLuRelationTypesByCluId(cluId, relatedCluId);
424     }
425 
426     @Override
427     public List<CluInfo> getClusByRelatedCluAndRelationType(String relatedCluId,
428                                                             String luLuRelationTypeKey, ContextInfo context) throws DoesNotExistException,
429             InvalidParameterException, MissingParameterException,
430             OperationFailedException {
431         checkForMissingParameter(relatedCluId, "relatedCluId");
432         checkForMissingParameter(luLuRelationTypeKey, "luLuRelationTypeKey");
433 
434         List<Clu> clus = luDao.getClusByRelation(relatedCluId,
435                 luLuRelationTypeKey);
436         List<CluInfo> result = CluServiceAssembler.toCluInfos(clus);
437         return result;
438 
439     }
440 
441     @Override
442     public List<String> getCluIdsByRelatedCluAndRelationType(String relatedCluId,
443                                                              String cluCluRelationTypeKey,
444                                                              ContextInfo contextInfo)
445             throws DoesNotExistException,
446             InvalidParameterException,
447             MissingParameterException,
448             OperationFailedException,
449             PermissionDeniedException {
450 
451         checkForMissingParameter(relatedCluId, "relatedCluId");
452         checkForMissingParameter(cluCluRelationTypeKey, "cluCluRelationTypeKey");
453 
454         List<String> cluIds = luDao.getCluIdsByRelatedCluId(relatedCluId, cluCluRelationTypeKey);
455         return cluIds;
456     }
457 
458     @Override
459     public List<CluInfo> getRelatedClusByCluAndRelationType(String relatedCluId,
460                                                             String cluCLuRelationTypeKey,
461                                                             ContextInfo contextInfo)
462             throws DoesNotExistException,
463             InvalidParameterException,
464             MissingParameterException,
465             OperationFailedException,
466             PermissionDeniedException {
467         checkForMissingParameter(relatedCluId, "cluId");
468         checkForMissingParameter(cluCLuRelationTypeKey, "cluCLuRelationTypeKey");
469         List<Clu> relatedClus = luDao.getRelatedClusByCluId(relatedCluId,
470                 cluCLuRelationTypeKey);
471         return CluServiceAssembler.toCluInfos(relatedClus);
472     }
473 
474     @Override
475     public List<String> getRelatedCluIdsByCluAndRelationType(String cluId,
476                                                              String luLuRelationTypeKey, ContextInfo context) throws DoesNotExistException,
477             InvalidParameterException, MissingParameterException,
478             OperationFailedException {
479         checkForMissingParameter(cluId, "cluId");
480         checkForMissingParameter(luLuRelationTypeKey, "luLuRelationTypeKey");
481         List<String> relatedCluIds = luDao.getRelatedCluIdsByCluId(cluId,
482                 luLuRelationTypeKey);
483         return relatedCluIds;
484     }
485 
486     @Override
487     public CluCluRelationInfo getCluCluRelation(String cluCluRelationId, ContextInfo context)
488             throws DoesNotExistException, InvalidParameterException,
489             MissingParameterException, OperationFailedException {
490         checkForMissingParameter(cluCluRelationId, "cluCluRelationId");
491         try {
492             return CluServiceAssembler.toCluCluRelationInfo(luDao.fetch(
493                     CluCluRelation.class, cluCluRelationId));
494         } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException ex) {
495             throw new DoesNotExistException(cluCluRelationId, ex);
496         }
497     }
498 
499     @Override
500     public List<CluCluRelationInfo> getCluCluRelationsByClu(String cluId, ContextInfo context)
501             throws DoesNotExistException, InvalidParameterException,
502             MissingParameterException, OperationFailedException {
503         checkForMissingParameter(cluId, "cluId");
504         List<CluCluRelation> cluCluRelations = luDao.getCluCluRelationsByClu(cluId);
505         return CluServiceAssembler.toCluCluRelationInfos(cluCluRelations);
506     }
507 
508     
509     @Override
510     public List<CluPublicationInfo> getCluPublicationsByClu(String cluId, ContextInfo context)
511             throws DoesNotExistException, InvalidParameterException,
512             MissingParameterException, OperationFailedException {
513         checkForMissingParameter(cluId, "cluId");
514         List<CluPublication> cluPublications = luDao.getCluPublicationsByCluId(cluId);
515         return CluServiceAssembler.toCluPublicationInfos(cluPublications);
516     }
517 
518     @Override
519     public List<CluPublicationInfo> getCluPublicationsByType(
520             String luPublicationTypeKey, ContextInfo context) throws DoesNotExistException,
521             InvalidParameterException, MissingParameterException,
522             OperationFailedException {
523         checkForMissingParameter(luPublicationTypeKey, "luPublicationTypeKey");
524         List<CluPublication> cluPublications = luDao.getCluPublicationsByType(luPublicationTypeKey);
525         return CluServiceAssembler.toCluPublicationInfos(cluPublications);
526     }
527 
528     @Override
529     public CluPublicationInfo getCluPublication(String cluPublicationId, ContextInfo context)
530             throws DoesNotExistException, InvalidParameterException,
531             MissingParameterException, OperationFailedException {
532         checkForMissingParameter(cluPublicationId, "cluPublicationId");
533         CluPublication cluPublication;
534         try {
535             cluPublication = luDao.fetch(CluPublication.class, cluPublicationId);
536         } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException ex) {
537             throw new DoesNotExistException(cluPublicationId, ex);
538         }
539         return CluServiceAssembler.toCluPublicationInfo(cluPublication);
540     }
541 
542     
543     @Override
544     public CluResultInfo getCluResult(String cluResultId, ContextInfo context)
545             throws DoesNotExistException, InvalidParameterException,
546             MissingParameterException, OperationFailedException {
547 
548         checkForMissingParameter(cluResultId, "cluResultId");
549 
550         CluResult cluResult;
551         try {
552             cluResult = luDao.fetch(CluResult.class, cluResultId);
553         } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException ex) {
554             throw new DoesNotExistException(cluResultId, ex);
555         }
556         return CluServiceAssembler.toCluResultInfo(cluResult);
557     }
558 
559     @Override
560     public List<CluResultInfo> getCluResultByClu(String cluId, ContextInfo context)
561             throws DoesNotExistException, InvalidParameterException,
562             MissingParameterException, OperationFailedException {
563 
564         checkForMissingParameter(cluId, "cluId");
565 
566         return CluServiceAssembler.toCluResultInfos(luDao.getCluResultByClu(cluId));
567     }
568 
569     @Override
570     public List<String> getCluIdsByResultUsageType(String resultUsageTypeKey, ContextInfo context)
571             throws DoesNotExistException, InvalidParameterException,
572             MissingParameterException, OperationFailedException {
573         return luDao.getCluIdsByResultUsageType(resultUsageTypeKey);
574     }
575 
576     @Override
577     public List<String> getCluIdsByResultComponent(String resultComponentId, ContextInfo context)
578             throws DoesNotExistException, InvalidParameterException,
579             MissingParameterException, OperationFailedException {
580         return luDao.getCluIdsByResultComponentId(resultComponentId);
581     }
582 
583     
584     @Override
585     public CluLoRelationInfo getCluLoRelation(String cluLoRelationId, ContextInfo context)
586             throws DoesNotExistException, InvalidParameterException,
587             MissingParameterException, OperationFailedException,
588             PermissionDeniedException {
589 
590         checkForMissingParameter(cluLoRelationId, "cluLoRelationId");
591 
592         CluLoRelation reltn;
593         try {
594             reltn = luDao.fetch(CluLoRelation.class, cluLoRelationId);
595         } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException ex) {
596             throw new DoesNotExistException(cluLoRelationId, ex);
597         }
598         return CluServiceAssembler.toCluLoRelationInfo(reltn);
599 
600     }
601 
602     @Override
603     public List<CluLoRelationInfo> getCluLoRelationsByClu(String cluId, ContextInfo context)
604             throws DoesNotExistException, InvalidParameterException,
605             MissingParameterException, OperationFailedException {
606 
607         checkForMissingParameter(cluId, "cluId");
608         List<CluLoRelation> cluLoRelations = luDao.getCluLoRelationsByClu(cluId);
609         return CluServiceAssembler.toCluLoRelationInfos(cluLoRelations);
610 
611     }
612 
613     @Override
614     public List<CluLoRelationInfo> getCluLoRelationsByLo(String loId, ContextInfo context)
615             throws DoesNotExistException, InvalidParameterException,
616             MissingParameterException, OperationFailedException {
617         checkForMissingParameter(loId, "loId");
618         List<CluLoRelation> cluLoRelations = luDao.getCluLoRelationsByLo(loId);
619         return CluServiceAssembler.toCluLoRelationInfos(cluLoRelations);
620     }
621 
622     
623     @Override
624     public List<String> getResourceRequirementsForClu(String cluId, ContextInfo context)
625             throws DoesNotExistException, InvalidParameterException,
626             MissingParameterException, OperationFailedException {
627         return new ArrayList<String>();
628     }
629 
630     
631     @Override
632     public CluSetInfo getCluSet(String cluSetId, ContextInfo contextInfo)
633             throws DoesNotExistException, InvalidParameterException,
634             MissingParameterException, OperationFailedException,
635             PermissionDeniedException {
636         checkForMissingParameter(cluSetId, "cluSetId");
637         CluSet cluSet;
638         try {
639             cluSet = luDao.fetch(CluSet.class, cluSetId);
640         } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException ex) {
641             throw new DoesNotExistException(cluSetId, ex);
642         }
643         CluSetInfo cluSetInfo = CluServiceAssembler.toCluSetInfo(cluSet);
644         setMembershipQuerySearchResult(cluSetInfo, contextInfo);
645         return cluSetInfo;
646     }
647 
648     @Override
649     public CluSetTreeViewInfo getCluSetTreeView(String cluSetId, ContextInfo context)
650             throws DoesNotExistException, InvalidParameterException,
651             MissingParameterException, OperationFailedException,
652             PermissionDeniedException {
653 
654         checkForMissingParameter(cluSetId, "cluSetId");
655         CluSetInfo cluSet = getCluSet(cluSetId, context);
656         if (cluSet == null) {
657             return null;
658         }
659 
660         CluSetTreeViewInfo cluSetTreeView = new CluSetTreeViewInfo();
661         getCluSetTreeViewHelper(cluSet, cluSetTreeView, context);
662         return cluSetTreeView;
663     }
664 
665     
666 
667 
668 
669 
670 
671 
672 
673 
674 
675 
676 
677     private void getCluSetTreeViewHelper(CluSetInfo cluSetInfo,
678                                          CluSetTreeViewInfo cluSetTreeViewInfo, ContextInfo context) throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException {
679         cluSetTreeViewInfo.setName(cluSetInfo.getName());
680         cluSetTreeViewInfo.setDescr(cluSetInfo.getDescr());
681         cluSetTreeViewInfo.setEffectiveDate(cluSetInfo.getEffectiveDate());
682         cluSetTreeViewInfo.setExpirationDate(cluSetInfo.getExpirationDate());
683         cluSetTreeViewInfo.setAdminOrg(cluSetInfo.getAdminOrg());
684         cluSetTreeViewInfo.setIsReusable(cluSetInfo.getIsReusable());
685         cluSetTreeViewInfo.setIsReferenceable(cluSetInfo.getIsReferenceable());
686         cluSetTreeViewInfo.setMeta(cluSetInfo.getMeta());
687         cluSetTreeViewInfo.setAttributes(cluSetInfo.getAttributes());
688         cluSetTreeViewInfo.setTypeKey(cluSetInfo.getTypeKey());
689         cluSetTreeViewInfo.setStateKey(cluSetInfo.getStateKey());
690         cluSetTreeViewInfo.setId(cluSetInfo.getId());
691 
692         if (!cluSetInfo.getCluSetIds().isEmpty()) {
693             for (String cluSetId : cluSetInfo.getCluSetIds()) {
694                 CluSetInfo subCluSet = getCluSet(cluSetId, context);
695                 List<CluSetTreeViewInfo> cluSets =
696                         cluSetTreeViewInfo.getCluSets() == null
697                                 ? new ArrayList<CluSetTreeViewInfo>(0) : cluSetTreeViewInfo.getCluSets();
698 
699                 CluSetTreeViewInfo subCluSetTreeViewInfo = new CluSetTreeViewInfo();
700                 getCluSetTreeViewHelper(subCluSet, subCluSetTreeViewInfo, context);
701                 cluSets.add(subCluSetTreeViewInfo);
702 
703                 cluSetTreeViewInfo.setCluSets(cluSets);
704             }
705         }
706         List<CluInfo> clus = new ArrayList<CluInfo>();
707         for (String cluId : cluSetInfo.getCluIds()) {
708             if (cluId != null) {
709                 
710                 
711                 logger.info("CluID: " + cluId);
712                 Clu clu = luDao.getCurrentCluVersion(cluId);
713                 CluInfo cluInfo = new CluInfo();
714                 cluInfo.setId(clu.getId());
715                 cluInfo.setTypeKey(clu.getLuType().getId());
716                 cluInfo.setOfficialIdentifier(CluServiceAssembler.toCluIdentifierInfo(clu.getOfficialIdentifier()));
717                 clus.add(cluInfo);
718             }
719         }
720         cluSetTreeViewInfo.setClus(clus);
721     }
722 
723     @Override
724     public List<CluSetInfo> getCluSetsByIds(List<String> cluSetIds, ContextInfo context)
725             throws DoesNotExistException, InvalidParameterException,
726             MissingParameterException, OperationFailedException,
727             PermissionDeniedException {
728         checkForMissingParameter(cluSetIds, "cluSetIds");
729         checkForEmptyList(cluSetIds, "cluSetIds");
730         List<CluSet> cluSets = luDao.getCluSetInfoByIdList(cluSetIds);
731         return CluServiceAssembler.toCluSetInfos(cluSets);
732     }
733 
734     @Override
735     public List<String> getCluSetIdsFromCluSet(String cluSetId, ContextInfo context)
736             throws DoesNotExistException, InvalidParameterException,
737             MissingParameterException, OperationFailedException,
738             PermissionDeniedException {
739         checkForMissingParameter(cluSetId, "cluSetId");
740         CluSet cluSet;
741         try {
742             cluSet = luDao.fetch(CluSet.class, cluSetId);
743         } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException ex) {
744             throw new DoesNotExistException(cluSetId, ex);
745         }
746         List<String> Ids = new ArrayList<String>(cluSet.getCluVerIndIds().size());
747         if (cluSet.getCluSets() != null) {
748             for (CluSet cluSet2 : cluSet.getCluSets()) {
749                 Ids.add(cluSet2.getId());
750             }
751         }
752         return Ids;
753     }
754 
755     @Override
756     public Boolean isCluSetDynamic(String cluSetId, ContextInfo context)
757             throws DoesNotExistException, InvalidParameterException,
758             MissingParameterException, OperationFailedException,
759             PermissionDeniedException {
760         return null;
761     }
762 
763     @Override
764     public List<CluInfo> getClusFromCluSet(String cluSetId, ContextInfo context)
765             throws DoesNotExistException, InvalidParameterException,
766             MissingParameterException, OperationFailedException,
767             PermissionDeniedException {
768         checkForMissingParameter(cluSetId, "cluSetId");
769         CluSet cluSet;
770         try {
771             cluSet = luDao.fetch(CluSet.class, cluSetId);
772         } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException ex) {
773             throw new DoesNotExistException(cluSetId, ex);
774         }
775         List<CluInfo> clus = new ArrayList<CluInfo>(cluSet.getCluVerIndIds().size());
776         for (CluSetJoinVersionIndClu cluSetJnClu : cluSet.getCluVerIndIds()) {
777             clus.add(CluServiceAssembler.toCluInfo(luDao.getCurrentCluVersion(cluSetJnClu.getCluVersionIndId())));
778         }
779         return clus;
780     }
781 
782     @Override
783     public List<String> getCluIdsFromCluSet(String cluSetId, ContextInfo context)
784             throws DoesNotExistException, InvalidParameterException,
785             MissingParameterException, OperationFailedException,
786             PermissionDeniedException {
787         checkForMissingParameter(cluSetId, "cluSetId");
788         CluSet cluSet;
789         try {
790             cluSet = luDao.fetch(CluSet.class, cluSetId);
791         } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException ex) {
792             throw new DoesNotExistException(cluSetId, ex);
793         }
794         List<String> Ids = new ArrayList<String>(cluSet.getCluVerIndIds().size());
795         for (CluSetJoinVersionIndClu cluSetJnClu : cluSet.getCluVerIndIds()) {
796             Ids.add(cluSetJnClu.getCluVersionIndId());
797         }
798         return Ids;
799     }
800 
801     @Override
802     public List<CluInfo> getAllClusInCluSet(String cluSetId, ContextInfo context)
803             throws DoesNotExistException, InvalidParameterException,
804             MissingParameterException, OperationFailedException,
805             PermissionDeniedException {
806         checkForMissingParameter(cluSetId, "cluSetId");
807         List<String> cluIndIds = new ArrayList<String>();
808         CluSet cluSet;
809         try {
810             cluSet = luDao.fetch(CluSet.class, cluSetId);
811         } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException ex) {
812             throw new DoesNotExistException(cluSetId, ex);
813         }
814         findClusInCluSet(cluIndIds, cluSet);
815         List<CluInfo> infos = new ArrayList<CluInfo>(cluIndIds.size());
816         for (String cluIndId : cluIndIds) {
817             infos.add(CluServiceAssembler.toCluInfo(luDao.getCurrentCluVersion(cluIndId)));
818         }
819         return infos;
820     }
821 
822     private void findClusInCluSet(List<String> clus, CluSet parentCluSet)
823             throws DoesNotExistException {
824         List<String> processedCluSetIds = new ArrayList<String>();
825         doFindClusInCluSet(processedCluSetIds, clus, parentCluSet);
826     }
827 
828     private void doFindClusInCluSet(List<String> processedCluSetIds,
829                                     List<String> clus, CluSet parentCluSet) {
830         for (CluSetJoinVersionIndClu join : parentCluSet.getCluVerIndIds()) {
831             if (!clus.contains(join.getCluVersionIndId())) {
832                 clus.add(join.getCluVersionIndId());
833             }
834         }
835         if (parentCluSet.getCluSets() != null) {
836             for (CluSet cluSet : parentCluSet.getCluSets()) {
837                 
838                 if (!processedCluSetIds.contains(cluSet.getId())) {
839                     processedCluSetIds.add(cluSet.getId());
840                     doFindClusInCluSet(processedCluSetIds, clus, cluSet);
841                 }
842             }
843         }
844     }
845 
846     @Override
847     public List<String> getAllCluIdsInCluSet(String cluSetId, ContextInfo context)
848             throws DoesNotExistException, InvalidParameterException,
849             MissingParameterException, OperationFailedException,
850             PermissionDeniedException {
851         checkForMissingParameter(cluSetId, "cluSetId");
852         List<String> Ids = new ArrayList<String>();
853         CluSet cluSet;
854         try {
855             cluSet = luDao.fetch(CluSet.class, cluSetId);
856         } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException ex) {
857             throw new DoesNotExistException(cluSetId, ex);
858         }
859         findClusInCluSet(Ids, cluSet);
860         return Ids;
861     }
862 
863     @Override
864     public Boolean isCluInCluSet(String cluId, String cluSetId, ContextInfo context)
865             throws DoesNotExistException, InvalidParameterException,
866             MissingParameterException, OperationFailedException,
867             PermissionDeniedException {
868         checkForMissingParameter(cluId, "cluId");
869         checkForMissingParameter(cluSetId, "cluSetId");
870         return luDao.isCluInCluSet(cluId, cluSetId);
871     }
872 
873     
874 
875 
876     @Override
877     public List<ValidationResultInfo> validateClu(String validationType,
878                                                   CluInfo cluInfo, ContextInfo context) throws DoesNotExistException,
879             InvalidParameterException, MissingParameterException,
880             OperationFailedException {
881         checkForMissingParameter(validationType, "validationType");
882         checkForMissingParameter(cluInfo, "cluInfo");
883 
884         ObjectStructureDefinition objStructure = this.getObjectStructure(CluInfo.class.getName());
885         Validator defaultValidator = validatorFactory.getValidator();
886         List<org.kuali.student.r2.common.dto.ValidationResultInfo> vris = defaultValidator.validateObject(cluInfo, objStructure, context);
887         return vris;
888     }
889 
890     @Override
891     @Transactional(readOnly = false)
892     public CluInfo createClu(String luTypeKey, CluInfo cluInfo, ContextInfo context)
893             throws DataValidationErrorException,
894             DoesNotExistException, InvalidParameterException,
895             MissingParameterException, OperationFailedException,
896             PermissionDeniedException {
897         Clu clu;
898         try {
899             clu = toCluForCreate(luTypeKey, cluInfo, context);
900         } catch (AlreadyExistsException ex) {
901             throw new OperationFailedException(ex.getMessage(), ex);
902         }
903         
904         if (clu.getVersion() == null) {
905             clu.setVersion(new Version());
906         }
907         clu.getVersion().setCurrentVersionStart(new Date());
908         luDao.create(clu);
909         return CluServiceAssembler.toCluInfo(clu);
910     }
911 
912     public Clu toCluForCreate(String luTypeKey, CluInfo cluInfo, ContextInfo context)
913             throws AlreadyExistsException, DataValidationErrorException,
914             DoesNotExistException, InvalidParameterException,
915             MissingParameterException, OperationFailedException,
916             PermissionDeniedException {
917         checkForMissingParameter(luTypeKey, "luTypeKey");
918         checkForMissingParameter(cluInfo, "cluInfo");
919 
920         
921         List<ValidationResultInfo> val = validateClu("SYSTEM", cluInfo, context);
922         if (null != val && val.size() > 0) {
923             throw new DataValidationErrorException("Validation error!", val);
924         }
925 
926         Clu clu = new Clu();
927 
928         LuType luType;
929         try {
930             luType = luDao.fetch(LuType.class, luTypeKey);
931         } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException ex) {
932             throw new DoesNotExistException(luTypeKey, ex);
933         }
934         clu.setLuType(luType);
935 
936         if (cluInfo.getOfficialIdentifier() != null) {
937             clu.setOfficialIdentifier(CluServiceAssembler.createOfficialIdentifier(cluInfo, luDao));
938         }
939         clu.setAlternateIdentifiers(CluServiceAssembler.createAlternateIdentifiers(cluInfo, luDao));
940         if (cluInfo.getDescr() != null) {
941             LuRichText descr = CluServiceAssembler.toRichText(LuRichText.class, cluInfo.getDescr());
942             if (descr.getPlain() != null || descr.getFormatted() != null) {
943                 clu.setDescr(descr);
944             }
945         }
946 
947         if (clu.getAdminOrgs() == null) {
948             clu.setAdminOrgs(new ArrayList<CluAdminOrg>(0));
949         }
950         List<CluAdminOrg> adminOrgs = clu.getAdminOrgs();
951         for (AdminOrgInfo orgInfo : cluInfo.getAdminOrgs()) {
952             CluAdminOrg instructor = new CluAdminOrg();
953             BeanUtils.copyProperties(orgInfo, instructor,
954                     new String[]{"attributes"});
955             instructor.setAttributes(CluServiceAssembler.toGenericAttributes(
956                     CluAdminOrgAttribute.class, orgInfo.getAttributes(),
957                     instructor, luDao));
958             instructor.setClu(clu);
959             adminOrgs.add(instructor);
960         }
961 
962         if (cluInfo.getPrimaryInstructor() != null) {
963             CluInstructor primaryInstructor = new CluInstructor();
964             BeanUtils.copyProperties(cluInfo.getPrimaryInstructor(),
965                     primaryInstructor, new String[]{"id", "attributes"});
966             primaryInstructor.setAttributes(CluServiceAssembler.toGenericAttributes(CluInstructorAttribute.class, cluInfo.getPrimaryInstructor().getAttributes(),
967                     primaryInstructor, luDao));
968             clu.setPrimaryInstructor(primaryInstructor);
969         }
970 
971         if (clu.getInstructors() == null) {
972             clu.setInstructors(new ArrayList<CluInstructor>(0));
973         }
974         List<CluInstructor> instructors = clu.getInstructors();
975         for (CluInstructorInfo instructorInfo : cluInfo.getInstructors()) {
976             CluInstructor instructor = new CluInstructor();
977             BeanUtils.copyProperties(instructorInfo, instructor,
978                     new String[]{"id", "attributes"});
979             instructor.setAttributes(CluServiceAssembler.toGenericAttributes(
980                     CluInstructorAttribute.class, instructorInfo.getAttributes(), instructor, luDao));
981             instructors.add(instructor);
982         }
983 
984         if (cluInfo.getStdDuration() != null) {
985             clu.setStdDuration(CluServiceAssembler.toTimeAmount(cluInfo.getStdDuration()));
986         }
987 
988         if (clu.getLuCodes() == null) {
989             clu.setLuCodes(new ArrayList<LuCode>(0));
990         }
991         List<LuCode> luCodes = clu.getLuCodes();
992         for (LuCodeInfo luCodeInfo : cluInfo.getLuCodes()) {
993             LuCode luCode = new LuCode();
994             luCode.setAttributes(CluServiceAssembler.toGenericAttributes(
995                     LuCodeAttribute.class, luCodeInfo.getAttributes(), luCode,
996                     luDao));
997             BeanUtils.copyProperties(luCodeInfo, luCode, new String[]{
998                     "attributes", "meta", "descr", "typeKey"});
999             if (luCodeInfo.getDescr() != null) {
1000                 luCode.setDescr(luCodeInfo.getDescr().getPlain());
1001             }
1002             luCode.setType(luCodeInfo.getTypeKey());
1003             luCode.setClu(clu);
1004             luCodes.add(luCode);
1005         }
1006 
1007         if (clu.getOfferedAtpTypes() == null) {
1008             clu.setOfferedAtpTypes(new ArrayList<CluAtpTypeKey>(0));
1009         }
1010         List<CluAtpTypeKey> offeredAtpTypes = clu.getOfferedAtpTypes();
1011         for (String atpTypeKey : cluInfo.getOfferedAtpTypes()) {
1012             CluAtpTypeKey cluAtpTypeKey = new CluAtpTypeKey();
1013             cluAtpTypeKey.setAtpTypeKey(atpTypeKey);
1014             cluAtpTypeKey.setClu(clu);
1015             offeredAtpTypes.add(cluAtpTypeKey);
1016         }
1017 
1018         
1019         if (cluInfo.getFeeInfo() != null) {
1020             CluFee cluFee = null;
1021             try {
1022                 cluFee = CluServiceAssembler.toCluFee(clu, false, cluInfo.getFeeInfo(), luDao);
1023             } catch (VersionMismatchException e) {
1024                 
1025             }
1026             clu.setFee(cluFee);
1027         }
1028 
1029         if (cluInfo.getAccountingInfo() != null) {
1030             CluAccounting cluAccounting = new CluAccounting();
1031             cluAccounting.setAttributes(CluServiceAssembler.toGenericAttributes(
1032                     CluAccountingAttribute.class, cluInfo.getAccountingInfo().getAttributes(), cluAccounting, luDao));
1033             cluAccounting.setAffiliatedOrgs(CluServiceAssembler.toAffiliatedOrgs(false, cluAccounting.getAffiliatedOrgs(),
1034                     cluInfo.getAccountingInfo().getAffiliatedOrgs(),
1035                     luDao));
1036             clu.setAccounting(cluAccounting);
1037         }
1038 
1039         clu.setAttributes(CluServiceAssembler.toGenericAttributes(
1040                 CluAttribute.class, cluInfo.getAttributes(), clu, luDao));
1041 
1042 
1043         if (cluInfo.getIntensity() != null) {
1044             clu.setIntensity(CluServiceAssembler.toAmount(cluInfo.getIntensity()));
1045         }
1046 
1047         if (clu.getCampusLocations() == null) {
1048             clu.setCampusLocations(new ArrayList<CluCampusLocation>(0));
1049         }
1050         List<CluCampusLocation> locations = clu.getCampusLocations();
1051         for (String locationName : cluInfo.getCampusLocations()) {
1052             CluCampusLocation location = new CluCampusLocation();
1053             location.setCampusLocation(locationName);
1054             location.setClu(clu);
1055             locations.add(location);
1056         }
1057 
1058         if (clu.getAccreditations() == null) {
1059             clu.setAccreditations(new ArrayList<CluAccreditation>(0));
1060         }
1061         List<CluAccreditation> accreditations = clu.getAccreditations();
1062         for (AccreditationInfo accreditationInfo : cluInfo.getAccreditations()) {
1063             CluAccreditation accreditation = new CluAccreditation();
1064             BeanUtils.copyProperties(accreditationInfo, accreditation,
1065                     new String[]{"attributes", "meta"});
1066             accreditation.setAttributes(CluServiceAssembler.toGenericAttributes(
1067                     CluAccreditationAttribute.class, accreditationInfo.getAttributes(), accreditation, luDao));
1068             accreditations.add(accreditation);
1069         }
1070 
1071 
1072         
1073         
1074         
1075                 if (cluInfo.getCanCreateLui() != null) {
1076                     clu.setCanCreateLui(cluInfo.getCanCreateLui());
1077                 }
1078 
1079                 if (cluInfo.getIsEnrollable() != null) {
1080                     clu.setEnrollable(cluInfo.getIsEnrollable());
1081                 }
1082 
1083                 if (cluInfo.getIsHasEarlyDropDeadline() != null) {
1084                     clu.setHasEarlyDropDeadline(cluInfo.getIsHasEarlyDropDeadline());
1085                 }
1086 
1087                 if (cluInfo.getIsHazardousForDisabledStudents() != null) {
1088                     clu.setHazardousForDisabledStudents(cluInfo.getIsHazardousForDisabledStudents());
1089                 }
1090 
1091 
1092          
1093         BeanUtils.copyProperties(cluInfo, clu, new String[]{"luType",
1094                 "officialIdentifier", "alternateIdentifiers", "descr",
1095                 "luCodes", "primaryInstructor", "instructors", "stdDuration",
1096                 "offeredAtpTypes", "feeInfo", "accountingInfo", "attributes",
1097                 "meta", "version", "intensity",
1098                 "campusLocations", "accreditations",
1099                 "adminOrgs", "canCreateLui", "hasEarlyDropDeadline", ""});
1100 
1101         return clu;
1102     }
1103 
1104     @Override
1105     @Transactional(readOnly = false)
1106     public CluInfo updateClu(String cluId, CluInfo cluInfo, ContextInfo context)
1107             throws DataValidationErrorException, DoesNotExistException,
1108             InvalidParameterException, MissingParameterException,
1109             OperationFailedException, PermissionDeniedException,
1110             VersionMismatchException {
1111 
1112         checkForMissingParameter(cluId, "cluId");
1113         checkForMissingParameter(cluInfo, "cluInfo");
1114 
1115         
1116         List<ValidationResultInfo> val = validateClu("SYSTEM", cluInfo, context);
1117         if (null != val && val.size() > 0) {
1118             throw new DataValidationErrorException("Validation error!", val);
1119         }
1120 
1121         Clu clu;
1122         try {
1123             clu = luDao.fetch(Clu.class, cluId);
1124         } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException ex) {
1125             throw new DoesNotExistException(cluId, ex);
1126         }
1127 
1128         if (!String.valueOf(clu.getVersionNumber()).equals(
1129                 cluInfo.getMeta().getVersionInd())) {
1130             throw new VersionMismatchException(
1131                     "Clu to be updated is not the current version");
1132         }
1133 
1134         LuType luType;
1135         try {
1136             luType = luDao.fetch(LuType.class, cluInfo.getTypeKey());
1137         } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException ex) {
1138             throw new DoesNotExistException(cluInfo.getTypeKey(), ex);
1139         }
1140         clu.setLuType(luType);
1141 
1142         if (cluInfo.getOfficialIdentifier() != null) {
1143             CluServiceAssembler.updateOfficialIdentifier(clu, cluInfo, luDao);
1144         } else if (clu.getOfficialIdentifier() != null) {
1145             luDao.delete(clu.getOfficialIdentifier());
1146         }
1147 
1148         
1149         
1150         
1151         Map<String, CluIdentifier> oldAltIdMap = new HashMap<String, CluIdentifier>();
1152         CluServiceAssembler.updateAlternateIdentifier(oldAltIdMap, clu, cluInfo, luDao);
1153         
1154         for (Entry<String, CluIdentifier> entry : oldAltIdMap.entrySet()) {
1155             luDao.delete(entry.getValue());
1156         }
1157 
1158         if (cluInfo.getDescr() != null && (cluInfo.getDescr().getPlain() != null || cluInfo.getDescr().getFormatted() != null)) {
1159             if (clu.getDescr() == null) {
1160                 clu.setDescr(new LuRichText());
1161             }
1162             BeanUtils.copyProperties(cluInfo.getDescr(), clu.getDescr());
1163         } else if (clu.getDescr() != null) {
1164             luDao.delete(clu.getDescr());
1165             clu.setDescr(null);
1166         }
1167 
1168         if (cluInfo.getPrimaryInstructor() != null) {
1169             if (clu.getPrimaryInstructor() == null) {
1170                 clu.setPrimaryInstructor(new CluInstructor());
1171             }
1172             BeanUtils.copyProperties(cluInfo.getPrimaryInstructor(), clu.getPrimaryInstructor(), new String[]{"attributes"});
1173             clu.getPrimaryInstructor().setAttributes(
1174                     CluServiceAssembler.toGenericAttributes(
1175                             CluInstructorAttribute.class, cluInfo.getPrimaryInstructor().getAttributes(),
1176                             clu.getPrimaryInstructor(), luDao));
1177         } else if (clu.getPrimaryInstructor() != null) {
1178             luDao.delete(clu.getPrimaryInstructor());
1179         }
1180 
1181         
1182         
1183         
1184         Map<String, CluInstructor> oldInstructorMap = new HashMap<String, CluInstructor>();
1185         for (CluInstructor cluInstructor : clu.getInstructors()) {
1186             oldInstructorMap.put(cluInstructor.getId(), cluInstructor);
1187         }
1188         clu.getInstructors().clear();
1189 
1190         
1191         
1192         
1193         for (CluInstructorInfo instructorInfo : cluInfo.getInstructors()) {
1194             CluInstructor cluInstructor = oldInstructorMap.remove(instructorInfo.getId());
1195             if (cluInstructor == null) {
1196                 cluInstructor = new CluInstructor();
1197             }
1198             
1199             BeanUtils.copyProperties(instructorInfo, cluInstructor,
1200                     new String[]{"attributes"});
1201             cluInstructor.setAttributes(CluServiceAssembler.toGenericAttributes(
1202                     CluInstructorAttribute.class, instructorInfo.getAttributes(), cluInstructor, luDao));
1203             clu.getInstructors().add(cluInstructor);
1204         }
1205 
1206         
1207         for (Entry<String, CluInstructor> entry : oldInstructorMap.entrySet()) {
1208             luDao.delete(entry.getValue());
1209         }
1210 
1211         if (cluInfo.getStdDuration() != null) {
1212             if (clu.getStdDuration() == null) {
1213                 clu.setStdDuration(new TimeAmount());
1214             }
1215             BeanUtils.copyProperties(cluInfo.getStdDuration(), clu.getStdDuration());
1216         } else if (clu.getStdDuration() != null) {
1217             luDao.delete(clu.getStdDuration());
1218         }
1219 
1220         
1221         
1222         
1223         Map<String, LuCode> oldLuCodeMap = new HashMap<String, LuCode>();
1224         for (LuCode luCode : clu.getLuCodes()) {
1225             oldLuCodeMap.put(luCode.getId(), luCode);
1226         }
1227         clu.getLuCodes().clear();
1228 
1229         
1230         
1231         
1232         for (LuCodeInfo luCodeInfo : cluInfo.getLuCodes()) {
1233             LuCode luCode = oldLuCodeMap.remove(luCodeInfo.getId());
1234             if (luCode == null) {
1235                 luCode = new LuCode();
1236             } else {
1237                 if (!String.valueOf(luCode.getVersionNumber()).equals(
1238                         luCodeInfo.getMeta().getVersionInd())) {
1239                     throw new VersionMismatchException(
1240                             "LuCode to be updated is not the current version");
1241                 }
1242             }
1243             
1244             luCode.setAttributes(CluServiceAssembler.toGenericAttributes(
1245                     LuCodeAttribute.class, luCodeInfo.getAttributes(), luCode,
1246                     luDao));
1247 
1248             luCode.setValue(luCodeInfo.getValue());
1249             if (luCodeInfo.getDescr() != null) {
1250                 luCode.setDescr(luCodeInfo.getDescr().getPlain());
1251             }
1252             luCode.setType(luCodeInfo.getTypeKey());
1253             luCode.setClu(clu);
1254 
1255             clu.getLuCodes().add(luCode);
1256         }
1257 
1258         
1259         for (Entry<String, LuCode> entry : oldLuCodeMap.entrySet()) {
1260             luDao.delete(entry.getValue());
1261         }
1262 
1263         
1264         
1265         
1266         Map<String, CluAtpTypeKey> oldOfferedAtpTypesMap = new HashMap<String, CluAtpTypeKey>();
1267         for (CluAtpTypeKey cluAtpTypeKey : clu.getOfferedAtpTypes()) {
1268             oldOfferedAtpTypesMap.put(cluAtpTypeKey.getAtpTypeKey(),
1269                     cluAtpTypeKey);
1270         }
1271         clu.getOfferedAtpTypes().clear();
1272 
1273         
1274         
1275         
1276         for (String atpTypeKey : cluInfo.getOfferedAtpTypes()) {
1277             CluAtpTypeKey cluAtpTypeKey = oldOfferedAtpTypesMap.remove(atpTypeKey);
1278             if (cluAtpTypeKey == null) {
1279                 cluAtpTypeKey = new CluAtpTypeKey();
1280             }
1281             
1282             cluAtpTypeKey.setAtpTypeKey(atpTypeKey);
1283             cluAtpTypeKey.setClu(clu);
1284             clu.getOfferedAtpTypes().add(cluAtpTypeKey);
1285         }
1286 
1287         
1288         for (Entry<String, CluAtpTypeKey> entry : oldOfferedAtpTypesMap.entrySet()) {
1289             luDao.delete(entry.getValue());
1290         }
1291 
1292         if (cluInfo.getFeeInfo() != null) {
1293             if (clu.getFee() == null) {
1294                 clu.setFee(CluServiceAssembler.toCluFee(clu, false, cluInfo.getFeeInfo(), luDao));
1295             } else {
1296                 clu.setFee(CluServiceAssembler.toCluFee(clu, true, cluInfo.getFeeInfo(), luDao));
1297             }
1298         } else if (clu.getFee() != null) {
1299             luDao.delete(clu.getFee());
1300             clu.setFee(null);
1301         }
1302 
1303         if (cluInfo.getAccountingInfo() != null) {
1304             if (clu.getAccounting() == null) {
1305                 clu.setAccounting(new CluAccounting());
1306             }
1307             clu.getAccounting().setAttributes(
1308                     CluServiceAssembler.toGenericAttributes(
1309                             CluAccountingAttribute.class, cluInfo.getAccountingInfo().getAttributes(), clu.getAccounting(), luDao));
1310             clu.getAccounting().setAffiliatedOrgs(CluServiceAssembler.toAffiliatedOrgs(true, clu.getAccounting().getAffiliatedOrgs(),
1311                     cluInfo.getAccountingInfo().getAffiliatedOrgs(),
1312                     luDao));
1313 
1314         } else if (clu.getAccounting() != null) {
1315             clu.setAccounting(null);
1316         }
1317 
1318         clu.setAttributes(CluServiceAssembler.toGenericAttributes(
1319                 CluAttribute.class, cluInfo.getAttributes(), clu, luDao));
1320 
1321         if (cluInfo.getIntensity() != null) {
1322             if (clu.getIntensity() == null) {
1323                 clu.setIntensity(new Amount());
1324             }
1325             clu.getIntensity().setUnitQuantity(cluInfo.getIntensity().getUnitQuantity());
1326             clu.getIntensity().setUnitType(cluInfo.getIntensity().getUnitTypeKey());
1327         } else if (clu.getIntensity() != null) {
1328             luDao.delete(clu.getIntensity());
1329         }
1330 
1331         
1332         
1333         
1334         Map<String, CluCampusLocation> oldLocationsMap = new HashMap<String, CluCampusLocation>();
1335         for (CluCampusLocation campus : clu.getCampusLocations()) {
1336             oldLocationsMap.put(campus.getCampusLocation(), campus);
1337         }
1338         clu.getCampusLocations().clear();
1339 
1340         
1341         
1342         
1343         for (String locationName : cluInfo.getCampusLocations()) {
1344             CluCampusLocation location = oldLocationsMap.remove(locationName);
1345             if (location == null) {
1346                 location = new CluCampusLocation();
1347             }
1348             
1349             location.setCampusLocation(locationName);
1350             location.setClu(clu);
1351             clu.getCampusLocations().add(location);
1352         }
1353 
1354         
1355         for (Entry<String, CluCampusLocation> entry : oldLocationsMap.entrySet()) {
1356             luDao.delete(entry.getValue());
1357         }
1358 
1359         
1360         
1361         
1362         Map<String, CluAccreditation> oldAccreditationMap = new HashMap<String, CluAccreditation>();
1363         for (CluAccreditation cluAccreditation : clu.getAccreditations()) {
1364             oldAccreditationMap.put(cluAccreditation.getId(),
1365                     cluAccreditation);
1366         }
1367         clu.getAccreditations().clear();
1368 
1369         
1370         
1371         
1372         for (AccreditationInfo accreditationInfo : cluInfo.getAccreditations()) {
1373             CluAccreditation cluAccreditation = null;
1374             if (accreditationInfo.getId() != null) {
1375                 cluAccreditation = oldAccreditationMap.remove(accreditationInfo.getId());
1376             }
1377 
1378             if (cluAccreditation == null) {
1379                 cluAccreditation = new CluAccreditation();
1380             }
1381             
1382             BeanUtils.copyProperties(accreditationInfo, cluAccreditation,
1383                     new String[]{"attributes", "meta"});
1384             cluAccreditation.setAttributes(CluServiceAssembler.toGenericAttributes(CluAccreditationAttribute.class,
1385                     accreditationInfo.getAttributes(),
1386                     cluAccreditation, luDao));
1387             clu.getAccreditations().add(cluAccreditation);
1388         }
1389 
1390         
1391         for (Entry<String, CluAccreditation> entry : oldAccreditationMap.entrySet()) {
1392             luDao.delete(entry.getValue());
1393         }
1394 
1395         
1396         
1397         
1398         Map<String, CluAdminOrg> oldAdminOrgsMap = new HashMap<String, CluAdminOrg>();
1399         if (clu.getAdminOrgs() != null) {
1400             for (CluAdminOrg cluOrg : clu.getAdminOrgs()) {
1401                 oldAdminOrgsMap.put(cluOrg.getId(), cluOrg);
1402             }
1403         }
1404         clu.setAdminOrgs(new ArrayList<CluAdminOrg>());
1405 
1406         
1407         
1408         
1409         for (AdminOrgInfo orgInfo : cluInfo.getAdminOrgs()) {
1410             CluAdminOrg cluOrg = null;
1411             if (orgInfo.getId() != null) {
1412                 cluOrg = oldAdminOrgsMap.remove(orgInfo.getId());
1413             }
1414 
1415             if (cluOrg == null) {
1416                 cluOrg = new CluAdminOrg();
1417             }
1418 
1419             
1420             BeanUtils.copyProperties(orgInfo, cluOrg,
1421                     new String[]{"attributes", "id"});
1422             cluOrg.setAttributes(CluServiceAssembler.toGenericAttributes(
1423                     CluAdminOrgAttribute.class, orgInfo.getAttributes(),
1424                     cluOrg, luDao));
1425             cluOrg.setClu(clu);
1426             clu.getAdminOrgs().add(cluOrg);
1427         }
1428 
1429         for (Entry<String, CluAdminOrg> entry : oldAdminOrgsMap.entrySet()) {
1430             luDao.delete(entry.getValue());
1431         }
1432 
1433         clu.setHasEarlyDropDeadline(cluInfo.getIsHasEarlyDropDeadline());
1434         clu.setHazardousForDisabledStudents(cluInfo.getIsHazardousForDisabledStudents());
1435         clu.setEnrollable(cluInfo.getIsEnrollable());
1436         clu.setCanCreateLui(cluInfo.getCanCreateLui());
1437 
1438         
1439         BeanUtils.copyProperties(cluInfo, clu, new String[]{"luType",
1440                 "officialIdentifier", "alternateIdentifiers", "descr",
1441                 "luCodes", "primaryInstructor", "instructors", "stdDuration",
1442                 "offeredAtpTypes", "feeInfo", "accountingInfo", "attributes",
1443                 "meta", "version", "intensity",
1444                 "campusLocations", "accreditations",
1445                 "adminOrgs", "canCreateLui", "hasEarlyDropDeadline",
1446                 "hazardousForDisabledStudents", "enrollable", ""});
1447         Clu updated = null;
1448         try {
1449             updated = luDao.update(clu);
1450         } catch (Exception e) {
1451             logger.error("Exception occured: ", e);
1452         }
1453         return CluServiceAssembler.toCluInfo(updated);
1454     }
1455 
1456     @Override
1457     @Transactional(readOnly = false)
1458     public StatusInfo deleteClu(String cluId, ContextInfo context) throws DoesNotExistException,
1459             InvalidParameterException, MissingParameterException,
1460             DependentObjectsExistException, OperationFailedException,
1461             PermissionDeniedException {
1462         checkForMissingParameter(cluId, "cluId");
1463         try {
1464             luDao.delete(Clu.class, cluId);
1465         } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException ex) {
1466             throw new DoesNotExistException(cluId, ex);
1467         }
1468 
1469         StatusInfo statusInfo = new StatusInfo();
1470         statusInfo.setSuccess(true);
1471 
1472         return statusInfo;
1473     }
1474 
1475     @Override
1476     @Transactional(readOnly = false)
1477     public CluInfo updateCluState(String cluId, String luState, ContextInfo context)
1478             throws DataValidationErrorException, DoesNotExistException,
1479             InvalidParameterException, MissingParameterException,
1480             OperationFailedException, PermissionDeniedException {
1481         
1482         checkForMissingParameter(cluId, "cluId");
1483         checkForMissingParameter(luState, "luState");
1484         Clu clu;
1485         try {
1486             clu = luDao.fetch(Clu.class, cluId);
1487         } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException ex) {
1488             throw new DoesNotExistException(cluId, ex);
1489         }
1490         clu.setState(luState);
1491         Clu updated = luDao.update(clu);
1492         return CluServiceAssembler.toCluInfo(updated);
1493     }
1494 
1495     @Override
1496     public List<ValidationResultInfo> validateCluCluRelation(String validationTypeKey,
1497                                                              String cluId, String relatedCluId,
1498                                                              String cluCluRelationTypeKey,
1499                                                              CluCluRelationInfo cluCluRelationInfo, ContextInfo contextInfo) throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException {
1500 
1501         checkForMissingParameter(validationTypeKey, "validationTypeKey");
1502         checkForMissingParameter(cluCluRelationInfo, "cluCluRelationInfo");
1503 
1504         ObjectStructureDefinition objStructure = this.getObjectStructure(CluCluRelationInfo.class.getName());
1505         Validator defaultValidator = validatorFactory.getValidator();
1506 
1507         List<org.kuali.student.r2.common.dto.ValidationResultInfo> vris = defaultValidator.validateObject(cluCluRelationInfo, objStructure, null);
1508         return vris;
1509     }
1510 
1511     @Override
1512     @Transactional(readOnly = false)
1513     public CluCluRelationInfo createCluCluRelation(String cluId,
1514                                                    String relatedCluId, String luLuRelationTypeKey,
1515                                                    CluCluRelationInfo cluCluRelationInfo, ContextInfo context)
1516             throws DataValidationErrorException,
1517             DoesNotExistException, InvalidParameterException,
1518             MissingParameterException, OperationFailedException,
1519             PermissionDeniedException, CircularRelationshipException {
1520         checkForMissingParameter(cluId, "cluId");
1521         checkForMissingParameter(relatedCluId, "relatedCluId");
1522         checkForMissingParameter(luLuRelationTypeKey, "luLuRelationTypeKey");
1523         checkForMissingParameter(cluCluRelationInfo, "cluCluRelationInfo");
1524 
1525         if (cluId.equals(relatedCluId)) {
1526             throw new CircularRelationshipException(
1527                     "Can not relate a Clu to itself");
1528         }
1529 
1530         
1531         List<ValidationResultInfo> val =
1532                 validateCluCluRelation("SYSTEM", cluId, relatedCluId, luLuRelationTypeKey, cluCluRelationInfo, context);
1533         if (null != val && val.size() > 0) {
1534             throw new DataValidationErrorException("Validation error!", val);
1535         }
1536 
1537 
1538         Clu clu;
1539         try {
1540             clu = luDao.fetch(Clu.class, cluId);
1541         } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException ex) {
1542             throw new DoesNotExistException(cluId, ex);
1543         }
1544         Clu relatedClu;
1545         try {
1546             relatedClu = luDao.fetch(Clu.class, relatedCluId);
1547         } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException ex) {
1548             throw new DoesNotExistException(relatedCluId, ex);
1549         }
1550 
1551         CluCluRelation cluCluRelation = new CluCluRelation();
1552         BeanUtils.copyProperties(cluCluRelationInfo, cluCluRelation,
1553                 new String[]{"cluId", "relatedCluId",
1554                         "isCluRelationRequired", "attributes", "meta"});
1555 
1556         cluCluRelation.setClu(clu);
1557         cluCluRelation.setRelatedClu(relatedClu);
1558         cluCluRelation.setCluRelationRequired(cluCluRelationInfo.getIsCluRelationRequired() == null ? true : cluCluRelationInfo.getIsCluRelationRequired()); 
1559         
1560         cluCluRelation.setAttributes(CluServiceAssembler.toGenericAttributes(
1561                 CluCluRelationAttribute.class, cluCluRelationInfo.getAttributes(), cluCluRelation, luDao));
1562 
1563         LuLuRelationType luLuRelationType;
1564         try {
1565             luLuRelationType = luDao.fetch(LuLuRelationType.class,
1566                     luLuRelationTypeKey);
1567         } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException ex) {
1568             throw new DoesNotExistException(luLuRelationTypeKey, ex);
1569         }
1570 
1571         cluCluRelation.setLuLuRelationType(luLuRelationType);
1572 
1573         luDao.create(cluCluRelation);
1574 
1575         return CluServiceAssembler.toCluCluRelationInfo(cluCluRelation);
1576     }
1577 
1578     @Override
1579     @Transactional(readOnly = false)
1580     public CluCluRelationInfo updateCluCluRelation(
1581             final String cluCluRelationId,
1582             final CluCluRelationInfo cluCluRelationInfo, ContextInfo context)
1583             throws DataValidationErrorException, DoesNotExistException,
1584             InvalidParameterException, MissingParameterException,
1585             OperationFailedException, PermissionDeniedException,
1586             VersionMismatchException {
1587         checkForMissingParameter(cluCluRelationId, "cluCluRelationId");
1588         checkForMissingParameter(cluCluRelationInfo, "cluCluRelationInfo");
1589 
1590         
1591         List<ValidationResultInfo> val =
1592                 validateCluCluRelation("SYSTEM",
1593                         cluCluRelationInfo.getCluId(),
1594                         cluCluRelationInfo.getRelatedCluId(),
1595                         cluCluRelationInfo.getTypeKey(),
1596                         cluCluRelationInfo,
1597                         context);
1598         if (null != val && val.size() > 0) {
1599             throw new DataValidationErrorException("Validation error!", val);
1600         }
1601 
1602         final CluCluRelation cluCluRelation;
1603         try {
1604             cluCluRelation = luDao.fetch(CluCluRelation.class,
1605                     cluCluRelationId);
1606         } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException ex) {
1607             throw new DoesNotExistException(cluCluRelationId, ex);
1608         }
1609         BeanUtils.copyProperties(cluCluRelationInfo, cluCluRelation,
1610                 new String[]{"cluId", "relatedCluId",
1611                         "isCluRelationRequired", "attributes", "meta"});
1612         try {
1613             cluCluRelation.setClu(luDao.fetch(Clu.class, cluCluRelationInfo.getCluId()));
1614         } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException ex) {
1615             throw new DoesNotExistException(cluCluRelationInfo.getCluId(), ex);
1616         }
1617         try {
1618             cluCluRelation.setRelatedClu(luDao.fetch(Clu.class, cluCluRelationInfo.getRelatedCluId()));
1619         } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException ex) {
1620             throw new DoesNotExistException(cluCluRelationInfo.getRelatedCluId(), ex);
1621         }
1622         cluCluRelation.setCluRelationRequired(cluCluRelationInfo.getIsCluRelationRequired() == null ? true : cluCluRelationInfo.getIsCluRelationRequired()); 
1623         
1624         cluCluRelation.setAttributes(CluServiceAssembler.toGenericAttributes(
1625                 CluCluRelationAttribute.class, cluCluRelationInfo.getAttributes(), cluCluRelation, luDao));
1626         try {
1627             cluCluRelation.setLuLuRelationType(luDao.fetch(LuLuRelationType.class,
1628                     cluCluRelationInfo.getTypeKey()));
1629         } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException ex) {
1630             throw new DoesNotExistException(cluCluRelationInfo.getTypeKey(), ex);
1631         }
1632 
1633         final CluCluRelation update = luDao.update(cluCluRelation);
1634 
1635         return CluServiceAssembler.toCluCluRelationInfo(update);
1636     }
1637 
1638     @Override
1639     @Transactional(readOnly = false)
1640     public StatusInfo deleteCluCluRelation(String cluCluRelationId, ContextInfo context)
1641             throws DoesNotExistException, InvalidParameterException,
1642             MissingParameterException, OperationFailedException,
1643             PermissionDeniedException {
1644         checkForMissingParameter(cluCluRelationId, "cluCluRelationId");
1645         try {
1646             luDao.delete(CluCluRelation.class, cluCluRelationId);
1647         } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException ex) {
1648             throw new DoesNotExistException(cluCluRelationId, ex);
1649         }
1650 
1651         StatusInfo statusInfo = new StatusInfo();
1652         statusInfo.setSuccess(true);
1653 
1654         return statusInfo;
1655     }
1656 
1657     @Override
1658     public List<ValidationResultInfo> validateCluPublication(
1659             String validationType, String cluId, String luPublicationTypeKey,
1660             CluPublicationInfo cluPublicationInfo, ContextInfo context)
1661             throws DoesNotExistException, InvalidParameterException,
1662             MissingParameterException, OperationFailedException {
1663 
1664         checkForMissingParameter(validationType, "validationType");
1665         checkForMissingParameter(cluPublicationInfo, "cluPublicationInfo");
1666 
1667         ObjectStructureDefinition objStructure = this.getObjectStructure(CluPublicationInfo.class.getName());
1668         Validator defaultValidator = validatorFactory.getValidator();
1669         List<org.kuali.student.r2.common.dto.ValidationResultInfo> vris =
1670                 defaultValidator.validateObject(cluPublicationInfo, objStructure, null);
1671         return vris;
1672     }
1673 
1674     @Override
1675     @Transactional(readOnly = false)
1676     public CluPublicationInfo createCluPublication(String cluId,
1677                                                    String luPublicationType, CluPublicationInfo cluPublicationInfo, ContextInfo context)
1678             throws DataValidationErrorException,
1679             InvalidParameterException, MissingParameterException,
1680             OperationFailedException, PermissionDeniedException {
1681         checkForMissingParameter(cluId, "cluId");
1682         checkForMissingParameter(luPublicationType, "luPublicationType");
1683         checkForMissingParameter(cluPublicationInfo, "cluPublicationInfo");
1684 
1685         
1686         List<ValidationResultInfo> val;
1687         try {
1688             val = validateCluPublication("SYSTEM", cluId, luPublicationType, cluPublicationInfo, context);
1689             if (null != val && val.size() > 0) {
1690                 throw new DataValidationErrorException("Validation error!", val);
1691             }
1692         } catch (DoesNotExistException e) {
1693             throw new OperationFailedException("Error creating clu", e);
1694         }
1695 
1696 
1697         CluPublication cluPub = new CluPublication();
1698         Clu clu;
1699         try {
1700             clu = luDao.fetch(Clu.class, cluId);
1701         } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException e) {
1702             throw new InvalidParameterException("Clu does not exist for id:" + cluId);
1703         }
1704 
1705         CluPublicationType type;
1706         try {
1707             type = luDao.fetch(CluPublicationType.class, luPublicationType);
1708         } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException e) {
1709             throw new InvalidParameterException("CluPublication Type does not exist for id:" + luPublicationType);
1710         }
1711 
1712         cluPub.setClu(clu);
1713         cluPub.setId(cluPublicationInfo.getId());
1714         cluPub.setEndCycle(cluPublicationInfo.getEndCycle());
1715         cluPub.setStartCycle(cluPublicationInfo.getStartCycle());
1716         cluPub.setEffectiveDate(cluPublicationInfo.getEffectiveDate());
1717         cluPub.setExpirationDate(cluPublicationInfo.getExpirationDate());
1718         cluPub.setState(cluPublicationInfo.getStateKey());
1719         cluPub.setType(type);
1720         cluPub.setAttributes(CluServiceAssembler.toGenericAttributes(CluPublicationAttribute.class, cluPublicationInfo.getAttributes(), cluPub, luDao));
1721         cluPub.setVariants(CluServiceAssembler.toCluPublicationVariants(cluPublicationInfo.getVariants(), cluPub, luDao));
1722 
1723         luDao.create(cluPub);
1724 
1725         return CluServiceAssembler.toCluPublicationInfo(cluPub);
1726     }
1727 
1728     @Override
1729     @Transactional(readOnly = false)
1730     public CluPublicationInfo updateCluPublication(String cluPublicationId,
1731                                                    CluPublicationInfo cluPublicationInfo, ContextInfo context)
1732             throws DataValidationErrorException, DoesNotExistException,
1733             InvalidParameterException, MissingParameterException,
1734             OperationFailedException, PermissionDeniedException,
1735             VersionMismatchException {
1736         checkForMissingParameter(cluPublicationId, "cluPublicationId");
1737         checkForMissingParameter(cluPublicationInfo, "cluPublicationInfo");
1738 
1739         
1740         List<ValidationResultInfo> val;
1741 
1742         val = validateCluPublication("SYSTEM",
1743                 cluPublicationInfo.getCluId(),
1744                 cluPublicationInfo.getTypeKey(),
1745                 cluPublicationInfo, context);
1746         if (null != val && val.size() > 0) {
1747             throw new DataValidationErrorException("Validation error!", val);
1748         }
1749 
1750         CluPublication cluPub;
1751         try {
1752             cluPub = luDao.fetch(CluPublication.class, cluPublicationId);
1753         } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException ex) {
1754             throw new DoesNotExistException(ex.getMessage(), ex);
1755         }
1756 
1757         if (!String.valueOf(cluPub.getVersionNumber()).equals(
1758                 cluPublicationInfo.getMeta().getVersionInd())) {
1759             throw new VersionMismatchException(
1760                     "CluPublication to be updated is not the current version");
1761         }
1762 
1763         Clu clu;
1764         try {
1765             clu = luDao.fetch(Clu.class, cluPublicationInfo.getCluId());
1766         } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException e) {
1767             throw new InvalidParameterException("Clu does not exist for id:" + cluPublicationInfo.getCluId());
1768         }
1769 
1770         CluPublicationType type;
1771         try {
1772             type = luDao.fetch(CluPublicationType.class, cluPublicationInfo.getTypeKey());
1773         } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException e) {
1774             throw new InvalidParameterException("CluPublication Type does not exist for id:" + cluPublicationInfo.getTypeKey());
1775         }
1776 
1777         
1778         
1779         
1780         Map<String, CluPublicationVariant> oldVariantMap = new HashMap<String, CluPublicationVariant>();
1781         for (CluPublicationVariant variant : cluPub.getVariants()) {
1782             oldVariantMap.put(variant.getKey(), variant);
1783         }
1784         cluPub.getVariants().clear();
1785 
1786         
1787         
1788         CluPublicationVariant variant = null;
1789         for (FieldInfo fieldInfo : cluPublicationInfo.getVariants()) {
1790             if (!oldVariantMap.containsKey(fieldInfo.getId())) {
1791                 
1792                 variant = new CluPublicationVariant();
1793                 variant.setKey(fieldInfo.getId());
1794                 variant.setValue(fieldInfo.getValue());
1795             } else {
1796                 
1797                 variant = oldVariantMap.get(fieldInfo.getId());
1798                 variant.setValue(fieldInfo.getValue());
1799                 oldVariantMap.remove(fieldInfo.getId());
1800             }
1801 
1802             cluPub.getVariants().add(variant);
1803         }
1804 
1805         
1806         for (Entry<String, CluPublicationVariant> entry : oldVariantMap.entrySet()) {
1807             luDao.delete(entry.getValue());
1808         }
1809 
1810         cluPub.setClu(clu);
1811         cluPub.setEndCycle(cluPublicationInfo.getEndCycle());
1812         cluPub.setStartCycle(cluPublicationInfo.getStartCycle());
1813         cluPub.setEffectiveDate(cluPublicationInfo.getEffectiveDate());
1814         cluPub.setExpirationDate(cluPublicationInfo.getExpirationDate());
1815         cluPub.setState(cluPublicationInfo.getStateKey());
1816         cluPub.setType(type);
1817         cluPub.setAttributes(CluServiceAssembler.toGenericAttributes(CluPublicationAttribute.class, cluPublicationInfo.getAttributes(), cluPub, luDao));
1818 
1819         CluPublication updated = luDao.update(cluPub);
1820 
1821         return CluServiceAssembler.toCluPublicationInfo(updated);
1822     }
1823 
1824     @Override
1825     @Transactional(readOnly = false)
1826     public StatusInfo deleteCluPublication(String cluPublicationId, ContextInfo context)
1827             throws DoesNotExistException, InvalidParameterException,
1828             MissingParameterException, DependentObjectsExistException,
1829             OperationFailedException, PermissionDeniedException {
1830         checkForMissingParameter(cluPublicationId, "cluPublicationId");
1831         try {
1832             luDao.delete(CluPublication.class, cluPublicationId);
1833         } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException ex) {
1834             throw new DoesNotExistException(cluPublicationId, ex);
1835         }
1836 
1837         StatusInfo statusInfo = new StatusInfo();
1838         statusInfo.setSuccess(true);
1839 
1840         return statusInfo;
1841     }
1842 
1843     @Override
1844     public List<ValidationResultInfo> validateCluResult(String validationType,
1845                                                         String cluId, String cluResultTypeKey,
1846                                                         CluResultInfo cluResultInfo, ContextInfo context)
1847             throws DoesNotExistException,
1848             InvalidParameterException, MissingParameterException,
1849             OperationFailedException {
1850         checkForMissingParameter(validationType, "validationType");
1851         checkForMissingParameter(cluResultInfo, "cluResultInfo");
1852 
1853         ObjectStructureDefinition objStructure = this.getObjectStructure(CluResultInfo.class.getName());
1854         Validator defaultValidator = validatorFactory.getValidator();
1855         List<org.kuali.student.r2.common.dto.ValidationResultInfo> vris = defaultValidator.validateObject(cluResultInfo, objStructure, null);
1856         return vris;
1857     }
1858 
1859     @Override
1860     @Transactional(readOnly = false)
1861     public CluResultInfo createCluResult(String cluId, String cluResultTypeKey,
1862                                          CluResultInfo cluResultInfo, ContextInfo context) throws
1863             DataValidationErrorException, InvalidParameterException,
1864             MissingParameterException, OperationFailedException,
1865             PermissionDeniedException, DoesNotExistException {
1866 
1867         checkForMissingParameter(cluId, "cluId");
1868         checkForMissingParameter(cluResultTypeKey, "cluResultTypeKey");
1869         checkForMissingParameter(cluResultInfo, "cluResultInfo");
1870 
1871         
1872         List<ValidationResultInfo> val = validateCluResult("SYSTEM",
1873                 cluResultInfo.getCluId(),
1874                 cluResultInfo.getTypeKey(),
1875                 cluResultInfo, context);
1876         if (null != val && val.size() > 0) {
1877             throw new DataValidationErrorException("Validation error!", val);
1878         }
1879 
1880         cluResultInfo.setTypeKey(cluResultTypeKey);
1881         cluResultInfo.setCluId(cluId);
1882 
1883         List<ResultOption> resOptList = new ArrayList<ResultOption>();
1884         for (ResultOptionInfo resOptInfo : cluResultInfo.getResultOptions()) {
1885             ResultOption resOpt = new ResultOption();
1886             BeanUtils.copyProperties(resOptInfo, resOpt, new String[]{"id",
1887                     "meta", "resultUsageType", "desc"});
1888 
1889             if (resOptInfo.getResultUsageTypeKey() != null) {
1890                 ResultUsageType resUsageType;
1891                 try {
1892                     resUsageType = luDao.fetch(ResultUsageType.class,
1893                             resOptInfo.getResultUsageTypeKey());
1894                 } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException ex) {
1895                     throw new DoesNotExistException(resOptInfo.getResultUsageTypeKey(), ex);
1896                 }
1897                 resOpt.setResultUsageType(resUsageType);
1898             }
1899             resOpt.setDesc(CluServiceAssembler.toRichText(LuRichText.class, resOptInfo.getDescr()));
1900             resOpt.setCreateId(context.getPrincipalId());
1901             resOpt.setCreateTime(context.getCurrentDate());
1902             luDao.create(resOpt);
1903             resOptList.add(resOpt);
1904         }
1905 
1906         CluResult cluResult = new CluResult();
1907         BeanUtils.copyProperties(cluResultInfo, cluResult, new String[]{"id",
1908                 "desc", "resultOptions", "meta"});
1909 
1910         cluResult.setDesc(CluServiceAssembler.toRichText(LuRichText.class, cluResultInfo.getDescr()));
1911         cluResult.setResultOptions(resOptList);
1912 
1913         Clu clu;
1914         try {
1915             clu = luDao.fetch(Clu.class, cluId);
1916         } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException ex) {
1917             throw new DoesNotExistException(cluId, ex);
1918         }
1919         cluResult.setClu(clu);
1920 
1921         CluResultType type;
1922         try {
1923             type = luDao.fetch(CluResultType.class, cluResultTypeKey);
1924         } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException ex) {
1925             throw new DoesNotExistException(cluResultTypeKey, ex);
1926         }
1927         cluResult.setCluResultType(type);
1928         cluResult.setCreateId(context.getPrincipalId());
1929         cluResult.setCreateTime(context.getCurrentDate());
1930 
1931         luDao.create(cluResult);
1932 
1933         return CluServiceAssembler.toCluResultInfo(cluResult);
1934     }
1935 
1936     @Override
1937     @Transactional(readOnly = false)
1938     public CluResultInfo updateCluResult(String cluResultId,
1939                                          CluResultInfo cluResultInfo, ContextInfo context) throws DataValidationErrorException,
1940             DoesNotExistException, InvalidParameterException,
1941             MissingParameterException, OperationFailedException,
1942             PermissionDeniedException, VersionMismatchException {
1943 
1944         checkForMissingParameter(cluResultId, "cluResultId");
1945         checkForMissingParameter(cluResultInfo, "cluResultInfo");
1946 
1947         
1948         List<ValidationResultInfo> val = validateCluResult("SYSTEM",
1949                 cluResultInfo.getCluId(),
1950                 cluResultInfo.getTypeKey(),
1951                 cluResultInfo,
1952                 context);
1953         if (null != val && val.size() > 0) {
1954             throw new DataValidationErrorException("Validation error!", val);
1955         }
1956 
1957         CluResult result;
1958         try {
1959             result = luDao.fetch(CluResult.class, cluResultId);
1960         } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException ex) {
1961             throw new DoesNotExistException(cluResultId,ex);
1962         }
1963         if (!String.valueOf(result.getVersionNumber()).equals(
1964                 cluResultInfo.getMeta().getVersionInd())) {
1965             throw new VersionMismatchException(
1966                     "CluResult to be updated is not the current version");
1967         }
1968 
1969         
1970         
1971         
1972         Map<String, ResultOption> oldResultOptionMap = new HashMap<String, ResultOption>();
1973         for (ResultOption opt : result.getResultOptions()) {
1974             oldResultOptionMap.put(opt.getId(), opt);
1975         }
1976         result.getResultOptions().clear();
1977 
1978         
1979         
1980         for (ResultOptionInfo resOptInfo : cluResultInfo.getResultOptions()) {
1981             ResultOption opt = oldResultOptionMap.remove(resOptInfo.getId());
1982             if (opt == null) {
1983                 
1984                 opt = new ResultOption();
1985                 
1986                 BeanUtils.copyProperties(resOptInfo, opt, new String[]{
1987                         "resultUsageType", "desc"});
1988                 opt.setCreateId(context.getPrincipalId());
1989                 opt.setCreateTime(context.getCurrentDate());
1990             } else {
1991                 try {
1992                     
1993                     opt = luDao.fetch(ResultOption.class, resOptInfo.getId());
1994                 } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException ex) {
1995                     throw new DoesNotExistException(resOptInfo.getId(), ex);
1996                 }
1997                 
1998                 BeanUtils.copyProperties(resOptInfo, opt, new String[]{
1999                         "id", "resultUsageType", "desc"});
2000             }
2001             if (resOptInfo.getResultUsageTypeKey() != null && !resOptInfo.getResultUsageTypeKey().isEmpty()) {
2002                 ResultUsageType resUsageType;
2003                 try {
2004                     resUsageType = luDao.fetch(ResultUsageType.class,
2005                             resOptInfo.getResultUsageTypeKey());
2006                 } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException ex) {
2007                     throw new DoesNotExistException(resOptInfo.getResultUsageTypeKey(), ex);
2008                 }
2009                 opt.setResultUsageType(resUsageType);
2010             }
2011             opt.setDesc(CluServiceAssembler.toRichText(LuRichText.class, resOptInfo.getDescr()));
2012             result.getResultOptions().add(opt);
2013         }
2014 
2015         
2016         for (Entry<String, ResultOption> entry : oldResultOptionMap.entrySet()) {
2017             luDao.delete(entry.getValue());
2018         }
2019 
2020         BeanUtils.copyProperties(cluResultInfo, result, new String[]{"id",
2021                 "desc", "resultOptions"});
2022 
2023         result.setDesc(CluServiceAssembler.toRichText(LuRichText.class, cluResultInfo.getDescr()));
2024         CluResultType type;
2025         try {
2026             type = luDao.fetch(CluResultType.class, cluResultInfo.getTypeKey());
2027         } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException ex) {
2028             throw new DoesNotExistException(cluResultInfo.getTypeKey(), ex);
2029         }
2030         result.setCluResultType(type);
2031 
2032         CluResult updated = luDao.update(result);
2033 
2034         return CluServiceAssembler.toCluResultInfo(updated);
2035     }
2036 
2037     @Override
2038     @Transactional(readOnly = false)
2039     public StatusInfo deleteCluResult(String cluResultId, ContextInfo context)
2040             throws DoesNotExistException, InvalidParameterException,
2041             MissingParameterException, DependentObjectsExistException,
2042             OperationFailedException, PermissionDeniedException {
2043 
2044         checkForMissingParameter(cluResultId, "cluResultId");
2045         try {
2046             luDao.delete(CluResult.class, cluResultId);
2047         } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException ex) {
2048             throw new DoesNotExistException(cluResultId, ex);
2049         }
2050 
2051         StatusInfo statusInfo = new StatusInfo();
2052         statusInfo.setSuccess(true);
2053 
2054         return statusInfo;
2055     }
2056 
2057     @Override
2058     public List<ValidationResultInfo> validateCluLoRelation(
2059             String validationType,
2060             String cluId,
2061             String loId,
2062             String cluLoRelationType,
2063             CluLoRelationInfo cluLoRelationInfo, ContextInfo context)
2064             throws DoesNotExistException, InvalidParameterException,
2065             MissingParameterException, OperationFailedException {
2066 
2067         checkForMissingParameter(validationType, "validationType");
2068         checkForMissingParameter(cluLoRelationInfo, "cluLoRelationInfo");
2069 
2070         ObjectStructureDefinition objStructure = this.getObjectStructure(CluLoRelation.class.getName());
2071         Validator defaultValidator = validatorFactory.getValidator();
2072         List<org.kuali.student.r2.common.dto.ValidationResultInfo> vris = defaultValidator.validateObject(cluLoRelationInfo, objStructure, null);
2073         return vris;
2074     }
2075 
2076     @Override
2077     @Transactional(readOnly = false)
2078     public CluLoRelationInfo createCluLoRelation(String cluId, String loId,
2079                                                  String cluLoRelationType, CluLoRelationInfo cluLoRelationInfo, ContextInfo context)
2080             throws DoesNotExistException,
2081             InvalidParameterException, MissingParameterException,
2082             OperationFailedException, PermissionDeniedException, DataValidationErrorException {
2083         checkForMissingParameter(loId, "loId");
2084         checkForMissingParameter(cluId, "cluId");
2085         checkForEmptyList(cluLoRelationType, "cluLoRelationType");
2086         checkForEmptyList(cluLoRelationInfo, "cluLoRelationInfo");
2087 
2088         
2089         List<ValidationResultInfo> val = validateCluLoRelation("SYSTEM", cluId, loId, cluLoRelationType, cluLoRelationInfo, context);
2090         if (null != val && val.size() > 0) {
2091             throw new DataValidationErrorException("Validation error!", val);
2092         }
2093 
2094         Clu clu;
2095         try {
2096             clu = luDao.fetch(Clu.class, cluId);
2097         } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException ex) {
2098             throw new DoesNotExistException(cluId, ex);
2099         }
2100         if (clu == null) {
2101             throw new DoesNotExistException("Clu does not exist for id: "
2102                     + cluId);
2103         }
2104 
2105         CluLoRelationType cluLoRelationTypeEntity;
2106         try {
2107             cluLoRelationTypeEntity = luDao.fetch(CluLoRelationType.class, cluLoRelationType);
2108         } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException ex) {
2109             throw new DoesNotExistException(cluLoRelationType, ex);
2110         }
2111         if (cluLoRelationTypeEntity == null) {
2112             throw new DoesNotExistException("CluLoRelationType does not exist for id: "
2113                     + cluLoRelationType);
2114         }
2115 
2116         
2117         List<CluLoRelation> reltns = luDao.getCluLoRelationsByCludIdAndLoId(
2118                 cluId, loId);
2119         if (reltns.size() > 0) {
2120             
2121             
2122             
2123             
2124             throw new OperationFailedException(
2125                     "Relation already exists for cluId:" + cluId + " and Lo:"
2126                             + loId);
2127         }
2128 
2129         CluLoRelation cluLoRelation = new CluLoRelation();
2130         BeanUtils.copyProperties(cluLoRelationInfo, cluLoRelation,
2131                 new String[]{"cluId", "attributes", "meta", "type"});
2132 
2133         cluLoRelation.setClu(clu);
2134         cluLoRelation.setAttributes(CluServiceAssembler.toGenericAttributes(
2135                 CluLoRelationAttribute.class,
2136                 cluLoRelationInfo.getAttributes(), cluLoRelation, luDao));
2137         cluLoRelation.setType(cluLoRelationTypeEntity);
2138 
2139         luDao.create(cluLoRelation);
2140 
2141         return CluServiceAssembler.toCluLoRelationInfo(cluLoRelation);
2142     }
2143 
2144     @Override
2145     @Transactional(readOnly = false)
2146     public CluLoRelationInfo updateCluLoRelation(String cluLoRelationId,
2147                                                  CluLoRelationInfo cluLoRelationInfo, ContextInfo context)
2148             throws DataValidationErrorException, DoesNotExistException,
2149             InvalidParameterException, MissingParameterException,
2150             OperationFailedException, PermissionDeniedException,
2151             VersionMismatchException {
2152         checkForMissingParameter(cluLoRelationId, "cluLoRelationId");
2153         checkForMissingParameter(cluLoRelationInfo, "cluLoRelationInfo");
2154 
2155         
2156         List<ValidationResultInfo> val = validateCluLoRelation("SYSTEM",
2157                 cluLoRelationInfo.getCluId(),
2158                 cluLoRelationInfo.getLoId(),
2159                 cluLoRelationInfo.getTypeKey(),
2160                 cluLoRelationInfo, context);
2161         if (null != val && val.size() > 0) {
2162             throw new DataValidationErrorException("Validation error!", val);
2163         }
2164 
2165         CluLoRelation reltn;
2166         try {
2167             reltn = luDao.fetch(CluLoRelation.class, cluLoRelationId);
2168         } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException ex) {
2169             throw new DoesNotExistException(cluLoRelationId, ex);
2170         }
2171 
2172         if (!String.valueOf(reltn.getVersionNumber()).equals(
2173                 cluLoRelationInfo.getMeta().getVersionInd())) {
2174             throw new VersionMismatchException(
2175                     "CluLoRelation to be updated is not the current version");
2176         }
2177 
2178         Clu clu;
2179         try {
2180             clu = luDao.fetch(Clu.class, cluLoRelationInfo.getCluId());
2181         } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException ex) {
2182             throw new DoesNotExistException(cluLoRelationInfo.getCluId(), ex);
2183         }
2184         if (clu == null) {
2185             throw new DoesNotExistException("Clu does not exist for id: "
2186                     + cluLoRelationInfo.getCluId());
2187         }
2188 
2189         CluLoRelationType cluLoRelationTypeEntity;
2190         try {
2191             cluLoRelationTypeEntity = luDao.fetch(CluLoRelationType.class, cluLoRelationInfo.getTypeKey());
2192         } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException ex) {
2193             throw new DoesNotExistException(cluLoRelationInfo.getTypeKey(), ex);
2194         }
2195         if (cluLoRelationTypeEntity == null) {
2196             throw new DoesNotExistException("CluLoRelationType does not exist for id: "
2197                     + cluLoRelationInfo.getTypeKey());
2198         }
2199 
2200         BeanUtils.copyProperties(cluLoRelationInfo, reltn, new String[]{
2201                 "cluId", "attributes", "meta", "type"});
2202 
2203         reltn.setClu(clu);
2204         reltn.setAttributes(CluServiceAssembler.toGenericAttributes(
2205                 CluLoRelationAttribute.class,
2206                 cluLoRelationInfo.getAttributes(), reltn, luDao));
2207         reltn.setType(cluLoRelationTypeEntity);
2208         CluLoRelation updated = luDao.update(reltn);
2209 
2210         return CluServiceAssembler.toCluLoRelationInfo(updated);
2211     }
2212 
2213     @Override
2214     @Transactional(readOnly = false)
2215     public StatusInfo deleteCluLoRelation(String cluLoRelationId, ContextInfo context)
2216             throws DoesNotExistException, InvalidParameterException,
2217             MissingParameterException, OperationFailedException,
2218             PermissionDeniedException {
2219         checkForMissingParameter(cluLoRelationId, "cluLoRelationId");
2220 
2221         CluLoRelation reltn;
2222         try {
2223             reltn = luDao.fetch(CluLoRelation.class, cluLoRelationId);
2224         } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException ex) {
2225             throw new DoesNotExistException(cluLoRelationId);
2226         }
2227         if (reltn == null) {
2228             throw new DoesNotExistException(
2229                     "CluLoRelation does not exist for id: " + cluLoRelationId);
2230         }
2231         try {
2232             luDao.delete(CluLoRelation.class, cluLoRelationId);
2233         } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException ex) {
2234             throw new DoesNotExistException(cluLoRelationId, ex);
2235         }
2236 
2237         StatusInfo statusInfo = new StatusInfo();
2238         statusInfo.setSuccess(true);
2239 
2240         return statusInfo;
2241     }
2242 
2243     @Override
2244     @Transactional(readOnly = false)
2245     public StatusInfo addCluResourceRequirement(String resourceTypeKey,
2246                                                 String cluId, ContextInfo context) throws AlreadyExistsException, DoesNotExistException,
2247             InvalidParameterException, MissingParameterException,
2248             OperationFailedException, PermissionDeniedException {
2249         throw new OperationFailedException("not yet implemented");
2250     }
2251 
2252     @Override
2253     @Transactional(readOnly = false)
2254     public StatusInfo removeCluResourceRequirement(String resourceTypeKey,
2255                                                    String cluId, ContextInfo context) throws DoesNotExistException,
2256             InvalidParameterException, MissingParameterException,
2257             OperationFailedException, PermissionDeniedException {
2258         return null;
2259     }
2260 
2261     @Override
2262     public List<ValidationResultInfo> validateCluSet(String validationType,
2263                                                      String cluSetType,
2264                                                      CluSetInfo cluSetInfo, ContextInfo context) throws DoesNotExistException,
2265             InvalidParameterException, MissingParameterException,
2266             OperationFailedException {
2267         checkForMissingParameter(validationType, "validationType");
2268         checkForMissingParameter(cluSetInfo, "cluSetInfo");
2269 
2270         ObjectStructureDefinition objStructure = this.getObjectStructure(CluSetInfo.class.getName());
2271         Validator defaultValidator = validatorFactory.getValidator();
2272         List<org.kuali.student.r2.common.dto.ValidationResultInfo> vris = defaultValidator.validateObject(cluSetInfo, objStructure, null);
2273         return vris;
2274     }
2275 
2276     @Override
2277     @Transactional(readOnly = false)
2278     public CluSetInfo createCluSet(String cluSetType, CluSetInfo cluSetInfo, ContextInfo contextInfo)
2279             throws DataValidationErrorException,
2280             InvalidParameterException, MissingParameterException,
2281             OperationFailedException, PermissionDeniedException,
2282             UnsupportedActionException {
2283 
2284         checkForMissingParameter(cluSetType, "cluSetType");
2285         checkForMissingParameter(cluSetInfo, "cluSetInfo");
2286 
2287         cluSetInfo.setTypeKey(cluSetType);
2288 
2289         validateCluSet(cluSetInfo);
2290 
2291         
2292         List<ValidationResultInfo> val;
2293         try {
2294             val = validateCluSet("SYSTEM",
2295                     cluSetInfo.getTypeKey(),
2296                     cluSetInfo, contextInfo);
2297         } catch (DoesNotExistException e) {
2298             throw new DataValidationErrorException("Validation error! " + e.getMessage(), e);
2299         }
2300         if (null != val && val.size() > 0) {
2301             throw new DataValidationErrorException("Validation error!", val);
2302         }
2303 
2304         List<String> cluIds = getMembershipQuerySearchResult(cluSetInfo.getMembershipQuery(), contextInfo);
2305 
2306         CluSet cluSet = null;
2307         try {
2308             cluSet = CluServiceAssembler.toCluSetEntity(cluSetInfo, this.luDao);
2309         } catch (DoesNotExistException e) {
2310             throw new DataValidationErrorException("Creating CluSet entity failed. Clu or CluSet does not exist: " + e.getMessage(), e);
2311         }
2312 
2313         cluSet = luDao.create(cluSet);
2314 
2315         CluSetInfo newCluSetInfo = CluServiceAssembler.toCluSetInfo(cluSet);
2316 
2317         if (cluIds != null) {
2318             newCluSetInfo.getCluIds().addAll(cluIds);
2319         }
2320 
2321         return newCluSetInfo;
2322     }
2323 
2324     private void setMembershipQuerySearchResult(CluSetInfo cluSetInfo, ContextInfo contextInfo) throws MissingParameterException, PermissionDeniedException, OperationFailedException, InvalidParameterException {
2325         if (cluSetInfo.getMembershipQuery() == null) {
2326             return;
2327         }
2328         List<String> cluIds = getMembershipQuerySearchResult(cluSetInfo.getMembershipQuery(), contextInfo);
2329         cluSetInfo.getCluIds().addAll(cluIds);
2330     }
2331 
2332     private List<String> getMembershipQuerySearchResult(MembershipQueryInfo query, ContextInfo contextInfo) throws MissingParameterException, OperationFailedException, PermissionDeniedException, InvalidParameterException {
2333         if (query == null) {
2334             return null;
2335         }
2336 
2337         SearchRequestInfo request = new SearchRequestInfo();
2338         request.setSearchKey(query.getSearchTypeKey());
2339         request.setParams(query.getQueryParamValues());
2340 
2341         SearchResultInfo result = search(request, contextInfo);
2342 
2343         Set<String> cluIds = new HashSet<String>();
2344         List<SearchResultRowInfo> rows = result.getRows();
2345         for (SearchResultRowInfo row : rows) {
2346             List<SearchResultCellInfo> cells = row.getCells();
2347             for (SearchResultCellInfo cell : cells) {
2348                 if (cell.getKey().equals("lu.resultColumn.luOptionalVersionIndId") && cell.getValue() != null) {
2349                     cluIds.add(cell.getValue());
2350                 }
2351             }
2352         }
2353         return new ArrayList<String>(cluIds);
2354     }
2355 
2356     private void validateCluSet(CluSetInfo cluSetInfo) throws UnsupportedActionException {
2357         MembershipQueryInfo mqInfo = cluSetInfo.getMembershipQuery();
2358 
2359         if (cluSetInfo.getTypeKey() == null) {
2360             throw new UnsupportedActionException("CluSet type cannot be null. CluSet id=" + cluSetInfo.getId());
2361         } else if (mqInfo != null && mqInfo.getSearchTypeKey() != null && !mqInfo.getSearchTypeKey().isEmpty()
2362                 && (cluSetInfo.getCluIds().size() > 0 || cluSetInfo.getCluSetIds().size() > 0)) {
2363             throw new UnsupportedActionException("Dynamic CluSet cannot contain Clus and/or CluSets. CluSet id=" + cluSetInfo.getId());
2364         } else if (cluSetInfo.getCluIds().size() > 0 && cluSetInfo.getCluSetIds().size() > 0) {
2365             throw new UnsupportedActionException("CluSet cannot contain both Clus and CluSets. CluSet id=" + cluSetInfo.getId());
2366         }
2367     }
2368 
2369     @Override
2370     @Transactional(readOnly = false)
2371     public CluSetInfo updateCluSet(String cluSetId, CluSetInfo cluSetInfo, ContextInfo contextInfo)
2372             throws DataValidationErrorException, DoesNotExistException,
2373             InvalidParameterException, MissingParameterException,
2374             OperationFailedException, PermissionDeniedException,
2375             VersionMismatchException, CircularRelationshipException,
2376             UnsupportedActionException {
2377 
2378         
2379         checkForMissingParameter(cluSetId, "cluSetId");
2380         checkForMissingParameter(cluSetInfo, "cluSetInfo");
2381 
2382         
2383         List<ValidationResultInfo> val = validateCluSet("SYSTEM",
2384                 cluSetInfo.getTypeKey(),
2385                 cluSetInfo,
2386                 contextInfo);
2387         if (null != val && val.size() > 0) {
2388             throw new DataValidationErrorException("Validation error!", val);
2389         }
2390 
2391         cluSetInfo.setId(cluSetId);
2392 
2393         validateCluSet(cluSetInfo);
2394 
2395         List<String> cluIds = getMembershipQuerySearchResult(cluSetInfo.getMembershipQuery(), contextInfo);
2396 
2397         CluSet cluSet;
2398         try {
2399             cluSet = luDao.fetch(CluSet.class, cluSetId);
2400         } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException ex) {
2401             throw new DoesNotExistException(cluSetId, ex);
2402         }
2403 
2404         if (!cluSetInfo.getTypeKey().equals(cluSet.getType())) {
2405             throw new UnsupportedActionException("CluSet type is set at creation time and cannot be updated. CluSet id=" + cluSetId);
2406         }
2407 
2408         if (!String.valueOf(cluSet.getVersionNumber()).equals(
2409                 cluSetInfo.getMeta().getVersionInd())) {
2410             throw new VersionMismatchException(
2411                     "CluSet (id=" + cluSetId
2412                             + ") to be updated is not the current version "
2413                             + "(version=" + cluSetInfo.getMeta().getVersionInd()
2414                             + "), current version=" + cluSet.getVersionNumber());
2415         }
2416 
2417         
2418         Map<String, CluSetJoinVersionIndClu> oldClus = new HashMap<String, CluSetJoinVersionIndClu>();
2419         for (CluSetJoinVersionIndClu join : cluSet.getCluVerIndIds()) {
2420             oldClus.put(join.getCluVersionIndId(), join);
2421         }
2422 
2423         cluSet.getCluVerIndIds().clear();
2424         
2425         for (String newCluId : cluSetInfo.getCluIds()) {
2426             CluSetJoinVersionIndClu join = oldClus.remove(newCluId);
2427             if (join == null) {
2428                 join = new CluSetJoinVersionIndClu();
2429                 join.setCluSet(cluSet);
2430                 join.setCluVersionIndId(newCluId);
2431             }
2432             cluSet.getCluVerIndIds().add(join);
2433         }
2434 
2435         
2436         for (Entry<String, CluSetJoinVersionIndClu> entry : oldClus.entrySet()) {
2437             luDao.delete(entry.getValue());
2438         }
2439 
2440         
2441         if (cluSetInfo.getId() != null) {
2442             CluSetInfo originalCluSet = getCluSet(cluSetInfo.getId(), contextInfo);
2443             List<CluSetInfo> origSubCSs = null;
2444             List<String> origSubCSIds = originalCluSet.getCluSetIds();
2445             if (origSubCSIds != null && !origSubCSIds.isEmpty()) {
2446                 origSubCSs = getCluSetsByIds(origSubCSIds, contextInfo);
2447             }
2448             if (origSubCSs != null) {
2449                 for (CluSetInfo origSubCS : origSubCSs) {
2450                     if (!origSubCS.getIsReusable()) {
2451                         deleteCluSet(origSubCS.getId(), contextInfo);
2452                     }
2453                 }
2454             }
2455         }
2456 
2457         
2458         if (cluSet.getCluSets() == null) {
2459             cluSet.setCluSets(new ArrayList<CluSet>());
2460         }
2461         cluSet.setCluSets(null);
2462         if (!cluSetInfo.getCluSetIds().isEmpty()) {
2463             Set<String> newCluSetIds = new HashSet<String>(cluSetInfo.getCluSetIds());
2464             if (cluSet.getCluSets() != null) {
2465                 for (Iterator<CluSet> i = cluSet.getCluSets().iterator(); i.hasNext();) {
2466                     if (!newCluSetIds.remove(i.next().getId())) {
2467                         i.remove();
2468                     }
2469                 }
2470             }
2471             List<CluSet> cluSetList = luDao.getCluSetInfoByIdList(new ArrayList<String>(newCluSetIds));
2472             cluSet.setCluSets(cluSetList);
2473         }
2474 
2475         BeanUtils.copyProperties(cluSetInfo, cluSet, new String[]{"descr",
2476                 "attributes", "meta", "membershipQuery"});
2477         cluSet.setAttributes(CluServiceAssembler.toGenericAttributes(
2478                 CluSetAttribute.class, cluSetInfo.getAttributes(), cluSet, luDao));
2479         cluSet.setDescr(CluServiceAssembler.toRichText(LuRichText.class, cluSetInfo.getDescr()));
2480 
2481         MembershipQuery mq = CluServiceAssembler.toMembershipQueryEntity(cluSetInfo.getMembershipQuery());
2482         cluSet.setMembershipQuery(mq);
2483 
2484         CluSet updated = luDao.update(cluSet);
2485 
2486         CluSetInfo updatedCluSetInfo = CluServiceAssembler.toCluSetInfo(updated);
2487 
2488         if (cluIds != null) {
2489             updatedCluSetInfo.getCluIds().addAll(cluIds);
2490         }
2491 
2492         return updatedCluSetInfo;
2493     }
2494 
2495     @Override
2496     @Transactional(readOnly = false)
2497     public StatusInfo deleteCluSet(String cluSetId, ContextInfo context)
2498             throws DoesNotExistException, InvalidParameterException,
2499             MissingParameterException, OperationFailedException,
2500             PermissionDeniedException {
2501 
2502         checkForMissingParameter(cluSetId, "cluSetId");
2503         try {
2504             luDao.delete(CluSet.class, cluSetId);
2505         } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException ex) {
2506             throw new DoesNotExistException(cluSetId, ex);
2507         }
2508 
2509         StatusInfo statusInfo = new StatusInfo();
2510         statusInfo.setSuccess(true);
2511 
2512         return statusInfo;
2513     }
2514 
2515     @Override
2516     @Transactional(readOnly = false)
2517     public StatusInfo addCluSetToCluSet(String cluSetId, String addedCluSetId, ContextInfo context)
2518             throws DoesNotExistException, InvalidParameterException,
2519             MissingParameterException, OperationFailedException,
2520             PermissionDeniedException, UnsupportedActionException,
2521             CircularRelationshipException {
2522         checkForMissingParameter(cluSetId, "cluSetId");
2523         checkForMissingParameter(addedCluSetId, "addedCluSetId");
2524 
2525         CluSet cluSet;
2526         try {
2527             cluSet = luDao.fetch(CluSet.class, cluSetId);
2528         } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException ex) {
2529             throw new DoesNotExistException(cluSetId, ex);
2530         }
2531 
2532         checkCluSetAlreadyAdded(cluSet, addedCluSetId);
2533 
2534         CluSet addedCluSet;
2535         try {
2536             addedCluSet = luDao.fetch(CluSet.class, addedCluSetId);
2537         } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException ex) {
2538             throw new DoesNotExistException(addedCluSetId, ex);
2539         }
2540 
2541         checkCluSetCircularReference(addedCluSet, cluSetId);
2542 
2543         if (cluSet.getCluSets() == null) {
2544             cluSet.setCluSets(new ArrayList<CluSet>());
2545         }
2546         cluSet.getCluSets().add(addedCluSet);
2547 
2548         luDao.update(cluSet);
2549 
2550         StatusInfo statusInfo = new StatusInfo();
2551         statusInfo.setSuccess(true);
2552 
2553         return statusInfo;
2554     }
2555 
2556     private void checkCluSetAlreadyAdded(CluSet cluSet, String cluSetIdToAdd)
2557             throws OperationFailedException {
2558         if (cluSet.getCluSets() != null) {
2559             for (CluSet childCluSet : cluSet.getCluSets()) {
2560                 if (childCluSet.getId().equals(cluSetIdToAdd)) {
2561                     throw new OperationFailedException("CluSet (id=" + cluSet.getId()
2562                             + ") already contains CluSet (id='" + cluSetIdToAdd + "')");
2563                 }
2564             }
2565         }
2566     }
2567 
2568     private void checkCluSetCircularReference(CluSet addedCluSet, String hostCluSetId)
2569             throws CircularRelationshipException {
2570         if (addedCluSet.getId().equals(hostCluSetId)) {
2571             throw new CircularRelationshipException(
2572                     "Cannot add a CluSet (id=" + hostCluSetId + ") to ifself");
2573         }
2574         if (addedCluSet.getCluSets() != null) {
2575             for (CluSet childSet : addedCluSet.getCluSets()) {
2576                 if (childSet.getId().equals(hostCluSetId)) {
2577                     throw new CircularRelationshipException(
2578                             "CluSet (id=" + hostCluSetId
2579                                     + ") already contains this CluSet (id="
2580                                     + childSet.getId() + ")");
2581                 }
2582                 checkCluSetCircularReference(childSet, hostCluSetId);
2583             }
2584         }
2585     }
2586 
2587     @Override
2588     @Transactional(readOnly = false)
2589     public StatusInfo removeCluSetFromCluSet(String cluSetId,
2590                                              String removedCluSetId, ContextInfo context) throws DoesNotExistException,
2591             InvalidParameterException, MissingParameterException,
2592             OperationFailedException, PermissionDeniedException,
2593             UnsupportedActionException {
2594 
2595         checkForMissingParameter(cluSetId, "cluSetId");
2596         checkForMissingParameter(removedCluSetId, "removedCluSetId");
2597 
2598         CluSet cluSet;
2599         try {
2600             cluSet = luDao.fetch(CluSet.class, cluSetId);
2601         } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException ex) {
2602             throw new DoesNotExistException(cluSetId, ex);
2603         }
2604         if (cluSet.getCluSets() != null) {
2605             for (Iterator<CluSet> i = cluSet.getCluSets().iterator(); i.hasNext();) {
2606                 CluSet childCluSet = i.next();
2607                 if (childCluSet.getId().equals(removedCluSetId)) {
2608                     i.remove();
2609                     luDao.update(cluSet);
2610                     StatusInfo statusInfo = new StatusInfo();
2611                     statusInfo.setSuccess(true);
2612 
2613                     return statusInfo;
2614                 }
2615             }
2616         }
2617 
2618         StatusInfo statusInfo = new StatusInfo();
2619         statusInfo.setSuccess(false);
2620         statusInfo.setMessage("CluSet does not contain CluSet:"
2621                 + removedCluSetId);
2622 
2623         return statusInfo;
2624     }
2625 
2626     @Override
2627     @Transactional(readOnly = false)
2628     public StatusInfo addCluToCluSet(String cluId, String cluSetId, ContextInfo context)
2629             throws DoesNotExistException, InvalidParameterException,
2630             MissingParameterException, OperationFailedException,
2631             PermissionDeniedException, UnsupportedActionException {
2632 
2633         checkForMissingParameter(cluId, "cluId");
2634         checkForMissingParameter(cluSetId, "cluSetId");
2635 
2636         StatusInfo statusInfo = new StatusInfo();
2637 
2638         CluSet cluSet;
2639         try {
2640             cluSet = luDao.fetch(CluSet.class, cluSetId);
2641         } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException ex) {
2642             throw new DoesNotExistException(cluSetId, ex);
2643         }
2644 
2645         if(!checkCluAlreadyAdded(cluSet, cluId)) {
2646             statusInfo.setSuccess(Boolean.FALSE);
2647             statusInfo.setMessage("CluSet already contains Clu (id='" + cluId + "')");
2648         }else {
2649             try {
2650                 luDao.getCurrentCluVersionInfo(cluId, CluServiceConstants.CLU_NAMESPACE_URI);
2651             } catch (NoResultException e) {
2652                 throw new DoesNotExistException("Could not get current clu version info by cluId", e);
2653             }
2654 
2655             CluSetJoinVersionIndClu join = new CluSetJoinVersionIndClu();
2656             join.setCluSet(cluSet);
2657             join.setCluVersionIndId(cluId);
2658 
2659             cluSet.getCluVerIndIds().add(join);
2660 
2661             luDao.update(cluSet);
2662 
2663 
2664             statusInfo.setSuccess(true);
2665         }
2666 
2667         return statusInfo;
2668     }
2669 
2670     private boolean checkCluAlreadyAdded(CluSet cluSet, String cluId)
2671             throws OperationFailedException {
2672         for (CluSetJoinVersionIndClu join : cluSet.getCluVerIndIds()) {
2673             if (join.getCluVersionIndId().equals(cluId)) {
2674                 return false;
2675             }
2676         }
2677         return true;
2678     }
2679 
2680     @Override
2681     @Transactional(readOnly = false)
2682     public StatusInfo removeCluFromCluSet(String cluId, String cluSetId, ContextInfo context)
2683             throws DoesNotExistException, InvalidParameterException,
2684             MissingParameterException, OperationFailedException,
2685             PermissionDeniedException, UnsupportedActionException {
2686 
2687         checkForMissingParameter(cluId, "cluId");
2688         checkForMissingParameter(cluSetId, "cluSetId");
2689 
2690         CluSet cluSet;
2691         try {
2692             cluSet = luDao.fetch(CluSet.class, cluSetId);
2693         } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException ex) {
2694             throw new DoesNotExistException(cluSetId, ex);
2695         }
2696 
2697         for (Iterator<CluSetJoinVersionIndClu> i = cluSet.getCluVerIndIds().iterator(); i.hasNext();) {
2698             CluSetJoinVersionIndClu join = i.next();
2699             if (join.getCluVersionIndId().equals(cluId)) {
2700                 i.remove();
2701                 luDao.delete(join);
2702                 luDao.update(cluSet);
2703                 StatusInfo statusInfo = new StatusInfo();
2704                 statusInfo.setSuccess(true);
2705 
2706                 return statusInfo;
2707             }
2708         }
2709 
2710         StatusInfo statusInfo = new StatusInfo();
2711         statusInfo.setSuccess(false);
2712         statusInfo.setMessage("Clu set does not contain Clu:" + cluId);
2713 
2714         return statusInfo;
2715     }
2716 
2717     public LuDao getLuDao() {
2718         return luDao;
2719     }
2720 
2721     public void setLuDao(LuDao luDao) {
2722         this.luDao = luDao;
2723     }
2724 
2725     
2726 
2727 
2728 
2729 
2730 
2731 
2732     private void checkForMissingParameter(Object param, String paramName)
2733             throws MissingParameterException {
2734         if (param == null) {
2735             throw new MissingParameterException(paramName + " can not be null");
2736         }
2737     }
2738 
2739     
2740 
2741 
2742 
2743 
2744     private void checkForEmptyList(Object param, String paramName)
2745             throws MissingParameterException {
2746         if (param != null && param instanceof List<?>
2747                 && ((List<?>) param).size() == 0) {
2748             throw new MissingParameterException(paramName
2749                     + " can not be an empty list");
2750         }
2751     }
2752 
2753     @Override
2754     @Transactional(readOnly = false)
2755     public StatusInfo addCluSetsToCluSet(String cluSetId, List<String> cluSetIds, ContextInfo context)
2756             throws CircularRelationshipException,
2757             DoesNotExistException, InvalidParameterException,
2758             MissingParameterException, OperationFailedException,
2759             PermissionDeniedException, UnsupportedActionException {
2760 
2761         checkForMissingParameter(cluSetId, "cluSetId");
2762         checkForMissingParameter(cluSetIds, "cluSetIds");
2763         try {
2764             
2765             luDao.fetch(CluSet.class, cluSetId);
2766         } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException ex) {
2767             throw new DoesNotExistException(cluSetId, ex);
2768         }
2769 
2770         for (String cluSetIdToAdd : cluSetIds) {
2771             StatusInfo status = addCluSetToCluSet(cluSetId, cluSetIdToAdd, context);
2772             if (!status.getIsSuccess()) {
2773                 return status;
2774             }
2775         }
2776 
2777         StatusInfo statusInfo = new StatusInfo();
2778         statusInfo.setSuccess(true);
2779 
2780         return statusInfo;
2781     }
2782 
2783     @Override
2784     @Transactional(readOnly = false)
2785     public StatusInfo addClusToCluSet(List<String> cluIds, String cluSetId, ContextInfo context)
2786             throws DoesNotExistException, InvalidParameterException,
2787             MissingParameterException, OperationFailedException,
2788             PermissionDeniedException, UnsupportedActionException {
2789         StatusInfo statusInfo = new StatusInfo();
2790 
2791         checkForMissingParameter(cluIds, "cluIds");
2792         checkForMissingParameter(cluSetId, "cluSetId");
2793 
2794         for (String cluId : cluIds) {
2795             StatusInfo status = addCluToCluSet(cluId, cluSetId, context);
2796             if (!status.getIsSuccess()) {
2797                 if(statusInfo.getMessage().isEmpty()){
2798                     statusInfo.setMessage(status.getMessage());
2799                 }else{
2800                     statusInfo.setMessage(statusInfo.getMessage()+"\n"+status.getMessage());
2801                 }
2802             }
2803         }
2804 
2805         statusInfo.setSuccess(true);
2806 
2807         return statusInfo;
2808     }
2809 
2810     public ValidatorFactory getValidatorFactory() {
2811         return validatorFactory;
2812     }
2813 
2814     public void setValidatorFactory(ValidatorFactory validatorFactory) {
2815         this.validatorFactory = validatorFactory;
2816     }
2817 
2818     
2819     @Override
2820     @Transactional(readOnly = false)
2821     public CluInfo createNewCluVersion(String versionIndCluId,
2822                                        String versionComment,
2823                                        ContextInfo context)
2824             throws DataValidationErrorException, DoesNotExistException, InvalidParameterException,
2825             MissingParameterException, OperationFailedException, PermissionDeniedException {
2826         Clu latestClu;
2827         Clu currentClu;
2828         try {
2829             latestClu = luDao.getLatestCluVersion(versionIndCluId);
2830         } catch (NoResultException e) {
2831             throw new DoesNotExistException("There are no matching versions of this clu", e);
2832         }
2833         try {
2834             currentClu = luDao.getCurrentCluVersion(versionIndCluId);
2835         } catch (NoResultException e) {
2836             throw new DoesNotExistException("There is no current version of this clu. Only current clus can be versioned. Use setCurrentCluVersion to make a clu current.", e);
2837         }
2838 
2839         CluInfo cluInfo = CluServiceAssembler.toCluInfo(currentClu);
2840 
2841         
2842         clearCluIds(cluInfo);
2843 
2844         
2845         CluInfo newClu = null;
2846 
2847         try {
2848             Clu clu = toCluForCreate(cluInfo.getTypeKey(), cluInfo, context);
2849             
2850             Version version = new Version();
2851             version.setSequenceNumber(latestClu.getVersion().getSequenceNumber() + 1);
2852             version.setVersionIndId(versionIndCluId);
2853             version.setCurrentVersionStart(null);
2854             version.setCurrentVersionEnd(null);
2855             version.setVersionComment(versionComment);
2856             version.setVersionedFromId(currentClu.getId());
2857             clu.setVersion(version);
2858             luDao.create(clu);
2859             newClu = CluServiceAssembler.toCluInfo(clu);
2860         } catch (AlreadyExistsException e) {
2861             throw new OperationFailedException("Error creating a new clu version", e);
2862         }
2863 
2864         return newClu;
2865     }
2866 
2867     private void clearCluIds(CluInfo clu) {
2868         
2869         clu.setStateKey(DtoConstants.STATE_DRAFT);
2870         clu.setId(null);
2871 
2872         if (clu.getAccountingInfo() != null) {
2873             clu.getAccountingInfo().setId(null);
2874 
2875             for (AffiliatedOrgInfo affiliatedOrg : clu.getAccountingInfo().getAffiliatedOrgs()) {
2876                 affiliatedOrg.setId(null);
2877             }
2878         }
2879         for (AccreditationInfo accredation : clu.getAccreditations()) {
2880             accredation.setId(null);
2881         }
2882         for (AdminOrgInfo adminOrg : clu.getAdminOrgs()) {
2883             adminOrg.setId(null);
2884         }
2885         for (CluIdentifierInfo alternateIdentifier : clu.getAlternateIdentifiers()) {
2886             alternateIdentifier.setId(null);
2887         }
2888         if (clu.getFeeInfo() != null) {
2889             clu.getFeeInfo().setId(null);
2890             for (CluFeeRecordInfo cluFeeRecord : clu.getFeeInfo().getCluFeeRecords()) {
2891                 cluFeeRecord.setId(null);
2892                 for (AffiliatedOrgInfo affiliatedOrg : cluFeeRecord.getAffiliatedOrgs()) {
2893                     affiliatedOrg.setId(null);
2894                 }
2895             }
2896         }
2897         for (LuCodeInfo luCode : clu.getLuCodes()) {
2898             luCode.setId(null);
2899         }
2900         if (clu.getOfficialIdentifier() != null) {
2901             clu.getOfficialIdentifier().setId(null);
2902         }
2903     }
2904 
2905     
2906 
2907 
2908 
2909 
2910 
2911     @Override
2912     @Transactional(readOnly = false)
2913     public StatusInfo setCurrentCluVersion(String cluVersionId, Date currentVersionStart, ContextInfo context) throws DoesNotExistException, InvalidParameterException, MissingParameterException, IllegalVersionSequencingException, OperationFailedException, PermissionDeniedException {
2914         
2915         Date currentDbDate = new Date();
2916         if (currentVersionStart != null && currentVersionStart.compareTo(currentDbDate) < 0) {
2917             throw new InvalidParameterException("currentVersionStart must be in the future.");
2918         }
2919         
2920         if (currentVersionStart == null) {
2921             currentVersionStart = currentDbDate;
2922         }
2923 
2924         
2925         Clu clu;
2926         try {
2927             clu = luDao.fetch(Clu.class, cluVersionId);
2928         } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException ex) {
2929             throw new DoesNotExistException(cluVersionId, ex);
2930         }
2931         String versionIndId = clu.getVersion().getVersionIndId();
2932 
2933         Clu oldClu = null;
2934         try {
2935             oldClu = luDao.getCurrentCluVersion(versionIndId);
2936         } catch (NoResultException e) {
2937         }
2938 
2939         
2940         if (oldClu != null) {
2941             if (clu.getVersion().getSequenceNumber() <= oldClu.getVersion().getSequenceNumber()) {
2942                 throw new OperationFailedException("Clu to make current must have been versioned from the current Clu");
2943             }
2944         } else {
2945             
2946             currentVersionStart = currentDbDate;
2947         }
2948 
2949 
2950         
2951         List<VersionDisplayInfo> versionsInFuture = luDao.getVersionsInDateRange(versionIndId, null, currentDbDate, null);
2952         for (VersionDisplayInfo versionInFuture : versionsInFuture) {
2953             if (oldClu == null || !versionInFuture.getId().equals(oldClu.getId())) {
2954                 VersionEntity futureClu;
2955                 try {
2956                     futureClu = luDao.fetch(Clu.class, versionInFuture.getId());
2957                 } catch (org.kuali.student.r2.common.exceptions.DoesNotExistException ex) {
2958                     throw new DoesNotExistException(versionInFuture.getId(), ex);
2959                 }
2960                 futureClu.getVersion().setCurrentVersionStart(null);
2961                 futureClu.getVersion().setCurrentVersionEnd(null);
2962                 futureClu = luDao.update(futureClu);
2963             }
2964         }
2965 
2966         
2967         if (oldClu != null) {
2968             oldClu.getVersion().setCurrentVersionEnd(currentVersionStart);
2969             oldClu = luDao.update(oldClu);
2970         }
2971 
2972         
2973         clu.getVersion().setCurrentVersionStart(currentVersionStart);
2974         clu.getVersion().setCurrentVersionEnd(null);
2975         clu = luDao.update(clu);
2976 
2977         StatusInfo statusInfo = new StatusInfo();
2978         statusInfo.setSuccess(true);
2979         return statusInfo;
2980     }
2981 
2982     private SearchResultInfo doBrowseProgramSearch(ContextInfo contextInfo) throws MissingParameterException, PermissionDeniedException, OperationFailedException, InvalidParameterException {
2983         
2984         SearchResultInfo programSearchResults = searchManager.search(new SearchRequestInfo(SEARCH_KEY_BROWSE_PROGRAM), contextInfo);
2985 
2986         
2987         SearchResultInfo variationSearchResults = searchManager.search(new SearchRequestInfo(SEARCH_KEY_BROWSE_VARIATIONS),
2988                 contextInfo);
2989 
2990         
2991         Map<String, List<String>> variationMapping = new HashMap<String, List<String>>();
2992         for (SearchResultRowInfo row : variationSearchResults.getRows()) {
2993             String programId = null;
2994             String variationLongName = null;
2995             for (SearchResultCellInfo cell : row.getCells()) {
2996                 if ("lu.resultColumn.cluId".equals(cell.getKey())) {
2997                     programId = cell.getValue();
2998                 } else if ("lu.resultColumn.luOptionalLongName".equals(cell.getKey())) {
2999                     variationLongName = cell.getValue();
3000                 }
3001             }
3002             List<String> variationLongNames = variationMapping.get(programId);
3003             if (variationLongNames == null) {
3004                 variationLongNames = new ArrayList<String>();
3005                 variationMapping.put(programId, variationLongNames);
3006             }
3007             variationLongNames.add(variationLongName);
3008         }
3009 
3010         
3011         SearchRequestInfo resultComponentSearchRequest = new SearchRequestInfo(SEARCH_KEY_RESULT_COMPONENT);
3012         resultComponentSearchRequest.addParam("lrc.queryParam.resultComponent.type",
3013                 "kuali.result.values.group.type.fixed");
3014         resultComponentSearchRequest.addParam("lrc.queryParam.resultComponent.resultScaleId",
3015                 "kuali.result.scale.degree");
3016 
3017         SearchResultInfo resultComponentSearchResults = searchDispatcher.search(resultComponentSearchRequest, contextInfo);
3018 
3019         
3020         Map<String, String> resultComponentMapping = new HashMap<String, String>();
3021         for (SearchResultRowInfo row : resultComponentSearchResults.getRows()) {
3022             String resultComponentTypeId = null;
3023             String resultComponentTypeName = null;
3024             for (SearchResultCellInfo cell : row.getCells()) {
3025                 if ("lrc.resultColumn.resultComponent.id".equals(cell.getKey())) {
3026                     resultComponentTypeId = cell.getValue();
3027                 } else if ("lrc.resultColumn.resultComponent.name".equals(cell.getKey())) {
3028                     resultComponentTypeName = cell.getValue();
3029                 }
3030             }
3031             resultComponentMapping.put(resultComponentTypeId, resultComponentTypeName);
3032         }
3033 
3034         Map<String, Set<SearchResultCellInfo>> orgIdToCellMapping = new HashMap<String, Set<SearchResultCellInfo>>();
3035         Map<String, Set<SearchResultCellInfo>> resultComponentToCellMapping = new HashMap<String, Set<SearchResultCellInfo>>();
3036         Map<String, Set<SearchResultCellInfo>> campusToCellMapping = new HashMap<String, Set<SearchResultCellInfo>>();
3037         Map<String, SearchResultCellInfo> progIdToOrgCellMapping = new HashMap<String, SearchResultCellInfo>();
3038         Map<String, SearchResultCellInfo> progIdToResultComponentCellMapping = new HashMap<String, SearchResultCellInfo>();
3039         Map<String, SearchResultCellInfo> progIdToCampusCellMapping = new HashMap<String, SearchResultCellInfo>();
3040 
3041         
3042         for (Iterator<SearchResultRowInfo> rowIter = programSearchResults.getRows().iterator(); rowIter.hasNext();) {
3043             SearchResultRowInfo row = rowIter.next();
3044             String programId = null;
3045             String orgId = null;
3046             String resultComponentName = null;
3047             String campusCode = null;
3048             SearchResultCellInfo orgCell = null;
3049             SearchResultCellInfo resultComponentCell = null;
3050             SearchResultCellInfo variationCell = null;
3051             SearchResultCellInfo campusLocationCell = null;
3052 
3053             for (SearchResultCellInfo cell : row.getCells()) {
3054                 if ("lu.resultColumn.cluId".equals(cell.getKey())) {
3055                     programId = cell.getValue();
3056                 } else if ("lu.resultColumn.luOptionalAdminOrg".equals(cell.getKey())) {
3057                     orgId = cell.getValue();
3058                     orgCell = cell;
3059                 } else if ("lu.resultColumn.resultComponentId".equals(cell.getKey())) {
3060                     resultComponentName = resultComponentMapping.get(cell.getValue());
3061                     resultComponentCell = cell;
3062                 } else if ("lu.resultColumn.variationId".equals(cell.getKey())) {
3063                     variationCell = cell;
3064                 } else if ("lu.resultColumn.luOptionalCampusLocation".equals(cell.getKey())) {
3065                     campusLocationCell = cell;
3066                     campusCode = cell.getValue();
3067                 }
3068             }
3069             if (!progIdToOrgCellMapping.containsKey(programId)) {
3070                 
3071                 List<String> variations = variationMapping.get(programId);
3072                 variationCell.setValue("");
3073                 if (variations != null) {
3074                     for (Iterator<String> variationIter = variations.iterator(); variationIter.hasNext();) {
3075                         String variation = variationIter.next();
3076                         if (variationIter.hasNext()) {
3077                             variation += "<br/>";
3078                         }
3079                         variationCell.setValue(variationCell.getValue() + variation);
3080                     }
3081                 }
3082 
3083                 
3084                 Set<SearchResultCellInfo> orgCells = orgIdToCellMapping.get(orgId);
3085                 if (orgCells == null) {
3086                     orgCells = new HashSet<SearchResultCellInfo>();
3087                     orgIdToCellMapping.put(orgId, orgCells);
3088                 }
3089                 orgCells.add(orgCell);
3090                 orgCell.setValue(null);
3091 
3092                 
3093                 Set<SearchResultCellInfo> campusCells = campusToCellMapping.get(campusCode);
3094                 if (campusCells == null) {
3095                     campusCells = new HashSet<SearchResultCellInfo>();
3096                     campusToCellMapping.put(campusCode, campusCells);
3097                 }
3098                 campusCells.add(campusLocationCell);
3099                 campusLocationCell.setValue(null);
3100 
3101                 
3102                 Set<SearchResultCellInfo> resultCells = resultComponentToCellMapping.get(resultComponentName);
3103                 if (resultCells == null) {
3104                     resultCells = new HashSet<SearchResultCellInfo>();
3105                     resultComponentToCellMapping.put(resultComponentName, resultCells);
3106                 }
3107                 resultCells.add(resultComponentCell);
3108                 resultComponentCell.setValue(null);
3109 
3110                 progIdToOrgCellMapping.put(programId, orgCell);
3111                 progIdToResultComponentCellMapping.put(programId, resultComponentCell);
3112                 progIdToCampusCellMapping.put(programId, campusLocationCell);
3113             } else {
3114                 
3115                 
3116                 Set<SearchResultCellInfo> resultCells = resultComponentToCellMapping.get(resultComponentName);
3117                 if (resultCells == null) {
3118                     resultCells = new HashSet<SearchResultCellInfo>();
3119                     resultComponentToCellMapping.put(resultComponentName, resultCells);
3120                 }
3121                 resultCells.add(progIdToResultComponentCellMapping.get(programId));
3122 
3123                 
3124                 Set<SearchResultCellInfo> orgCells = orgIdToCellMapping.get(orgId);
3125                 if (orgCells == null) {
3126                     orgCells = new HashSet<SearchResultCellInfo>();
3127                     orgIdToCellMapping.put(orgId, orgCells);
3128                 }
3129                 orgCells.add(progIdToOrgCellMapping.get(programId));
3130 
3131                 
3132                 Set<SearchResultCellInfo> campusCells = campusToCellMapping.get(campusCode);
3133                 if (campusCells == null) {
3134                     campusCells = new HashSet<SearchResultCellInfo>();
3135                     campusToCellMapping.put(campusCode, campusCells);
3136                 }
3137                 campusCells.add(progIdToCampusCellMapping.get(programId));
3138 
3139                 
3140                 rowIter.remove();
3141             }
3142         }
3143 
3144         if (!resultComponentToCellMapping.isEmpty()) {
3145             List<String> resultComponentNames = new ArrayList<String>(resultComponentToCellMapping.keySet());
3146             Collections.sort(resultComponentNames);
3147             for (String resultComponentName : resultComponentNames) {
3148                 
3149                 Set<SearchResultCellInfo> cells = resultComponentToCellMapping.get(resultComponentName);
3150                 if (cells != null) {
3151                     for (SearchResultCellInfo cell : cells) {
3152                         if (cell.getValue() == null) {
3153                             cell.setValue(resultComponentName);
3154                         } else {
3155                             cell.setValue(cell.getValue() + "<br/>" + resultComponentName);
3156                         }
3157                     }
3158                 }
3159             }
3160         }
3161 
3162         if (!campusToCellMapping.isEmpty()) {
3163             List<String> campusCodes = new ArrayList<String>(campusToCellMapping.keySet());
3164             Collections.sort(campusCodes);
3165             for (String campusCode : campusCodes) {
3166                 
3167                 Set<SearchResultCellInfo> cells = campusToCellMapping.get(campusCode);
3168                 if (cells != null) {
3169                     for (SearchResultCellInfo cell : cells) {
3170                         if (cell.getValue() == null) {
3171                             cell.setValue(campusCode);
3172                         } else {
3173                             cell.setValue(cell.getValue() + "<br/>" + campusCode);
3174                         }
3175                     }
3176                 }
3177             }
3178         }
3179 
3180         
3181         if (!orgIdToCellMapping.isEmpty()) {
3182             
3183             SearchRequestInfo orgIdTranslationSearchRequest = new SearchRequestInfo("org.search.generic");
3184             orgIdTranslationSearchRequest.addParam("org.queryParam.orgOptionalIds", new ArrayList<String>(
3185                     orgIdToCellMapping.keySet()));
3186             orgIdTranslationSearchRequest.setSortColumn("org.resultColumn.orgShortName");
3187             SearchResultInfo orgIdTranslationSearchResult = searchDispatcher.search(orgIdTranslationSearchRequest, contextInfo);
3188 
3189             
3190             for (SearchResultRowInfo row : orgIdTranslationSearchResult.getRows()) {
3191 
3192                 
3193                 String orgId = "";
3194                 String orgName = "";
3195                 for (SearchResultCellInfo cell : row.getCells()) {
3196                     if ("org.resultColumn.orgId".equals(cell.getKey())) {
3197                         orgId = cell.getValue();
3198                         continue;
3199                     } else if ("org.resultColumn.orgShortName".equals(cell.getKey())) {
3200                         orgName = cell.getValue();
3201                     }
3202                 }
3203 
3204                 
3205                 Set<SearchResultCellInfo> cells = orgIdToCellMapping.get(orgId);
3206                 if (cells != null) {
3207                     for (SearchResultCellInfo cell : cells) {
3208                         if (cell.getValue() == null) {
3209                             cell.setValue(orgName);
3210                         } else {
3211                             cell.setValue(cell.getValue() + "<br/>" + orgName);
3212                         }
3213                     }
3214                 }
3215             }
3216         }
3217 
3218         return programSearchResults;
3219     }
3220 
3221     private SearchResultInfo doDependencyAnalysisSearch(String cluId, ContextInfo contextInfo) throws MissingParameterException,
3222             DoesNotExistException, PermissionDeniedException, OperationFailedException, InvalidParameterException {
3223 
3224         checkForMissingParameter(cluId, "cluId");
3225 
3226         Clu triggerClu = luDao.fetch(Clu.class, cluId);
3227 
3228         List<String> cluVersionIndIds = new ArrayList<String>();
3229         cluVersionIndIds.add(triggerClu.getVersion().getVersionIndId());
3230 
3231         
3232         List<CluSet> cluSets = luDao.getCluSetsByCluVersionIndId(cluVersionIndIds);
3233 
3234         
3235         Map<String, CluSet> cluSetMap = new HashMap<String, CluSet>();
3236         if (cluSets != null) {
3237             for (CluSet cluSet : cluSets) {
3238                 cluSetMap.put(cluSet.getId(), cluSet);
3239             }
3240         }
3241 
3242         
3243         List<CluSet> dynamicCluSets = luDao.getAllDynamicCluSets();
3244         if (dynamicCluSets != null) {
3245             for (CluSet cluSet : dynamicCluSets) {
3246                 MembershipQueryInfo queryInfo = CluServiceAssembler.toMembershipQueryInfo(cluSet.getMembershipQuery());
3247                 List<String> memberCluVersionIndIds = getMembershipQuerySearchResult(queryInfo, contextInfo);
3248                 if (memberCluVersionIndIds != null) {
3249                     for (String cluVersionIndId : cluVersionIndIds) {
3250                         if (memberCluVersionIndIds.contains(cluVersionIndId)) {
3251                             cluSetMap.put(cluSet.getId(), cluSet);
3252                             break;
3253                         }
3254                     }
3255                 }
3256             }
3257         }
3258         
3259         
3260 
3261         
3262         
3263         
3264         SearchRequestInfo statementSearchRequest = new SearchRequestInfo("stmt.search.dependencyAnalysis");
3265 
3266         statementSearchRequest.addParam("stmt.queryParam.cluSetIds", new ArrayList<String>(cluSetMap.keySet()));
3267         statementSearchRequest.addParam("stmt.queryParam.cluVersionIndIds", cluVersionIndIds);
3268 
3269         SearchResultInfo statementSearchResult = searchDispatcher.search(statementSearchRequest, contextInfo);
3270 
3271         
3272         SearchResultInfo searchResult = new SearchResultInfo();
3273 
3274         Map<String, List<SearchResultCellInfo>> orgIdToCellMapping = new HashMap<String, List<SearchResultCellInfo>>();
3275 
3276         
3277         
3278         
3279         Set<String> processed = new HashSet<String>();
3280         for (SearchResultRowInfo stmtRow : statementSearchResult.getRows()) {
3281 
3282             
3283             String refObjId = null;
3284             String statementType = null;
3285             String statementTypeName = null;
3286             String rootId = null;
3287             String requirementComponentIds = null;
3288 
3289             for (SearchResultCellInfo stmtCell : stmtRow.getCells()) {
3290                 if ("stmt.resultColumn.refObjId".equals(stmtCell.getKey())) {
3291                     refObjId = stmtCell.getValue();
3292                     continue;
3293                 } else if ("stmt.resultColumn.statementTypeId".equals(stmtCell.getKey())) {
3294                     statementType = stmtCell.getValue();
3295                     continue;
3296                 } else if ("stmt.resultColumn.statementTypeName".equals(stmtCell.getKey())) {
3297                     statementTypeName = stmtCell.getValue();
3298                     continue;
3299                 } else if ("stmt.resultColumn.rootId".equals(stmtCell.getKey())) {
3300                     rootId = stmtCell.getValue();
3301                     continue;
3302                 } else if ("stmt.resultColumn.requirementComponentIds".equals(stmtCell.getKey())) {
3303                     requirementComponentIds = stmtCell.getValue();
3304                 }
3305             }
3306 
3307             
3308             Clu clu = luDao.fetch(Clu.class, refObjId);
3309 
3310             
3311             if ("kuali.lu.type.Requirement".equals(clu.getLuType().getId())) {
3312 
3313                 List<Clu> clus = luDao.getClusByRelatedCluId(clu.getId(),
3314                         "kuali.lu.lu.relation.type.hasProgramRequirement");
3315 
3316                 rootId = clu.getId();
3317 
3318                 if (clus == null || clus.size() == 0) {
3319                     throw new RuntimeException("Statement Dependency clu found, but no parent Program exists");
3320                 } else if (clus.size() > 1) {
3321                     throw new RuntimeException("Statement Dependency clu can only have one parent Program relation");
3322                 }
3323                 clu = clus.get(0);
3324             }
3325 
3326             
3327             String rowId = clu.getId() + "|" + statementType + "|" + rootId;
3328 
3329             if ("Active".equals(clu.getState()) && !processed.contains(rowId)) {
3330 
3331                 processed.add(rowId);
3332 
3333                 SearchResultRowInfo resultRow = new SearchResultRowInfo();
3334 
3335                 
3336                 resultRow.addCell("lu.resultColumn.cluId", clu.getId());
3337                 resultRow.addCell("lu.resultColumn.cluType", clu.getLuType().getId());
3338                 resultRow.addCell("lu.resultColumn.luOptionalCode", clu.getOfficialIdentifier().getCode());
3339                 resultRow.addCell("lu.resultColumn.luOptionalShortName", clu.getOfficialIdentifier().getShortName());
3340                 resultRow.addCell("lu.resultColumn.luOptionalLongName", clu.getOfficialIdentifier().getLongName());
3341                 resultRow.addCell("lu.resultColumn.luOptionalDependencyType", statementType);
3342                 resultRow.addCell("lu.resultColumn.luOptionalDependencyTypeName", statementTypeName);
3343                 resultRow.addCell("lu.resultColumn.luOptionalDependencyRootId", rootId);
3344                 resultRow.addCell("lu.resultColumn.luOptionalDependencyRequirementComponentIds",
3345                         requirementComponentIds);
3346 
3347                 
3348                 SearchResultCellInfo orgIdsCell = new SearchResultCellInfo("lu.resultColumn.luOptionalOversightCommitteeIds",
3349                         null);
3350                 resultRow.getCells().add(orgIdsCell);
3351 
3352                 
3353                 SearchResultCellInfo orgNamesCell = new SearchResultCellInfo(
3354                         "lu.resultColumn.luOptionalOversightCommitteeNames", null);
3355                 resultRow.getCells().add(orgNamesCell);
3356 
3357                 
3358                 
3359                 
3360                 boolean differentAdminOrg = true;
3361                 for (CluAdminOrg adminOrg : clu.getAdminOrgs()) {
3362                     if ("kuali.adminOrg.type.CurriculumOversight".equals(adminOrg.getType()) ||
3363                             "kuali.adminOrg.type.CurriculumOversightUnit".equals(adminOrg.getType())) {
3364 
3365                         
3366                         List<SearchResultCellInfo> cells = orgIdToCellMapping.get(adminOrg.getOrgId());
3367                         if (cells == null) {
3368                             cells = new ArrayList<SearchResultCellInfo>();
3369                             orgIdToCellMapping.put(adminOrg.getOrgId(), cells);
3370                         }
3371                         cells.add(orgNamesCell);
3372 
3373                         
3374                         if (orgIdsCell.getValue() == null) {
3375                             orgIdsCell.setValue(adminOrg.getId());
3376                         } else {
3377                             orgIdsCell.setValue(orgIdsCell.getValue() + "," + adminOrg.getId());
3378                         }
3379 
3380                         for (CluAdminOrg triggerAdminOrg : triggerClu.getAdminOrgs()) {
3381                             if (triggerAdminOrg.getOrgId().equals(adminOrg.getOrgId())) {
3382                                 differentAdminOrg = false;
3383                             }
3384                         }
3385                     }
3386                 }
3387                 resultRow.addCell("lu.resultColumn.luOptionalDependencyRequirementDifferentAdminOrg",
3388                         String.valueOf(differentAdminOrg));
3389 
3390                 
3391                 searchResult.getRows().add(resultRow);
3392             }
3393         }
3394 
3395         
3396         if (!orgIdToCellMapping.isEmpty()) {
3397             
3398             SearchRequestInfo orgIdTranslationSearchRequest = new SearchRequestInfo("org.search.generic");
3399             orgIdTranslationSearchRequest.addParam("org.queryParam.orgOptionalIds", new ArrayList<String>(
3400                     orgIdToCellMapping.keySet()));
3401             SearchResultInfo orgIdTranslationSearchResult = searchDispatcher.search(orgIdTranslationSearchRequest, contextInfo);
3402 
3403             
3404             for (SearchResultRowInfo row : orgIdTranslationSearchResult.getRows()) {
3405 
3406                 
3407                 String orgId = "";
3408                 String orgName = "";
3409                 for (SearchResultCellInfo cell : row.getCells()) {
3410                     if ("org.resultColumn.orgId".equals(cell.getKey())) {
3411                         orgId = cell.getValue();
3412                         continue;
3413                     } else if ("org.resultColumn.orgShortName".equals(cell.getKey())) {
3414                         orgName = cell.getValue();
3415                     }
3416                 }
3417 
3418                 
3419                 List<SearchResultCellInfo> cells = orgIdToCellMapping.get(orgId);
3420                 if (cells != null) {
3421                     for (SearchResultCellInfo cell : cells) {
3422                         if (cell.getValue() == null) {
3423                             cell.setValue(orgName);
3424                         } else {
3425                             cell.setValue(cell.getValue() + ", " + orgName);
3426                         }
3427                     }
3428                 }
3429             }
3430         }
3431 
3432         
3433         for (CluSet cluSet : cluSetMap.values()) {
3434             if (!"AdHock".equals(cluSet.getName())) {
3435 
3436                 SearchResultRowInfo resultRow = new SearchResultRowInfo();
3437 
3438                 resultRow.addCell("lu.resultColumn.cluId", cluSet.getId());
3439                 resultRow.addCell("lu.resultColumn.luOptionalShortName", cluSet.getName());
3440                 resultRow.addCell("lu.resultColumn.luOptionalLongName", cluSet.getName());
3441                 resultRow.addCell("lu.resultColumn.luOptionalDependencyType", "cluSet");
3442                 resultRow.addCell("lu.resultColumn.luOptionalDependencyTypeName", "Course Set");
3443 
3444                 searchResult.getRows().add(resultRow);
3445             }
3446         }
3447 
3448         
3449         List<Clu> joints = luDao.getClusByRelation(cluId, "kuali.lu.relation.type.co-located");
3450         if (joints != null) {
3451             for (Clu clu : joints) {
3452 
3453                 SearchResultRowInfo resultRow = new SearchResultRowInfo();
3454 
3455                 resultRow.addCell("lu.resultColumn.cluId", clu.getId());
3456                 resultRow.addCell("lu.resultColumn.luOptionalCode", clu.getOfficialIdentifier().getCode());
3457                 resultRow.addCell("lu.resultColumn.luOptionalShortName", clu.getOfficialIdentifier().getShortName());
3458                 resultRow.addCell("lu.resultColumn.luOptionalLongName", clu.getOfficialIdentifier().getLongName());
3459                 resultRow.addCell("lu.resultColumn.luOptionalDependencyType", "joint");
3460                 resultRow.addCell("lu.resultColumn.luOptionalDependencyTypeName", "jointly offered");
3461 
3462                 searchResult.getRows().add(resultRow);
3463             }
3464         }
3465 
3466         
3467         for (CluIdentifier altId : triggerClu.getAlternateIdentifiers()) {
3468             if ("kuali.lu.type.CreditCourse.identifier.crosslisting".equals(altId.getType())) {
3469                 SearchResultRowInfo resultRow = new SearchResultRowInfo();
3470 
3471                 resultRow.addCell("lu.resultColumn.luOptionalCode", altId.getCode());
3472                 resultRow.addCell("lu.resultColumn.luOptionalShortName", altId.getShortName());
3473                 resultRow.addCell("lu.resultColumn.luOptionalLongName", altId.getLongName());
3474                 resultRow.addCell("lu.resultColumn.luOptionalDependencyType", "crossListed");
3475                 resultRow.addCell("lu.resultColumn.luOptionalDependencyTypeName", "cross-listed");
3476 
3477                 searchResult.getRows().add(resultRow);
3478             }
3479         }
3480 
3481         
3482         Collections.sort(searchResult.getRows(), new SearchResultRowComparator("lu.resultColumn.luOptionalCode"));
3483 
3484         return searchResult;
3485     }
3486 
3487     public class SearchResultRowComparator implements Comparator<SearchResultRowInfo> {
3488         private String sortColumn;
3489 
3490         SearchResultRowComparator(String sortColumn) {
3491             super();
3492             this.sortColumn = sortColumn;
3493         }
3494 
3495         @Override
3496         public int compare(SearchResultRowInfo o1, SearchResultRowInfo o2) {
3497             String o1SortValue = null;
3498             String o2SortValue = null;
3499             for (SearchResultCellInfo cell : o1.getCells()) {
3500                 if (sortColumn.equals(cell.getKey())) {
3501                     o1SortValue = cell.getValue();
3502                     break;
3503                 }
3504             }
3505             for (SearchResultCellInfo cell : o2.getCells()) {
3506                 if (sortColumn.equals(cell.getKey())) {
3507                     o2SortValue = cell.getValue();
3508                     break;
3509                 }
3510             }
3511             if (o1SortValue != null) {
3512                 if (o2SortValue == null) {
3513                     return 1;
3514                 }
3515                 return o1SortValue.compareTo(o2SortValue);
3516             }
3517             if (o2SortValue == null) {
3518                 return 0;
3519             }
3520             return -1;
3521         }
3522 
3523     }
3524 
3525     private SearchResultInfo doSearchProposalsByCourseCode(String courseCode, ContextInfo contextInfo) throws MissingParameterException, PermissionDeniedException, OperationFailedException, InvalidParameterException {
3526         if(courseCode==null||courseCode.isEmpty()){
3527             return new SearchResultInfo();
3528         }
3529         
3530         SearchRequestInfo sr = new SearchRequestInfo("lu.search.mostCurrent.union");
3531         sr.addParam("lu.queryParam.luOptionalCode", courseCode);
3532         sr.addParam("lu.queryParam.luOptionalType","kuali.lu.type.CreditCourse");
3533         SearchResultInfo results = search(sr, contextInfo);
3534         Map<String,String> cluIdToCodeMap = new HashMap<String,String>();
3535         for(SearchResultRowInfo row:results.getRows()){
3536             String cluId = null;
3537             String code = null;
3538             for(SearchResultCellInfo cell:row.getCells()){
3539                 if("lu.resultColumn.cluId".equals(cell.getKey())){
3540                     cluId = cell.getValue();
3541                 }else if("lu.resultColumn.luOptionalCode".equals(cell.getKey())){
3542                     code = cell.getValue();
3543                 }
3544             }
3545             
3546             if(code!=null&&cluId!=null){
3547                 cluIdToCodeMap.put(cluId, code);
3548             }
3549         }
3550 
3551         
3552         sr = new SearchRequestInfo("proposal.search.proposalsForReferenceIds");
3553         sr.addParam("proposal.queryParam.proposalOptionalReferenceIds", new ArrayList<String>(cluIdToCodeMap.keySet()));
3554         results = searchDispatcher.search(sr, contextInfo);
3555         for(SearchResultRowInfo row:results.getRows()){
3556             String cluId = null;
3557             SearchResultCellInfo proposalNameCell = null;
3558 
3559             for(SearchResultCellInfo cell:row.getCells()){
3560                 if("proposal.resultColumn.proposalOptionalName".equals(cell.getKey())){
3561                     proposalNameCell = cell;
3562                     cell.setKey("lu.resultColumn.proposalOptionalName");
3563                 }else if("proposal.resultColumn.proposalOptionalReferenceId".equals(cell.getKey())){
3564                     cluId = cell.getValue();
3565                     cell.setKey("lu.resultColumn.proposalOptionalReferenceId");
3566                 }else if("proposal.resultColumn.proposalId".equals(cell.getKey())){
3567                     cell.setKey("lu.resultColumn.proposalId");
3568                 }
3569             }
3570             
3571             proposalNameCell.setValue(cluIdToCodeMap.get(cluId)+" ("+proposalNameCell.getValue()+")");
3572         }
3573 
3574         return results;
3575     }
3576 
3577     
3578 
3579 
3580 
3581 
3582 
3583     private SearchResultInfo doBrowseVersionsSearch(SearchRequestInfo searchRequest, ContextInfo contextInfo) throws MissingParameterException, PermissionDeniedException, OperationFailedException, InvalidParameterException {
3584         SearchResultInfo searchResult = searchManager.search(searchRequest, contextInfo);
3585 
3586         Map<String,List<SearchResultCellInfo>> atpIdToCellMapping = new HashMap<String,List<SearchResultCellInfo>>();
3587 
3588         for(SearchResultRowInfo row:searchResult.getRows()){
3589             for(SearchResultCellInfo cell:row.getCells()){
3590                 if(cell.getValue()!=null &&
3591                         ("lu.resultColumn.luOptionalExpFirstAtpDisplay".equals(cell.getKey()) ||
3592                                 "lu.resultColumn.luOptionalLastAtpDisplay".equals(cell.getKey()))) {
3593                     List<SearchResultCellInfo> cells = atpIdToCellMapping.get(cell.getValue());
3594                     if(cells==null){
3595                         cells = new ArrayList<SearchResultCellInfo>();
3596                         atpIdToCellMapping.put(cell.getValue(), cells);
3597                     }
3598                     cells.add(cell);
3599                 }
3600             }
3601         }
3602         
3603 
3604         SearchRequestInfo atpSearchRequest = new SearchRequestInfo("atp.search.advancedAtpSearch");
3605         atpSearchRequest.addParam("atp.advancedAtpSearchParam.optionalAtpIds", new ArrayList<String>(atpIdToCellMapping.keySet()));
3606         SearchResultInfo atpSearchResults = searchDispatcher.search(atpSearchRequest, contextInfo);
3607         for(SearchResultRowInfo row:atpSearchResults.getRows()){
3608             String atpId = null;
3609             String atpName = null;
3610             for(SearchResultCellInfo cell:row.getCells()){
3611                 if("atp.resultColumn.atpId".equals(cell.getKey())){
3612                     atpId = cell.getValue();
3613                 }else if("atp.resultColumn.atpShortName".equals(cell.getKey())){
3614                     atpName = cell.getValue();
3615                 }
3616             }
3617             if(atpId!=null && atpIdToCellMapping.get(atpId)!=null){
3618                 for(SearchResultCellInfo cell : atpIdToCellMapping.get(atpId)){
3619                     cell.setValue(atpName);
3620                 }
3621             }
3622         }
3623 
3624         return searchResult;
3625     }
3626 
3627     
3628 
3629 
3630 
3631 
3632 
3633     private SearchResultInfo doResultComponentTypesForCluSearch(SearchRequestInfo cluSearchRequest, ContextInfo contextInfo) throws MissingParameterException, PermissionDeniedException, OperationFailedException, InvalidParameterException {
3634 
3635         SearchResultInfo searchResult = searchManager.search(cluSearchRequest, contextInfo);
3636 
3637         
3638         Map<String,List<SearchResultRowInfo>> rcIdToRowMapping = new HashMap<String,List<SearchResultRowInfo>>();
3639 
3640         
3641         for(SearchResultRowInfo row:searchResult.getRows()){
3642             for(SearchResultCellInfo cell:row.getCells()){
3643                 if(cell.getValue()!=null &&
3644                         "lu.resultColumn.resultComponentId".equals(cell.getKey())) {
3645                     List<SearchResultRowInfo> rows = rcIdToRowMapping.get(cell.getValue());
3646                     if(rows==null){
3647                         rows = new ArrayList<SearchResultRowInfo>();
3648                         rcIdToRowMapping.put(cell.getValue(), rows);
3649                     }
3650                     rows.add(row);
3651                 }
3652             }
3653         }
3654 
3655         
3656         SearchRequestInfo lrcSearchRequest = new SearchRequestInfo(SEARCH_KEY_RESULT_COMPONENT);
3657         lrcSearchRequest.addParam("lrc.queryParam.resultComponent.idRestrictionList", new ArrayList<String>(rcIdToRowMapping.keySet()));
3658         SearchResultInfo lrcSearchResults = searchDispatcher.search(lrcSearchRequest, contextInfo);
3659 
3660         
3661         for(SearchResultRowInfo row:lrcSearchResults.getRows()){
3662             String lrcId = null;
3663             String lrcName = null;
3664             for(SearchResultCellInfo cell:row.getCells()){
3665                 if("lrc.resultColumn.resultComponent.id".equals(cell.getKey())){
3666                     lrcId = cell.getValue();
3667                 }else if("lrc.resultColumn.resultComponent.name".equals(cell.getKey())){
3668                     lrcName = cell.getValue();
3669                 }
3670             }
3671             if(lrcId!=null && rcIdToRowMapping.get(lrcId)!=null){
3672                 for(SearchResultRowInfo resultRow : rcIdToRowMapping.get(lrcId)){
3673                     resultRow.addCell("lu.resultColumn.resultComponentName",lrcName);
3674                 }
3675             }
3676         }
3677 
3678         return searchResult;
3679     }
3680 
3681     @Override
3682     @Transactional(readOnly=true)
3683     public SearchResultInfo search(SearchRequestInfo searchRequest, ContextInfo contextInfo) throws MissingParameterException, PermissionDeniedException, OperationFailedException, InvalidParameterException {
3684         checkForMissingParameter(searchRequest, "searchRequest");
3685 
3686         if (SEARCH_KEY_DEPENDENCY_ANALYSIS.equals(searchRequest.getSearchKey())) {
3687             String cluId = null;
3688             for (SearchParamInfo param : searchRequest.getParams()) {
3689                 if ("lu.queryParam.luOptionalCluId".equals(param.getKey())) {
3690                     cluId = (String) param.getValues().get(0);
3691                     break;
3692                 }
3693             }
3694             try {
3695                 return doDependencyAnalysisSearch(cluId, contextInfo);
3696             } catch (DoesNotExistException e) {
3697                 throw new RuntimeException("Error performing search");
3698             }
3699         } else if (SEARCH_KEY_BROWSE_PROGRAM.equals(searchRequest.getSearchKey())) {
3700             return doBrowseProgramSearch(contextInfo);
3701         }else if(SEARCH_KEY_PROPOSALS_BY_COURSE_CODE.equals(searchRequest.getSearchKey())){
3702             String courseCode = null;
3703             for(SearchParamInfo param:searchRequest.getParams()){
3704                 if("lu.queryParam.luOptionalCode".equals(param.getKey())){
3705                     courseCode = (String)param.getValues().get(0);
3706                     break;
3707                 }
3708             }
3709             return doSearchProposalsByCourseCode(courseCode, contextInfo);
3710         }else if(SEARCH_KEY_BROWSE_VERSIONS.equals(searchRequest.getSearchKey())){
3711             return doBrowseVersionsSearch(searchRequest, contextInfo);
3712         }else if(SEARCH_KEY_LU_RESULT_COMPONENTS.equals(searchRequest.getSearchKey())){
3713             return doResultComponentTypesForCluSearch(searchRequest, contextInfo);
3714         }else if(SEARCH_KEY_CLUSET_SEARCH_GENERIC.equals(searchRequest.getSearchKey())){
3715             
3716             for(SearchParamInfo param:searchRequest.getParams()){
3717                 if(param.getKey().contains("queryParam.luOptional")){
3718                     searchRequest.setSearchKey(SEARCH_KEY_CLUSET_SEARCH_GENERICWITHCLUS);
3719                     break;
3720                 }
3721             }
3722         }
3723         return searchManager.search(searchRequest, contextInfo);
3724 
3725 
3726     }
3727 
3728     @Override
3729     public VersionDisplayInfo getLatestVersion(String refObjectTypeURI, String refObjectId, ContextInfo context)
3730             throws DoesNotExistException, InvalidParameterException,
3731             MissingParameterException, OperationFailedException, PermissionDeniedException {
3732         VersionDisplayInfo versionInfo = null;
3733         if (CluServiceConstants.CLU_NAMESPACE_URI.equals(refObjectTypeURI)) {
3734             try {
3735                 versionInfo = this.getLatestVersion(refObjectId, refObjectTypeURI, context);
3736             } catch (NoResultException e) {
3737                 throw new DoesNotExistException("getLatestVersion returned no result", e);
3738             }
3739         } else {
3740             throw new UnsupportedOperationException("This method does not know how to handle object type:" + refObjectTypeURI);
3741         }
3742         return versionInfo;
3743     }
3744 
3745     @Override
3746     public VersionDisplayInfo getCurrentVersion(String refObjectTypeURI, String refObjectId, ContextInfo context)
3747             throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException {
3748         VersionDisplayInfo versionInfo = null;
3749         if (CluServiceConstants.CLU_NAMESPACE_URI.equals(refObjectTypeURI)) {
3750             try {
3751                 versionInfo = luDao.getCurrentCluVersionInfo(refObjectId, refObjectTypeURI);
3752             } catch (NoResultException e) {
3753                 throw new DoesNotExistException("getCurrentCluVersionInfo could not get current CLU version info", e);
3754             }
3755         } else {
3756             throw new UnsupportedOperationException("This method does not know how to handle object type:" + refObjectTypeURI);
3757         }
3758         return versionInfo;
3759     }
3760 
3761     @Override
3762     public VersionDisplayInfo getCurrentVersionOnDate(String refObjectTypeURI, String refObjectId, Date date, ContextInfo context) throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException {
3763         VersionDisplayInfo versionInfo = null;
3764         if (CluServiceConstants.CLU_NAMESPACE_URI.equals(refObjectTypeURI)) {
3765             try {
3766                 versionInfo = luDao.getCurrentVersionOnDate(refObjectId, refObjectTypeURI, date);
3767             } catch (NoResultException e) {
3768                 throw new DoesNotExistException("getCurrentCluVersionInfo could not get current CLU version info", e);
3769             }
3770         } else {
3771             throw new UnsupportedOperationException("This method does not know how to handle object type:" + refObjectTypeURI);
3772         }
3773         return versionInfo;
3774     }
3775 
3776     @Override
3777     public VersionDisplayInfo getFirstVersion(String refObjectTypeURI, String refObjectId, ContextInfo context)
3778             throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException {
3779         VersionDisplayInfo versionInfo = null;
3780         if (CluServiceConstants.CLU_NAMESPACE_URI.equals(refObjectTypeURI)) {
3781             try {
3782                 versionInfo = luDao.getFirstVersion(refObjectId, refObjectTypeURI);
3783             } catch (NoResultException e) {
3784                 throw new DoesNotExistException("getFirstVersion could not get first version", e);
3785             }
3786         } else {
3787             throw new UnsupportedOperationException("This method does not know how to handle object type:" + refObjectTypeURI);
3788         }
3789         return versionInfo;
3790     }
3791 
3792     @Override
3793     public VersionDisplayInfo getVersionBySequenceNumber(String refObjectTypeURI, String refObjectId,
3794                                                          Long sequence, ContextInfo context)
3795             throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException {
3796         VersionDisplayInfo versionInfo = null;
3797         if (CluServiceConstants.CLU_NAMESPACE_URI.equals(refObjectTypeURI)) {
3798             try {
3799                 versionInfo = luDao.getVersionBySequenceNumber(refObjectId, refObjectTypeURI, sequence);
3800             } catch (NoResultException e) {
3801                 throw new DoesNotExistException("getVersionBySequenceNumber", e);
3802             }
3803         } else {
3804             throw new UnsupportedOperationException("This method does not know how to handle object type:" + refObjectTypeURI);
3805         }
3806         return versionInfo;
3807     }
3808 
3809     @Override
3810     public List<VersionDisplayInfo> getVersions(String refObjectTypeURI, String refObjectId, ContextInfo context)
3811             throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException {
3812         List<VersionDisplayInfo> versionInfos = null;
3813         if (CluServiceConstants.CLU_NAMESPACE_URI.equals(refObjectTypeURI)) {
3814             versionInfos = luDao.getVersions(refObjectId, refObjectTypeURI);
3815             if (versionInfos == null) {
3816                 versionInfos = Collections.<VersionDisplayInfo>emptyList();
3817             }
3818         } else {
3819             throw new UnsupportedOperationException("This method does not know how to handle object type:" + refObjectTypeURI);
3820         }
3821         return versionInfos;
3822     }
3823 
3824     @Override
3825     public List<VersionDisplayInfo> getVersionsInDateRange(String refObjectTypeURI,
3826                                                            String refObjectId,
3827                                                            Date from,
3828                                                            Date to,
3829                                                            ContextInfo context)
3830             throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException {
3831         List<VersionDisplayInfo> versionInfos = null;
3832         if (CluServiceConstants.CLU_NAMESPACE_URI.equals(refObjectTypeURI)) {
3833             versionInfos = luDao.getVersionsInDateRange(refObjectId, refObjectTypeURI, from, to);
3834             if (versionInfos == null) {
3835                 versionInfos = Collections.<VersionDisplayInfo>emptyList();
3836             }
3837         } else {
3838             throw new UnsupportedOperationException("This method does not know how to handle object type:" + refObjectTypeURI);
3839         }
3840         return versionInfos;
3841     }
3842 
3843     public void setSearchDispatcher(SearchService searchDispatcher) {
3844         this.searchDispatcher = searchDispatcher;
3845     }
3846 
3847     private ObjectStructureDefinition getObjectStructure(String objectTypeKey) {
3848         return dictionaryServiceDelegate.getObjectStructure(objectTypeKey);
3849     }
3850 
3851     
3852 
3853 
3854     @Override
3855     public List<CluResultInfo> getCluResultsByClus(
3856              List<String> cluIds,
3857              ContextInfo contextInfo)
3858             throws DoesNotExistException, InvalidParameterException,
3859             MissingParameterException, OperationFailedException {
3860         checkForMissingParameter(cluIds, "cluIds");
3861         checkForEmptyList(cluIds, "cluIds");
3862         return CluServiceAssembler.toCluResultInfos(luDao.getCluResultsByClus(cluIds));
3863 
3864     }
3865 
3866     
3867 
3868 
3869     @Override
3870     public List<CluInfo> searchForClus(
3871              QueryByCriteria criteria,
3872              ContextInfo contextInfo)
3873             throws InvalidParameterException, MissingParameterException,
3874             OperationFailedException, PermissionDeniedException {
3875         
3876         throw new UnsupportedOperationException("not implemented");
3877     }
3878 
3879     
3880 
3881 
3882     @Override
3883     public List<String> searchForCluIds(
3884              QueryByCriteria criteria,
3885              ContextInfo contextInfo)
3886             throws InvalidParameterException, MissingParameterException,
3887             OperationFailedException, PermissionDeniedException {
3888         
3889         throw new UnsupportedOperationException("not implemented");
3890     }
3891 
3892     
3893 
3894 
3895     @Override
3896     public List<CluCluRelationInfo> searchForCluCluRelations(
3897              QueryByCriteria criteria,
3898              ContextInfo contextInfo)
3899             throws InvalidParameterException, MissingParameterException,
3900             OperationFailedException, PermissionDeniedException {
3901         
3902         throw new UnsupportedOperationException("not implemented");
3903     }
3904 
3905     
3906 
3907 
3908     @Override
3909     public List<String> searchForCluCluRelationIds(
3910              QueryByCriteria criteria,
3911              ContextInfo contextInfo)
3912             throws InvalidParameterException, MissingParameterException,
3913             OperationFailedException, PermissionDeniedException {
3914         
3915         throw new UnsupportedOperationException("not implemented");
3916     }
3917 
3918     
3919 
3920 
3921     @Override
3922     public List<CluLoRelationInfo> searchForCluLoRelations(
3923              QueryByCriteria criteria,
3924              ContextInfo contextInfo)
3925             throws InvalidParameterException, MissingParameterException,
3926             OperationFailedException, PermissionDeniedException {
3927         
3928         throw new UnsupportedOperationException("not implemented");
3929     }
3930 
3931     
3932 
3933 
3934     @Override
3935     public List<String> searchForCluLoRelationIds(
3936              QueryByCriteria criteria,
3937              ContextInfo contextInfo)
3938             throws InvalidParameterException, MissingParameterException,
3939             OperationFailedException, PermissionDeniedException {
3940         
3941         throw new UnsupportedOperationException("not implemented");
3942     }
3943 
3944     
3945 
3946 
3947     @Override
3948     public List<CluPublicationInfo> searchForCluPublications(
3949              QueryByCriteria criteria,
3950              ContextInfo contextInfo)
3951             throws InvalidParameterException, MissingParameterException,
3952             OperationFailedException, PermissionDeniedException {
3953         
3954         throw new UnsupportedOperationException("not implemented");
3955     }
3956 
3957     
3958 
3959 
3960     @Override
3961     public List<String> searchForCluPublicationIds(
3962              QueryByCriteria criteria,
3963              ContextInfo contextInfo)
3964             throws InvalidParameterException, MissingParameterException,
3965             OperationFailedException, PermissionDeniedException {
3966         
3967         throw new UnsupportedOperationException("not implemented");
3968     }
3969 
3970     
3971 
3972 
3973     @Override
3974     public List<CluResultInfo> searchForCluResults(
3975              QueryByCriteria criteria,
3976              ContextInfo contextInfo)
3977             throws InvalidParameterException, MissingParameterException,
3978             OperationFailedException, PermissionDeniedException {
3979         
3980         throw new UnsupportedOperationException("not implemented");
3981     }
3982 
3983     
3984 
3985 
3986     @Override
3987     public List<String> searchForCluResultIds(
3988              QueryByCriteria criteria,
3989              ContextInfo contextInfo)
3990             throws InvalidParameterException, MissingParameterException,
3991             OperationFailedException, PermissionDeniedException {
3992         
3993         throw new UnsupportedOperationException("not implemented");
3994     }
3995     
3996     
3997 }