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