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