View Javadoc

1   package org.kuali.student.lum.course.service.impl;
2   
3   import static org.apache.commons.collections.CollectionUtils.isEmpty;
4   
5   import java.util.ArrayList;
6   import java.util.Date;
7   import java.util.List;
8   
9   import org.apache.log4j.Logger;
10  import org.kuali.student.common.validator.Validator;
11  import org.kuali.student.common.validator.ValidatorFactory;
12  import org.kuali.student.core.assembly.BaseDTOAssemblyNode;
13  import org.kuali.student.core.assembly.BaseDTOAssemblyNode.NodeOperation;
14  import org.kuali.student.core.assembly.BusinessServiceMethodInvoker;
15  import org.kuali.student.core.assembly.data.AssemblyException;
16  import org.kuali.student.core.dictionary.dto.ObjectStructureDefinition;
17  import org.kuali.student.core.dictionary.service.DictionaryService;
18  import org.kuali.student.core.dto.StatusInfo;
19  import org.kuali.student.core.exceptions.AlreadyExistsException;
20  import org.kuali.student.core.exceptions.CircularReferenceException;
21  import org.kuali.student.core.exceptions.CircularRelationshipException;
22  import org.kuali.student.core.exceptions.DataValidationErrorException;
23  import org.kuali.student.core.exceptions.DependentObjectsExistException;
24  import org.kuali.student.core.exceptions.DoesNotExistException;
25  import org.kuali.student.core.exceptions.IllegalVersionSequencingException;
26  import org.kuali.student.core.exceptions.InvalidParameterException;
27  import org.kuali.student.core.exceptions.MissingParameterException;
28  import org.kuali.student.core.exceptions.OperationFailedException;
29  import org.kuali.student.core.exceptions.PermissionDeniedException;
30  import org.kuali.student.core.exceptions.UnsupportedActionException;
31  import org.kuali.student.core.exceptions.VersionMismatchException;
32  import org.kuali.student.core.statement.dto.RefStatementRelationInfo;
33  import org.kuali.student.core.statement.dto.ReqCompFieldInfo;
34  import org.kuali.student.core.statement.dto.ReqComponentInfo;
35  import org.kuali.student.core.statement.dto.StatementTreeViewInfo;
36  import org.kuali.student.core.statement.service.StatementService;
37  import org.kuali.student.core.validation.dto.ValidationResultInfo;
38  import org.kuali.student.core.versionmanagement.dto.VersionDisplayInfo;
39  import org.kuali.student.lum.course.dto.ActivityInfo;
40  import org.kuali.student.lum.course.dto.CourseInfo;
41  import org.kuali.student.lum.course.dto.CourseJointInfo;
42  import org.kuali.student.lum.course.dto.FormatInfo;
43  import org.kuali.student.lum.course.dto.LoDisplayInfo;
44  import org.kuali.student.lum.course.service.CourseService;
45  import org.kuali.student.lum.course.service.CourseServiceConstants;
46  import org.kuali.student.lum.course.service.assembler.CourseAssembler;
47  import org.kuali.student.lum.course.service.assembler.CourseAssemblerConstants;
48  import org.kuali.student.lum.lu.dto.CluInfo;
49  import org.kuali.student.lum.lu.dto.CluSetInfo;
50  import org.kuali.student.lum.lu.service.LuService;
51  import org.kuali.student.lum.lu.service.LuServiceConstants;
52  import org.kuali.student.lum.statement.typekey.ReqComponentFieldTypes;
53  import org.springframework.transaction.annotation.Transactional;
54  /**
55   * CourseServiceImpl implements CourseService Interface by mapping DTOs in CourseInfo to underlying entity DTOs like CluInfo
56   * and CluCluRelationInfo.
57   *
58   * For Credits, there are three credit types that are set with a combination of type and dynamic attributes
59   * To set a variable(range) credit option,
60   * set the ResultComponentInfo type to CourseAssemblerConstants.COURSE_RESULT_COMP_TYPE_CREDIT_VARIABLE
61   * and add the dynamic attributes CourseAssemblerConstants.COURSE_RESULT_COMP_ATTR_MIN_CREDIT_VALUE and 
62   * CourseAssemblerConstants.COURSE_RESULT_COMP_ATTR_MAX_CREDIT_VALUE with respective credit min and max values.
63   * 
64   * To set a fixed credit option,
65   * set the ResultComponentInfo type to CourseAssemblerConstants.COURSE_RESULT_COMP_TYPE_CREDIT_FIXED
66   * and add the dynamic attribute CourseAssemblerConstants.COURSE_RESULT_COMP_ATTR_FIXED_CREDIT_VALUE
67   * with the fixed credit value
68   * 
69   * To Set multiple credit options, 
70   * set the ResultComponentInfo type to CourseAssemblerConstants.COURSE_RESULT_COMP_TYPE_CREDIT_MULTIPLE
71   * and add each credit as a numeric ResultValue on the ResultComponentInfo for each credit you desire
72   *
73   * @author Kuali Student Team
74   */
75  @Transactional(readOnly=true,noRollbackFor={DoesNotExistException.class},rollbackFor={Throwable.class})
76  public class CourseServiceImpl implements CourseService {
77      final static Logger LOG = Logger.getLogger(CourseServiceImpl.class);
78  
79      private LuService luService;
80      private CourseAssembler courseAssembler;
81      private BusinessServiceMethodInvoker courseServiceMethodInvoker;
82      private DictionaryService dictionaryServiceDelegate;
83      private ValidatorFactory validatorFactory;
84      private StatementService statementService;
85  
86      @Override
87      @Transactional(readOnly=false)
88  	public CourseInfo createCourse(CourseInfo courseInfo) throws AlreadyExistsException, DataValidationErrorException, InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException, VersionMismatchException, DoesNotExistException, CircularRelationshipException, DependentObjectsExistException, UnsupportedActionException {
89  
90          checkForMissingParameter(courseInfo, "CourseInfo");
91  
92          // Validate
93          List<ValidationResultInfo> validationResults = validateCourse("OBJECT", courseInfo);
94          if (null != validationResults && validationResults.size() > 0) {
95              throw new DataValidationErrorException("Validation error!", validationResults);
96          }
97  
98          try {
99              return processCourseInfo(courseInfo, NodeOperation.CREATE);
100         } catch (AssemblyException e) {
101             LOG.error("Error disassembling course", e);
102             throw new OperationFailedException("Error disassembling course");
103         } catch (Exception e){
104         	LOG.error("Error disassembling course", e);
105         	throw new OperationFailedException("Error disassembling course");
106         }
107     }
108 
109     @Override
110     @Transactional(readOnly=false)
111 	public CourseInfo updateCourse(CourseInfo courseInfo) throws DataValidationErrorException, DoesNotExistException, InvalidParameterException, MissingParameterException, VersionMismatchException, OperationFailedException, PermissionDeniedException, AlreadyExistsException, CircularRelationshipException, DependentObjectsExistException, UnsupportedActionException, UnsupportedOperationException, CircularReferenceException {
112 
113         checkForMissingParameter(courseInfo, "CourseInfo");
114         
115         // Validate
116         List<ValidationResultInfo> validationResults = validateCourse("OBJECT", courseInfo);
117         if (null != validationResults && validationResults.size() > 0) {
118             throw new DataValidationErrorException("Validation error!", validationResults);
119         }
120 
121         try {
122 
123             return processCourseInfo(courseInfo, NodeOperation.UPDATE);
124 
125         } catch (AssemblyException e) {
126             LOG.error("Error disassembling course", e);
127             throw new OperationFailedException("Error disassembling course");
128         }
129     }
130 
131     @Override
132     @Transactional(readOnly=false)
133 	public StatusInfo deleteCourse(String courseId) throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException, VersionMismatchException, DataValidationErrorException, AlreadyExistsException, CircularRelationshipException, DependentObjectsExistException, UnsupportedActionException, UnsupportedOperationException, CircularReferenceException {
134 
135         try {
136             CourseInfo course = getCourse(courseId);
137 
138             processCourseInfo(course, NodeOperation.DELETE);
139 
140             StatusInfo status = new StatusInfo();
141             status.setSuccess(true);
142             return status;
143 
144         } catch (AssemblyException e) {
145             LOG.error("Error disassembling course", e);
146             throw new OperationFailedException("Error disassembling course");
147         }
148     }
149 
150     @Override
151     public CourseInfo getCourse(String courseId) throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException {
152 
153         CluInfo clu = luService.getClu(courseId);
154 
155         CourseInfo course;
156         try {
157             course = courseAssembler.assemble(clu, null, false);
158         } catch (AssemblyException e) {
159             LOG.error("Error assembling course", e);
160             throw new OperationFailedException("Error assembling course");
161         }
162 
163         return course;
164 
165     }
166 
167     @Override
168     public List<ActivityInfo> getCourseActivities(String formatId) throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException {
169         throw new UnsupportedOperationException("GetCourseActivities");
170     }
171 
172     @Override
173     public List<FormatInfo> getCourseFormats(String courseId) throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException {
174         throw new UnsupportedOperationException("GetCourseFormats");
175     }
176 
177     @Override
178     public List<LoDisplayInfo> getCourseLos(String courseId) throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException {
179         throw new UnsupportedOperationException("GetCourseLos");
180     }
181 
182     @Override
183     public List<StatementTreeViewInfo> getCourseStatements(String courseId, String nlUsageTypeKey, String language) throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException {
184     	checkForMissingParameter(courseId, "courseId");
185 
186     	CluInfo clu = luService.getClu(courseId);
187 		if (!CourseAssemblerConstants.COURSE_TYPE.equals(clu.getType())) {
188 			throw new DoesNotExistException("Specified CLU is not a Course");
189 		}
190 		List<RefStatementRelationInfo> relations = statementService.getRefStatementRelationsByRef(CourseAssemblerConstants.COURSE_TYPE, clu.getId());
191 		if (relations == null) {
192 			return new ArrayList<StatementTreeViewInfo>(0);
193 		}
194 
195 		List<StatementTreeViewInfo> tree = new ArrayList<StatementTreeViewInfo>(relations.size());
196 		for (RefStatementRelationInfo relation : relations) {
197 			tree.add(statementService.getStatementTreeView(relation.getStatementId()));
198 		}
199     	return tree;
200     }
201 
202     @Override
203     public List<ValidationResultInfo> validateCourse(String validationType, CourseInfo courseInfo) throws InvalidParameterException, MissingParameterException, OperationFailedException {
204 
205         ObjectStructureDefinition objStructure = this.getObjectStructure(CourseInfo.class.getName());
206         Validator defaultValidator = validatorFactory.getValidator();
207         List<ValidationResultInfo> validationResults = defaultValidator.validateObject(courseInfo, objStructure);
208         return validationResults;
209     }
210 
211     @Override
212     @Transactional(readOnly=false)
213 	public StatementTreeViewInfo createCourseStatement(String courseId, StatementTreeViewInfo statementTreeViewInfo) throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException, DataValidationErrorException {
214     	checkForMissingParameter(courseId, "courseId");
215     	checkForMissingParameter(statementTreeViewInfo, "statementTreeViewInfo");
216 
217         // Validate
218         List<ValidationResultInfo> validationResults = validateCourseStatement(courseId, statementTreeViewInfo);
219         if (!isEmpty(validationResults)) {
220             throw new DataValidationErrorException("Validation error!", validationResults);
221         }
222 
223         if (findStatementReference(courseId, statementTreeViewInfo) != null) {
224         	throw new InvalidParameterException("Statement is already referenced by this course");
225         }
226 
227 		try {
228 			StatementTreeViewInfo tree = statementService.createStatementTreeView(statementTreeViewInfo);
229 			RefStatementRelationInfo relation = new RefStatementRelationInfo();
230 			relation.setRefObjectId(courseId);
231 			relation.setRefObjectTypeKey(CourseAssemblerConstants.COURSE_TYPE);
232 			relation.setStatementId(tree.getId());
233 	        relation.setType(CourseAssemblerConstants.COURSE_REFERENCE_TYPE);
234 	        relation.setState(CourseAssemblerConstants.ACTIVE);
235 			statementService.createRefStatementRelation(relation);
236 		} catch (Exception e) {
237 			throw new OperationFailedException("Unable to create clu/tree relation", e);
238 		}
239     	return statementTreeViewInfo;
240     }
241 
242 	@Override
243     @Transactional(readOnly=false)
244 	public StatusInfo deleteCourseStatement(String courseId, StatementTreeViewInfo statementTreeViewInfo) throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException {
245     	checkForMissingParameter(courseId, "courseId");
246     	checkForMissingParameter(statementTreeViewInfo, "statementTreeViewInfo");
247 
248     	RefStatementRelationInfo relation = findStatementReference(courseId, statementTreeViewInfo);
249     	if (relation != null) {
250     		statementService.deleteRefStatementRelation(relation.getId());
251     		statementService.deleteStatementTreeView(statementTreeViewInfo.getId());
252     		StatusInfo result = new StatusInfo();
253     		return result;
254     	}
255 
256     	throw new DoesNotExistException("Course does not have this StatemenTree");
257 	}
258 
259     @Override
260     @Transactional(readOnly=false)
261 	public StatementTreeViewInfo updateCourseStatement(String courseId, StatementTreeViewInfo statementTreeViewInfo) throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException, DataValidationErrorException, CircularReferenceException, VersionMismatchException {
262     	checkForMissingParameter(courseId, "courseId");
263     	checkForMissingParameter(statementTreeViewInfo, "statementTreeViewInfo");
264 
265         // Validate
266         List<ValidationResultInfo> validationResults = validateCourseStatement(courseId, statementTreeViewInfo);
267         if (!isEmpty(validationResults)) {
268             throw new DataValidationErrorException("Validation error!", validationResults);
269         }
270 
271         if (findStatementReference(courseId, statementTreeViewInfo) == null) {
272         	throw new InvalidParameterException("Statement is not part of this course");
273         }
274 
275         return statementService.updateStatementTreeView(statementTreeViewInfo.getId(), statementTreeViewInfo);
276     }
277 
278     @Override
279     public List<ValidationResultInfo> validateCourseStatement(String courseId, StatementTreeViewInfo statementTreeViewInfo) throws InvalidParameterException, MissingParameterException, OperationFailedException {
280     	checkForMissingParameter(courseId, "courseId");
281     	checkForMissingParameter(statementTreeViewInfo, "statementTreeViewInfo");
282 
283     	try {
284 			CluInfo clu = luService.getClu(courseId);
285 		} catch (DoesNotExistException e) {
286 			throw new InvalidParameterException("course does not exist");
287 		}
288 
289     	ObjectStructureDefinition objStructure = this.getObjectStructure(StatementTreeViewInfo.class.getName());
290         Validator defaultValidator = validatorFactory.getValidator();
291         List<ValidationResultInfo> validationResults = defaultValidator.validateObject(statementTreeViewInfo, objStructure);
292         return validationResults;
293     }   
294 
295     @Override
296     public ObjectStructureDefinition getObjectStructure(String objectTypeKey) {
297         return dictionaryServiceDelegate.getObjectStructure(objectTypeKey);
298     }
299 
300     @Override
301     public List<String> getObjectTypes() {
302         return dictionaryServiceDelegate.getObjectTypes();
303     }
304 
305     public CourseAssembler getCourseAssembler() {
306         return courseAssembler;
307     }
308 
309     public void setCourseAssembler(CourseAssembler courseAssembler) {
310         this.courseAssembler = courseAssembler;
311     }
312 
313     public BusinessServiceMethodInvoker getCourseServiceMethodInvoker() {
314         return courseServiceMethodInvoker;
315     }
316 
317     public void setCourseServiceMethodInvoker(BusinessServiceMethodInvoker courseServiceMethodInvoker) {
318         this.courseServiceMethodInvoker = courseServiceMethodInvoker;
319     }
320 
321     public DictionaryService getDictionaryServiceDelegate() {
322         return dictionaryServiceDelegate;
323     }
324 
325     public void setDictionaryServiceDelegate(DictionaryService dictionaryServiceDelegate) {
326         this.dictionaryServiceDelegate = dictionaryServiceDelegate;
327     }
328 
329     private CourseInfo processCourseInfo(CourseInfo courseInfo, NodeOperation operation) throws AssemblyException, OperationFailedException, VersionMismatchException, PermissionDeniedException, MissingParameterException, InvalidParameterException, DoesNotExistException, DataValidationErrorException, AlreadyExistsException, CircularRelationshipException, DependentObjectsExistException, UnsupportedActionException, UnsupportedOperationException, CircularReferenceException {
330 
331         BaseDTOAssemblyNode<CourseInfo, CluInfo> results = courseAssembler.disassemble(courseInfo, operation);
332 
333         // Use the results to make the appropriate service calls here
334 		courseServiceMethodInvoker.invokeServiceCalls(results);
335 
336         return results.getBusinessDTORef();
337     }
338 
339     public ValidatorFactory getValidatorFactory() {
340 		return validatorFactory;
341 	}
342 
343 	public void setValidatorFactory(ValidatorFactory validatorFactory) {
344 		this.validatorFactory = validatorFactory;
345 	}
346 
347 	public LuService getLuService() {
348         return luService;
349     }
350 
351     public void setLuService(LuService luService) {
352         this.luService = luService;
353     }
354 
355 	public StatementService getStatementService() {
356 		return statementService;
357 	}
358 
359 	public void setStatementService(StatementService statementService) {
360 		this.statementService = statementService;
361 	}
362 
363 	@Override
364 	@Transactional(readOnly=false)
365 	public CourseInfo createNewCourseVersion(String versionIndCourseId,
366 			String versionComment) throws DataValidationErrorException,
367 			DoesNotExistException, InvalidParameterException,
368 			MissingParameterException, OperationFailedException,
369 			PermissionDeniedException, VersionMismatchException {
370 
371 		//step one, get the original course
372 		VersionDisplayInfo currentVersion = luService.getCurrentVersion(LuServiceConstants.CLU_NAMESPACE_URI, versionIndCourseId);
373 		CourseInfo originalCourse = getCourse(currentVersion.getId());
374 
375 		//Version the Clu
376 		CluInfo newVersionClu = luService.createNewCluVersion(versionIndCourseId, versionComment);
377 
378 		try {
379 	        BaseDTOAssemblyNode<CourseInfo, CluInfo> results;
380 
381 	        //Integrate changes into the original course. (should this just be just the id?)
382 			courseAssembler.assemble(newVersionClu, originalCourse, true);
383 
384 			//Clear Ids from the original course
385 			resetIds(originalCourse);
386 
387 			//Disassemble the new course
388 			results = courseAssembler.disassemble(originalCourse, NodeOperation.UPDATE);
389 
390 			// Use the results to make the appropriate service calls here
391 			courseServiceMethodInvoker.invokeServiceCalls(results);
392 
393 			//copy statements
394 			List<StatementTreeViewInfo> statementTreeViews = getCourseStatements(currentVersion.getId(),null,null);
395 			
396 			clearStatementTreeViewIds(statementTreeViews);
397 			
398 			for(StatementTreeViewInfo statementTreeView:statementTreeViews){
399 				createCourseStatement(results.getBusinessDTORef().getId(), statementTreeView);
400 			}
401 			
402 			return results.getBusinessDTORef();
403 		} catch (AlreadyExistsException e) {
404 			throw new OperationFailedException("Error creating new course version",e);
405 		} catch (DependentObjectsExistException e) {
406 			throw new OperationFailedException("Error creating new course version",e);
407 		} catch (CircularRelationshipException e) {
408 			throw new OperationFailedException("Error creating new course version",e);
409 		} catch (UnsupportedActionException e) {
410 			throw new OperationFailedException("Error creating new course version",e);
411 		} catch (AssemblyException e) {
412 			throw new OperationFailedException("Error creating new course version",e);
413 		} catch (UnsupportedOperationException e) {
414 			throw new OperationFailedException("Error creating new course version",e);
415 		} catch (CircularReferenceException e) {
416 			throw new OperationFailedException("Error creating new course version",e);
417 		}
418 
419 	}
420 
421 	private void clearStatementTreeViewIds(
422 			List<StatementTreeViewInfo> statementTreeViews) throws OperationFailedException {
423 		for(StatementTreeViewInfo statementTreeView:statementTreeViews){
424 			clearStatementTreeViewIdsRecursively(statementTreeView);
425 		}
426 	}
427 
428 	private void clearStatementTreeViewIdsRecursively(StatementTreeViewInfo statementTreeView) throws OperationFailedException{
429 		statementTreeView.setId(null);
430 		for(ReqComponentInfo reqComp:statementTreeView.getReqComponents()){
431 			reqComp.setId(null);
432 			for(ReqCompFieldInfo field:reqComp.getReqCompFields()){
433 				field.setId(null);
434 				//copy any clusets that are adhoc'd and set the field value to the new cluset
435 				if(ReqComponentFieldTypes.COURSE_CLUSET_KEY.getId().equals(field.getType())||
436 				   ReqComponentFieldTypes.PROGRAM_CLUSET_KEY.getId().equals(field.getType())||
437 				   ReqComponentFieldTypes.CLUSET_KEY.getId().equals(field.getType())){
438 					try {
439 						CluSetInfo cluSet = luService.getCluSetInfo(field.getValue());
440 						cluSet.setId(null);
441 						//Clear clu ids if membership info exists, they will be re-added based on membership info 
442 						if (cluSet.getMembershipQuery() != null){
443 							cluSet.getCluIds().clear();
444 							cluSet.getCluSetIds().clear();
445 						}
446 						cluSet = luService.createCluSet(cluSet.getType(), cluSet);
447 						field.setValue(cluSet.getId());
448 					} catch (Exception e) {
449 						throw new OperationFailedException("Error copying clusets.", e);
450 					}
451 				}
452 				
453 			}
454 		}
455 		for(StatementTreeViewInfo child: statementTreeView.getStatements()){
456 			clearStatementTreeViewIdsRecursively(child);
457 		}
458 	}
459 
460 	private void resetIds(CourseInfo course) {
461 		//Clear/Reset Joint info ids
462 		for(CourseJointInfo joint:course.getJoints()){
463 			joint.setRelationId(null);
464 		}
465 		//Clear Los
466 		for(LoDisplayInfo lo:course.getCourseSpecificLOs()){
467 			resetLoRecursively(lo);
468 		}
469 		//Clear format/activity ids
470 		for(FormatInfo format:course.getFormats()){
471 			format.setId(null);
472 			for(ActivityInfo activity:format.getActivities()){
473 				activity.setId(null);
474 			}
475 		}
476 	}
477 
478 	private void resetLoRecursively(LoDisplayInfo lo){
479 		lo.getLoInfo().setId(null);
480 		for(LoDisplayInfo nestedLo:lo.getLoDisplayInfoList()){
481 			resetLoRecursively(nestedLo);
482 		}
483 	}
484 
485 	@Override
486 	@Transactional(readOnly=false)
487 	public StatusInfo setCurrentCourseVersion(String courseVersionId,
488 			Date currentVersionStart) throws DoesNotExistException,
489 			InvalidParameterException, MissingParameterException,
490 			IllegalVersionSequencingException, OperationFailedException,
491 			PermissionDeniedException {
492 		return luService.setCurrentCluVersion(courseVersionId, currentVersionStart);
493 	}
494 
495 	@Override
496 	public VersionDisplayInfo getCurrentVersion(String refObjectTypeURI,
497 			String refObjectId) throws DoesNotExistException,
498 			InvalidParameterException, MissingParameterException,
499 			OperationFailedException, PermissionDeniedException {
500 		if(CourseServiceConstants.COURSE_NAMESPACE_URI.equals(refObjectTypeURI)){
501 			return luService.getCurrentVersion(LuServiceConstants.CLU_NAMESPACE_URI, refObjectId);
502 		}
503 		throw new InvalidParameterException("Object type: " + refObjectTypeURI + " is not known to this implementation");
504 	}
505 
506 	@Override
507 	public VersionDisplayInfo getCurrentVersionOnDate(String refObjectTypeURI,
508 			String refObjectId, Date date) throws DoesNotExistException,
509 			InvalidParameterException, MissingParameterException,
510 			OperationFailedException, PermissionDeniedException {
511 		if(CourseServiceConstants.COURSE_NAMESPACE_URI.equals(refObjectTypeURI)){
512 			return luService.getCurrentVersionOnDate(LuServiceConstants.CLU_NAMESPACE_URI, refObjectId, date);
513 		}
514 		throw new InvalidParameterException("Object type: " + refObjectTypeURI + " is not known to this implementation");
515 	}
516 
517 	@Override
518 	public VersionDisplayInfo getFirstVersion(String refObjectTypeURI,
519 			String refObjectId) throws DoesNotExistException,
520 			InvalidParameterException, MissingParameterException,
521 			OperationFailedException, PermissionDeniedException {
522 		if(CourseServiceConstants.COURSE_NAMESPACE_URI.equals(refObjectTypeURI)){
523 			return luService.getFirstVersion(LuServiceConstants.CLU_NAMESPACE_URI, refObjectId);
524 		}
525 		throw new InvalidParameterException("Object type: " + refObjectTypeURI + " is not known to this implementation");
526 
527 	}
528 
529 	@Override
530 	public VersionDisplayInfo getLatestVersion(String refObjectTypeURI,
531 			String refObjectId) throws DoesNotExistException,
532 			InvalidParameterException, MissingParameterException,
533 			OperationFailedException, PermissionDeniedException {
534 		if(CourseServiceConstants.COURSE_NAMESPACE_URI.equals(refObjectTypeURI)){
535 			return luService.getLatestVersion(LuServiceConstants.CLU_NAMESPACE_URI, refObjectId);
536 		}
537 		throw new InvalidParameterException("Object type: " + refObjectTypeURI + " is not known to this implementation");
538 
539 	}
540 
541 	@Override
542 	public VersionDisplayInfo getVersionBySequenceNumber(
543 			String refObjectTypeURI, String refObjectId, Long sequence)
544 			throws DoesNotExistException, InvalidParameterException,
545 			MissingParameterException, OperationFailedException,
546 			PermissionDeniedException {
547 		if(CourseServiceConstants.COURSE_NAMESPACE_URI.equals(refObjectTypeURI)){
548 			return luService.getVersionBySequenceNumber(LuServiceConstants.CLU_NAMESPACE_URI, refObjectId, sequence);
549 		}
550 		throw new InvalidParameterException("Object type: " + refObjectTypeURI + " is not known to this implementation");
551 	}
552 
553 	@Override
554 	public List<VersionDisplayInfo> getVersions(String refObjectTypeURI,
555 			String refObjectId) throws DoesNotExistException,
556 			InvalidParameterException, MissingParameterException,
557 			OperationFailedException, PermissionDeniedException {
558 		if(CourseServiceConstants.COURSE_NAMESPACE_URI.equals(refObjectTypeURI)){
559 			return luService.getVersions(LuServiceConstants.CLU_NAMESPACE_URI, refObjectId);
560 		}
561 		throw new InvalidParameterException("Object type: " + refObjectTypeURI + " is not known to this implementation");
562 	}
563 
564 	@Override
565 	public List<VersionDisplayInfo> getVersionsInDateRange(
566 			String refObjectTypeURI, String refObjectId, Date from, Date to)
567 			throws DoesNotExistException, InvalidParameterException,
568 			MissingParameterException, OperationFailedException,
569 			PermissionDeniedException {
570 		if(CourseServiceConstants.COURSE_NAMESPACE_URI.equals(refObjectTypeURI)){
571 			return luService.getVersionsInDateRange(LuServiceConstants.CLU_NAMESPACE_URI, refObjectId, from, to);
572 		}
573 		throw new InvalidParameterException("Object type: " + refObjectTypeURI + " is not known to this implementation");
574 	}
575 
576 	/**
577 	 * Check for missing parameter and throw localized exception if missing
578 	 *
579 	 * @param param
580 	 * @param parameter name
581 	 * @throws MissingParameterException
582 	 */
583 	private void checkForMissingParameter(Object param, String paramName)
584 			throws MissingParameterException {
585 		if (param == null) {
586 			throw new MissingParameterException(paramName + " can not be null");
587 		}
588 	}
589 
590 	/**
591 	 * @param courseId
592 	 * @param statementTreeViewInfo
593 	 * @return reference exists
594 	 *
595 	 * @throws InvalidParameterException
596 	 * @throws MissingParameterException
597 	 * @throws OperationFailedException
598 	 * @throws DoesNotExistException
599 	 */
600 	private RefStatementRelationInfo findStatementReference(String courseId,
601 			StatementTreeViewInfo statementTreeViewInfo)
602 			throws InvalidParameterException, MissingParameterException,
603 			OperationFailedException, DoesNotExistException {
604 		List<RefStatementRelationInfo> course = statementService.getRefStatementRelationsByRef(CourseAssemblerConstants.COURSE_TYPE, courseId);
605 		if (course != null) {
606 			for (RefStatementRelationInfo refRelation : course) {
607 				if (refRelation.getStatementId().equals(statementTreeViewInfo.getId())) {
608 					return refRelation;
609 				}
610 			}
611 		}
612 		return null;
613 	}
614 }