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