1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  package org.kuali.student.lum.lo.service.impl;
17  
18  import java.util.ArrayList;
19  import java.util.HashMap;
20  import java.util.Iterator;
21  import java.util.List;
22  import java.util.Map;
23  
24  import javax.jws.WebService;
25  
26  import org.kuali.student.common.dictionary.dto.ObjectStructureDefinition;
27  import org.kuali.student.common.dictionary.service.DictionaryService;
28  import org.kuali.student.common.dto.DtoConstants;
29  import org.kuali.student.common.dto.StatusInfo;
30  import org.kuali.student.common.exceptions.AlreadyExistsException;
31  import org.kuali.student.common.exceptions.DataValidationErrorException;
32  import org.kuali.student.common.exceptions.DependentObjectsExistException;
33  import org.kuali.student.common.exceptions.DoesNotExistException;
34  import org.kuali.student.common.exceptions.InvalidParameterException;
35  import org.kuali.student.common.exceptions.MissingParameterException;
36  import org.kuali.student.common.exceptions.OperationFailedException;
37  import org.kuali.student.common.exceptions.PermissionDeniedException;
38  import org.kuali.student.common.exceptions.UnsupportedActionException;
39  import org.kuali.student.common.exceptions.VersionMismatchException;
40  import org.kuali.student.common.search.dto.SearchCriteriaTypeInfo;
41  import org.kuali.student.common.search.dto.SearchParam;
42  import org.kuali.student.common.search.dto.SearchRequest;
43  import org.kuali.student.common.search.dto.SearchResult;
44  import org.kuali.student.common.search.dto.SearchResultCell;
45  import org.kuali.student.common.search.dto.SearchResultRow;
46  import org.kuali.student.common.search.dto.SearchResultTypeInfo;
47  import org.kuali.student.common.search.dto.SearchTypeInfo;
48  import org.kuali.student.common.search.service.SearchManager;
49  import org.kuali.student.common.validation.dto.ValidationResultInfo;
50  import org.kuali.student.common.validator.Validator;
51  import org.kuali.student.common.validator.ValidatorFactory;
52  import org.kuali.student.lum.lo.dao.LoDao;
53  import org.kuali.student.lum.lo.dto.LoCategoryInfo;
54  import org.kuali.student.lum.lo.dto.LoCategoryTypeInfo;
55  import org.kuali.student.lum.lo.dto.LoInfo;
56  import org.kuali.student.lum.lo.dto.LoLoRelationInfo;
57  import org.kuali.student.lum.lo.dto.LoLoRelationTypeInfo;
58  import org.kuali.student.lum.lo.dto.LoRepositoryInfo;
59  import org.kuali.student.lum.lo.dto.LoTypeInfo;
60  import org.kuali.student.lum.lo.entity.Lo;
61  import org.kuali.student.lum.lo.entity.LoCategory;
62  import org.kuali.student.lum.lo.entity.LoCategoryType;
63  import org.kuali.student.lum.lo.entity.LoLoRelation;
64  import org.kuali.student.lum.lo.entity.LoLoRelationType;
65  import org.kuali.student.lum.lo.entity.LoRepository;
66  import org.kuali.student.lum.lo.entity.LoType;
67  import org.kuali.student.lum.lo.service.LearningObjectiveService;
68  import org.springframework.transaction.annotation.Transactional;
69  
70  
71  
72  
73  
74  @WebService(endpointInterface = "org.kuali.student.lum.lo.service.LearningObjectiveService", serviceName = "LearningObjectiveService", portName = "LearningObjectiveService", targetNamespace = "http://student.kuali.org/wsdl/lo")
75  public class LearningObjectiveServiceImpl implements LearningObjectiveService {
76      private LoDao loDao;
77  	private SearchManager searchManager;
78      private DictionaryService dictionaryServiceDelegate;
79  	private ValidatorFactory validatorFactory;
80  
81  	public LoDao getLoDao() {
82          return loDao;
83      }
84  
85      public void setLoDao(LoDao dao) {
86          this.loDao = dao;
87      }
88  
89  	public void setSearchManager(SearchManager searchManager) {
90  		this.searchManager = searchManager;
91  	}
92  
93      public void setDictionaryServiceDelegate(DictionaryService dictionaryServiceDelegate) {
94          this.dictionaryServiceDelegate = dictionaryServiceDelegate;
95      }
96  
97  	public ValidatorFactory getValidatorFactory() {
98          return validatorFactory;
99      }
100 
101     public void setValidatorFactory(ValidatorFactory validatorFactory) {
102         this.validatorFactory = validatorFactory;
103     }
104 
105     
106 
107 
108 
109 	@Override
110     @Transactional(readOnly=true)
111 	public List<LoRepositoryInfo> getLoRepositories()
112 			throws OperationFailedException {
113 	    List<LoRepository> repositories = loDao.find(LoRepository.class);
114 		return LearningObjectiveServiceAssembler.toLoRepositoryInfos(repositories);
115 	}
116 	
117 	
118 
119 
120 
121 	@Override
122     @Transactional(readOnly=true)
123 	public LoRepositoryInfo getLoRepository(String loRepositoryKey)
124 			throws DoesNotExistException, InvalidParameterException,
125 			MissingParameterException, OperationFailedException {
126 	    checkForMissingParameter(loRepositoryKey, "loRepositoryKey");
127 		return LearningObjectiveServiceAssembler.toLoRepositoryInfo(loDao.fetch(LoRepository.class, loRepositoryKey));
128 	}
129 
130 	
131 
132 
133 
134 	@Override
135     @Transactional(readOnly=true)
136 	public List<LoTypeInfo> getLoTypes() throws OperationFailedException {
137 	    List<LoType> find = loDao.find(LoType.class);
138 		return LearningObjectiveServiceAssembler.toLoTypeInfos(find);
139 	}
140 
141 	
142 
143 
144 
145 	@Override
146     @Transactional(readOnly=true)
147 	public LoTypeInfo getLoType(String loTypeKey) throws DoesNotExistException,
148 			InvalidParameterException, MissingParameterException,
149 			OperationFailedException {
150 	    checkForMissingParameter(loTypeKey, "loTypeKey");
151 	    LoType fetch = loDao.fetch(LoType.class, loTypeKey);
152 		return LearningObjectiveServiceAssembler.toLoTypeInfo(fetch);
153 	}
154 
155 	
156 
157 
158 
159 	@Override
160     @Transactional(readOnly=true)
161 	public List<LoLoRelationTypeInfo> getLoLoRelationTypes()
162 			throws OperationFailedException {
163 	    List<LoLoRelationType> fetch = loDao.find(LoLoRelationType.class);
164 		return LearningObjectiveServiceAssembler.toLoLoRelationTypeInfos(fetch);
165 	}
166 
167 	
168 
169 
170 
171 	@Override
172     @Transactional(readOnly=true)
173 	public LoLoRelationTypeInfo getLoLoRelationType(String loLoRelationTypeKey)
174 			throws OperationFailedException, MissingParameterException, DoesNotExistException {
175 	    checkForMissingParameter(loLoRelationTypeKey, "loLoRelationTypeKey");
176 		return LearningObjectiveServiceAssembler.toLoLoRelationTypeInfo(loDao.fetch(LoLoRelationType.class, loLoRelationTypeKey));
177 	}
178 
179 	@Override
180     @Transactional(readOnly=true)
181 	public List<String> getAllowedLoLoRelationTypesForLoType(String loTypeKey, String relatedLoTypeKey)
182 			throws DoesNotExistException, InvalidParameterException,
183 					MissingParameterException, OperationFailedException {
184 	    checkForMissingParameter(loTypeKey, "loTypeKey");
185 	    checkForMissingParameter(relatedLoTypeKey, "relatedLoTypeKey");
186 	    
187 	    return loDao.getAllowedLoLoRelationTypesForLoType(loTypeKey, relatedLoTypeKey);
188 	}
189 
190     
191 
192 
193 
194 	@Override
195 	@Transactional(readOnly=false,noRollbackFor={DoesNotExistException.class},rollbackFor={Throwable.class})
196 	public StatusInfo addLoCategoryToLo(String loCategoryId, String loId)
197 			throws AlreadyExistsException, DoesNotExistException,
198 			InvalidParameterException, MissingParameterException,
199 			OperationFailedException, PermissionDeniedException,
200 			UnsupportedActionException {
201 	    checkForMissingParameter(loCategoryId, "loCategoryId");
202 	    checkForMissingParameter(loId, "loId");
203         StatusInfo statusInfo = new StatusInfo();
204         statusInfo.setSuccess(loDao.addLoCategoryToLo(loCategoryId, loId));
205         return statusInfo;
206 	}
207 
208 	
209 
210 
211 	@Override
212 	@Transactional(readOnly=false,noRollbackFor={DoesNotExistException.class},rollbackFor={Throwable.class})
213 	public LoInfo createLo(String repositoryId, String loType, LoInfo loInfo)
214 			throws DataValidationErrorException, DoesNotExistException,
215 			InvalidParameterException, MissingParameterException,
216 			OperationFailedException, PermissionDeniedException {
217 	    checkForMissingParameter(repositoryId, "repositoryId");
218 	    checkForMissingParameter(loType, "loType");
219 	    checkForMissingParameter(loInfo, "loInfo");
220 	    
221 	    
222 		
223 		List<ValidationResultInfo> val = validateLo("SYSTEM", loInfo);
224 		if(null != val && val.size() > 0) {
225 			for (ValidationResultInfo result : val) {
226 				System.err.println("Validation error. Element: " + result.getElement() + ",  Value: " + result.getMessage());
227 			}
228             throw new DataValidationErrorException("Validation error!", val);
229 		}
230 		
231 	    
232 	    
233 	    LoType type = null;
234 	    LoRepository repository = null;
235 	    try {
236 		    type = loDao.fetch(LoType.class, loType);
237 		    repository = loDao.fetch(LoRepository.class, repositoryId); 
238 	    } catch (DoesNotExistException dnee) {
239 	    	throw new DoesNotExistException("Specified " + (null == type ? "LoType" : "LoRepository") + " does not exist", dnee);
240 	    }
241 	    
242 	    loInfo.setLoRepositoryKey(repositoryId);
243 	    loInfo.setType(loType);
244 	    
245 	    Lo lo = null;
246 	    try {
247 		    lo = LearningObjectiveServiceAssembler.toLo(false, loInfo, loDao);
248 	    } catch (VersionMismatchException vme) {
249 	    	
250 	    	throw new OperationFailedException("VersionMismatchException caught during Learning Objective creation");
251 	    }
252 	    lo.setLoType(type);
253 	    lo.setLoRepository(repository);
254 	    loDao.create(lo);
255 	    
256 		return LearningObjectiveServiceAssembler.toLoInfo(lo);
257 	}
258 
259 	
260 
261 
262 	@Override
263 	@Transactional(readOnly=false,noRollbackFor={DoesNotExistException.class},rollbackFor={Throwable.class})
264 	public StatusInfo deleteLo(String loId)
265 			throws DependentObjectsExistException, DoesNotExistException,
266 			InvalidParameterException, MissingParameterException,
267 			OperationFailedException, PermissionDeniedException {
268 	    checkForMissingParameter(loId, "loId");
269 	    
270 	    StatusInfo returnStatus = new StatusInfo();
271 	    returnStatus.setSuccess(loDao.deleteLo(loId));
272 		return returnStatus;
273 	}
274 
275 	
276 
277 
278 	@Override
279 	@Transactional(readOnly=false,noRollbackFor={DoesNotExistException.class},rollbackFor={Throwable.class})
280 	public StatusInfo deleteLoCategory(String loCategoryId)
281 			throws DependentObjectsExistException, DoesNotExistException,
282 			InvalidParameterException, MissingParameterException,
283 			OperationFailedException, PermissionDeniedException {
284 	    checkForMissingParameter(loCategoryId, "loCategoryId");
285 	    
286 	    loDao.deleteLoCategory(loCategoryId);
287 	    
288 		return new StatusInfo();
289 	}
290 
291 	
292 
293 
294 	@Override
295     @Transactional(readOnly=true)
296 	public LoInfo getLo(String loId) throws DoesNotExistException,
297 			InvalidParameterException, MissingParameterException,
298 			OperationFailedException {
299 	    checkForMissingParameter(loId, "loId");
300 	    
301 		return LearningObjectiveServiceAssembler.toLoInfo(loDao.fetch(Lo.class, loId));
302 	}
303 
304 	
305 
306 
307 	@Override
308     @Transactional(readOnly=true)
309 	public List<LoInfo> getLoByIdList(List<String> loIds)
310 			throws InvalidParameterException, MissingParameterException,
311 			OperationFailedException {
312 	    checkForMissingParameter(loIds, "loId");
313 	    checkForEmptyList(loIds, "loId");
314 	    List<Lo> los = loDao.getLoByIdList(loIds);
315 		return LearningObjectiveServiceAssembler.toLoInfos(los);
316 	}
317 
318 	
319 
320 
321 	@Override
322     @Transactional(readOnly=true)
323 	public List<LoCategoryInfo> getLoCategories(String loRepositoryKey)
324 			throws DoesNotExistException, InvalidParameterException,
325 			MissingParameterException, OperationFailedException {
326 	    checkForMissingParameter(loRepositoryKey, "loRepositoryKey");
327 	    List<LoCategory> categories = loDao.getLoCategories(loRepositoryKey);
328         return LearningObjectiveServiceAssembler.toLoCategoryInfos(categories);
329 	}
330 
331 	
332 
333 
334 	@Override
335     @Transactional(readOnly=true)
336 	public List<LoCategoryInfo> getLoCategoriesForLo(String loId)
337 			throws DoesNotExistException, InvalidParameterException,
338 			MissingParameterException, OperationFailedException {
339 	    checkForMissingParameter(loId, "loId");
340 	    List<LoCategory> categories = loDao.getLoCategoriesForLo(loId);
341 		return LearningObjectiveServiceAssembler.toLoCategoryInfos(categories);
342 	}
343 
344 	
345 
346 
347 	@Override
348     @Transactional(readOnly=true)
349 	public LoCategoryInfo getLoCategory(String loCategoryId)
350 			throws DoesNotExistException, InvalidParameterException,
351 			MissingParameterException, OperationFailedException {
352 	    checkForMissingParameter(loCategoryId, "loCategoryId");
353 	    
354 		return LearningObjectiveServiceAssembler.toLoCategoryInfo(loDao.fetch(LoCategory.class, loCategoryId));
355 	}
356 
357 	
358 
359 
360 
361 
362 
363 
364 
365 
366 
367 
368 	
369 
370 
371 	@Override
372     @Transactional(readOnly=true)
373 	public List<LoInfo> getLosByLoCategory(String loCategoryId)
374 			throws DoesNotExistException, InvalidParameterException,
375 			MissingParameterException, OperationFailedException {
376 	    checkForMissingParameter(loCategoryId, "loCategoryId");
377 	    List<Lo> los = loDao.getLosByLoCategory(loCategoryId);
378 		return LearningObjectiveServiceAssembler.toLoInfos(los);
379 	}
380 
381 	
382 
383 
384 
385 
386 
387 
388 
389 
390 
391 
392 
393 	
394 
395 
396 
397 
398 
399 
400 
401 
402 
403 
404 
405 	
406 
407 
408 
409 
410 
411 
412 
413 
414 
415 
416 
417 
418 
419 
420 
421 
422 	
423 
424 
425 
426 
427 
428 
429 
430 
431 
432 
433 
434 
435 
436 
437 
438 
439 	
440 
441 
442 	@Override
443 	@Transactional(readOnly=false,noRollbackFor={DoesNotExistException.class},rollbackFor={Throwable.class})
444 	public StatusInfo removeLoCategoryFromLo(String loCategoryId, String loId)
445 			throws DoesNotExistException, InvalidParameterException,
446 			MissingParameterException, OperationFailedException,
447 			PermissionDeniedException, UnsupportedActionException {
448 	    checkForMissingParameter(loCategoryId, "loCategoryId");
449 	    checkForMissingParameter(loId, "loId");
450 	    
451         StatusInfo statusInfo = new StatusInfo();
452         statusInfo.setSuccess(loDao.removeLoCategoryFromLo(loCategoryId, loId));
453         return statusInfo;
454 	}
455 
456 	
457 
458 
459 	@Override
460 	@Transactional(readOnly=false,noRollbackFor={DoesNotExistException.class},rollbackFor={Throwable.class})
461 	public LoInfo updateLo(String loId, LoInfo loInfo)
462 			throws DataValidationErrorException, DoesNotExistException,
463 			InvalidParameterException, MissingParameterException,
464 			OperationFailedException, PermissionDeniedException,
465 			VersionMismatchException {
466 	    checkForMissingParameter(loId, "loId");
467 	    checkForMissingParameter(loInfo, "loInfo");
468 
469 		
470 		List<ValidationResultInfo> val = validateLo("SYSTEM", loInfo);
471 		if(null != val && val.size() > 0) {
472 			for (ValidationResultInfo result : val) {
473 				System.err.println("Validation error. Element: " + result.getElement() + ",  Value: " + result.getMessage());
474 			}
475 			throw new DataValidationErrorException("Validation error!", val);
476 		}
477 		
478 	    Lo lo = loDao.fetch(Lo.class, loId);
479         
480         if (!String.valueOf(lo.getVersionNumber()).equals(loInfo.getMetaInfo().getVersionInd())){
481             throw new VersionMismatchException("LO to be updated is not the current version");
482         }
483         
484         lo = LearningObjectiveServiceAssembler.toLo(true, lo, loInfo, loDao);
485         loDao.update(lo);
486         return LearningObjectiveServiceAssembler.toLoInfo(lo);
487 	}
488 
489 	
490 
491 
492 	@Override
493 	@Transactional(readOnly=false,noRollbackFor={DoesNotExistException.class},rollbackFor={Throwable.class})
494 	public LoCategoryInfo updateLoCategory(String loCategoryId,
495 			LoCategoryInfo loCategoryInfo) throws DataValidationErrorException,
496 			DoesNotExistException, InvalidParameterException,
497 			MissingParameterException, OperationFailedException,
498 			PermissionDeniedException, VersionMismatchException {
499 	    checkForMissingParameter(loCategoryId, "loCategoryId");
500 	    checkForMissingParameter(loCategoryInfo, "loCategoryInfo");
501 	    
502 		
503 		List<ValidationResultInfo> val = validateLoCategory("SYSTEM", loCategoryInfo);
504 
505 		
506         if (doesLoCategoryExist(loCategoryInfo.getLoRepository(), loCategoryInfo, loCategoryId)) {
507             ValidationResultInfo vr = new ValidationResultInfo();
508             vr.setElement("LO Category Name");
509             vr.setError("LO Category already exists");
510             val.add(vr);
511         }
512         if(null != val && val.size() > 0) {
513             for (ValidationResultInfo result : val) {
514                 System.err.println("Validation error. Element: " + result.getElement() + ",  Value: " + result.getMessage());
515             }
516             throw new DataValidationErrorException("Validation error!", val);
517         }
518 	    LoCategory loCategory = loDao.fetch(LoCategory.class, loCategoryId);
519         
520         if (!String.valueOf(loCategory.getVersionNumber()).equals(loCategoryInfo.getMetaInfo().getVersionInd())){
521             throw new VersionMismatchException("LoCategory to be updated is not the current version");
522         }
523         
524         
525         if (loCategory.getState().equals("active") && ( ! loCategoryInfo.getState().equals("active") )) {
526     		
527     		
528         	List<LoInfo> loInfos = getLosByLoCategory(loCategoryId);
529     		if (null != loInfos) {
530 				
531     			for (LoInfo info : loInfos) {
532     				if (info.getState().equals("active"))  {
533 	    				try {
534 							removeLoCategoryFromLo(loCategoryId, info.getId());
535 						} catch (UnsupportedActionException uaee) {
536 				    		throw new OperationFailedException("Unable to update LoCategory: could not remove association with active LearningObjective", uaee);
537 						}
538     				}
539     			}
540     		}
541         }
542         	
543         
544         if ( ! loCategory.getLoCategoryType().getId().equals(loCategoryInfo.getType()) ) {
545         	loCategory = cloneLoCategory(loCategory, loCategoryInfo);
546         } else {
547 	        loCategory = LearningObjectiveServiceAssembler.toLoCategory(loCategory, loCategoryInfo, loDao);
548 	        loDao.update(loCategory);
549         }
550         return LearningObjectiveServiceAssembler.toLoCategoryInfo(loCategory);
551 	}
552 
553     
554 	
555 	
556 	private LoCategory cloneLoCategory(LoCategory loCategory, LoCategoryInfo loCategoryInfo) throws DoesNotExistException, InvalidParameterException, OperationFailedException {
557     	LoCategoryType catType = null;
558     	
559     	try {
560         	catType = loDao.fetch(LoCategoryType.class, loCategoryInfo.getType());
561     	} catch (DoesNotExistException dnee) {
562     		throw new DoesNotExistException("Attempt to set LoCategory's type to nonexistent LoCategoryType", dnee);
563     	}
564         	
565     	
566     	LoCategoryInfo newLoCategoryInfo = LearningObjectiveServiceAssembler.toLoCategoryInfo(loCategory);
567     	newLoCategoryInfo.setType(catType.getId());
568     	newLoCategoryInfo.setName(loCategoryInfo.getName());
569     	LoCategory newLoCategory = loDao.create(LearningObjectiveServiceAssembler.toLoCategory(newLoCategoryInfo, loDao));
570         	
571     	
572     	List<Lo> catsLos = loDao.getLosByLoCategory(loCategory.getId());         	
573     	for (Lo lo : catsLos) {
574     		try {
575     			
576 				loDao.addLoCategoryToLo(newLoCategory.getId(), lo.getId());
577 				
578 				loDao.removeLoCategoryFromLo(loCategory.getId(), lo.getId());
579 			} catch (UnsupportedActionException uae) {
580 				throw new OperationFailedException(uae.getMessage(), uae);
581 			}
582     	}
583         	
584     	
585     	loCategory.setState("Suspended");
586     	loDao.update(loCategory);
587         	
588     	return newLoCategory;
589 	}
590 
591 	
592 
593 
594 	@Override
595 	public List<ValidationResultInfo> validateLo(String validationType,
596 			LoInfo loInfo) throws DoesNotExistException,
597 			InvalidParameterException, MissingParameterException,
598 			OperationFailedException {
599 	    checkForMissingParameter(validationType, "validationType");
600 	    checkForMissingParameter(loInfo, "loInfo");
601 
602      
603 
604 
605 
606 
607 
608 
609 	    
610 	    ObjectStructureDefinition objStructure = this.getObjectStructure(LoInfo.class.getName());
611 	    Validator validator = validatorFactory.getValidator();
612 	    return validator.validateObject(loInfo, objStructure);
613 	}
614 
615 	
616 
617 
618 	@Override
619 	public List<ValidationResultInfo> validateLoCategory(String validationType,
620 			LoCategoryInfo loCategoryInfo) throws DoesNotExistException,
621 			InvalidParameterException, MissingParameterException,
622 			OperationFailedException {
623 	    checkForMissingParameter(validationType, "validationType");
624 	    checkForMissingParameter(loCategoryInfo, "loCategoryInfo");
625 
626      
627 
628 
629 
630 
631 
632 
633 
634         ObjectStructureDefinition objStructure = this.getObjectStructure(LoCategoryInfo.class.getName());
635         Validator validator = validatorFactory.getValidator();
636         return validator.validateObject(loCategoryInfo, objStructure);
637 
638 	}
639 
640 	@Override
641 	public List<ValidationResultInfo> validateLoLoRelation(
642 			String validationType, LoLoRelationInfo loLoRelationInfo)
643 			throws DoesNotExistException, InvalidParameterException,
644 			MissingParameterException, OperationFailedException {
645 
646         ObjectStructureDefinition objStructure = this.getObjectStructure(LoLoRelationInfo.class.getName());
647         Validator validator = validatorFactory.getValidator();
648         return validator.validateObject(loLoRelationInfo, objStructure);
649 	}
650 
651     
652 
653 
654 
655 
656 
657 
658     private void checkForMissingParameter(Object param, String paramName)
659             throws MissingParameterException {
660         if (param == null) {
661             throw new MissingParameterException(paramName + " can not be null");
662         }
663     }
664 
665     
666 
667 
668 
669 
670     private void checkForEmptyList(Object param, String paramName)
671             throws MissingParameterException {
672         if (param != null && param instanceof List && ((List<?>)param).size() == 0) {
673             throw new MissingParameterException(paramName + " can not be an empty list");
674         }
675     }
676 
677     
678     
679 
680 
681 
682 
683 
684 
685 
686 
687 
688 
689 
690 
691     
692 
693 
694 
695 
696 
697     private boolean doesLoCategoryExist(String loRepositoryKey, LoCategoryInfo loCategoryInfo, String loCategoryId)
698             throws MissingParameterException, DataValidationErrorException {
699     if (loCategoryInfo.getName() == null)
700     {
701      return false;
702     }
703         boolean exists = false;
704 	    SearchRequest request = new SearchRequest();
705 	    request.setSearchKey("lo.search.loCategoriesByNameRepoTypeState");
706 	    
707  		List<SearchParam> searchParams = new ArrayList<SearchParam>();
708 		SearchParam qpv1 = new SearchParam();
709 		qpv1.setKey("lo.queryParam.loCategoryName");
710 		qpv1.setValue(loCategoryInfo.getName().toLowerCase());
711 		searchParams.add(qpv1);
712 		SearchParam qpv2 = new SearchParam();
713 		qpv2.setKey("lo.queryParam.loCategoryRepo");
714 		qpv2.setValue(loRepositoryKey);
715 		searchParams.add(qpv2);
716 		SearchParam qpv3 = new SearchParam();
717 		qpv3.setKey("lo.queryParam.loCategoryType");
718 		qpv3.setValue(loCategoryInfo.getType());
719 		searchParams.add(qpv3);
720 		SearchParam qpv4 = new SearchParam();
721 		qpv4.setKey("lo.queryParam.loCategoryState");
722 		qpv4.setValue(loCategoryInfo.getState());
723 		searchParams.add(qpv4);
724 		
725 		request.setParams(searchParams);
726 		
727 		SearchResult result = search(request);
728 		
729 		if(loCategoryId != null && !loCategoryId.trim().equals("")){
730 			if (result.getRows().size() > 0) {
731 				for(SearchResultRow srrow : result.getRows()){
732 					List<SearchResultCell> srCells = srrow.getCells();
733 					if(srCells != null && srCells.size() > 0){
734 						for(SearchResultCell srcell : srCells){
735 							if(!srcell.getValue().equals(loCategoryId)) {
736                                 exists = true;
737                             }
738 						}
739 					}
740 				}
741 			}
742 		}
743 		else{
744 			if (result.getRows().size() > 0) {
745                 exists = true;
746 			}
747 		}
748         return exists;
749     }
750     
751     @Override
752     public ObjectStructureDefinition getObjectStructure(String objectTypeKey) {
753         return dictionaryServiceDelegate.getObjectStructure(objectTypeKey);
754     }
755 
756     @Override
757     public List<String> getObjectTypes() {
758         return dictionaryServiceDelegate.getObjectTypes();
759     }
760 
761 	
762 
763 
764     @Override
765     public SearchCriteriaTypeInfo getSearchCriteriaType(
766             String searchCriteriaTypeKey) throws DoesNotExistException,
767             InvalidParameterException, MissingParameterException,
768             OperationFailedException {
769 
770         return searchManager.getSearchCriteriaType(searchCriteriaTypeKey);
771     }
772 
773 	
774 
775 
776     @Override
777     public List<SearchCriteriaTypeInfo> getSearchCriteriaTypes()
778     throws OperationFailedException {
779         return searchManager.getSearchCriteriaTypes();
780     }
781 
782 	
783 
784 
785     @Override
786     public SearchResultTypeInfo getSearchResultType(String searchResultTypeKey)
787     throws DoesNotExistException, InvalidParameterException,
788     MissingParameterException, OperationFailedException {
789         checkForMissingParameter(searchResultTypeKey, "searchResultTypeKey");
790         return searchManager.getSearchResultType(searchResultTypeKey);
791     }
792 
793 	
794 
795 
796     @Override
797     public List<SearchResultTypeInfo> getSearchResultTypes()
798     throws OperationFailedException {
799         return searchManager.getSearchResultTypes();
800     }
801 
802 	
803 
804 
805     @Override
806     public SearchTypeInfo getSearchType(String searchTypeKey)
807     throws DoesNotExistException, InvalidParameterException,
808     MissingParameterException, OperationFailedException {
809         checkForMissingParameter(searchTypeKey, "searchTypeKey");
810         return searchManager.getSearchType(searchTypeKey);
811     }
812 
813 	
814 
815 
816     @Override
817     public List<SearchTypeInfo> getSearchTypes()
818     throws OperationFailedException {
819         return searchManager.getSearchTypes();
820     }
821 
822 	
823 
824 
825     @Override
826     public List<SearchTypeInfo> getSearchTypesByCriteria(
827             String searchCriteriaTypeKey) throws DoesNotExistException,
828             InvalidParameterException, MissingParameterException,
829             OperationFailedException {
830         checkForMissingParameter(searchCriteriaTypeKey, "searchCriteriaTypeKey");
831         return searchManager.getSearchTypesByCriteria(searchCriteriaTypeKey);
832     }
833 
834 	
835 
836 
837     @Override
838     public List<SearchTypeInfo> getSearchTypesByResult(
839             String searchResultTypeKey) throws DoesNotExistException,
840             InvalidParameterException, MissingParameterException,
841             OperationFailedException {
842         checkForMissingParameter(searchResultTypeKey, "searchResultTypeKey");
843         return searchManager.getSearchTypesByResult(searchResultTypeKey);
844     }
845 
846 	@Override
847 	@Transactional(readOnly=false,noRollbackFor={DoesNotExistException.class},rollbackFor={Throwable.class})
848 	public LoLoRelationInfo createLoLoRelation(String loId, String relatedLoId,
849 			String loLoRelationType, LoLoRelationInfo loLoRelationInfo)
850 			throws AlreadyExistsException, 
851 			DataValidationErrorException, DoesNotExistException,
852 			InvalidParameterException, MissingParameterException,
853 			OperationFailedException, PermissionDeniedException {
854 	    checkForMissingParameter(loId, "loId");
855 	    checkForMissingParameter(relatedLoId, "relatedLoId");
856 	    checkForMissingParameter(loLoRelationType, "loLoRelationType");
857 	    checkForMissingParameter(loLoRelationInfo, "loLoRelationInfo");
858 	    
859 		
860 		List<ValidationResultInfo> val = validateLoLoRelation("SYSTEM", loLoRelationInfo);
861 		if(null != val && val.size() > 0) {
862 			for (ValidationResultInfo result : val) {
863 				System.err.println("Validation error. Element: " + result.getElement() + ",  Value: " + result.getMessage());
864 			}
865 			throw new DataValidationErrorException("Validation error!", val);
866 		}
867 	    
868 	    if (null == loLoRelationInfo.getState()) {
869 	    	loLoRelationInfo.setState(DtoConstants.STATE_DRAFT);
870 	    }
871 	    Lo lo = loDao.fetch(Lo.class, loId);
872 	    Lo relatedLo = loDao.fetch(Lo.class, relatedLoId);
873 	    LoLoRelationType type = loDao.fetch(LoLoRelationType.class, loLoRelationType);
874 	    loLoRelationInfo.setLoId(loId);
875 	    loLoRelationInfo.setRelatedLoId(relatedLoId);
876 	    loLoRelationInfo.setType(loLoRelationType);
877 	    
878 	    LoLoRelation relation = null;
879 	    try {
880 		    relation = LearningObjectiveServiceAssembler.toLoLoRelation(false, loLoRelationInfo, loDao);
881 	    } catch (VersionMismatchException vme) {
882 	    	
883 	    	throw new OperationFailedException("VersionMismatchException caught during LoLoRelation creation");
884 	    }
885 	    relation.setLo(lo);
886 	    relation.setRelatedLo(relatedLo);
887 	    relation.setLoLoRelationType(type);
888 	    
889 	    relation = loDao.create(relation);
890 	    
891 		return LearningObjectiveServiceAssembler.toLoLoRelationInfo(relation);
892 	}
893 
894 	@Override
895 	@Transactional(readOnly=false,noRollbackFor={DoesNotExistException.class},rollbackFor={Throwable.class})
896 	public StatusInfo deleteLoLoRelation(String loLoRelationId)
897 			throws DoesNotExistException, InvalidParameterException,
898 			MissingParameterException, OperationFailedException,
899 			PermissionDeniedException {
900 	    checkForMissingParameter(loLoRelationId, "loLoRelationId");
901 	    
902 	    loDao.deleteLoLoRelation(loLoRelationId);
903 	    
904 		return new StatusInfo();
905 	}
906 
907 	@Override
908     @Transactional(readOnly=true)
909 	public LoLoRelationInfo getLoLoRelation(String loLoRelationId)
910 			throws DoesNotExistException, InvalidParameterException,
911 			MissingParameterException, OperationFailedException {
912 	    checkForMissingParameter(loLoRelationId, "loLoRelationId");
913 		return LearningObjectiveServiceAssembler.toLoLoRelationInfo(loDao.fetch(LoLoRelation.class, loLoRelationId));
914 	}
915 
916 	@Override
917     @Transactional(readOnly=true)
918 	public List<LoLoRelationInfo> getLoLoRelationsByLoId(String loId)
919 			throws DoesNotExistException, InvalidParameterException,
920 			MissingParameterException, OperationFailedException {
921 		List<LoLoRelation> llRelations = loDao.getLoLoRelationsByLoId(loId);
922 		return LearningObjectiveServiceAssembler.toLoLoRelationInfos(llRelations);
923 	}
924 
925 	@Override
926     @Transactional(readOnly=true)
927 	public List<LoInfo> getLosByRelatedLoId(String relatedLoId,
928 			String loLoRelationType) throws DoesNotExistException,
929 			InvalidParameterException, MissingParameterException,
930 			OperationFailedException {
931 		List<Lo> relatedLos = loDao.getLosByRelatedLoId(relatedLoId, loLoRelationType);
932 		return LearningObjectiveServiceAssembler.toLoInfos(relatedLos);
933 	}
934 
935 	@Override
936     @Transactional(readOnly=true)
937 	public List<LoInfo> getRelatedLosByLoId(String loId, String loLoRelationTypeKey)
938 			throws DoesNotExistException, InvalidParameterException,
939 			MissingParameterException, OperationFailedException {
940 	    checkForMissingParameter(loId, "loId");
941 	    checkForMissingParameter(loLoRelationTypeKey, "loLoRelationTypeKey");
942 	    List<Lo> relatedLos = loDao.getRelatedLosByLoId(loId, loLoRelationTypeKey);
943 		return LearningObjectiveServiceAssembler.toLoInfos(relatedLos);
944 	}
945 
946 	@Override
947 	@Transactional(readOnly=false,noRollbackFor={DoesNotExistException.class},rollbackFor={Throwable.class})
948 	public LoLoRelationInfo updateLoLoRelation(String loLoRelationId,
949 			LoLoRelationInfo loLoRelationInfo)
950 			throws DataValidationErrorException, DoesNotExistException,
951 			InvalidParameterException, MissingParameterException,
952 			OperationFailedException, PermissionDeniedException,
953 			VersionMismatchException {
954 		
955 
956 		
957 		List<ValidationResultInfo> val = validateLoLoRelation("SYSTEM", loLoRelationInfo);
958 		if(null != val && val.size() > 0) {
959 			throw new DataValidationErrorException("Validation error!", val);
960 		}
961 
962 	    
963 		return null;
964 	}
965 
966 	@Override
967 	@Transactional(readOnly=false,noRollbackFor={DoesNotExistException.class},rollbackFor={Throwable.class})
968 	public LoCategoryInfo createLoCategory(String loRepositoryKey,
969 			String loCategoryTypeKey, LoCategoryInfo loCategoryInfo)
970 			throws DataValidationErrorException, DoesNotExistException,
971 			InvalidParameterException, MissingParameterException,
972 			OperationFailedException, PermissionDeniedException {
973 	    checkForMissingParameter(loRepositoryKey, "loRepositoryKey");
974 	    checkForMissingParameter(loCategoryTypeKey, "loCategoryTypeKey");
975 	    checkForMissingParameter(loCategoryInfo, "loCategoryInfo");
976 	    
977 		
978 		List<ValidationResultInfo> val = validateLoCategory("SYSTEM", loCategoryInfo);
979 
980         
981         if (doesLoCategoryExist(loRepositoryKey, loCategoryInfo, null)) {
982             ValidationResultInfo vr = new ValidationResultInfo();
983             vr.setElement("LO Category Name");
984             vr.setError("LO Category already exists");
985             val.add(vr);
986         }
987         if(null != val && val.size() > 0) {
988 			for (ValidationResultInfo result : val) {
989 				System.err.println("Validation error. Element: " + result.getElement() + ",  Value: " + result.getMessage());
990 			}
991 			throw new DataValidationErrorException("Validation error!", val);
992 		}
993 
994 	    LoCategory category = LearningObjectiveServiceAssembler.toLoCategory(loCategoryInfo, loDao);
995 	    LoCategoryType loCatType = loDao.fetch(LoCategoryType.class, loCategoryTypeKey);
996 	    category.setLoCategoryType(loCatType);
997 	    LoRepository loRepository = loDao.fetch(LoRepository.class, loRepositoryKey);
998 	    category.setLoRepository(loRepository);
999 	    loDao.create(category);
1000 		return LearningObjectiveServiceAssembler.toLoCategoryInfo(category);
1001 	}
1002 
1003 	@Override
1004     @Transactional(readOnly=true)
1005 	public LoCategoryTypeInfo getLoCategoryType(String loCategoryTypeKey)
1006 			throws DoesNotExistException, InvalidParameterException,
1007 			MissingParameterException, OperationFailedException {
1008 	    checkForMissingParameter(loCategoryTypeKey, "loCategoryTypeKey");
1009 	    LoCategoryType loCatType = loDao.fetch(LoCategoryType.class, loCategoryTypeKey);
1010 	    return LearningObjectiveServiceAssembler.toLoCategoryTypeInfo(loCatType);
1011 	}
1012 
1013 	@Override
1014     @Transactional(readOnly=true)
1015 	public List<LoCategoryTypeInfo> getLoCategoryTypes()
1016 			throws OperationFailedException {
1017 		List<LoCategoryType> categoryTypes = loDao.find(LoCategoryType.class);
1018 		return LearningObjectiveServiceAssembler.toLoCategoryTypeInfos(categoryTypes);
1019 	}
1020 
1021 	@Override
1022     @Transactional(readOnly=true)
1023 	public List<LoInfo> getLosByRepository(String loRepositoryKey,
1024 			String loTypeKey, String loStateKey)
1025 			throws InvalidParameterException, MissingParameterException,
1026 			OperationFailedException {
1027 	    checkForMissingParameter(loRepositoryKey, "loRepositoryKey");
1028 	    List<Lo> los = loDao.getLosByRepository(loRepositoryKey);
1029 		return LearningObjectiveServiceAssembler.toLoInfos(los);
1030 	}
1031 
1032 	@Override
1033 	public SearchResult search(SearchRequest searchRequest) throws MissingParameterException {
1034         checkForMissingParameter(searchRequest, "searchRequest");
1035         SearchResult result =  searchManager.search(searchRequest, loDao);
1036         if("lo.search.loByCategory".equals(searchRequest.getSearchKey())){
1037 
1038 
1039         	groupCategories(result);
1040 
1041 
1042         }
1043         
1044         return result;
1045 	}
1046 
1047 	
1048 	private void groupCategories(SearchResult result) {
1049 		Map<String,SearchResultCell> idToCellMap = new HashMap<String,SearchResultCell>();
1050 		for(Iterator<SearchResultRow> iter = result.getRows().iterator();iter.hasNext();){
1051 			SearchResultRow row = iter.next();
1052 			SearchResultCell categoryCell = null;
1053 			String loId = null;
1054 			
1055 			for(SearchResultCell cell:row.getCells()){
1056 				if("lo.resultColumn.categoryName".equals(cell.getKey())){
1057 					categoryCell = cell;
1058 					break;
1059 				}else if("lo.resultColumn.loId".equals(cell.getKey())){
1060 					loId = cell.getValue();
1061 				}
1062 			}
1063 			
1064 			if(loId!=null){
1065 				if(idToCellMap.containsKey(loId)){
1066 					SearchResultCell cell = idToCellMap.get(loId);
1067 					if(cell == null){
1068 						cell = new SearchResultCell("lo.resultColumn.categoryName","");
1069 						idToCellMap.put(loId, cell);
1070 					}
1071 					if(categoryCell!=null){
1072 						if(cell.getValue()==null||cell.getValue().isEmpty()){
1073 							cell.setValue(categoryCell.getValue());
1074 						}else if(categoryCell.getValue()!=null && !categoryCell.getValue().isEmpty()){
1075 							cell.setValue(cell.getValue()+", "+categoryCell.getValue());
1076 						}
1077 					}
1078 					
1079 					iter.remove();
1080 				} else {
1081 					
1082 					idToCellMap.put(loId, categoryCell);
1083 				}
1084 			}
1085 		}
1086 	}
1087 	
1088 }