Java tutorial
/* * Copyright 2006 The National Library of New Zealand * * Licensed under the Apache 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.apache.org/licenses/LICENSE-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.webcurator.ui.target.controller; import java.beans.PropertyEditorSupport; import java.text.NumberFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.collections.iterators.ArrayIterator; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.propertyeditors.CustomNumberEditor; import org.springframework.context.MessageSource; import org.springframework.context.support.DefaultMessageSourceResolvable; import org.springframework.validation.BindException; import org.springframework.validation.ValidationUtils; import org.springframework.web.bind.ServletRequestDataBinder; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.AbstractFormController; import org.webcurator.auth.AuthorityManager; import org.webcurator.core.agency.AgencyUserManager; import org.webcurator.core.common.Environment; import org.webcurator.core.exceptions.WCTRuntimeException; import org.webcurator.core.harvester.coordinator.HarvestCoordinator; import org.webcurator.core.profiles.ProfileManager; import org.webcurator.core.scheduler.TargetInstanceManager; import org.webcurator.core.store.DigitalAssetStore; import org.webcurator.core.targets.TargetManager; import org.webcurator.core.util.AuthUtil; import org.webcurator.domain.model.auth.Agency; import org.webcurator.domain.model.auth.Privilege; import org.webcurator.domain.model.auth.User; import org.webcurator.domain.model.core.Annotation; import org.webcurator.domain.model.core.BusinessObjectFactory; import org.webcurator.domain.model.core.CustomDepositFormCriteriaDTO; import org.webcurator.domain.model.core.CustomDepositFormResultDTO; import org.webcurator.domain.model.core.DublinCore; import org.webcurator.domain.model.core.HarvestResult; import org.webcurator.domain.model.core.Indicator; import org.webcurator.domain.model.core.LogFilePropertiesDTO; import org.webcurator.domain.model.core.Profile; import org.webcurator.domain.model.core.RejReason; import org.webcurator.domain.model.core.Schedule; import org.webcurator.domain.model.core.Target; import org.webcurator.domain.model.core.TargetInstance; import org.webcurator.domain.model.dto.HarvestHistoryDTO; import org.webcurator.ui.common.Constants; import org.webcurator.ui.common.validation.ValidatorUtil; import org.webcurator.ui.target.command.ProfileCommand; import org.webcurator.ui.target.command.TargetInstanceCommand; import org.webcurator.ui.target.command.TargetInstanceSummaryCommand; import org.webcurator.ui.target.command.TargetSchedulesCommand; import org.webcurator.ui.target.command.Time; import org.webcurator.ui.util.DateUtils; import org.webcurator.ui.util.TabbedController.TabbedModelAndView; /** * The controller for displaying the Target Instance QA Summary Page. * @author twoods */ public class QaTiSummaryController extends AbstractFormController { /** The manager to use to access the target instance. */ private TargetInstanceManager targetInstanceManager; /** The harvest coordinator for looking at the harvesters. */ private Environment environment; /** The manager to use for user, role and agency data. */ private AgencyUserManager agencyUserManager; /** The component that will provide an <code>Indicator</code> based QA recommendation **/ private HarvestCoordinator harvestCoordinator; /** the logger. */ private Log log; /** the profile manager to use. */ private ProfileManager profileManager; /** Authority Manager */ private AuthorityManager authorityManager = null; /** Business object factory */ private BusinessObjectFactory businessObjectFactory; /** used to retrieve a complete target **/ private TargetManager targetManager; /** the message source. */ private MessageSource messageSource = null; private DigitalAssetStore digitalAssetStore; private static Map<String, Integer> monthMap = new HashMap<String, Integer>(20); private static Map<String, Integer> dayMap = new HashMap<String, Integer>(60); /** static Map of months used by the schedule panel **/ static { monthMap.put("JAN", new Integer(0)); monthMap.put("FEB", new Integer(1)); monthMap.put("MAR", new Integer(2)); monthMap.put("APR", new Integer(3)); monthMap.put("MAY", new Integer(4)); monthMap.put("JUN", new Integer(5)); monthMap.put("JUL", new Integer(6)); monthMap.put("AUG", new Integer(7)); monthMap.put("SEP", new Integer(8)); monthMap.put("OCT", new Integer(9)); monthMap.put("NOV", new Integer(10)); monthMap.put("DEC", new Integer(11)); dayMap.put("SUN", new Integer(1)); dayMap.put("MON", new Integer(2)); dayMap.put("TUE", new Integer(3)); dayMap.put("WED", new Integer(4)); dayMap.put("THU", new Integer(5)); dayMap.put("FRI", new Integer(6)); dayMap.put("SAT", new Integer(7)); } /** Default constructor. */ public QaTiSummaryController() { super(); setCommandClass(TargetInstanceSummaryCommand.class); log = LogFactory.getLog(getClass()); } public void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception { binder.registerCustomEditor(java.util.Date.class, DateUtils.get().getFullDateTimeEditor(true)); NumberFormat nf = NumberFormat.getInstance(request.getLocale()); binder.registerCustomEditor(java.lang.Long.class, new CustomNumberEditor(java.lang.Long.class, nf, true)); binder.registerCustomEditor(Date.class, new PropertyEditorSupport() { public void setAsText(String value) { try { setValue(new SimpleDateFormat("dd/MM/yyyy").parse(value)); } catch (ParseException e) { setValue(null); } } public String getAsText() { Date value = (Date) getValue(); if (value != null) { return new SimpleDateFormat("dd/MM/yyyy").format(value); } else { return ""; } } }); } /** * binds the data to the <code>ModelAndView</code> * @param mav the <code>ModelAndView</code> to bind to * @param ti the <code>TargetInstance</code> whose data should be bound to the <code>ModelAndView</code> */ private ModelAndView buildModelAndView(HttpServletRequest request, TargetInstance ti, TargetInstance rcti, TargetInstanceSummaryCommand command, BindException errors) { ModelAndView mav = new ModelAndView(Constants.VIEW_TARGET_INSTANCE_QA_SUMMARY); mav.addObject(TargetInstanceSummaryCommand.MDL_INSTANCE, ti); if (command != null) mav.addObject(Constants.GBL_CMD_DATA, command); // fetch any QA indicators (and retain the order of insertion - ie: the original sort order) LinkedHashSet<Indicator> indicators = new LinkedHashSet<Indicator>(ti.getIndicators()); mav.addObject(TargetInstanceSummaryCommand.MDL_INDICATORS, indicators); // fetch any QA indicators for the reference crawl if defined HashMap<String, Indicator> rcIndicators = new HashMap<String, Indicator>(); if (rcti != null) { List<Indicator> rcis = rcti.getIndicators(); Iterator<Indicator> rciit = rcis.iterator(); // add them to the HashMap so that we can pull them out directly in the ui while (rciit.hasNext()) { Indicator rci = rciit.next(); rcIndicators.put(rci.getName(), rci); } } mav.addObject(TargetInstanceSummaryCommand.MDL_RC_INDICATORS, rcIndicators); // bind the HarvesterStatus mav.addObject(TargetInstanceSummaryCommand.MDL_STATUS, ti.getStatus()); // bind the HarvestHistory List<HarvestHistoryDTO> history = targetInstanceManager.getHarvestHistory(ti.getTarget().getOid()); mav.addObject(TargetInstanceSummaryCommand.MDL_HISTORY, history); // add the seeds Set<String> seeds = ti.getOriginalSeeds(); mav.addObject(TargetInstanceSummaryCommand.MDL_SEEDS, seeds); // add the log list LogFilePropertiesDTO[] arrLogs = harvestCoordinator.listLogFileAttributes(ti); mav.addObject(TargetInstanceSummaryCommand.MDL_LOGS, arrLogs); // add the harvest results mav.addObject(TargetInstanceSummaryCommand.MDL_RESULTS, ti.getHarvestResults()); // fetch the valid rejection reasons for targets // (used to populate the rejection reason drop-down) User user = AuthUtil.getRemoteUserObject(); List<RejReason> rejectionReasons = agencyUserManager.getValidRejReasonsForTIs(user.getAgency().getOid()); mav.addObject(TargetInstanceSummaryCommand.MDL_REASONS, rejectionReasons); // the annotations are not recovered by hibernate during the ti fetch so we need to add them ti.setAnnotations(targetInstanceManager.getAnnotations(ti)); // add profile information to support overrides buildProfile(mav, request, ti, command); // add schedule info to support schedule management buildSchedule(mav, request, ti, command, errors); includeCustomFormDetails(request, mav, ti); return mav; } private void includeCustomFormDetails(HttpServletRequest request, ModelAndView mav, TargetInstance ti) { boolean customDepositFormRequired = false; if (TargetInstance.STATE_ENDORSED.equals(ti.getState())) { try { User user = org.webcurator.core.util.AuthUtil.getRemoteUserObject(); Agency agency = user.getAgency(); CustomDepositFormCriteriaDTO criteria = new CustomDepositFormCriteriaDTO(); criteria.setUserId(user.getUsername()); DublinCore dc = ti.getTarget().getDublinCoreMetaData(); if (dc != null) criteria.setTargetType(ti.getTarget().getDublinCoreMetaData().getType()); if (agency != null) criteria.setAgencyId(String.valueOf(agency.getOid())); criteria.setAgencyName(agency.getName()); CustomDepositFormResultDTO response = digitalAssetStore.getCustomDepositFormDetails(criteria); if (response != null && response.isCustomDepositFormRequired()) { String customDepositFormHTMLContent = response.getHTMLForCustomDepositForm(); String customDepositFormURL = response.getUrlForCustomDepositForm(); if (customDepositFormURL != null) { customDepositFormRequired = true; } if (customDepositFormHTMLContent != null) { customDepositFormRequired = true; } } } catch (Exception e) { throw new WCTRuntimeException( "Exception when trying to determine the custom deposit form details: " + e.getMessage(), e); } } mav.addObject("customDepositFormRequired", customDepositFormRequired); } private void buildSchedule(ModelAndView mav, HttpServletRequest request, TargetInstance ti, TargetInstanceSummaryCommand command, BindException errors) { // add schedule info to support schedule management mav.addObject(TargetInstanceSummaryCommand.MDL_SCHEDULES, ti.getTarget().getSchedules()); // model for the schedule subform LinkedHashMap<Long, TargetSchedulesCommand> scheduleCommands = new LinkedHashMap<Long, TargetSchedulesCommand>(); // the model schedules Set<Schedule> schedules = ti.getTarget().getSchedules(); // the month options for each schedule LinkedHashMap<Long, Map<String, String>> scheduleMonthOptions = new LinkedHashMap<Long, Map<String, String>>(); Iterator<Schedule> it = schedules.iterator(); Boolean scheduleHasChanged = false; // iterate thorough the schedules and set the command values to their corresponding schedule values while (it.hasNext()) { Schedule schedule = it.next(); TargetSchedulesCommand scheduleCommand = null; // update the form command if an update to the schedule has been posted from the ui if (command != null && command.getScheduleOid() != null) { int scheduleIndex = command.getScheduleOid().indexOf(schedule.getOid().toString()); if (scheduleIndex != -1) { scheduleCommand = buildScheduleCommand(mav, command, scheduleIndex, errors); } else { // build a new schedule command scheduleCommand = TargetSchedulesCommand.buildFromModel(schedule); } } else { // build a new schedule command scheduleCommand = TargetSchedulesCommand.buildFromModel(schedule); } scheduleCommands.put(schedule.getOid(), scheduleCommand); // get the month options scheduleMonthOptions.put(schedule.getOid(), EditScheduleController.getMonthOptionsByType(scheduleCommand.getScheduleType())); // if the schedule has changed then note this so that the action buttons can be enabled/disabled in the ui if (!scheduleHasChanged && (!schedule.getCronPattern().equals(scheduleCommand.getCronExpression()) || schedule.getScheduleType() != scheduleCommand.getScheduleType())) { scheduleHasChanged = true; } } mav.addObject(TargetInstanceSummaryCommand.MDL_SCHEDULE_COMMANDS, scheduleCommands); mav.addObject(TargetInstanceSummaryCommand.MDL_SCHEDULE_MONTH_OPTIONS, scheduleMonthOptions); mav.addObject(TargetInstanceSummaryCommand.MDL_SCHEDULE_HAS_CHANGED, scheduleHasChanged.toString()); } private TargetSchedulesCommand buildScheduleCommand(ModelAndView mav, TargetInstanceSummaryCommand command, int scheduleIndex, BindException errors) { TargetSchedulesCommand scheduleCommand = new TargetSchedulesCommand(); scheduleCommand.setScheduleType(Integer.parseInt(command.getScheduleType().get(scheduleIndex))); try { if (!command.getStartDate().get(scheduleIndex).equals("") || command.getStartDate().get(scheduleIndex) == null) { scheduleCommand.setStartDate( new SimpleDateFormat("d/M/yyyy").parse(command.getStartDate().get(scheduleIndex))); } else { mav.addObject(Constants.GBL_MESSAGES, "From Date is a required field"); } } catch (ParseException e) { mav.addObject(Constants.GBL_MESSAGES, messageSource.getMessage("typeMismatch.java.util.Date", new Object[] { command.getStartDate().get(scheduleIndex) }, Locale.getDefault())); } try { if (!command.getEndDate().get(scheduleIndex).equals("")) { scheduleCommand.setEndDate( new SimpleDateFormat("d/M/yyyy").parse(command.getEndDate().get(scheduleIndex))); if (scheduleCommand.getStartDate() != null && scheduleCommand.getEndDate() != null && scheduleCommand.getStartDate().getTime() > scheduleCommand.getEndDate().getTime()) { mav.addObject(Constants.GBL_MESSAGES, messageSource .getMessage("time.range", new Object[] { command.getEndDate().get(scheduleIndex), command.getStartDate().get(scheduleIndex) }, Locale.getDefault())); } } } catch (ParseException e) { mav.addObject(Constants.GBL_MESSAGES, messageSource.getMessage("typeMismatch.java.util.Date", new Object[] { command.getEndDate().get(scheduleIndex) }, Locale.getDefault())); } scheduleCommand.setMinutes(command.getMinutes().get(scheduleIndex)); scheduleCommand.setHours(command.getHours().get(scheduleIndex)); scheduleCommand.setDaysOfMonth(command.getDaysOfMonth().get(scheduleIndex)); scheduleCommand.setMonths(command.getMonths().get(scheduleIndex)); scheduleCommand.setDaysOfWeek(command.getDaysOfWeek().get(scheduleIndex)); scheduleCommand.setYears(command.getYears().get(scheduleIndex)); if (Integer.parseInt(command.getScheduleType().get(scheduleIndex)) < 0) { int hours = Integer.parseInt(command.getHours().get(scheduleIndex)); int minutes = Integer.parseInt(command.getMinutes().get(scheduleIndex)); scheduleCommand.setTime(new Time(hours, minutes)); } return scheduleCommand; } private void buildProfile(ModelAndView mav, HttpServletRequest request, TargetInstance ti, TargetInstanceSummaryCommand command) { // setup the model attributes to support profile override editing mav.addObject("ownable", ti.getTarget()); mav.addObject("privlege", Privilege.MODIFY_TARGET + ";" + Privilege.CREATE_TARGET); mav.addObject("editMode", Boolean.toString(true)); mav.addObject("profiles", profileManager.getAvailableProfiles(ti.getTarget().getProfile().getOid())); Profile newProfile = profileManager.load(ti.getTarget().getProfile().getOid()); // The user can set the profile if they have a high enough level // or if the profile is marked as the default. int userLevel = authorityManager.getProfileLevel(); if (newProfile.getRequiredLevel() <= userLevel || newProfile.isDefaultProfile()) { ti.getTarget().setProfile(newProfile); } // now fetch the profile overrides and populate a ProfileCommand object (used to render the form) ProfileCommand profileCommand = new ProfileCommand(); profileCommand.setProfileOid(ti.getTarget().getProfile().getOid()); profileCommand.setFromOverrides(ti.getTarget().getProfileOverrides()); mav.addObject(TargetInstanceSummaryCommand.CMD_PROFILE, profileCommand); } @Override protected ModelAndView showForm(HttpServletRequest request, HttpServletResponse response, BindException errors) throws Exception { if (request.getParameter(TargetInstanceSummaryCommand.PARAM_OID) != null) { // fetch the ti Long tiOid = new Long(request.getParameter(TargetInstanceSummaryCommand.PARAM_OID)); TargetInstance ti = targetInstanceManager.getTargetInstance(tiOid); // bind the ti to the session request.getSession().setAttribute(TargetInstanceCommand.SESSION_TI, ti); // put the session into edit mode (so that edit mode it rendered if the user clicks through to the harvest results) request.getSession().setAttribute(TargetInstanceCommand.SESSION_MODE, true); request.getSession().setAttribute(Constants.GBL_SESS_EDIT_MODE, true); // fetch the reference crawl Long refCrawlOid = ti.getTarget().getReferenceCrawlOid(); TargetInstance rcti = null; if (refCrawlOid != null) rcti = targetInstanceManager.getTargetInstance(refCrawlOid); return buildModelAndView(request, ti, rcti, null, errors); } return null; } @Override protected ModelAndView processFormSubmission(HttpServletRequest request, HttpServletResponse response, Object cmd, BindException error) throws Exception { TargetInstanceSummaryCommand command = (TargetInstanceSummaryCommand) cmd; if (log.isDebugEnabled()) { log.debug("process command " + command.getCmd()); } // fetch the ti TargetInstance ti = targetInstanceManager.getTargetInstance(command.getTargetInstanceOid()); // fetch the reference crawl Long refCrawlOid = ti.getTarget().getReferenceCrawlOid(); TargetInstance rcti = null; if (refCrawlOid != null) rcti = targetInstanceManager.getTargetInstance(refCrawlOid); // resolve and execute the form action if (command.getCmd().equals(TargetInstanceSummaryCommand.ACTION_RERUN_QA)) { processRunQa(request, response, command, error); return buildModelAndView(request, ti, rcti, command, error); } else if (command.getCmd().equals(TargetInstanceSummaryCommand.ACTION_DENOTE_REF_CRAWL)) { processDenoteReferenceCrawl(request, response, command, error); return buildModelAndView(request, ti, rcti, command, error); } else if (command.getCmd().equals(TargetInstanceSummaryCommand.ACTION_ARCHIVE)) { // redirect to the ArchiveController for processing StringBuilder queryString = new StringBuilder("redirect:/curator/archive/submit.html?"); queryString.append("instanceID="); queryString.append(command.getTargetInstanceOid()); return new ModelAndView(queryString.toString()); } else if (command.getCmd().equals(TargetInstanceSummaryCommand.ACTION_ENDORSE)) { // set the ti to endorsed processEndorse(request, response, command, error); return buildModelAndView(request, ti, rcti, command, error); } else if (command.getCmd().equals(TargetInstanceSummaryCommand.ACTION_REJECT)) { processReject(request, response, command, error); return buildModelAndView(request, ti, rcti, command, error); } else if (command.getCmd().equals(TargetInstanceSummaryCommand.ACTION_ADD_NOTE)) { if (log.isDebugEnabled()) { log.debug("Processing add annotation."); } if (!error.hasErrors()) { Annotation annotation = new Annotation(); annotation.setDate(new Date()); annotation.setNote(command.getNote()); annotation.setAlertable(command.isAlertable()); annotation.setUser(AuthUtil.getRemoteUserObject()); annotation.setObjectType(TargetInstance.class.getName()); annotation.setObjectOid(command.getTargetInstanceOid()); ti.addAnnotation(annotation); targetInstanceManager.save(ti); } return buildModelAndView(request, ti, rcti, command, error); } else if (command.getCmd().equals(TargetInstanceSummaryCommand.ACTION_SAVE_PROFILE)) { processSaveProfile(ti, request, response, command, error); return buildModelAndView(request, ti, rcti, command, error); } else if (command.getCmd().equals(TargetInstanceSummaryCommand.ACTION_REFRESH)) { // we just refresh view (only performed for schedule management) return buildModelAndView(request, ti, rcti, command, error); } else if (command.getCmd().equals(TargetInstanceSummaryCommand.ACTION_SAVE_SCHEDULE)) { ModelAndView mav = buildModelAndView(request, ti, rcti, command, error); processSaveSchedule(mav, ti, request, error, command); return buildModelAndView(request, ti, rcti, command, error); } else if (command.getCmd().equals(TargetInstanceSummaryCommand.ACTION_RESET_SCHEDULE)) { command = null; return buildModelAndView(request, ti, rcti, command, error); } else if (command.getCmd().equals(TargetInstanceSummaryCommand.ACTION_RUN_TARGET_NOW)) { Target target = targetManager.load(ti.getTarget().getOid(), true); ModelAndView mav = buildModelAndView(request, ti, rcti, command, error); // check if the target can be run if (command != null && command.getRunTargetNow() && target.getState() != Target.STATE_APPROVED && target.getState() != Target.STATE_COMPLETED) { mav.addObject(Constants.GBL_MESSAGES, messageSource.getMessage("target.error.notapproved", new Object[] {}, Locale.getDefault())); } else { if (command != null) { if (command.getCmd().equals(TargetInstanceSummaryCommand.ACTION_RUN_TARGET_NOW)) { int beforeSaveState = target.getState(); target.setHarvestNow(true); if (target.getState() == Target.STATE_COMPLETED) { target.changeState(Target.STATE_APPROVED); } targetManager.save(target, null); int afterSaveState = target.getState(); if (beforeSaveState == afterSaveState) { if (target.isHarvestNow() && afterSaveState == Target.STATE_APPROVED) { mav.addObject(Constants.GBL_MESSAGES, messageSource.getMessage("target.saved.schedulednow", new Object[] { target.getName() }, Locale.getDefault())); } else { mav.addObject(Constants.GBL_MESSAGES, messageSource.getMessage("target.saved", new Object[] { target.getName() }, Locale.getDefault())); } } else if (afterSaveState == Target.STATE_NOMINATED) { mav.addObject(Constants.GBL_MESSAGES, messageSource.getMessage("target.saved.nominated", new Object[] { target.getName() }, Locale.getDefault())); } else if (afterSaveState == Target.STATE_REINSTATED) { mav.addObject(Constants.GBL_MESSAGES, messageSource.getMessage("target.saved.reinstated", new Object[] { target.getName() }, Locale.getDefault())); } } } } return mav; } else { throw new WCTRuntimeException("Unknown command " + command.getCmd() + " recieved."); } } /** * Examines changes made to a <code>Schedule</code> for a <code>Target</code> by the user and saves any changes.<p/> * The changed <code>Schedule</code>'s end date is set to the current date, and a new <code>Schedule</code> is added to represent the changes. * @param ti the <code>TargetInstance</code> associated with the <code>Target</code> to which this <code>Schedule</code> belongs * @param request the <code>HttpServletRequest</code> that holds the <code>Schedule</code> changes * @param errors any errors * @throws Exception */ private void processSaveSchedule(ModelAndView mav, TargetInstance ti, HttpServletRequest request, BindException errors, TargetInstanceSummaryCommand command) throws Exception { // fetch the schedule changes submitted by the user LinkedHashMap<Long, TargetSchedulesCommand> scheduleCommands = new LinkedHashMap<Long, TargetSchedulesCommand>(); // fetch the original schedules for comparison (array avoid concurrent modifications) // iterate over the schedules and determine if any changes have been made Iterator<Schedule> it = new ArrayIterator(ti.getTarget().getSchedules().toArray()); if (scheduleCommands != null) { while (it.hasNext()) { Schedule schedule = it.next(); // fetch the stored schedule modified by the ui int scheduleIndex = command.getScheduleOid().indexOf(schedule.getOid().toString()); if (scheduleIndex != -1) { TargetSchedulesCommand scheduleCommand = buildScheduleCommand(mav, command, scheduleIndex, errors); // validate the schedule validateschedule(scheduleCommand, errors); // if the schedule has changed if (!schedule.getCronPattern().equals(scheduleCommand.getCronExpression())) { Schedule oldSchedule = businessObjectFactory.newSchedule(ti.getTarget()); oldSchedule.setCronPattern(schedule.getCronPattern()); oldSchedule.setStartDate(schedule.getStartDate()); oldSchedule.setEndDate(schedule.getEndDate()); oldSchedule.setScheduleType(schedule.getScheduleType()); // remove the changed schedule ti.getTarget().removeSchedule(schedule); // save everything targetInstanceManager.save(ti); // set the end date of the schedule to the current date oldSchedule.setEndDate(new Date()); // store the original schedule with the modified end date ti.getTarget().addSchedule(oldSchedule); // save everything targetInstanceManager.save(ti); // generate a new schedule to represent the changes posted from the ui Schedule newSchedule = businessObjectFactory.newSchedule(ti.getTarget()); newSchedule.setCronPattern(scheduleCommand.getCronExpression()); newSchedule.setStartDate(scheduleCommand.getStartDate()); newSchedule.setEndDate(scheduleCommand.getEndDate()); newSchedule.setScheduleType(scheduleCommand.getScheduleType()); // store the new schedule ti.getTarget().addSchedule(newSchedule); // save everything targetInstanceManager.save(ti); } else { // the schedule start and end dates are stored as sql timestamps in the dao, whereas the // scheduleCommand stores its dates as Date() // we therefore need to compare them using a date independent format (ie: milliseconds) Long scheduleStartDate = 0L; Long scheduleEndDate = 0L; Long scheduleCommandStartDate = 0L; Long scheduleCommandEndDate = 0L; if (schedule.getStartDate() != null) scheduleStartDate = schedule.getStartDate().getTime(); if (schedule.getEndDate() != null) scheduleEndDate = schedule.getEndDate().getTime(); if (scheduleCommand.getStartDate() != null) scheduleCommandStartDate = scheduleCommand.getStartDate().getTime(); if (scheduleCommand.getEndDate() != null) scheduleCommandEndDate = scheduleCommand.getEndDate().getTime(); // if the start or end date has changed if (!scheduleStartDate.equals(scheduleCommandStartDate) || !scheduleEndDate.equals(scheduleCommandEndDate)) { Schedule oldSchedule = businessObjectFactory.newSchedule(ti.getTarget()); oldSchedule.setCronPattern(schedule.getCronPattern()); oldSchedule.setStartDate(scheduleCommand.getStartDate()); oldSchedule.setEndDate(scheduleCommand.getEndDate()); oldSchedule.setScheduleType(scheduleCommand.getScheduleType()); // remove the changed schedule ti.getTarget().removeSchedule(schedule); // save everything targetInstanceManager.save(ti); // store the original schedule with the modified dates ti.getTarget().addSchedule(oldSchedule); // save everything targetInstanceManager.save(ti); } } } } } } private void validateschedule(TargetSchedulesCommand scheduleCommand, BindException errors) { ValidationUtils.rejectIfEmptyOrWhitespace(errors, "startDate", "", getObjectArrayForLabel(TargetInstanceSummaryCommand.PARAM_START_DATE), "From Date is a required field"); ValidatorUtil.validateStartBeforeOrEqualEndTime(errors, scheduleCommand.getStartDate(), scheduleCommand.getEndDate(), "time.range", getObjectArrayForTwoLabels(TargetInstanceSummaryCommand.PARAM_START_DATE, TargetInstanceSummaryCommand.PARAM_END_DATE), "The start time must be before the end time."); } private void processSaveProfile(TargetInstance ti, HttpServletRequest request, HttpServletResponse response, TargetInstanceSummaryCommand command, BindException errors) throws Exception { ProfileCommand profileCommand = new ProfileCommand(); profileCommand.setFromSummaryCommand(command); profileCommand.updateOverrides(ti.getTarget().getProfileOverrides()); // update the profile used by the target if it has changed if (command.getProfileOid() != ti.getTarget().getProfile().getOid()) { Profile newProfile = profileManager.load(profileCommand.getProfileOid()); ti.getTarget().setProfile(newProfile); } // save everything targetInstanceManager.save(ti); } private void processDenoteReferenceCrawl(HttpServletRequest request, HttpServletResponse response, TargetInstanceSummaryCommand command, BindException errors) throws Exception { TargetInstance ti = targetInstanceManager.getTargetInstance(command.getTargetInstanceOid()); ti.getTarget().setReferenceCrawlOid(command.getReferenceCrawlOid()); // save everything targetInstanceManager.save(ti); } private void processRunQa(HttpServletRequest request, HttpServletResponse response, TargetInstanceSummaryCommand command, BindException errors) throws Exception { TargetInstance ti = targetInstanceManager.getTargetInstance(command.getTargetInstanceOid()); harvestCoordinator.runQaRecommentationService(ti); } /** * @param aTargetInstanceManager The targetInstanceManager to set. */ public void setTargetInstanceManager(TargetInstanceManager aTargetInstanceManager) { targetInstanceManager = aTargetInstanceManager; } /** * process the endorse target instance action. * @see AbstractFormController#processFormSubmission(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.Object, org.springframework.validation.BindException) */ private void processEndorse(HttpServletRequest aReq, HttpServletResponse aResp, TargetInstanceSummaryCommand aCmd, BindException aErrors) throws Exception { // set the ti state and the hr states TargetInstance ti = targetInstanceManager.getTargetInstance(aCmd.getTargetInstanceOid()); ti.setState(TargetInstance.STATE_ENDORSED); for (HarvestResult hr : ti.getHarvestResults()) { if (hr.getOid().equals(aCmd.getHarvestResultId())) { hr.setState(HarvestResult.STATE_ENDORSED); } else { if (hr.getState() != HarvestResult.STATE_REJECTED) { hr.setState(HarvestResult.STATE_REJECTED); harvestCoordinator.removeIndexes(hr); } } targetInstanceManager.save(hr); } targetInstanceManager.save(ti); aReq.getSession().setAttribute(TargetInstanceCommand.SESSION_TI, ti); } /** * process the reject target instance action. * @see AbstractFormController#processFormSubmission(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.Object, org.springframework.validation.BindException) */ private void processReject(HttpServletRequest aReq, HttpServletResponse aResp, TargetInstanceSummaryCommand aCmd, BindException aErrors) throws Exception { // set the ti state and the hr states TargetInstance ti = targetInstanceManager.getTargetInstance(aCmd.getTargetInstanceOid()); for (HarvestResult hr : ti.getHarvestResults()) { if (hr.getOid().equals(aCmd.getHarvestResultId())) { if (hr.getState() != HarvestResult.STATE_REJECTED) { hr.setState(HarvestResult.STATE_REJECTED); RejReason rejReason = agencyUserManager.getRejReasonByOid(aCmd.getRejReasonId()); hr.setRejReason(rejReason); harvestCoordinator.removeIndexes(hr); } targetInstanceManager.save(hr); } } boolean allRejected = true; for (HarvestResult hr : ti.getHarvestResults()) { if ((HarvestResult.STATE_REJECTED != hr.getState()) && (HarvestResult.STATE_ABORTED != hr.getState())) { allRejected = false; break; } } if (allRejected) { ti.setState(TargetInstance.STATE_REJECTED); ti.setArchivedTime(new Date()); } targetInstanceManager.save(ti); aReq.getSession().setAttribute(TargetInstanceCommand.SESSION_TI, ti); } /** * Helper method to return the last harvest result oid for a specified harvest instance * @param targetInstanceOid the harvest instance oid that contains the list of harvest results * @return the last harvest result oid */ private final Long getLastHarvestResultOid(Long targetInstanceOid) { // get the harvest results for the specified target instance oid int results = targetInstanceManager.getHarvestResults(targetInstanceOid).size(); // return the last harvest result return targetInstanceManager.getHarvestResults(targetInstanceOid).get(results - 1).getOid(); } /** * Retrurn the Object array containing the specified label. * @param aLabel the label to add to the array * @return the object array */ protected Object[] getObjectArrayForLabel(String aLabel) { return new Object[] { new DefaultMessageSourceResolvable(new String[] { Constants.GBL_CMD_DATA + "." + aLabel }) }; } /** * Return an Object array containing two specific labels. * @param aLabel1 the first label * @param aLabel2 the second label * @return the Object array */ protected Object[] getObjectArrayForTwoLabels(String aLabel1, String aLabel2) { return new Object[] { new DefaultMessageSourceResolvable(new String[] { Constants.GBL_CMD_DATA + "." + aLabel1 }), new DefaultMessageSourceResolvable(new String[] { Constants.GBL_CMD_DATA + "." + aLabel2 }) }; } /** * @param harvestCoordinator The harvestCoordinator to set. */ public void setHarvestCoordinator(HarvestCoordinator harvestCoordinator) { this.harvestCoordinator = harvestCoordinator; } public void setEnvironment(Environment environment) { this.environment = environment; } /** * @param agencyUserManager the agencyUserManager to set */ public void setAgencyUserManager(AgencyUserManager agencyUserManager) { this.agencyUserManager = agencyUserManager; } /** * @param profileManager the profileManager to set */ public void setProfileManager(ProfileManager profileManager) { this.profileManager = profileManager; } /** * @param authorityManager The authorityManager to set. */ public void setAuthorityManager(AuthorityManager authorityManager) { this.authorityManager = authorityManager; } /** * @param businessObjectFactory The businessObjectFactory to set. */ public void setBusinessObjectFactory(BusinessObjectFactory businessObjectFactory) { this.businessObjectFactory = businessObjectFactory; } /** * @param targetManager The targetManager to set. */ public void setTargetManager(TargetManager targetManager) { this.targetManager = targetManager; } public void setMessageSource(MessageSource messageSource) { this.messageSource = messageSource; } public void setDigitalAssetStore(DigitalAssetStore digitalAssetStore) { this.digitalAssetStore = digitalAssetStore; } }