001/* 002 * Copyright 2013-2014 the original author or authors. 003 * 004 * Licensed under the Apache 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 * https://www.apache.org/licenses/LICENSE-2.0 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 */ 016package org.springframework.batch.core.jsr.step; 017 018import java.util.ArrayList; 019import java.util.Collection; 020import java.util.List; 021 022import javax.batch.api.Decider; 023 024import org.springframework.batch.core.ExitStatus; 025import org.springframework.batch.core.Step; 026import org.springframework.batch.core.StepExecution; 027import org.springframework.batch.core.jsr.JsrStepExecution; 028import org.springframework.batch.core.step.AbstractStep; 029import org.springframework.batch.item.ExecutionContext; 030 031/** 032 * Implements a {@link Step} to follow the rules for a decision state 033 * as defined by JSR-352. Currently does not support the JSR requirement 034 * to provide all of the last {@link javax.batch.runtime.StepExecution}s from 035 * a split. 036 * 037 * @author Michael Minella 038 * @since 3.0 039 */ 040public class DecisionStep extends AbstractStep { 041 042 private final Decider decider; 043 044 /** 045 * @param decider a {@link Decider} implementation 046 */ 047 public DecisionStep(Decider decider) { 048 this.decider = decider; 049 } 050 051 @SuppressWarnings("unchecked") 052 @Override 053 protected void doExecute(StepExecution stepExecution) throws Exception { 054 ExecutionContext executionContext = stepExecution.getJobExecution().getExecutionContext(); 055 List<javax.batch.runtime.StepExecution> stepExecutions = new ArrayList<javax.batch.runtime.StepExecution>(); 056 057 if(executionContext.containsKey("batch.lastSteps")) { 058 List<String> stepNames = (List<String>) executionContext.get("batch.lastSteps"); 059 060 for (String stepName : stepNames) { 061 StepExecution curStepExecution = getJobRepository().getLastStepExecution(stepExecution.getJobExecution().getJobInstance(), stepName); 062 stepExecutions.add(new JsrStepExecution(curStepExecution)); 063 } 064 } else { 065 Collection<StepExecution> currentRunStepExecutions = stepExecution.getJobExecution().getStepExecutions(); 066 067 StepExecution lastExecution = null; 068 069 if(stepExecutions != null) { 070 for (StepExecution curStepExecution : currentRunStepExecutions) { 071 if(lastExecution == null || (curStepExecution.getEndTime() != null && curStepExecution.getEndTime().after(lastExecution.getEndTime()))) { 072 lastExecution = curStepExecution; 073 } 074 } 075 076 stepExecutions.add(new JsrStepExecution(lastExecution)); 077 } 078 } 079 080 try { 081 ExitStatus exitStatus = new ExitStatus(decider.decide(stepExecutions.toArray(new javax.batch.runtime.StepExecution[0]))); 082 083 stepExecution.getJobExecution().setExitStatus(exitStatus); 084 stepExecution.setExitStatus(exitStatus); 085 086 if(executionContext.containsKey("batch.lastSteps")) { 087 executionContext.remove("batch.lastSteps"); 088 } 089 } catch (Exception e) { 090 stepExecution.setTerminateOnly(); 091 stepExecution.addFailureException(e); 092 throw e; 093 } 094 } 095}