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