View Javadoc

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