com.ibm.jbatch.container.jsl.impl.FlowNavigatorImpl Maven / Gradle / Ivy
/*
* Copyright 2012 International Business Machines Corp.
*
* See the NOTICE file distributed with this work for additional information
* regarding copyright ownership. 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 com.ibm.jbatch.container.jsl.impl;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.ibm.jbatch.container.jsl.TransitionElement;
import com.ibm.jbatch.container.jsl.ExecutionElement;
import com.ibm.jbatch.container.jsl.Navigator;
import com.ibm.jbatch.container.jsl.Transition;
import com.ibm.jbatch.jsl.model.Decision;
import com.ibm.jbatch.jsl.model.End;
import com.ibm.jbatch.jsl.model.Fail;
import com.ibm.jbatch.jsl.model.Flow;
import com.ibm.jbatch.jsl.model.Next;
import com.ibm.jbatch.jsl.model.Split;
import com.ibm.jbatch.jsl.model.Step;
import com.ibm.jbatch.jsl.model.Stop;
public class FlowNavigatorImpl implements Navigator {
private final static Logger logger = Logger.getLogger(FlowNavigatorImpl.class.getName());
private Flow flow = null;
public FlowNavigatorImpl(Flow flow) {
this.flow = flow;
}
@Override
public Transition getNextTransition(ExecutionElement currentElem, String currentExitStatus) {
final String method = "getNextTransition";
if (logger.isLoggable(Level.FINE))
logger.fine(method + " ,currentExitStatus=" + currentExitStatus);
String nextAttrId = null;
ExecutionElement nextExecutionElement = null;
Transition returnTransition = new TransitionImpl();
if (currentElem instanceof Step) {
nextAttrId = ((Step) currentElem).getNextFromAttribute();
nextExecutionElement = getExecutionElementByID(nextAttrId);
} else if (currentElem instanceof Split) {
nextAttrId = ((Split) currentElem).getNextFromAttribute();
nextExecutionElement = getExecutionElementByID(nextAttrId);
} else if (currentElem instanceof Flow) {
nextAttrId = ((Flow) currentElem).getNextFromAttribute();
nextExecutionElement = getExecutionElementByID(nextAttrId);
} else if (currentElem instanceof Decision) {
// Nothing special to do in this case.
}
List transitionElements = currentElem.getTransitionElements();
if (nextExecutionElement == null && transitionElements.isEmpty()) {
if (logger.isLoggable(Level.FINE))
logger.fine(method + " return null, there is no next step");
// Don't set anything special on return transition.
return returnTransition;
} else if (nextExecutionElement != null) {
if (logger.isLoggable(Level.FINE))
logger.fine(method + " return execution element:" + nextExecutionElement);
returnTransition.setNextExecutionElement(nextExecutionElement);
return returnTransition;
} else if (transitionElements.size() > 0) {
Iterator iterator = transitionElements.iterator();
while (iterator.hasNext()) {
TransitionElement elem = iterator.next();
if (logger.isLoggable(Level.FINE)) {
logger.fine(method + " Trying to match next control element: " + elem);
}
if (elem instanceof Stop) {
String exitStatusToMatch = ((Stop) elem).getOn();
boolean isMatched = matchSpecifiedExitStatus(currentExitStatus, exitStatusToMatch);
if (isMatched == true) {
if (logger.isLoggable(Level.FINE))
logger.fine(method + " , Stop element matches to " + exitStatusToMatch);
returnTransition.setTransitionElement(elem);
return returnTransition;
}
} else if (elem instanceof End) {
String exitStatusToMatch = ((End) elem).getOn();
boolean isMatched = matchSpecifiedExitStatus(currentExitStatus, exitStatusToMatch);
if (isMatched == true) {
if (logger.isLoggable(Level.FINE))
logger.fine(method + " , End element matches to " + exitStatusToMatch);
returnTransition.setTransitionElement(elem);
return returnTransition;
}
} else if (elem instanceof Fail) {
String exitStatusToMatch = ((Fail) elem).getOn();
boolean isMatched = matchSpecifiedExitStatus(currentExitStatus, exitStatusToMatch);
if (isMatched == true) {
if (logger.isLoggable(Level.FINE))
logger.fine(method + " , Fail element matches to " + exitStatusToMatch);
returnTransition.setTransitionElement(elem);
return returnTransition;
}
} else if (elem instanceof Next) {
String exitStatusToMatch = ((Next) elem).getOn();
boolean isMatched = matchSpecifiedExitStatus(currentExitStatus, exitStatusToMatch);
if (isMatched == true) {
// go to next executionElement
nextExecutionElement = getExecutionElementByID(((Next) elem).getTo());
if (logger.isLoggable(Level.FINE))
logger.fine(method + " , match to " + exitStatusToMatch + ". Continue to step "
+ nextExecutionElement.getId());
// No point setting the TransitionElement in the transition.
returnTransition.setNextExecutionElement(nextExecutionElement);
return returnTransition;
}
} else {
throw new IllegalStateException("Shouldn't be possible to get here. Unknown control element, " + elem.toString());
}
}
}
//TODO - Is this an error case or a valid end/completion case?
return null;
}
@Override
public Step getFirstExecutionElement(String restartOn) {
final String method = "getFirstExecutionElement";
if (logger.isLoggable(Level.FINE)) {
logger.fine(method + " , restartOn = " + restartOn);
}
ExecutionElement startElement = null;
if (restartOn != null) {
startElement = getExecutionElementByID(restartOn);
if (startElement == null) {
throw new IllegalStateException("Didn't find an execution element maching restart-on designated element: " + restartOn);
}
} else {
if (flow.getExecutionElements().size() > 0) {
startElement = flow.getExecutionElements().get(0);
} else {
if (logger.isLoggable(Level.FINE)) {
logger.fine(method + " , Job appears to contain no execution elements. Returning.");
}
return null;
}
}
if (logger.isLoggable(Level.FINE)) {
logger.fine(method + " , Found start element: " + startElement);
}
if (startElement instanceof Step) {
return (Step) startElement;
} else {
throw new IllegalStateException("Didn't get this far yet implementing.\nOnly support as first execution element.");
}
}
public Flow getJSL() {
return this.flow;
}
private ExecutionElement getExecutionElementByID(String id) {
if (id != null) {
logger.finer("attribute value is " + id);
for (ExecutionElement elem : flow.getExecutionElements()) {
if (elem.getId().equals(id)) {
return elem;
}
}
logger.warning("In flow, no local execution element found with id = " + id);
throw new IllegalStateException("In flow, no local execution element found with id = " + id);
} else {
logger.finer("attribute value is , so simply exiting...");
return null;
}
}
/*
*
*/
private static boolean matchSpecifiedExitStatus(String currentStepExitStatus, String exitStatusPattern) {
if (logger.isLoggable(Level.FINER)) {
logger.finer("matchSpecifiedExitStatus, matching current exitStatus " + currentStepExitStatus +
" against pattern: " + exitStatusPattern);
}
GlobPatternMatcherImpl matcher = new GlobPatternMatcherImpl();
boolean match = matcher.matchWithoutBackslashEscape(currentStepExitStatus, exitStatusPattern);
if (match) {
if (logger.isLoggable(Level.FINER)) {
logger.finer("matchSpecifiedExitStatus, match=YES");
}
return true;
}
else {
if (logger.isLoggable(Level.FINER)) {
logger.finer("matchSpecifiedExitStatus, match=NO");
}
return false;
}
}
public String getId() {
return flow.getId();
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy