001    /*
002     * Copyright 2011 The Kuali Foundation.
003     * 
004     * Licensed under the Educational Community License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     * 
008     * http://www.opensource.org/licenses/ecl2.php
009     * 
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    package org.kuali.kfs.sys.web.struts;
017    
018    import java.util.Date;
019    
020    import javax.servlet.http.HttpServletRequest;
021    import javax.servlet.http.HttpServletResponse;
022    
023    import org.apache.commons.lang.StringUtils;
024    import org.apache.struts.action.ActionForm;
025    import org.apache.struts.action.ActionForward;
026    import org.apache.struts.action.ActionMapping;
027    import org.kuali.kfs.sys.KFSConstants;
028    import org.kuali.kfs.sys.batch.BatchJobStatus;
029    import org.kuali.kfs.sys.batch.service.SchedulerService;
030    import org.kuali.kfs.sys.context.SpringContext;
031    import org.kuali.kfs.sys.identity.KfsKimAttributes;
032    import org.kuali.kfs.sys.service.impl.KfsParameterConstants;
033    import org.kuali.rice.kim.bo.types.dto.AttributeSet;
034    import org.kuali.rice.kim.service.IdentityManagementService;
035    import org.kuali.rice.kim.service.KIMServiceLocator;
036    import org.kuali.rice.kim.util.KimCommonUtils;
037    import org.kuali.rice.kim.util.KimConstants;
038    import org.kuali.rice.kns.exception.AuthorizationException;
039    import org.kuali.rice.kns.service.DateTimeService;
040    import org.kuali.rice.kns.service.KualiConfigurationService;
041    import org.kuali.rice.kns.service.ParameterService;
042    import org.kuali.rice.kns.util.GlobalVariables;
043    import org.kuali.rice.kns.util.KNSConstants;
044    import org.kuali.rice.kns.util.UrlFactory;
045    import org.kuali.rice.kns.web.struts.action.KualiAction;
046    
047    public class KualiBatchJobModifyAction extends KualiAction {
048    
049        private static final String JOB_NAME_PARAMETER = "name";
050        private static final String JOB_GROUP_PARAMETER = "group";
051        private static final String START_STEP_PARAMETER = "startStep";
052        private static final String END_STEP_PARAMETER = "endStep";
053        private static final String START_TIME_PARAMETER = "startTime";
054        private static final String EMAIL_PARAMETER = "emailAddress";
055    
056        private static SchedulerService schedulerService;
057        private static ParameterService parameterService;
058        private static IdentityManagementService identityManagementService;
059        private static DateTimeService dateTimeService;
060        
061        @Override
062        protected void checkAuthorization(ActionForm form, String methodToCall) throws AuthorizationException {
063            if (form instanceof KualiBatchJobModifyForm) {
064                if (!getIdentityManagementService().isAuthorizedByTemplateName(GlobalVariables.getUserSession().getPrincipalId(), KNSConstants.KNS_NAMESPACE, KimConstants.PermissionTemplateNames.LOOK_UP_RECORDS, KimCommonUtils.getNamespaceAndComponentSimpleName(BatchJobStatus.class), new AttributeSet(getRoleQualification(form, "use")))) {
065                    throw new AuthorizationException(GlobalVariables.getUserSession().getPrincipalName(), "view", "batch jobs");
066                }
067            }
068            else {
069                super.checkAuthorization(form, methodToCall);
070            }
071        }
072    
073        /**
074         * Performs the actual authorization check for a given job and action against the current user. This method can be overridden by
075         * sub-classes if more granular controls are desired.
076         * 
077         * @param job
078         * @param actionType
079         * @throws AuthorizationException
080         */
081        protected boolean canModifyJob(KualiBatchJobModifyForm form, String actionType) {
082            AttributeSet permissionDetails = new AttributeSet();
083            permissionDetails.put(KfsKimAttributes.NAMESPACE_CODE, form.getJob().getNamespaceCode());
084            permissionDetails.put(KfsKimAttributes.BEAN_NAME, form.getJob().getName());
085            return getIdentityManagementService().isAuthorizedByTemplateName(GlobalVariables.getUserSession().getPrincipalId(), KNSConstants.KNS_NAMESPACE, KFSConstants.PermissionTemplate.MODIFY_BATCH_JOB.name, permissionDetails, new AttributeSet(getRoleQualification(form, actionType)));
086        }
087        
088        protected void checkJobAuthorization(KualiBatchJobModifyForm form, String actionType) throws AuthorizationException {
089            if (!canModifyJob(form, actionType)) {
090                throw new AuthorizationException(GlobalVariables.getUserSession().getPrincipalName(), "actionType", form.getJob().getName());
091            }
092        }
093        
094        @Override
095        public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
096            // load the given job and map into the form
097            String jobName = request.getParameter(JOB_NAME_PARAMETER);
098            String jobGroup = request.getParameter(JOB_GROUP_PARAMETER);
099            if (form instanceof KualiBatchJobModifyForm) {
100                ((KualiBatchJobModifyForm)form).setJob(getSchedulerService().getJob(jobGroup, jobName));
101            }
102            ActionForward forward = super.execute(mapping, form, request, response);
103            return forward;
104        }
105    
106        private IdentityManagementService getIdentityManagementService() {
107            if (identityManagementService == null) {
108                identityManagementService = SpringContext.getBean(IdentityManagementService.class);
109            }
110            return identityManagementService;
111        }
112    
113        private SchedulerService getSchedulerService() {
114            if (schedulerService == null) {
115                schedulerService = SpringContext.getBean(SchedulerService.class);
116            }
117            return schedulerService;
118        }
119    
120        public static ParameterService getParameterService() {
121            if (parameterService == null) {
122                parameterService = SpringContext.getBean(ParameterService.class);
123            }
124            return parameterService;
125        }
126    
127        public ActionForward start(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
128            KualiBatchJobModifyForm batchModifyForm = (KualiBatchJobModifyForm)form;
129    
130            request.setAttribute("job", batchModifyForm.getJob());
131            request.setAttribute("canRunJob", canModifyJob(batchModifyForm, "runJob"));
132            request.setAttribute("canSchedule", canModifyJob(batchModifyForm, "schedule"));
133            request.setAttribute("canUnschedule", canModifyJob(batchModifyForm, "unschedule"));
134            request.setAttribute("canStopJob", canModifyJob(batchModifyForm, "stopJob"));
135            request.setAttribute("userEmailAddress", GlobalVariables.getUserSession().getPerson().getEmailAddressUnmasked());
136    
137            return mapping.findForward(KFSConstants.MAPPING_BASIC);
138        }
139    
140        public ActionForward runJob(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
141            KualiBatchJobModifyForm batchModifyForm = (KualiBatchJobModifyForm)form;
142    
143            checkJobAuthorization(batchModifyForm, "runJob");
144    
145            String startStepStr = request.getParameter(START_STEP_PARAMETER);
146            String endStepStr = request.getParameter(END_STEP_PARAMETER);
147            String startTimeStr = request.getParameter(START_TIME_PARAMETER);
148            String emailAddress = request.getParameter(EMAIL_PARAMETER);
149    
150            int startStep = Integer.parseInt(startStepStr);
151            int endStep = Integer.parseInt(endStepStr);
152            Date startTime;
153            if (!StringUtils.isBlank(startTimeStr)) {
154                startTime = getDateTimeService().convertToDateTime(startTimeStr);
155            } else {
156                startTime = getDateTimeService().getCurrentDate();
157            }
158    
159            batchModifyForm.getJob().runJob(startStep, endStep, startTime, emailAddress);
160    
161            // redirect to display form to prevent re-execution of the job by mistake
162            return getForward(batchModifyForm.getJob());
163        }
164    
165        public ActionForward stopJob(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
166            KualiBatchJobModifyForm batchModifyForm = (KualiBatchJobModifyForm)form;
167    
168            checkJobAuthorization(batchModifyForm, "stopJob");
169    
170            batchModifyForm.getJob().interrupt();
171    
172            return getForward(batchModifyForm.getJob());
173        }
174    
175    
176        public ActionForward schedule(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
177            KualiBatchJobModifyForm batchModifyForm = (KualiBatchJobModifyForm)form;
178    
179            checkJobAuthorization(batchModifyForm, "schedule");
180    
181            batchModifyForm.getJob().schedule();
182    
183            return getForward(batchModifyForm.getJob());
184        }
185    
186        public ActionForward unschedule(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
187            KualiBatchJobModifyForm batchModifyForm = (KualiBatchJobModifyForm)form;
188    
189            checkJobAuthorization(batchModifyForm, "unschedule");
190    
191            batchModifyForm.getJob().unschedule();
192    
193            // move to the unscheduled job object since the scheduled one has been removed
194            batchModifyForm.setJob(getSchedulerService().getJob(SchedulerService.UNSCHEDULED_GROUP, batchModifyForm.getJob().getName()));
195    
196            return getForward(batchModifyForm.getJob());
197        }
198    
199        private ActionForward getForward(BatchJobStatus job) {
200            return new ActionForward(SpringContext.getBean(KualiConfigurationService.class).getPropertyString(KFSConstants.APPLICATION_URL_KEY) + "/batchModify.do?methodToCall=start&name=" + UrlFactory.encode(job.getName()) + "&group=" + UrlFactory.encode(job.getGroup()), true);
201        }
202    
203        public static DateTimeService getDateTimeService() {
204            if (dateTimeService == null) {
205                dateTimeService = SpringContext.getBean(DateTimeService.class);
206            }
207            return dateTimeService;
208        }
209    }
210