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