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 org.springframework.batch.repeat.RepeatStatus;
020import org.springframework.batch.repeat.RepeatContext;
021import org.springframework.batch.repeat.context.RepeatContextSupport;
022import org.springframework.batch.repeat.support.RepeatTemplate;
023import org.springframework.util.ClassUtils;
024
025/**
026 * Policy for terminating a batch after a fixed number of operations. Internal
027 * state is maintained and a counter incremented, so successful use of this
028 * policy requires that isComplete() is only called once per batch item. Using
029 * the standard {@link RepeatTemplate} should ensure this contract is kept, but it needs
030 * to be carefully monitored.
031 * 
032 * @author Dave Syer
033 * 
034 */
035public class SimpleCompletionPolicy extends DefaultResultCompletionPolicy {
036
037        public static final int DEFAULT_CHUNK_SIZE = 5;
038
039        int chunkSize = 0;
040
041        public SimpleCompletionPolicy() {
042                this(DEFAULT_CHUNK_SIZE);
043        }
044
045        public SimpleCompletionPolicy(int chunkSize) {
046                super();
047                this.chunkSize = chunkSize;
048        }
049
050        public void setChunkSize(int chunkSize) {
051                this.chunkSize = chunkSize;
052        }
053
054        /**
055         * Reset the counter.
056         * 
057         * @see org.springframework.batch.repeat.CompletionPolicy#start(RepeatContext)
058         */
059    @Override
060        public RepeatContext start(RepeatContext context) {
061                return new SimpleTerminationContext(context);
062        }
063
064        /**
065         * Terminate if the chunk size has been reached, or the result is null.
066         * 
067         * @see org.springframework.batch.repeat.CompletionPolicy#isComplete(RepeatContext,
068         * RepeatStatus)
069         * @throws RuntimeException (normally terminating the batch) if the result is
070         * itself an exception.
071         */
072    @Override
073        public boolean isComplete(RepeatContext context, RepeatStatus result) {
074                return super.isComplete(context, result) || ((SimpleTerminationContext) context).isComplete();
075        }
076
077        /**
078         * Terminate if the chunk size has been reached.
079         * 
080         * @see org.springframework.batch.repeat.CompletionPolicy#isComplete(RepeatContext)
081         */
082    @Override
083        public boolean isComplete(RepeatContext context) {
084                return ((SimpleTerminationContext) context).isComplete();
085        }
086
087        /**
088         * Increment the counter in the context.
089         * 
090         * @see org.springframework.batch.repeat.CompletionPolicy#update(RepeatContext)
091         */
092    @Override
093        public void update(RepeatContext context) {
094                ((SimpleTerminationContext) context).update();
095        }
096
097        protected class SimpleTerminationContext extends RepeatContextSupport {
098
099                public SimpleTerminationContext(RepeatContext context) {
100                        super(context);
101                }
102
103                public void update() {
104                        increment();
105                }
106
107                public boolean isComplete() {
108                        return getStartedCount() >= chunkSize;
109                }
110        }
111        
112        /* (non-Javadoc)
113         * @see java.lang.Object#toString()
114         */
115    @Override
116        public String toString() {
117                return ClassUtils.getShortName(SimpleCompletionPolicy.class)+": chunkSize="+chunkSize;
118        }
119
120}