001/* 002 * Copyright 2006-2007 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 */ 016 017package org.springframework.batch.repeat.policy; 018 019import java.util.ArrayList; 020import java.util.Arrays; 021import java.util.List; 022 023import org.springframework.batch.repeat.CompletionPolicy; 024import org.springframework.batch.repeat.RepeatContext; 025import org.springframework.batch.repeat.RepeatStatus; 026import org.springframework.batch.repeat.context.RepeatContextSupport; 027 028/** 029 * Composite policy that loops through a list of delegate policies and answers 030 * calls by a consensus. 031 * 032 * @author Dave Syer 033 * 034 */ 035public class CompositeCompletionPolicy implements CompletionPolicy { 036 037 CompletionPolicy[] policies = new CompletionPolicy[0]; 038 039 /** 040 * Setter for the policies. 041 * 042 * @param policies an array of completion policies to be used to determine 043 * {@link #isComplete(RepeatContext)} by consensus. 044 */ 045 public void setPolicies(CompletionPolicy[] policies) { 046 this.policies = Arrays.asList(policies).toArray(new CompletionPolicy[policies.length]); 047 } 048 049 /** 050 * This policy is complete if any of the composed policies is complete. 051 * 052 * @see org.springframework.batch.repeat.CompletionPolicy#isComplete(org.springframework.batch.repeat.RepeatContext, 053 * RepeatStatus) 054 */ 055 @Override 056 public boolean isComplete(RepeatContext context, RepeatStatus result) { 057 RepeatContext[] contexts = ((CompositeBatchContext) context).contexts; 058 CompletionPolicy[] policies = ((CompositeBatchContext) context).policies; 059 for (int i = 0; i < policies.length; i++) { 060 if (policies[i].isComplete(contexts[i], result)) { 061 return true; 062 } 063 } 064 return false; 065 } 066 067 /** 068 * This policy is complete if any of the composed policies is complete. 069 * 070 * @see org.springframework.batch.repeat.CompletionPolicy#isComplete(org.springframework.batch.repeat.RepeatContext) 071 */ 072 @Override 073 public boolean isComplete(RepeatContext context) { 074 RepeatContext[] contexts = ((CompositeBatchContext) context).contexts; 075 CompletionPolicy[] policies = ((CompositeBatchContext) context).policies; 076 for (int i = 0; i < policies.length; i++) { 077 if (policies[i].isComplete(contexts[i])) { 078 return true; 079 } 080 } 081 return false; 082 } 083 084 /** 085 * Create a new composite context from all the available policies. 086 * 087 * @see org.springframework.batch.repeat.CompletionPolicy#start(RepeatContext) 088 */ 089 @Override 090 public RepeatContext start(RepeatContext context) { 091 List<RepeatContext> list = new ArrayList<RepeatContext>(); 092 for (int i = 0; i < policies.length; i++) { 093 list.add(policies[i].start(context)); 094 } 095 return new CompositeBatchContext(context, list); 096 097 } 098 099 /** 100 * Update all the composed contexts, and also increment the parent context. 101 * 102 * @see org.springframework.batch.repeat.CompletionPolicy#update(org.springframework.batch.repeat.RepeatContext) 103 */ 104 @Override 105 public void update(RepeatContext context) { 106 RepeatContext[] contexts = ((CompositeBatchContext) context).contexts; 107 CompletionPolicy[] policies = ((CompositeBatchContext) context).policies; 108 for (int i = 0; i < policies.length; i++) { 109 policies[i].update(contexts[i]); 110 } 111 ((RepeatContextSupport) context).increment(); 112 } 113 114 /** 115 * Composite context that knows about the policies and contexts is was 116 * created with. 117 * 118 * @author Dave Syer 119 * 120 */ 121 protected class CompositeBatchContext extends RepeatContextSupport { 122 123 private RepeatContext[] contexts; 124 125 // Save a reference to the policies when we were created - gives some 126 // protection against reference changes (e.g. if the number of policies 127 // change). 128 private CompletionPolicy[] policies; 129 130 public CompositeBatchContext(RepeatContext context, List<RepeatContext> contexts) { 131 super(context); 132 this.contexts = contexts.toArray(new RepeatContext[contexts.size()]); 133 this.policies = CompositeCompletionPolicy.this.policies; 134 } 135 136 } 137 138}