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