Java tutorial
/** * Copyright 2005-2013 The Kuali Foundation Licensed under the * Educational Community License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. You may * obtain a copy of the License at * * http://www.osedu.org/licenses/ECL-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an "AS IS" * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing * permissions and limitations under the License. * */ package org.kuali.student.cm.course.service.impl; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.Predicate; import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.BooleanUtils; import org.apache.commons.lang.StringUtils; import org.joda.time.DateTime; import org.kuali.rice.core.api.exception.RiceIllegalStateException; import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader; import org.kuali.rice.core.api.util.ConcreteKeyValue; import org.kuali.rice.core.api.util.KeyValue; import org.kuali.rice.kim.api.KimConstants; import org.kuali.rice.kim.api.identity.PersonService; import org.kuali.rice.krad.maintenance.MaintenanceDocument; import org.kuali.rice.krad.uif.element.Action; import org.kuali.rice.krad.uif.util.LifecycleElement; import org.kuali.rice.krad.uif.view.ViewModel; import org.kuali.rice.krad.web.form.MaintenanceDocumentForm; import org.kuali.rice.krms.api.repository.reference.ReferenceObjectBinding; import org.kuali.rice.krms.dto.AgendaEditor; import org.kuali.rice.krms.dto.AgendaTypeInfo; import org.kuali.rice.krms.service.RuleViewHelperService; import org.kuali.student.cm.common.util.CurriculumManagementConstants; import org.kuali.student.cm.course.form.wrapper.ActivityInfoWrapper; import org.kuali.student.cm.course.form.wrapper.CluInstructorInfoWrapper; import org.kuali.student.cm.course.form.wrapper.CourseCompareCollectionElement; import org.kuali.student.cm.course.form.wrapper.CourseCreateUnitsContentOwner; import org.kuali.student.cm.course.form.wrapper.CourseInfoWrapper; import org.kuali.student.cm.course.form.wrapper.CourseJointInfoWrapper; import org.kuali.student.cm.course.form.wrapper.FormatInfoWrapper; import org.kuali.student.cm.course.form.wrapper.LoCategoryInfoWrapper; import org.kuali.student.cm.course.form.wrapper.LoDisplayInfoWrapper; import org.kuali.student.cm.course.form.wrapper.LoDisplayWrapperModel; import org.kuali.student.cm.course.form.wrapper.OrganizationInfoWrapper; import org.kuali.student.cm.course.form.wrapper.OutcomeReviewSection; import org.kuali.student.cm.course.form.wrapper.ResultValuesGroupInfoWrapper; import org.kuali.student.cm.course.form.wrapper.ReviewProposalDisplay; import org.kuali.student.cm.course.form.wrapper.SubjectCodeWrapper; import org.kuali.student.cm.course.service.CourseCopyHelper; import org.kuali.student.cm.course.service.CourseMaintainable; import org.kuali.student.cm.course.service.util.CourseCodeSearchUtil; import org.kuali.student.cm.course.service.util.LoCategorySearchUtil; import org.kuali.student.cm.course.service.util.OrganizationSearchUtil; import org.kuali.student.cm.course.util.CourseProposalUtil; import org.kuali.student.cm.proposal.form.wrapper.ProposalElementsWrapper; import org.kuali.student.cm.proposal.service.ProposalMaintainable; import org.kuali.student.common.collection.KSCollectionUtils; import org.kuali.student.common.util.security.ContextUtils; import org.kuali.student.lum.lu.ui.course.keyvalues.OrgsBySubjectCodeValuesFinder; import org.kuali.student.lum.lu.ui.krms.dto.CluInformation; import org.kuali.student.lum.lu.ui.krms.util.CluInformationHelper; import org.kuali.student.lum.constants.ProgramConstants; import org.kuali.student.r1.core.personsearch.service.impl.QuickViewByGivenName; import org.kuali.student.r2.common.constants.CommonServiceConstants; import org.kuali.student.r2.common.dto.AttributeInfo; import org.kuali.student.r2.common.dto.ContextInfo; import org.kuali.student.r2.common.dto.DtoConstants; import org.kuali.student.r2.common.exceptions.DataValidationErrorException; import org.kuali.student.r2.common.exceptions.DoesNotExistException; import org.kuali.student.r2.common.util.AttributeHelper; import org.kuali.student.r2.common.util.constants.LearningObjectiveServiceConstants; import org.kuali.student.r2.core.class1.type.dto.TypeInfo; import org.kuali.student.r2.core.class1.type.service.TypeService; import org.kuali.student.r2.core.constants.EnumerationManagementServiceConstants; import org.kuali.student.r2.core.constants.KSKRMSServiceConstants; import org.kuali.student.r2.core.constants.ProposalServiceConstants; import org.kuali.student.r2.core.constants.TypeServiceConstants; import org.kuali.student.r2.core.enumerationmanagement.dto.EnumeratedValueInfo; import org.kuali.student.r2.core.enumerationmanagement.service.EnumerationManagementService; import org.kuali.student.r2.core.organization.dto.OrgInfo; import org.kuali.student.r2.core.organization.service.OrganizationService; import org.kuali.student.r2.core.proposal.dto.ProposalInfo; import org.kuali.student.r2.core.search.dto.SearchParamInfo; import org.kuali.student.r2.core.search.dto.SearchRequestInfo; import org.kuali.student.r2.core.search.dto.SearchResultCellInfo; import org.kuali.student.r2.core.search.dto.SearchResultInfo; import org.kuali.student.r2.core.search.dto.SearchResultRowInfo; import org.kuali.student.r2.lum.clu.dto.CluInstructorInfo; import org.kuali.student.r2.lum.clu.dto.MembershipQueryInfo; import org.kuali.student.r2.lum.clu.service.CluService; import org.kuali.student.r2.lum.course.dto.ActivityInfo; import org.kuali.student.r2.lum.course.dto.CourseCrossListingInfo; import org.kuali.student.r2.lum.course.dto.CourseInfo; import org.kuali.student.r2.lum.course.dto.CourseJointInfo; import org.kuali.student.r2.lum.course.dto.CourseVariationInfo; import org.kuali.student.r2.lum.course.dto.FormatInfo; import org.kuali.student.r2.lum.course.dto.LoDisplayInfo; import org.kuali.student.r2.lum.lo.dto.LoCategoryInfo; import org.kuali.student.r2.lum.lo.service.LearningObjectiveService; import org.kuali.student.r2.lum.lrc.dto.ResultValueRangeInfo; import org.kuali.student.r2.lum.lrc.dto.ResultValuesGroupInfo; import org.kuali.student.r2.lum.lrc.service.LRCService; import org.kuali.student.r2.lum.util.constants.CluServiceConstants; import org.kuali.student.r2.lum.util.constants.CourseServiceConstants; import org.kuali.student.r2.lum.util.constants.LrcServiceConstants; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.BeanUtils; import javax.xml.namespace.QName; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Date; import java.util.List; import java.util.Map; import static org.kuali.student.cm.common.util.CMUtils.getCluService; import static org.kuali.student.cm.course.util.CourseProposalUtil.isCurrentVersionOfCourse; /** * Base view helper service for both create and edit course info presentations. * * @author OpenCollab/rSmart KRAD CM Conversion Alliance! */ public class CourseMaintainableImpl extends CommonCourseMaintainableImpl implements CourseMaintainable, RuleViewHelperService { private static final Logger LOG = LoggerFactory.getLogger(CourseMaintainableImpl.class); protected transient static final String CREDIT_COURSE_CLU_TYPE_KEY = "kuali.lu.typeKey.CreditCourse"; private static final long serialVersionUID = 1338662637708570500L; private transient OrganizationService organizationService; private transient CluService cluService; private transient LearningObjectiveService learningObjectiveService; private transient TypeService typeService; private transient LRCService lrcService; private transient EnumerationManagementService enumerationManagementService; private PersonService personService; private CluInformationHelper cluInfoHelper; private CourseCopyHelper courseCopyHelper; /** * Method called when queryMethodToCall is executed for Administering Organizations in order to suggest back to the user an Administering Organization * * @param organizationName * @see org.kuali.student.cm.course.service.CourseMaintainable#getOrganizationsForSuggest(String) */ public List<OrganizationInfoWrapper> getOrganizationsForSuggest(final String organizationName) { return OrganizationSearchUtil.searchForOrganizations(organizationName, getOrganizationService()); } protected SearchResultInfo getInstructorsSearchResult(List<SearchParamInfo> queryParamValueList) throws Exception { SearchRequestInfo searchRequest = new SearchRequestInfo(); searchRequest.setSearchKey(QuickViewByGivenName.SEARCH_TYPE); searchRequest.setParams(queryParamValueList); searchRequest.setStartAt(0); searchRequest.setNeededTotalResults(false); searchRequest.setSortColumn(QuickViewByGivenName.DISPLAY_NAME_RESULT); SearchResultInfo searchResult = null; searchResult = getSearchService().search(searchRequest, ContextUtils.createDefaultContextInfo()); return searchResult; } private List<CluInstructorInfoWrapper> getInstructorsFromSearchResult(SearchResultInfo searchResult) { List<CluInstructorInfoWrapper> cluInstructorInfoDisplays = new ArrayList<CluInstructorInfoWrapper>(); for (SearchResultRowInfo result : searchResult.getRows()) { List<SearchResultCellInfo> cells = result.getCells(); CluInstructorInfoWrapper cluInstructorInfoDisplay = new CluInstructorInfoWrapper(); for (SearchResultCellInfo cell : cells) { if (QuickViewByGivenName.GIVEN_NAME_RESULT.equals(cell.getKey())) { cluInstructorInfoDisplay.setGivenName(cell.getValue()); } else if (QuickViewByGivenName.PERSON_ID_RESULT.equals(cell.getKey())) { cluInstructorInfoDisplay.setPersonId(cell.getValue()); } else if (QuickViewByGivenName.ENTITY_ID_RESULT.equals(cell.getKey())) { cluInstructorInfoDisplay.setId(cell.getValue()); } else if (QuickViewByGivenName.PRINCIPAL_NAME_RESULT.equals(cell.getKey())) { cluInstructorInfoDisplay.setPrincipalName(cell.getValue()); } else if (QuickViewByGivenName.DISPLAY_NAME_RESULT.equals(cell.getKey())) { cluInstructorInfoDisplay.setDisplayName(cell.getValue()); } } cluInstructorInfoDisplays.add(cluInstructorInfoDisplay); } return cluInstructorInfoDisplays; } public List<CluInstructorInfoWrapper> getInstructorsById(String id) { List<CluInstructorInfoWrapper> cluInstructorInfoDisplays = new ArrayList<CluInstructorInfoWrapper>(); SearchResultInfo searchResult = null; List<SearchParamInfo> queryParamValueList = new ArrayList<SearchParamInfo>(); SearchParamInfo displayNameParam = new SearchParamInfo(); try { displayNameParam.setKey(QuickViewByGivenName.ID_PARAM); displayNameParam.getValues().add(id); queryParamValueList.add(displayNameParam); searchResult = getInstructorsSearchResult(queryParamValueList); cluInstructorInfoDisplays = getInstructorsFromSearchResult(searchResult); } catch (Exception e) { throw new RuntimeException("No Instructor found for given ID :" + id, e); } return cluInstructorInfoDisplays; } /** * @see org.kuali.student.cm.course.service.CourseMaintainable#getInstructorsForSuggest(String) */ public List<CluInstructorInfoWrapper> getInstructorsForSuggest(String instructorName) { List<CluInstructorInfoWrapper> cluInstructorInfoDisplays = new ArrayList<CluInstructorInfoWrapper>(); List<SearchParamInfo> queryParamValueList = new ArrayList<SearchParamInfo>(); SearchParamInfo displayNameParam = new SearchParamInfo(); SearchResultInfo searchResult = null; try { displayNameParam.setKey(QuickViewByGivenName.NAME_PARAM); displayNameParam.getValues().add(instructorName.toUpperCase()); queryParamValueList.add(displayNameParam); searchResult = getInstructorsSearchResult(queryParamValueList); cluInstructorInfoDisplays = getInstructorsFromSearchResult(searchResult); } catch (Exception e) { LOG.error("An error occurred in the getInstructorsForSuggest method", e); } return cluInstructorInfoDisplays; } public LoDisplayWrapperModel getLoDisplayWrapperModel() { if (loDisplayWrapperModel == null) { loDisplayWrapperModel = new LoDisplayWrapperModel(); } return loDisplayWrapperModel; } public void setLoDisplayWrapperModel(LoDisplayWrapperModel loDisplayWrapperModel) { this.loDisplayWrapperModel = loDisplayWrapperModel; } private LoDisplayWrapperModel loDisplayWrapperModel; /** * @see org.kuali.student.cm.course.service.CourseMaintainable#getSubjectCodesForSuggest(String) */ public List<SubjectCodeWrapper> getSubjectCodesForSuggest(String subjectCode) { List<SubjectCodeWrapper> retrievedCodes = new ArrayList<SubjectCodeWrapper>(); List<SearchParamInfo> queryParamValueList = new ArrayList<SearchParamInfo>(); SearchParamInfo codeParam = new SearchParamInfo(); codeParam.setKey(CourseServiceConstants.SUBJECTCODE_CODE_PARAM); List<String> codeValues = new ArrayList<String>(); codeValues.add(subjectCode); codeParam.setValues(codeValues); queryParamValueList.add(codeParam); SearchRequestInfo searchRequest = new SearchRequestInfo(); searchRequest.setSearchKey(CourseServiceConstants.SUBJECTCODE_GENERIC_SEARCH); searchRequest.setParams(queryParamValueList); SearchResultInfo searchResult = null; try { searchResult = getSubjectCodeService().search(searchRequest, ContextUtils.createDefaultContextInfo()); for (SearchResultRowInfo result : searchResult.getRows()) { List<SearchResultCellInfo> cells = result.getCells(); String id = ""; String code = ""; for (SearchResultCellInfo cell : cells) { if (CourseServiceConstants.SUBJECTCODE_ID_RESULT.equals(cell.getKey())) { id = cell.getValue(); } else if (CourseServiceConstants.SUBJECTCODE_CODE_RESULT.equals(cell.getKey())) { code = cell.getValue(); } } retrievedCodes.add(new SubjectCodeWrapper(id, code)); } } catch (Exception e) { LOG.error("An error occurred retrieving the SubjectCodeDisplay", e); } return retrievedCodes; } @Override public List<CourseJointInfoWrapper> searchForJointOfferingCourses(String courseNumber) { return CourseCodeSearchUtil.searchForCourseJointInfos(courseNumber, getCluService()); } @Override public List<LoCategoryInfoWrapper> searchForLoCategories(String categoryName) { return LoCategorySearchUtil.searchForLoCategories(categoryName, getLearningObjectiveService()); } @SuppressWarnings("deprecation") @Override protected boolean performAddLineValidation(ViewModel viewModel, Object newLine, String collectionId, String collectionPath) { boolean returnValue = super.performAddLineValidation(viewModel, newLine, collectionId, collectionPath); // if return value is false then something failed in the parent class so just return false if (!returnValue) { return false; } if (newLine instanceof CourseCreateUnitsContentOwner) { MaintenanceDocumentForm modelForm = (MaintenanceDocumentForm) viewModel; CourseInfoWrapper courseInfoWrapper = (CourseInfoWrapper) modelForm.getDocument() .getNewMaintainableObject().getDataObject(); for (CourseCreateUnitsContentOwner unitsContentOwner : courseInfoWrapper.getUnitsContentOwner()) { if (StringUtils.isBlank(unitsContentOwner.getOrgId())) { return false; } } } else if (newLine instanceof LoCategoryInfo) { LoCategoryInfo loCategoryInfo = (LoCategoryInfo) newLine; boolean isCategoryAlreadyExist = false; if (StringUtils.isNotBlank(loCategoryInfo.getName())) { String categoryType = loCategoryInfo.getTypeKey(); String categoryName = loCategoryInfo.getName(); //If it's a new category, then user has to select the type. For the one selected from autosuggest, //name always include the type in the format "<name> - <type>". We need to split that to get the //name and type here if (StringUtils.isBlank(categoryType)) { categoryType = StringUtils.substringAfterLast(loCategoryInfo.getName(), "-").trim(); categoryName = StringUtils.substringBeforeLast(loCategoryInfo.getName(), "-").trim(); } //Check if Category is an existing one or a new. if (StringUtils.isNotBlank(categoryName)) { List<LoCategoryInfoWrapper> loCategoryInfoWrapper = searchForLoCategories(categoryName); if (loCategoryInfoWrapper != null && !loCategoryInfoWrapper.isEmpty()) { //Check against the each existing category and its type for (LoCategoryInfoWrapper loCategoryInfoWrap : loCategoryInfoWrapper) { if (loCategoryInfoWrap.getName().equals(categoryName) && loCategoryInfoWrap.getTypeName().equals(categoryType)) { //get the complete category record LoCategoryInfo origLoCat = (LoCategoryInfo) loCategoryInfoWrap; BeanUtils.copyProperties(origLoCat, loCategoryInfo); isCategoryAlreadyExist = true; break; } } } if (!isCategoryAlreadyExist) { //if category doesn't exist then create newly. loCategoryInfo.setStateKey(CurriculumManagementConstants.STATE_KEY_ACTIVE); loCategoryInfo.setLoRepositoryKey( CurriculumManagementConstants.KUALI_LO_REPOSITORY_KEY_SINGLE_USE); try { LoCategoryInfo savedLoCat = getLearningObjectiveService().createLoCategory( loCategoryInfo.getTypeKey(), loCategoryInfo, ContextUtils.createDefaultContextInfo()); BeanUtils.copyProperties(savedLoCat, loCategoryInfo); } catch (DataValidationErrorException e) { LOG.error( "An error occurred while trying to create a duplicate Learning Objective Category", e); } catch (Exception e) { LOG.error("An error occurred while trying to create a new Learning Objective Category", e); } } try { //Get the type info TypeInfo typeInfo = getLearningObjectiveService().getLoCategoryType( loCategoryInfo.getTypeKey(), ContextUtils.createDefaultContextInfo()); loCategoryInfo.setName((new StringBuilder().append(loCategoryInfo.getName()).append(" - ") .append(typeInfo.getName()).toString())); } catch (Exception e) { LOG.error("An error occurred while retrieving the LoCategoryType", e); } } else { return false; } } else { return false; } } return true; } @Override public void processMultipleValueLookupResults(ViewModel model, String collectionId, String collectionPath, String multiValueReturnFields, String lookupResultValues) { super.processMultipleValueLookupResults(model, collectionId, collectionPath, multiValueReturnFields, lookupResultValues); /** * If it;s LO lookup, rearrange all the line actions for LOs (indent,move etc) */ if (StringUtils.equals(collectionId, "LearningObjective-CollectionSection")) { setDataObject( ((MaintenanceDocumentForm) model).getDocument().getNewMaintainableObject().getDataObject()); setLOActions(); } } @Override public List<AgendaEditor> getAgendasForRef(String discriminatorType, String refObjectId) { // Initialize new array lists. List<AgendaEditor> agendas = new ArrayList<AgendaEditor>(); List<AgendaEditor> sortedAgendas = new ArrayList<AgendaEditor>(); if (refObjectId != null) { // Get the list of existing agendas List<ReferenceObjectBinding> refObjectsBindings = this.getRuleManagementService() .findReferenceObjectBindingsByReferenceObject(discriminatorType, refObjectId); for (ReferenceObjectBinding referenceObjectBinding : refObjectsBindings) { agendas.add(this.getAgendaEditor(referenceObjectBinding.getKrmsObjectId())); } } // Lookup existing agenda by type for (AgendaTypeInfo agendaTypeInfo : this.getTypeRelationships()) { AgendaEditor agenda = null; for (AgendaEditor existingAgenda : agendas) { if (existingAgenda.getTypeId().equals(agendaTypeInfo.getId())) { agenda = existingAgenda; break; } } if (agenda == null) { agenda = new AgendaEditor(); agenda.setTypeId(agendaTypeInfo.getId()); } agenda.setAgendaTypeInfo(agendaTypeInfo); agenda.setRuleEditors(this.getRulesForAgendas(agenda)); sortedAgendas.add(agenda); } return sortedAgendas; } protected LearningObjectiveService getLearningObjectiveService() { if (learningObjectiveService == null) { learningObjectiveService = GlobalResourceLoader.getService(new QName( LearningObjectiveServiceConstants.NAMESPACE, LearningObjectiveService.class.getSimpleName())); } return learningObjectiveService; } protected OrganizationService getOrganizationService() { if (organizationService == null) { organizationService = (OrganizationService) GlobalResourceLoader .getService(new QName("http://student.kuali.org/wsdl/organization", "OrganizationService")); } return organizationService; } @Override public void processAfterNew(MaintenanceDocument document, Map<String, String[]> requestParameters) { CourseInfoWrapper courseInfoWrapper = (CourseInfoWrapper) getDataObject(); if (courseInfoWrapper.isProposalDataUsed()) { super.processAfterNew(document, requestParameters); } if (!courseInfoWrapper.isDisableCourseDefaulting()) { courseInfoWrapper.getCourseInfo().setStateKey(DtoConstants.STATE_DRAFT); courseInfoWrapper.getCourseInfo().setEffectiveDate(new java.util.Date()); courseInfoWrapper.getCourseInfo().setTypeKey(CREDIT_COURSE_CLU_TYPE_KEY); } // We can actually get this from the workflow document initiator id. It doesn't need to be stored in the form. courseInfoWrapper.setUserId(ContextUtils.createDefaultContextInfo().getPrincipalId()); // Initialize Course Requisites courseInfoWrapper.setNamespace(KSKRMSServiceConstants.NAMESPACE_CODE); courseInfoWrapper.setRefDiscriminatorType(CourseServiceConstants.REF_OBJECT_URI_COURSE); courseInfoWrapper.setRefObjectId(courseInfoWrapper.getCourseInfo().getId()); courseInfoWrapper.setAgendas( getAgendasForRef(courseInfoWrapper.getRefDiscriminatorType(), courseInfoWrapper.getRefObjectId())); courseInfoWrapper.setLastUpdated(CurriculumManagementConstants.CM_DATE_FORMATTER.format(new DateTime())); // Initialize Curriculum Oversight if it hasn't already been. if (courseInfoWrapper.getCourseInfo().getUnitsContentOwner() == null) { courseInfoWrapper.getCourseInfo().setUnitsContentOwner(new ArrayList<String>()); } // Add a blank line for Curriculum Oversight if it is empty. if (courseInfoWrapper.getUnitsContentOwner().isEmpty()) { CourseCreateUnitsContentOwner newCourseCreateUnitsContentOwner = new CourseCreateUnitsContentOwner(); newCourseCreateUnitsContentOwner.getRenderHelper().setNewRow(true); courseInfoWrapper.getUnitsContentOwner().add(newCourseCreateUnitsContentOwner); } // Initialize Crosslistings if it hasn't already been. if (courseInfoWrapper.getCourseInfo().getCrossListings().isEmpty()) { List<CourseCrossListingInfo> crossListingInfoList = courseInfoWrapper.getCourseInfo() .getCrossListings(); crossListingInfoList.add(new CourseCrossListingInfo()); courseInfoWrapper.getCourseInfo().setCrossListings(crossListingInfoList); } // Initialize Joint Offerings if it hasn't already been. if (courseInfoWrapper.getCourseJointWrappers() == null || courseInfoWrapper.getCourseJointWrappers().isEmpty()) { List<CourseJointInfoWrapper> courseJointInfoList = courseInfoWrapper.getCourseJointWrappers(); courseJointInfoList.add(new CourseJointInfoWrapper()); courseInfoWrapper.setCourseJointWrappers(courseJointInfoList); } // Initialize Variations if it hasn't already been. if (courseInfoWrapper.getCourseInfo().getVariations().isEmpty()) { List<CourseVariationInfo> courseVariationInfoList = courseInfoWrapper.getCourseInfo().getVariations(); courseVariationInfoList.add(new CourseVariationInfo()); courseInfoWrapper.getCourseInfo().setVariations(courseVariationInfoList); } //Initialize formats/activities initializeFormat(courseInfoWrapper); //Initialize outcomes initializeOutcome(courseInfoWrapper); // Administering Organizations if (courseInfoWrapper.getAdministeringOrganizations().isEmpty()) { courseInfoWrapper.getAdministeringOrganizations().add(new OrganizationInfoWrapper()); } // Initialize Instructors if (courseInfoWrapper.getInstructorWrappers().isEmpty()) { courseInfoWrapper.getInstructorWrappers().add(new CluInstructorInfoWrapper()); } } /** * This method adds an empty Format if the format list is empty. This is needed to display a * blank row at format section at the ui. * * @param dataObject */ protected void initializeFormat(CourseInfoWrapper dataObject) { if (dataObject.getFormats().isEmpty()) { FormatInfo format = new FormatInfo(); ActivityInfo activity = new ActivityInfo(); format.getActivities().add(activity); dataObject.getFormats().add(format); } } protected void initializeOutcome(CourseInfoWrapper dataObject) { if (dataObject.getCreditOptionWrappers().isEmpty()) { ResultValuesGroupInfoWrapper resultValuesGroupInfoWrapper = new ResultValuesGroupInfoWrapper(); dataObject.getCreditOptionWrappers().add(resultValuesGroupInfoWrapper); } } @Override public void processCollectionAddBlankLine(ViewModel model, String collectionId, String collectionPath) { MaintenanceDocumentForm maintenanceForm = (MaintenanceDocumentForm) model; MaintenanceDocument document = maintenanceForm.getDocument(); CourseInfoWrapper courseInfoWrapper = (CourseInfoWrapper) document.getNewMaintainableObject() .getDataObject(); if (StringUtils.endsWith(collectionPath, "unitsContentOwner")) { //Before adding a new row, just make sure all the existing rows are not editable. for (CourseCreateUnitsContentOwner existing : courseInfoWrapper.getUnitsContentOwner()) { existing.getRenderHelper().setNewRow(false); if (!existing.isUserEntered()) { populateOrgName(courseInfoWrapper.getCourseInfo().getSubjectArea(), existing); } } OrgsBySubjectCodeValuesFinder optionsFinder = new OrgsBySubjectCodeValuesFinder(); List<KeyValue> availableOptions = optionsFinder.getAvailableOrgs(courseInfoWrapper); if (!availableOptions.isEmpty()) { CourseCreateUnitsContentOwner newCourseCreateUnitsContentOwner = new CourseCreateUnitsContentOwner(); newCourseCreateUnitsContentOwner.getRenderHelper().setNewRow(true); courseInfoWrapper.getUnitsContentOwner().add(newCourseCreateUnitsContentOwner); } return; } else if (StringUtils.endsWith(collectionPath, "formats")) { FormatInfo format = new FormatInfo(); ActivityInfo activity = new ActivityInfo(); format.getActivities().add(activity); courseInfoWrapper.getFormats().add(format); return; } super.processCollectionAddBlankLine(model, collectionId, collectionPath); } /** * Updates the ReviewProposalDisplay object for the Course Proposal and refreshes remote data elements based on passed in @shouldRepopulateRemoteData param * * @param shouldRepopulateRemoteData identifies whether remote data elements like Collaborators should be refreshed */ @Override protected void updateReview(ProposalElementsWrapper proposalElementsWrapper, boolean shouldRepopulateRemoteData) { CourseInfoWrapper courseInfoWrapper = (CourseInfoWrapper) proposalElementsWrapper; CourseInfo savedCourseInfo = courseInfoWrapper.getCourseInfo(); // Update course section ReviewProposalDisplay reviewData = courseInfoWrapper.getReviewProposalDisplay(); if (reviewData == null) { reviewData = new ReviewProposalDisplay(); courseInfoWrapper.setReviewProposalDisplay(reviewData); } if (StringUtils.isBlank(courseInfoWrapper.getPreviousSubjectCode()) && StringUtils.isNotBlank(savedCourseInfo.getSubjectArea())) { courseInfoWrapper.setPreviousSubjectCode(savedCourseInfo.getSubjectArea()); } reviewData.getCourseSection().setCourseTitle(savedCourseInfo.getCourseTitle()); reviewData.getCourseSection().setTranscriptTitle(savedCourseInfo.getTranscriptTitle()); reviewData.getCourseSection().setSubjectArea(savedCourseInfo.getSubjectArea()); reviewData.getCourseSection().setCourseNumberSuffix(savedCourseInfo.getCourseNumberSuffix()); if (StringUtils.isNotBlank(courseInfoWrapper.getProposalInfo().getId())) { Date updateTime = courseInfoWrapper.getProposalInfo().getMeta().getUpdateTime(); if (updateTime != null) { courseInfoWrapper .setLastUpdated(CurriculumManagementConstants.CM_DATE_FORMATTER.format(updateTime)); } } if (savedCourseInfo.getDescr() != null) { reviewData.getCourseSection().setDescription(savedCourseInfo.getDescr().getPlain()); } reviewData.getCourseSection().getInstructors().clear(); for (CluInstructorInfoWrapper insturctorWrappers : courseInfoWrapper.getInstructorWrappers()) { reviewData.getCourseSection().getInstructors().add(insturctorWrappers.getDisplayName()); } reviewData.getCourseSection().getCrossListings().clear(); if (!savedCourseInfo.getCrossListings().isEmpty()) { for (CourseCrossListingInfo crossListingInfo : savedCourseInfo.getCrossListings()) { reviewData.getCourseSection().getCrossListings().add(crossListingInfo.getCode()); } } reviewData.getCourseSection().getJointlyOfferedCourses().clear(); if (!savedCourseInfo.getJoints().isEmpty()) { for (CourseJointInfo jointInfo : savedCourseInfo.getJoints()) { reviewData.getCourseSection().getJointlyOfferedCourses() .add(jointInfo.getSubjectArea() + jointInfo.getCourseNumberSuffix()); } } reviewData.getCourseSection().getVariations().clear(); if (!savedCourseInfo.getVariations().isEmpty()) { for (CourseVariationInfo variationInfo : savedCourseInfo.getVariations()) { if (variationInfo.getVariationCode() == null && variationInfo.getVariationTitle() == null) { reviewData.getCourseSection().getVariations().add(""); } else if (variationInfo.getVariationCode() == null) { reviewData.getCourseSection().getVariations() .add("" + ": " + variationInfo.getVariationTitle()); } else { reviewData.getCourseSection().getVariations() .add(variationInfo.getVariationCode() + ": " + variationInfo.getVariationTitle()); } } } // Update governance section reviewData.getGovernanceSection().getCampusLocations().clear(); reviewData.getGovernanceSection().getCampusLocations() .addAll(updateCampusLocations(savedCourseInfo.getCampusLocations())); reviewData.getGovernanceSection().setCurriculumOversight(buildCurriculumOversightList( savedCourseInfo.getSubjectArea(), savedCourseInfo.getUnitsContentOwner())); reviewData.getGovernanceSection().getAdministeringOrganization().clear(); for (OrganizationInfoWrapper organizationInfoWrapper : courseInfoWrapper.getAdministeringOrganizations()) { if (organizationInfoWrapper.isUserEntered()) { reviewData.getGovernanceSection().getAdministeringOrganization() .add(organizationInfoWrapper.getOrganizationName()); } } // update course logistics section reviewData.getCourseLogisticsSection().getTerms().clear(); try { for (String termType : savedCourseInfo.getTermsOffered()) { TypeInfo term = getTypeService().getType(termType, ContextUtils.createDefaultContextInfo()); reviewData.getCourseLogisticsSection().getTerms().add(term.getName()); } } catch (Exception e) { throw new RiceIllegalStateException(e); } if (savedCourseInfo.getDuration() != null && StringUtils.isNotBlank(savedCourseInfo.getDuration().getAtpDurationTypeKey())) { try { TypeInfo type = getTypeService().getType(savedCourseInfo.getDuration().getAtpDurationTypeKey(), ContextUtils.createDefaultContextInfo()); reviewData.getCourseLogisticsSection().setAtpDurationType(type.getName()); } catch (Exception e) { throw new RiceIllegalStateException(e); } } if (savedCourseInfo.getDuration() != null) { reviewData.getCourseLogisticsSection().setTimeQuantity(savedCourseInfo.getDuration().getTimeQuantity()); } reviewData.getCourseLogisticsSection().setAudit(BooleanUtils.toStringYesNo(courseInfoWrapper.isAudit())); reviewData.getCourseLogisticsSection() .setPassFail(BooleanUtils.toStringYesNo(courseInfoWrapper.isPassFail())); reviewData.getCourseLogisticsSection().setGradingOptions(buildGradingOptionsList()); reviewData.getCourseLogisticsSection().setFinalExamStatus(getFinalExamString()); reviewData.getCourseLogisticsSection() .setFinalExamStatusRationale(courseInfoWrapper.getFinalExamRationale()); reviewData.getCourseLogisticsSection().getOutcomes().clear(); for (ResultValuesGroupInfoWrapper rvg : courseInfoWrapper.getCreditOptionWrappers()) { if (StringUtils.isNotBlank(rvg.getTypeKey())) { String creditOptionType = ""; String creditOptionValue = rvg.getUiHelper().getResultValue(); if (StringUtils.equals(rvg.getTypeKey(), LrcServiceConstants.RESULT_VALUES_GROUP_TYPE_KEY_FIXED)) { creditOptionType = "Fixed"; if (StringUtils.contains(rvg.getResultValueRange().getMinValue(), "degree.")) { creditOptionValue = StringUtils.substringAfterLast(rvg.getUiHelper().getResultValue(), "degree."); } else { creditOptionValue = rvg.getUiHelper().getResultValue(); } } else if (StringUtils.equals(rvg.getTypeKey(), LrcServiceConstants.RESULT_VALUES_GROUP_TYPE_KEY_MULTIPLE)) { creditOptionType = "Multiple"; } else if (StringUtils.equals(rvg.getTypeKey(), LrcServiceConstants.RESULT_VALUES_GROUP_TYPE_KEY_RANGE)) { creditOptionType = "Range"; } reviewData.getCourseLogisticsSection().getOutcomes() .add(new OutcomeReviewSection(creditOptionType, creditOptionValue)); } } List<FormatInfoWrapper> formatInfoWrappers = new ArrayList<FormatInfoWrapper>(); for (FormatInfo formatInfo : savedCourseInfo.getFormats()) { List<ActivityInfoWrapper> activityInfoWrapperList = new ArrayList<ActivityInfoWrapper>(); for (ActivityInfo activityInfo : formatInfo.getActivities()) { Integer anticipatedClassSize = activityInfo.getDefaultEnrollmentEstimate(); String activityType = activityInfo.getTypeKey(); String contactHours = ""; String durationCount = ""; if (activityInfo.getDuration() != null) { String durationType = null; if (StringUtils.isNotBlank(activityInfo.getDuration().getAtpDurationTypeKey())) { try { TypeInfo duration = getTypeService().getType( activityInfo.getDuration().getAtpDurationTypeKey(), createContextInfo()); durationType = duration.getName(); } catch (Exception e) { throw new RuntimeException(e); } } if (activityInfo.getDuration().getTimeQuantity() != null) { durationCount = activityInfo.getDuration().getTimeQuantity().toString(); } if (StringUtils.isNotBlank(durationType)) { durationCount = durationCount + " " + durationType + CurriculumManagementConstants.COLLECTION_ITEM_PLURAL_END; } } if (activityInfo.getContactHours() != null) { String contactType = activityInfo.getContactHours().getUnitTypeKey(); contactType = StringUtils.substringAfterLast(contactType, "."); if (activityInfo.getContactHours().getUnitQuantity() != null) { contactHours = activityInfo.getContactHours().getUnitQuantity(); } if (StringUtils.isNotBlank(contactType)) { contactHours = contactHours + " per " + StringUtils.lowerCase(contactType); } } ActivityInfoWrapper activityInfoWrapper = new ActivityInfoWrapper(anticipatedClassSize, activityType, durationCount, contactHours); activityInfoWrapperList.add(activityInfoWrapper); } FormatInfoWrapper formatInfoWrapper = new FormatInfoWrapper(activityInfoWrapperList); formatInfoWrappers.add(formatInfoWrapper); } if (!formatInfoWrappers.isEmpty()) { reviewData.getCourseLogisticsSection().setFormatInfoWrappers(formatInfoWrappers); } /** * Active Dates section */ reviewData.getActiveDatesSection() .setStartTerm(getTermDesc(courseInfoWrapper.getCourseInfo().getStartTerm())); reviewData.getActiveDatesSection().setEndTerm(getTermDesc(courseInfoWrapper.getCourseInfo().getEndTerm())); reviewData.getActiveDatesSection() .setPilotCourse(BooleanUtils.toStringYesNo(courseInfoWrapper.getCourseInfo().isPilotCourse())); /** * Financials section */ // reviewData.getFinancialsSection().setFee(); // reviewData.getFinancialsSection().setExpendingOrganization(); // reviewData.getFinancialsSection().setRevenueSource(); if (savedCourseInfo.getFeeJustification() != null) { reviewData.getFinancialsSection() .setJustificationOfFees(savedCourseInfo.getFeeJustification().getPlain()); } /** * Populate 'Proposal' specific model */ if (courseInfoWrapper.isProposalDataUsed()) { updateSupportingDocumentsForReviewPages(courseInfoWrapper); updateProposalDataForReviewPages(reviewData, shouldRepopulateRemoteData); } } /** * This method populates the proposal related model which can be displayed at review proposal page * @param reviewData * @param shouldRepopulateRemoteData */ protected void updateProposalDataForReviewPages(ReviewProposalDisplay reviewData, boolean shouldRepopulateRemoteData) { CourseInfoWrapper courseInfoWrapper = (CourseInfoWrapper) getDataObject(); ProposalInfo proposalInfo = courseInfoWrapper.getProposalInfo(); reviewData.getCourseSection().setProposalName(proposalInfo.getName()); if (proposalInfo.getRationale() != null) { reviewData.getCourseSection().setRationale(proposalInfo.getRationale().getPlain()); } // update the remote elements if needed but let the method decide which to repopulate updateRemoteDataElementsForReviewPages(courseInfoWrapper, shouldRepopulateRemoteData); // update supporting Documents Section on review page copySupportingDocumentsToReviewPages(courseInfoWrapper); } protected List<String> updateCampusLocations(List<String> campusLocations) { final List<KeyValue> keyValues = new ArrayList<KeyValue>(); try { final List<EnumeratedValueInfo> enumerationInfos = getEnumerationManagementService() .getEnumeratedValues(CluServiceConstants.CAMPUS_LOCATION_ENUM_KEY, null, null, null, ContextUtils.createDefaultContextInfo()); Collections.sort(enumerationInfos, new Comparator<EnumeratedValueInfo>() { @Override public int compare(EnumeratedValueInfo o1, EnumeratedValueInfo o2) { int result = o1.getSortKey().compareToIgnoreCase(o2.getSortKey()); return result; } }); for (final EnumeratedValueInfo enumerationInfo : enumerationInfos) { keyValues.add(new ConcreteKeyValue(enumerationInfo.getCode(), enumerationInfo.getValue())); } } catch (DoesNotExistException e) { throw new RuntimeException("No subject areas found! There should be some in the database", e); } catch (Exception e) { throw new RuntimeException("Error looking up Campus Locations", e); } List<String> newCampusLocationsName = new ArrayList<String>(); for (KeyValue kval : keyValues) { if (campusLocations.contains(kval.getKey())) { newCampusLocationsName.add(kval.getValue()); } } return newCampusLocationsName; } @Override public void saveDataObject() { CourseInfoWrapper courseInfoWrapper = (CourseInfoWrapper) getDataObject(); if (courseInfoWrapper.getCourseInfo().getDescr() != null && courseInfoWrapper.getCourseInfo().getDescr().getPlain() != null) { // replacing carriage return and new line with new line char. String courseDescription = courseInfoWrapper.getCourseInfo().getDescr().getPlain().replace("\r\n", "\n"); courseInfoWrapper.getCourseInfo().getDescr().setPlain(courseDescription); } courseInfoWrapper.getCourseInfo().getInstructors().clear(); if (courseInfoWrapper.getInstructorWrappers() != null) { for (final CluInstructorInfoWrapper instructorDisplay : courseInfoWrapper.getInstructorWrappers()) { courseInfoWrapper.getCourseInfo().getInstructors().add(instructorDisplay); } } for (int count = 0; count < (courseInfoWrapper.getCourseInfo().getCrossListings().size()); count++) { courseInfoWrapper.getCourseInfo().getCrossListings().get(count) .setTypeKey(CurriculumManagementConstants.COURSE_CROSSLISTING_IDENT_TYPE); } /* * Learning Objectives */ courseInfoWrapper.getCourseInfo().getCourseSpecificLOs().clear(); if (courseInfoWrapper.getLoDisplayWrapperModel() != null && courseInfoWrapper.getLoDisplayWrapperModel().getLoWrappers() != null) { List<LoDisplayInfoWrapper> loWrappers = courseInfoWrapper.getLoDisplayWrapperModel().getLoWrappers(); List<LoDisplayInfo> courseLos = courseInfoWrapper.getCourseInfo().getCourseSpecificLOs(); courseLos.clear(); // LOs are assigned a sequence via this variable which reflects and preserves the order in which they appeared in the form. int sequence = 0; for (int i = 0; i < loWrappers.size(); i++) { LoDisplayInfoWrapper currentLo = loWrappers.get(i); if (!currentLo.isUserEntered() && (currentLo.getLoCategoryInfoList().isEmpty())) { continue; } // (Re)Set the sequence in the LoInfo dynamic attributes. new AttributeHelper(currentLo.getLoInfo().getAttributes()) .put(CurriculumManagementConstants.LoProperties.SEQUENCE, String.valueOf(sequence++)); boolean rootLevel = true; int parentIndex = i - 1; while (parentIndex >= 0) { LoDisplayInfoWrapper potentialParent = loWrappers.get(parentIndex); boolean parentMatch = currentLo.getIndentLevel() > potentialParent.getIndentLevel(); if (parentMatch) { //currentLo.setParentLoRelationid(potentialParent.getLoInfo().getId()); //currentLo.setParentRelType(CourseAssemblerConstants.COURSE_LO_RELATION_INCLUDES); potentialParent.getLoDisplayInfoList().add(currentLo); rootLevel = false; break; } else { parentIndex--; } } if (rootLevel) { courseLos.add(currentLo); } } } // Set derived course fields before saving/updating courseInfoWrapper.setCourseInfo(calculateCourseDerivedFields(courseInfoWrapper.getCourseInfo())); courseInfoWrapper.getCourseInfo().getUnitsContentOwner().clear(); for (CourseCreateUnitsContentOwner wrapper : courseInfoWrapper.getUnitsContentOwner()) { courseInfoWrapper.getCourseInfo().getUnitsContentOwner().add(wrapper.getOrgId()); wrapper.getRenderHelper().setNewRow(false); if (!wrapper.isUserEntered()) { populateOrgName(courseInfoWrapper.getCourseInfo().getSubjectArea(), wrapper); } } courseInfoWrapper.getCourseInfo().getCreditOptions().clear(); //Credit Options if (courseInfoWrapper.isAudit()) { ResultValuesGroupInfo resultValuesGroupInfo = new ResultValuesGroupInfo(); resultValuesGroupInfo.setName("Audit"); resultValuesGroupInfo.setTypeKey(LrcServiceConstants.RESULT_GROUP_KEY_GRADE_AUDIT); //This should be based on the course state. But for now, it's draft resultValuesGroupInfo.setStateKey(LrcServiceConstants.RESULT_GROUPS_STATE_DRAFT); courseInfoWrapper.getCourseInfo().getCreditOptions().add(resultValuesGroupInfo); } populateAuditOnDTO(); populatePassFailOnDTO(); populateFinalExamOnDTO(); populateOutComesOnDTO(); populateFormatOnDTO(); populateJointCourseOnDTO(); try { LOG.info("Saving Proposal for course {}", courseInfoWrapper.getCourseInfo().getId()); updateAndSaveCourseInfo(); } catch (Exception e) { throw new RuntimeException(e); } courseInfoWrapper.setNamespace(KSKRMSServiceConstants.NAMESPACE_CODE); courseInfoWrapper.setRefDiscriminatorType(CourseServiceConstants.REF_OBJECT_URI_COURSE); courseInfoWrapper.setRefObjectId(courseInfoWrapper.getCourseInfo().getId()); super.saveDataObject(); // now that we've saved the proposal in the super call... we can try to update the updateTime if (StringUtils.isNotBlank(courseInfoWrapper.getProposalInfo().getId())) { Date updateTime = courseInfoWrapper.getProposalInfo().getMeta().getUpdateTime(); if (updateTime != null) { courseInfoWrapper .setLastUpdated(CurriculumManagementConstants.CM_DATE_FORMATTER.format(updateTime)); } } else { courseInfoWrapper .setLastUpdated(CurriculumManagementConstants.CM_DATE_FORMATTER.format(new DateTime())); } } /** * This method creates <class>CourseJointInfoWrapper</class> instances from <class>CourseJointInfo</class> instance */ protected void populateJointCourseOnDTO() { CourseInfoWrapper courseInfoWrapper = (CourseInfoWrapper) getDataObject(); courseInfoWrapper.getCourseInfo().getJoints().clear(); for (final CourseJointInfoWrapper jointInfoDisplay : courseInfoWrapper.getCourseJointWrappers()) { if (jointInfoDisplay.isUserEntered()) { courseInfoWrapper.getCourseInfo().getJoints().add(jointInfoDisplay); } } } protected void populateOutComesOnDTO() { CourseInfoWrapper courseInfoWrapper = (CourseInfoWrapper) getDataObject(); for (ResultValuesGroupInfoWrapper rvgWrapper : courseInfoWrapper.getCreditOptionWrappers()) { if (!rvgWrapper.isUserEntered()) { continue; } ResultValuesGroupInfo rvg = rvgWrapper.getResultValuesGroupInfo(); if (rvg == null) { rvg = new ResultValuesGroupInfo(); rvgWrapper.setResultValuesGroupInfo(rvg); } rvg.setTypeKey(rvgWrapper.getTypeKey()); rvg.setStateKey(LrcServiceConstants.RESULT_GROUPS_STATE_DRAFT); courseInfoWrapper.getCourseInfo().getCreditOptions().add(rvg); if (StringUtils.equals(rvgWrapper.getTypeKey(), LrcServiceConstants.RESULT_VALUES_GROUP_TYPE_KEY_FIXED)) { ResultValueRangeInfo range = new ResultValueRangeInfo(); range.setMinValue(rvgWrapper.getUiHelper().getResultValue()); rvg.setResultValueRange(range); rvg.setTypeKey(rvgWrapper.getTypeKey()); } else if (StringUtils.equals(rvgWrapper.getTypeKey(), LrcServiceConstants.RESULT_VALUES_GROUP_TYPE_KEY_MULTIPLE)) { String[] resultValues = StringUtils.split(rvgWrapper.getUiHelper().getResultValue(), ","); rvg.getResultValueKeys().clear(); for (String result : resultValues) { StringBuilder builder = new StringBuilder( LrcServiceConstants.RESULT_VALUE_KEY_CREDIT_DEGREE_PREFIX); float floatValue = Float.valueOf(result); builder.append(floatValue); rvg.getResultValueKeys().add(builder.toString()); rvg.setTypeKey(rvgWrapper.getTypeKey()); } } else if (StringUtils.equals(rvgWrapper.getTypeKey(), LrcServiceConstants.RESULT_VALUES_GROUP_TYPE_KEY_RANGE)) { ResultValueRangeInfo range = new ResultValueRangeInfo(); range.setMinValue(StringUtils.substringBefore(rvgWrapper.getUiHelper().getResultValue(), "-")); range.setMaxValue(StringUtils.substringAfter(rvgWrapper.getUiHelper().getResultValue(), "-")); rvg.setResultValueRange(range); rvg.setTypeKey(rvgWrapper.getTypeKey()); } } initializeOutcome(courseInfoWrapper); } /** * Populates format/activity to course dto to save */ protected void populateFormatOnDTO() { CourseInfoWrapper courseInfoWrapper = (CourseInfoWrapper) getDataObject(); courseInfoWrapper.getCourseInfo().getFormats().clear(); List<ActivityInfo> activities; for (FormatInfo format : courseInfoWrapper.getFormats()) { activities = new ArrayList<ActivityInfo>(); if (!isEmptyFormat(format)) { if (StringUtils.isBlank(format.getId())) { // If it's new format.setState(DtoConstants.STATE_DRAFT); if (StringUtils.isBlank(format.getTypeKey())) { format.setTypeKey(CluServiceConstants.COURSE_FORMAT_TYPE_KEY); } } for (ActivityInfo activity : format.getActivities()) { if (StringUtils.isBlank(activity.getId())) { // If it's new activity.setState(DtoConstants.STATE_DRAFT); } // blank activities are removed from the list. if (activity.getId() == null && (activity.getTypeKey() == null)) { continue; } // only non blank activities are added to the list activities.add(activity); } format.getActivities().clear(); format.setActivities(activities); courseInfoWrapper.getCourseInfo().getFormats().add(format); } } } /** * This method checks whether a format is empty or not by checking all the activities type. * * @param format * @return */ protected boolean isEmptyFormat(FormatInfo format) { for (ActivityInfo activity : format.getActivities()) { if (StringUtils.isNotBlank(activity.getTypeKey())) { return false; } } return true; } protected void populateOutComesOnWrapper() { CourseInfoWrapper courseInfoWrapper = (CourseInfoWrapper) getDataObject(); courseInfoWrapper.getCreditOptionWrappers().clear(); for (ResultValuesGroupInfo rvg : courseInfoWrapper.getCourseInfo().getCreditOptions()) { ResultValuesGroupInfoWrapper rvgWrapper = new ResultValuesGroupInfoWrapper(); BeanUtils.copyProperties(rvg, rvgWrapper); rvgWrapper.setResultValuesGroupInfo(rvg); if (StringUtils.equals(rvg.getTypeKey(), LrcServiceConstants.RESULT_VALUES_GROUP_TYPE_KEY_MULTIPLE)) { StringBuilder resultValue = new StringBuilder(""); List<String> resultValueList = new ArrayList<String>(); for (String rvKey : rvg.getResultValueKeys()) { String value = StringUtils.strip(rvKey, LrcServiceConstants.RESULT_VALUE_KEY_CREDIT_DEGREE_PREFIX); resultValueList.add(StringUtils.remove(value, ".0")); // This can be only be integer at ui. } // Sort the values to be displayed at ui Collections.sort(resultValueList); rvgWrapper.getUiHelper().setResultValue(StringUtils.join(resultValueList, ",")); } else if (StringUtils.equals(rvg.getTypeKey(), LrcServiceConstants.RESULT_VALUES_GROUP_TYPE_KEY_RANGE)) { String minValue = StringUtils.remove(rvg.getResultValueRange().getMinValue(), ".0"); // This can be only be integer at ui. String maxValue = StringUtils.remove(rvg.getResultValueRange().getMaxValue(), ".0"); // This can be only be integer at ui. rvgWrapper.getUiHelper().setResultValue(minValue + "-" + maxValue); } else if (StringUtils.equals(rvg.getTypeKey(), LrcServiceConstants.RESULT_VALUES_GROUP_TYPE_KEY_FIXED)) { rvgWrapper.getUiHelper() .setResultValue(StringUtils.remove(rvg.getResultValueRange().getMinValue(), ".0")); } courseInfoWrapper.getCreditOptionWrappers().add(rvgWrapper); } Collections.sort(courseInfoWrapper.getCreditOptionWrappers(), new Comparator<ResultValuesGroupInfoWrapper>() { public int compare(ResultValuesGroupInfoWrapper a, ResultValuesGroupInfoWrapper b) { if (a.getTypeKey() == null) { return 1; } else if (b.getTypeKey() == null) { return -1; } return a.getTypeKey().compareToIgnoreCase(b.getTypeKey()); } }); initializeOutcome(courseInfoWrapper); } protected void populateFormatOnWrapper() { CourseInfoWrapper courseInfoWrapper = (CourseInfoWrapper) getDataObject(); courseInfoWrapper.getFormats().clear(); courseInfoWrapper.getFormats().addAll(courseInfoWrapper.getCourseInfo().getFormats()); initializeFormat(courseInfoWrapper); } protected void populatePassFailOnDTO() { CourseInfoWrapper courseInfoWrapper = (CourseInfoWrapper) getDataObject(); AttributeInfo passFailAttr = null; for (AttributeInfo attr : courseInfoWrapper.getCourseInfo().getAttributes()) { if (StringUtils.equals(attr.getKey(), CurriculumManagementConstants.COURSE_RESULT_COMP_ATTR_PASSFAIL)) { passFailAttr = attr; break; } } if (passFailAttr == null) { passFailAttr = new AttributeInfo(); passFailAttr.setKey(CurriculumManagementConstants.COURSE_RESULT_COMP_ATTR_PASSFAIL); courseInfoWrapper.getCourseInfo().getAttributes().add(passFailAttr); } passFailAttr.setValue(BooleanUtils.toStringTrueFalse(courseInfoWrapper.isPassFail())); } protected void populatePassFailOnWrapper() { CourseInfoWrapper courseInfoWrapper = (CourseInfoWrapper) getDataObject(); for (AttributeInfo attr : courseInfoWrapper.getCourseInfo().getAttributes()) { if (StringUtils.equals(attr.getKey(), CurriculumManagementConstants.COURSE_RESULT_COMP_ATTR_PASSFAIL)) { courseInfoWrapper.setPassFail(BooleanUtils.toBoolean(attr.getValue())); break; } } } protected void populateAuditOnDTO() { CourseInfoWrapper courseInfoWrapper = (CourseInfoWrapper) getDataObject(); AttributeInfo auditAttr = null; for (AttributeInfo attr : courseInfoWrapper.getCourseInfo().getAttributes()) { if (StringUtils.equals(attr.getKey(), CurriculumManagementConstants.COURSE_RESULT_COMP_ATTR_AUDIT)) { auditAttr = attr; break; } } if (auditAttr == null) { auditAttr = new AttributeInfo(); auditAttr.setKey(CurriculumManagementConstants.COURSE_RESULT_COMP_ATTR_AUDIT); courseInfoWrapper.getCourseInfo().getAttributes().add(auditAttr); } auditAttr.setValue(BooleanUtils.toStringTrueFalse(courseInfoWrapper.isAudit())); } protected void populateAuditOnWrapper() { CourseInfoWrapper courseInfoWrapper = (CourseInfoWrapper) getDataObject(); for (AttributeInfo attr : courseInfoWrapper.getCourseInfo().getAttributes()) { if (StringUtils.equals(attr.getKey(), CurriculumManagementConstants.COURSE_RESULT_COMP_ATTR_AUDIT)) { courseInfoWrapper.setAudit(BooleanUtils.toBoolean(attr.getValue())); break; } } } protected void populateFinalExamOnDTO() { CourseInfoWrapper courseInfoWrapper = (CourseInfoWrapper) getDataObject(); AttributeInfo finalExamStatusDetail = null; AttributeInfo finalExamRationalDetail = null; for (AttributeInfo attr : courseInfoWrapper.getCourseInfo().getAttributes()) { if (StringUtils.equals(attr.getKey(), CourseServiceConstants.FINAL_EXAM)) { finalExamStatusDetail = attr; } else if (StringUtils.equals(attr.getKey(), CourseServiceConstants.FINAL_EXAM_RATIONALE)) { finalExamRationalDetail = attr; } } if (finalExamStatusDetail == null) { finalExamStatusDetail = new AttributeInfo(); finalExamStatusDetail.setKey(CourseServiceConstants.FINAL_EXAM); courseInfoWrapper.getCourseInfo().getAttributes().add(finalExamStatusDetail); } if (StringUtils.isNotBlank(courseInfoWrapper.getFinalExamStatus()) && !StringUtils .equals(courseInfoWrapper.getFinalExamStatus(), CourseServiceConstants.STD_EXAM_FINAL_ENUM_KEY) && finalExamRationalDetail == null) { finalExamRationalDetail = new AttributeInfo(); finalExamRationalDetail.setKey(CourseServiceConstants.FINAL_EXAM_RATIONALE); courseInfoWrapper.getCourseInfo().getAttributes().add(finalExamRationalDetail); } if (finalExamRationalDetail != null) { finalExamRationalDetail.setValue(courseInfoWrapper.getFinalExamRationale()); } finalExamStatusDetail.setValue(courseInfoWrapper.getFinalExamStatus()); } protected void populateFinalExamOnWrapper() { CourseInfoWrapper courseInfoWrapper = (CourseInfoWrapper) getDataObject(); for (AttributeInfo attr : courseInfoWrapper.getCourseInfo().getAttributes()) { if (StringUtils.equals(attr.getKey(), CourseServiceConstants.FINAL_EXAM)) { courseInfoWrapper.setFinalExamStatus(attr.getValue()); } else if (StringUtils.equals(attr.getKey(), CourseServiceConstants.FINAL_EXAM_RATIONALE)) { courseInfoWrapper.setFinalExamRationale(attr.getValue()); } } } /** * @return List list of grading options. */ protected List<String> buildGradingOptionsList() { List<String> gradingOptions = new ArrayList<String>(); CourseInfoWrapper courseInfoWrapper = (CourseInfoWrapper) getDataObject(); if (!courseInfoWrapper.getCourseInfo().getGradingOptions().isEmpty()) { try { List<ResultValuesGroupInfo> rvgs = getLRCService().getResultValuesGroupsByKeys( courseInfoWrapper.getCourseInfo().getGradingOptions(), createContextInfo()); for (ResultValuesGroupInfo rvg : rvgs) { gradingOptions.add(rvg.getName()); } } catch (Exception e) { throw new RuntimeException(e); } } return gradingOptions; } protected String getFinalExamString() { CourseInfoWrapper courseInfoWrapper = (CourseInfoWrapper) getDataObject(); if (StringUtils.isNotBlank(courseInfoWrapper.getFinalExamStatus())) { List<EnumeratedValueInfo> enumerationInfos = null; try { enumerationInfos = getEnumerationManagementService().getEnumeratedValues( CluServiceConstants.FINAL_EXAM_STATUS_ENUM_KEY, null, null, null, ContextUtils.createDefaultContextInfo()); for (EnumeratedValueInfo enumerationInfo : enumerationInfos) { if (StringUtils.equals(courseInfoWrapper.getFinalExamStatus(), enumerationInfo.getCode())) { return enumerationInfo.getValue(); } } } catch (Exception e) { throw new RuntimeException(e); } } return ""; } /** * Converts the display name of the instructor into the plain user name (for use in a search query) * * @param displayName The display name of the instructor. * @return The user name of the instructor. */ protected String getInstructorSearchString(String displayName) { if (displayName == null) { return StringUtils.EMPTY; } String searchString = ""; if (displayName.contains("(") && displayName.contains(")")) { searchString = displayName.substring(displayName.lastIndexOf('(') + 1, displayName.lastIndexOf(')')); } return searchString; } /** * Copied this method from CourseDataService. * This calculates and sets fields on course object that are derived from other course object fields. */ protected CourseInfo calculateCourseDerivedFields(CourseInfo courseInfo) { // Course code is not populated in UI, need to derive them from the subject area and suffix fields if (StringUtils.isNotBlank(courseInfo.getCourseNumberSuffix()) && StringUtils.isNotBlank(courseInfo.getSubjectArea())) { courseInfo .setCode(calculateCourseCode(courseInfo.getSubjectArea(), courseInfo.getCourseNumberSuffix())); } // Derive course code for crosslistings for (CourseCrossListingInfo crossListing : courseInfo.getCrossListings()) { if (StringUtils.isNotBlank(crossListing.getCourseNumberSuffix()) && StringUtils.isNotBlank(crossListing.getSubjectArea())) { crossListing.setCode( calculateCourseCode(crossListing.getSubjectArea(), crossListing.getCourseNumberSuffix())); } } return courseInfo; } /** * Copied this method from CourseDataService * This method calculates code for course and cross listed course. * * @param subjectArea * @param suffixNumber * @return */ protected String calculateCourseCode(final String subjectArea, final String suffixNumber) { return subjectArea + suffixNumber; } public void retrieveWrapperDataObject() { CourseInfoWrapper dataObject = (CourseInfoWrapper) getDataObject(); try { populateCourseAndReviewData(dataObject, false); } catch (Exception e) { throw new RuntimeException("Caught Exception while populating Course data", e); } } /** * Loads the data object for the maintenance view. */ public void retrieveDataObject() { super.retrieveDataObject(); CourseInfoWrapper dataObject = (CourseInfoWrapper) getDataObject(); CourseInfo course = null; try { course = getCourseService().getCourse(dataObject.getProposalInfo().getProposalReference().get(0), createContextInfo()); dataObject.setCourseInfo(course); } catch (Exception e) { throw new RuntimeException(e); } } /** * Populates the wrapper objects used on the create course proposal and course view pages. * * @param proposalElementsWrapper The wrapper to populate. */ @Override public void populateWrapperData(ProposalElementsWrapper proposalElementsWrapper) throws Exception { CourseInfoWrapper courseWrapper = (CourseInfoWrapper) proposalElementsWrapper; CourseInfo course = courseWrapper.getCourseInfo(); /* * Instructors */ courseWrapper.getInstructorWrappers().clear(); for (CluInstructorInfo instructorInfo : course.getInstructors()) { List<CluInstructorInfoWrapper> cluInstructorInfoWrapperList = getInstructorsById( instructorInfo.getPersonId()); CluInstructorInfoWrapper cluInstructorInfoWrapper = KSCollectionUtils .getRequiredZeroElement(cluInstructorInfoWrapperList); cluInstructorInfoWrapper.setId(instructorInfo.getId()); courseWrapper.getInstructorWrappers().add(cluInstructorInfoWrapper); } // Add an empty line if (courseWrapper.getInstructorWrappers().isEmpty()) { courseWrapper.getInstructorWrappers().add(new CluInstructorInfoWrapper()); } /* * Administering Organizations */ courseWrapper.getAdministeringOrganizations().clear(); for (String unitDeployment : course.getUnitsDeployment()) { OrgInfo org = getOrganizationService().getOrg(unitDeployment, createContextInfo()); OrganizationInfoWrapper organizationInfoWrapper = new OrganizationInfoWrapper(org); courseWrapper.getAdministeringOrganizations().add(organizationInfoWrapper); } // Add an empty line if (courseWrapper.getAdministeringOrganizations().isEmpty()) { courseWrapper.getAdministeringOrganizations().add(new OrganizationInfoWrapper()); } populateCurrentCourseEndTermShortName(); populateAuditOnWrapper(); populateFinalExamOnWrapper(); populatePassFailOnWrapper(); populateOutComesOnWrapper(); populateFormatOnWrapper(); populateJointCourseOnWrapper(); populateLearningObjectives(); populateRequisities(courseWrapper, course.getId()); super.populateWrapperData(courseWrapper); } /* * Calculate the end term for the current course and store the display text if this is a modify proposal and * the courseInfo state is draft. */ protected void populateCurrentCourseEndTermShortName() { CourseInfoWrapper dataObject = (CourseInfoWrapper) getDataObject(); boolean isModify = false; String docId = dataObject.getProposalInfo().getWorkflowId(); // If we don't know the docId then don't load the data. if (StringUtils.isNotBlank(docId)) { String docTypeName = findDocumentTypeName(docId); if (ArrayUtils.contains(CurriculumManagementConstants.DocumentTypeNames.COURSE_MODIFY_DOC_TYPE_NAMES, docTypeName)) { isModify = true; } } if (dataObject.getCourseInfo().getStateKey().equals(DtoConstants.STATE_DRAFT) && isModify) { String startTerm = dataObject.getCourseInfo().getStartTerm(); if (startTerm != null) { String versionIndependentId = dataObject.getCourseInfo().getVersion().getVersionIndId(); String endTermShortName = CourseProposalUtil .getEndTerm(startTerm, versionIndependentId, ContextUtils.createDefaultContextInfo()) .getShortName(); dataObject.setCurrentCourseEndTermShortName(endTermShortName); } } } /** * This method builds a course copy and returns CourseInfoWrapper for the new course. * * @param sourceCourseId * @return * @throws Exception */ public CourseInfoWrapper copyCourse(String sourceCourseId) throws Exception { CourseInfo sourceCourse = getCourseService().getCourse(sourceCourseId, createContextInfo()); CourseInfo targetCourse = new CourseInfo(); getCourseCopyHelper().copyCourse(sourceCourse, targetCourse); /** * Populate the source course wrapper first sothat we can create target from here. */ CourseInfoWrapper targetCourseWrapper = new CourseInfoWrapper(); targetCourseWrapper.setCourseInfo(targetCourse); setDataObject(targetCourseWrapper); // Most of the populate methods and requisities are using this dataobject targetCourseWrapper.setPreviousSubjectCode(sourceCourse.getSubjectArea()); /** * As we cleaned up target course which doesnt have course Id, we need to populate requisities seperately */ populateWrapperData(targetCourseWrapper); /** * Populate all the source requisities into the target */ populateRequisities(targetCourseWrapper, sourceCourse.getId()); /** * Needs final cleanup with requisitie Ids and other */ getCourseCopyHelper().cleanUpCourseWrapperOnCopy(targetCourseWrapper); initializeOutcome(targetCourseWrapper); return targetCourseWrapper; } public ProposalElementsWrapper copyWrapperObjectsToProposal(ProposalInfo sourceProposal) throws Exception { String courseId = sourceProposal.getProposalReference().get(0); return copyCourse(courseId); } /** * This method loads course information and populate to <class>CourseInfoWrapper</class> and also to * <class>ReviewProposalDisplay</class> for display purpose at 'review proposal' and 'view course'. * <p/> * Note: This method is used by non-maintenance views so you can't put anything maintenance specific here or in any * methods this method calls. * * @param courseId The id of the course to load. * @param courseWrapper The data object to populate. * @throws Exception */ public void populateCourseAndReviewData(String courseId, CourseInfoWrapper courseWrapper) throws Exception { populateCourseAndReviewData(courseId, courseWrapper, false); } public void populateCourseAndReviewData(CourseInfoWrapper courseWrapper, boolean loadVersionData) throws Exception { populateWrapperData(courseWrapper); updateReview(courseWrapper, false); if (loadVersionData) { loadVersionData(courseWrapper); } } /** * Same as above, but adds the option to load version data. * * @param courseId The id of the course to load. * @param courseWrapper The data object to populate. * @param loadVersionData A flag to indicate whether version info should be looked up and populated. */ public void populateCourseAndReviewData(String courseId, CourseInfoWrapper courseWrapper, boolean loadVersionData) throws Exception { CourseInfo course = getCourseService().getCourse(courseId, createContextInfo()); courseWrapper.setCourseInfo(course); populateCourseAndReviewData(courseWrapper, loadVersionData); } /** * Populates . * * @param courseWrapper */ protected void loadVersionData(CourseInfoWrapper courseWrapper) throws Exception { String currentCourseSuffix = ""; if (isCurrentVersionOfCourse(courseWrapper.getCourseInfo(), this.createContextInfo())) { courseWrapper.setCurrentVersion(true); currentCourseSuffix = "(current version)"; } else { courseWrapper.setCurrentVersion(false); } courseWrapper.setVersionText(String.format("Version %s %s", courseWrapper.getCourseInfo().getVersion().getSequenceNumber(), currentCourseSuffix)); } public void populateRequisities(CourseInfoWrapper courseInfoWrapper, String courseId) { if (StringUtils.isNotBlank(courseId)) { courseInfoWrapper.setRefObjectId(courseId); courseInfoWrapper.setAgendas( this.getAgendasForRef(CourseServiceConstants.REF_OBJECT_URI_COURSE, courseId, null)); } } /** * This method creates <class>LoDisplayWrapperModel</class> instances from <class>LoDisplayInfoWrapper</class> instances */ protected void populateLearningObjectives() { CourseInfoWrapper courseInfoWrapper = (CourseInfoWrapper) getDataObject(); courseInfoWrapper.getLoDisplayWrapperModel().clearLoWrappers(); List<LoDisplayInfoWrapper> newDisplayWrappers = new ArrayList<LoDisplayInfoWrapper>(); int indent = 0; for (LoDisplayInfo loDisplayInfo : courseInfoWrapper.getCourseInfo().getCourseSpecificLOs()) { LoDisplayInfoWrapper displayInfoWrapper = new LoDisplayInfoWrapper(loDisplayInfo); populateLOCategoryName(displayInfoWrapper); newDisplayWrappers.add(displayInfoWrapper); indentLoOnLoad(newDisplayWrappers, displayInfoWrapper, indent); } // Sort the wrappers by their sequence. Collections.sort(newDisplayWrappers, new Comparator<LoDisplayInfoWrapper>() { @Override public int compare(LoDisplayInfoWrapper o1, LoDisplayInfoWrapper o2) { int result = 0; if (o1.getSequence() < o2.getSequence()) { result = -1; } else if (o1.getSequence() > o2.getSequence()) { result = 1; } return result; } }); courseInfoWrapper.getLoDisplayWrapperModel().getLoWrappers().addAll(newDisplayWrappers); /** * Once we added all the child to a single list for display reasons, clear out all the children from each LOs to avoid * duplicates on save. Save will attach the children back to LOs based on the user indentation */ for (LoDisplayInfo loDisplayInfo : courseInfoWrapper.getLoDisplayWrapperModel().getLoWrappers()) { loDisplayInfo.getLoDisplayInfoList().clear(); } setLOActions(); } protected void indentLoOnLoad(List<LoDisplayInfoWrapper> newDisplayWrappers, LoDisplayInfoWrapper loDisplayInfoWrapper, int currentIndent) { if (loDisplayInfoWrapper.getLoDisplayInfoList().isEmpty()) { return; } int nextLevel = currentIndent + 1; for (LoDisplayInfo loDisplayInfo : loDisplayInfoWrapper.getLoDisplayInfoList()) { LoDisplayInfoWrapper displayInfoWrapper = new LoDisplayInfoWrapper(loDisplayInfo); populateLOCategoryName(displayInfoWrapper); newDisplayWrappers.add(displayInfoWrapper); displayInfoWrapper.setIndentLevel(nextLevel); indentLoOnLoad(newDisplayWrappers, displayInfoWrapper, nextLevel); } } protected void populateLOCategoryName(LoDisplayInfoWrapper displayInfoWrapper) { for (LoCategoryInfo loCategoryInfo : displayInfoWrapper.getLoCategoryInfoList()) { try { TypeInfo typeInfo = getLearningObjectiveService().getLoCategoryType(loCategoryInfo.getTypeKey(), ContextUtils.createDefaultContextInfo()); loCategoryInfo.setName((new StringBuilder().append(loCategoryInfo.getName()).append(" - ") .append(typeInfo.getName()).toString())); } catch (Exception e) { LOG.error("An error occurred while retrieving the LoCategoryType", e); throw new RuntimeException(e); } } } /** * This method enables/disables the indent, outdent, move up and move down actions for each LO. */ public void setLOActions() { CourseInfoWrapper courseInfoWrapper = (CourseInfoWrapper) getDataObject(); for (LoDisplayInfoWrapper loWrapper : courseInfoWrapper.getLoDisplayWrapperModel().getLoWrappers()) { loWrapper.setIndentable(courseInfoWrapper.getLoDisplayWrapperModel().isIndentable(loWrapper)); loWrapper.setOutdentable(courseInfoWrapper.getLoDisplayWrapperModel().isOutdentable(loWrapper)); loWrapper.setMoveDownable(courseInfoWrapper.getLoDisplayWrapperModel().isMoveDownable(loWrapper)); loWrapper.setMoveUpable(courseInfoWrapper.getLoDisplayWrapperModel().isMoveUpable(loWrapper)); } } /** * This method creates <class>CourseJointInfoWrapper</class> instances from <class>CourseJointInfo</class> instance */ protected void populateJointCourseOnWrapper() { CourseInfoWrapper courseInfoWrapper = (CourseInfoWrapper) getDataObject(); courseInfoWrapper.getCourseJointWrappers().clear(); for (final CourseJointInfo jointInfo : courseInfoWrapper.getCourseInfo().getJoints()) { CourseJointInfoWrapper jointInfoWrapper = new CourseJointInfoWrapper(); BeanUtils.copyProperties(jointInfo, jointInfoWrapper); jointInfoWrapper.setCourseCode(jointInfo.getSubjectArea() + jointInfo.getCourseNumberSuffix()); courseInfoWrapper.getCourseJointWrappers().add(jointInfoWrapper); } if (courseInfoWrapper.getCourseJointWrappers().isEmpty()) { List<CourseJointInfoWrapper> courseJointInfoList = courseInfoWrapper.getCourseJointWrappers(); courseJointInfoList.add(new CourseJointInfoWrapper()); courseInfoWrapper.setCourseJointWrappers(courseJointInfoList); } } protected void updateAndSaveCourseInfo() throws Exception { CourseInfoWrapper courseInfoWrapper = (CourseInfoWrapper) getDataObject(); final CourseInfo course = courseInfoWrapper.getCourseInfo(); for (final CourseVariationInfo variation : course.getVariations()) { variation.setTypeKey(ProgramConstants.VARIATION_TYPE_KEY); } if (StringUtils.isBlank(course.getId())) { courseInfoWrapper.setCourseInfo( getCourseService().createCourse(course, ContextUtils.createDefaultContextInfo())); } else { courseInfoWrapper.setCourseInfo(getCourseService().updateCourse(course.getId(), course, ContextUtils.createDefaultContextInfo())); } } protected String getProposalTypeKey() { return ProposalServiceConstants.PROPOSAL_TYPE_COURSE_CREATE_KEY; } public String getProposalReferenceType() { return ProposalServiceConstants.PROPOSAL_DOC_RELATION_TYPE_CLU_KEY; } protected String getProposalReference() { CourseInfoWrapper courseInfoWrapper = (CourseInfoWrapper) getDataObject(); return courseInfoWrapper.getCourseInfo().getId(); } /** * The finalizeMethodToCall for the Review Proposal link. Populates the given action link with the URL for the * document. */ protected void buildProposalActionLink(Action actionLink, MaintenanceDocumentForm form, String methodToCall, String pageId) { String docId = form.getDocument().getDocumentNumber(); String href = StringUtils.EMPTY; if (form.getDocument() != null && form.getDocument().getNewMaintainableObject() != null && form.getDocument().getNewMaintainableObject().getDataObject() != null) { String proposalTypeKey = ((ProposalMaintainable) form.getDocument().getNewMaintainableObject()) .getProposalInfo().getTypeKey(); if (StringUtils.isNotBlank(proposalTypeKey)) { href = CourseProposalUtil.buildCourseProposalUrl(methodToCall, pageId, docId, proposalTypeKey); } } if (StringUtils.isBlank(href)) { actionLink.setRender(false); return; } actionLink.setActionScript("window.open('" + href + "', '_self');"); } @Override public String getViewTypeNameForProposal() { return KSKRMSServiceConstants.AGENDA_TYPE_COURSE; } /** * Return the clu id from the canonical course that is linked to the given course offering id. * * @param refObjectId - the course offering id. * @return * @throws Exception */ @Override public List<ReferenceObjectBinding> getParentRefObjectsForProposal(String refObjectId) { if (StringUtils.isBlank(refObjectId)) { return Collections.EMPTY_LIST; } return this.getRuleManagementService().findReferenceObjectBindingsByReferenceObject( CourseServiceConstants.REF_OBJECT_URI_COURSE, refObjectId); } protected PersonService getPersonService() { if (personService == null) { personService = GlobalResourceLoader.getService( new QName(KimConstants.Namespaces.KIM_NAMESPACE_2_0, KimConstants.KIM_PERSON_SERVICE)); } return personService; } protected TypeService getTypeService() { if (typeService == null) { typeService = (TypeService) GlobalResourceLoader.getService( new QName(TypeServiceConstants.NAMESPACE, TypeServiceConstants.SERVICE_NAME_LOCAL_PART)); } return typeService; } private LRCService getLRCService() { if (lrcService == null) { QName qname = new QName(LrcServiceConstants.NAMESPACE, LrcServiceConstants.SERVICE_NAME_LOCAL_PART); lrcService = (LRCService) GlobalResourceLoader.getService(qname); } return lrcService; } protected EnumerationManagementService getEnumerationManagementService() { if (enumerationManagementService == null) { enumerationManagementService = (EnumerationManagementService) GlobalResourceLoader .getService(new QName(EnumerationManagementServiceConstants.NAMESPACE, EnumerationManagementServiceConstants.SERVICE_NAME_LOCAL_PART)); } return this.enumerationManagementService; } public List<CluInformation> getCoursesInRange(MembershipQueryInfo membershipQuery) { return this.getCluInfoHelper().getCluInfosWithDetailForQuery(membershipQuery); } protected CluInformationHelper getCluInfoHelper() { if (cluInfoHelper == null) { cluInfoHelper = new CluInformationHelper(); cluInfoHelper.setCluService(getCluService()); LRCService lrcService = GlobalResourceLoader.getService( new QName(LrcServiceConstants.NAMESPACE, LrcServiceConstants.SERVICE_NAME_LOCAL_PART)); cluInfoHelper.setLrcService(lrcService); } return cluInfoHelper; } /** * As we're using this maintainable in course maintenace document (CourseMaintenanceView.xml) as well as * in regular view 'view course' (ViewCourseView.xml), we dont want any of the maintenance document specific * logics here to avoid form type casting issues. Also, we dont really need any of the logic here as our functionalities * are different than the out of the box logic. * * @param element * @param model */ @Override public void performCustomApplyModel(LifecycleElement element, Object model) { } /** * @see #performCustomApplyModel(org.kuali.rice.krad.uif.util.LifecycleElement, Object) * @param element * @param model * @param parent */ @Override public void performCustomFinalize(LifecycleElement element, Object model, LifecycleElement parent) { } /** * @see #performCustomApplyModel(org.kuali.rice.krad.uif.util.LifecycleElement, Object) * @param model */ @Override public void performCustomViewFinalize(Object model) { } public CourseCopyHelper getCourseCopyHelper() { if (courseCopyHelper == null) { courseCopyHelper = GlobalResourceLoader .getService(new QName(CommonServiceConstants.REF_OBJECT_URI_GLOBAL_PREFIX + "courseCopyHelper", CourseCopyHelper.class.getSimpleName())); } return courseCopyHelper; } public void setCourseCopyHelper(CourseCopyHelper courseCopyHelper) { this.courseCopyHelper = courseCopyHelper; } /** * @see CourseMaintainable#balanceCollectionsForCompare(org.kuali.student.cm.course.form.wrapper.CourseInfoWrapper, org.kuali.student.cm.course.form.wrapper.CourseInfoWrapper) * @param wrapper1 * @param wrapper2 */ public void balanceCollectionsForCompare(CourseInfoWrapper wrapper1, CourseInfoWrapper wrapper2) { List<OutcomeReviewSection> outcomes = wrapper1.getReviewProposalDisplay().getCourseLogisticsSection() .getOutcomes(); List<OutcomeReviewSection> compareOutcomes = wrapper2.getReviewProposalDisplay().getCourseLogisticsSection() .getOutcomes(); if (outcomes.size() > compareOutcomes.size()) { for (; compareOutcomes.size() < outcomes.size();) { OutcomeReviewSection outcome = new OutcomeReviewSection(StringUtils.EMPTY, StringUtils.EMPTY); outcome.setFakeObjectForCompare(true); compareOutcomes.add(outcome); } } if (compareOutcomes.size() > outcomes.size()) { for (; outcomes.size() < compareOutcomes.size();) { OutcomeReviewSection outcome = new OutcomeReviewSection(StringUtils.EMPTY, StringUtils.EMPTY); outcome.setFakeObjectForCompare(true); outcomes.add(outcome); } } List<LoDisplayInfoWrapper> loDisplays = wrapper1.getLoDisplayWrapperModel().getLoWrappers(); List<LoDisplayInfoWrapper> compareLoDisplays = wrapper2.getLoDisplayWrapperModel().getLoWrappers(); if (loDisplays.size() > compareLoDisplays.size()) { for (; compareLoDisplays.size() < loDisplays.size();) { LoDisplayInfoWrapper lo = new LoDisplayInfoWrapper(); lo.setFakeObjectForCompare(true); compareLoDisplays.add(lo); } } if (compareLoDisplays.size() > loDisplays.size()) { for (; loDisplays.size() < compareLoDisplays.size();) { LoDisplayInfoWrapper lo = new LoDisplayInfoWrapper(); lo.setFakeObjectForCompare(true); loDisplays.add(lo); } } List<FormatInfoWrapper> formats = wrapper1.getReviewProposalDisplay().getCourseLogisticsSection() .getFormatInfoWrappers(); List<FormatInfoWrapper> compareFormats = wrapper2.getReviewProposalDisplay().getCourseLogisticsSection() .getFormatInfoWrappers(); if (formats.size() > compareFormats.size()) { balanceFormatsForCompare(formats, compareFormats); } else if (compareFormats.size() > formats.size()) { balanceFormatsForCompare(compareFormats, formats); } balanceActivitiesForCompare(formats, compareFormats); } /** * This method adds fake formats to make sure both sides of the compare are of same size * * @param formats1 * @param formats2 */ protected void balanceFormatsForCompare(List<FormatInfoWrapper> formats1, List<FormatInfoWrapper> formats2) { if (formats1.size() > formats2.size()) { while (formats1.size() > formats2.size()) { FormatInfoWrapper format = new FormatInfoWrapper(); formats2.add(format); format.setFakeObjectForCompare(true); } } } /** * This method adds fake activities in formats to make sure both sides of the compare are of same size. * * @param formats1 * @param formats2 */ protected void balanceActivitiesForCompare(List<FormatInfoWrapper> formats1, List<FormatInfoWrapper> formats2) { int index = 0; for (FormatInfoWrapper format : formats1) { FormatInfoWrapper compareFormat = formats2.get(index); if (format.getActivities().size() < compareFormat.getActivities().size()) { while (format.getActivities().size() < compareFormat.getActivities().size()) { ActivityInfoWrapper activity = new ActivityInfoWrapper(); format.getActivities().add(activity); activity.setFakeObjectForCompare(true); } } else if (compareFormat.getActivities().size() < format.getActivities().size()) { while (compareFormat.getActivities().size() < format.getActivities().size()) { ActivityInfoWrapper activity = new ActivityInfoWrapper(); compareFormat.getActivities().add(activity); activity.setFakeObjectForCompare(true); } } index++; } } /** * @see CourseMaintainable#cleanUpCompareObjects(org.kuali.student.cm.course.form.wrapper.CourseInfoWrapper) * @param wrapper */ public void cleanUpCompareObjects(CourseInfoWrapper wrapper) { List<OutcomeReviewSection> outcomes = wrapper.getReviewProposalDisplay().getCourseLogisticsSection() .getOutcomes(); filterFakeCollectionElements(outcomes); List<FormatInfoWrapper> formats = wrapper.getReviewProposalDisplay().getCourseLogisticsSection() .getFormatInfoWrappers(); filterFakeCollectionElements(formats); for (FormatInfoWrapper format : formats) { filterFakeCollectionElements(format.getActivities()); } List<LoDisplayInfoWrapper> loDisplays = wrapper.getLoDisplayWrapperModel().getLoWrappers(); filterFakeCollectionElements(loDisplays); } /** * This method filters out all the fake elements added to the collection when building * * @param collection */ protected void filterFakeCollectionElements(List<? extends CourseCompareCollectionElement> collection) { CollectionUtils.filter(collection, new Predicate() { public boolean evaluate(Object input) { return !((CourseCompareCollectionElement) input).isFakeObjectForCompare(); } }); } }