diff --git a/src/main/java/org/springframework/repeat/CompletionPolicy.java b/src/main/java/org/springframework/repeat/CompletionPolicy.java
deleted file mode 100644
index 51fead0..0000000
--- a/src/main/java/org/springframework/repeat/CompletionPolicy.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright 2006-2007 the original author or authors.
- *
- * 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 org.springframework.repeat;
-
-
-/**
- * Interface for batch completion policies, to enable batch operations to
- * strategise normal completion conditions. Stateful implementations of batch
- * iterators should only update state using the update method. If you
- * need custom behaviour consider extending an existing implementation or using
- * the composite provided.
- *
- * @author Dave Syer
- *
- */
-public interface CompletionPolicy {
-
- /**
- * Determine whether a batch is complete given the latest result from the
- * callback. If this method returns true then
- * {@link #isComplete(RepeatContext)} should also (but not necessarily vice
- * versa, since the answer here depends on the result).
- *
- * @param context the current batch context.
- * @param result the result of the latest batch item processing.
- *
- * @return true if the batch should terminate.
- *
- * @see #isComplete(RepeatContext)
- */
- boolean isComplete(RepeatContext context, RepeatStatus result);
-
- /**
- * Allow policy to signal completion according to internal state, without
- * having to wait for the callback to complete.
- *
- * @param context the current batch context.
- *
- * @return true if the batch should terminate.
- */
- boolean isComplete(RepeatContext context);
-
- /**
- * Create a new context for the execution of a batch. N.B. implementations
- * should not return the parent from this method - they must
- * create a new context to meet the specific needs of the policy. The best
- * way to do this might be to override an existing implementation and use
- * the {@link RepeatContext} to store state in its attributes.
- *
- * @param parent the current context if one is already in progress.
- * @return a context object that can be used by the implementation to store
- * internal state for a batch.
- */
- RepeatContext start(RepeatContext parent);
-
- /**
- * Give implementations the opportunity to update the state of the current
- * batch. Will be called once per callback, after it has been
- * launched, but not necessarily after it completes (if the batch is
- * asynchronous).
- *
- * @param context the value returned by start.
- */
- void update(RepeatContext context);
-
-}
diff --git a/src/main/java/org/springframework/repeat/RepeatCallback.java b/src/main/java/org/springframework/repeat/RepeatCallback.java
deleted file mode 100644
index 2996171..0000000
--- a/src/main/java/org/springframework/repeat/RepeatCallback.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright 2006-2007 the original author or authors.
- *
- * 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 org.springframework.repeat;
-
-
-/**
- * Callback interface for batch operations. Many simple processes will be able
- * to use off-the-shelf implementations of this interface, enabling the
- * application developer to concentrate on business logic.
- *
- * @see RepeatOperations
- *
- * @author Dave Syer
- *
- */
-public interface RepeatCallback {
-
- /**
- * Implementations return true if they can continue processing - e.g. there
- * is a data source that is not yet exhausted. Exceptions are not necessarily
- * fatal - processing might continue depending on the Exception type and the
- * implementation of the caller.
- *
- * @param context the current context passed in by the caller.
- * @return an {@link RepeatStatus} which is continuable if there is (or may
- * be) more data to process.
- * @throws Exception if there is a problem with the processing.
- */
- RepeatStatus doInIteration(RepeatContext context) throws Exception;
-}
diff --git a/src/main/java/org/springframework/repeat/RepeatContext.java b/src/main/java/org/springframework/repeat/RepeatContext.java
deleted file mode 100644
index bcc528d..0000000
--- a/src/main/java/org/springframework/repeat/RepeatContext.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright 2006-2007 the original author or authors.
- *
- * 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 org.springframework.repeat;
-
-import org.springframework.core.AttributeAccessor;
-
-/**
- * Base interface for context which controls the state and completion /
- * termination of a batch step. A new context is created for each call to the
- * {@link RepeatOperations}. Within a batch callback code can communicate via
- * the {@link AttributeAccessor} interface.
- *
- * @author Dave Syer
- *
- * @see RepeatOperations#iterate(RepeatCallback)
- *
- */
-public interface RepeatContext extends AttributeAccessor {
-
- /**
- * If batches are nested, then the inner batch will be created with the
- * outer one as a parent. This is an accessor for the parent if it exists.
- *
- * @return the parent context or null if there is none
- */
- RepeatContext getParent();
-
- /**
- * Public access to a counter for the number of operations attempted.
- *
- * @return the number of batch operations started.
- */
- int getStartedCount();
-
- /**
- * Signal to the framework that the current batch should complete normally,
- * independent of the current {@link CompletionPolicy}.
- */
- void setCompleteOnly();
-
- /**
- * Public accessor for the complete flag.
- */
- boolean isCompleteOnly();
-
- /**
- * Signal to the framework that the current batch should complete
- * abnormally, independent of the current {@link CompletionPolicy}.
- */
- void setTerminateOnly();
-
- /**
- * Public accessor for the termination flag. If this flag is set then the
- * complete flag will also be.
- */
- boolean isTerminateOnly();
-
- /**
- * Register a callback to be executed on close, associated with the
- * attribute having the given name. The {@link Runnable} callback should not
- * throw any exceptions.
- *
- * @param name the name of the attribute to associated this callback with.
- * If this attribute is removed the callback should never be called.
- * @param callback a {@link Runnable} to execute when the context is closed.
- */
- void registerDestructionCallback(String name, Runnable callback);
-
- /**
- * Allow resources to be cleared, especially in destruction callbacks.
- * Implementations should ensure that any registered destruction callbacks
- * are executed here, as long as the corresponding attribute is still
- * available.
- */
- void close();
-
-}
diff --git a/src/main/java/org/springframework/repeat/RepeatException.java b/src/main/java/org/springframework/repeat/RepeatException.java
deleted file mode 100644
index 9f02abf..0000000
--- a/src/main/java/org/springframework/repeat/RepeatException.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright 2006-2007 the original author or authors.
- *
- * 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 org.springframework.repeat;
-
-import org.springframework.core.NestedRuntimeException;
-
-public class RepeatException extends NestedRuntimeException {
-
- public RepeatException(String msg) {
- super(msg);
- }
-
- public RepeatException(String msg, Throwable t) {
- super(msg, t);
- }
-
-}
diff --git a/src/main/java/org/springframework/repeat/RepeatListener.java b/src/main/java/org/springframework/repeat/RepeatListener.java
deleted file mode 100644
index 834d40b..0000000
--- a/src/main/java/org/springframework/repeat/RepeatListener.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright 2006-2007 the original author or authors.
- *
- * 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 org.springframework.repeat;
-
-
-/**
- * Interface for listeners to the batch process. Implementers can provide
- * enhance the behaviour of a batch in small cross-cutting modules. The
- * framework provides callbacks at key points in the processing.
- *
- * @author Dave Syer
- *
- */
-public interface RepeatListener {
- /**
- * Called by the framework before each batch item. Implementers can halt a
- * batch by setting the complete flag on the context.
- *
- * @param context the current batch context.
- */
- void before(RepeatContext context);
-
- /**
- * Called by the framework after each item has been processed, unless the
- * item processing results in an exception. This method is called as soon as
- * the result is known.
- *
- * @param context the current batch context
- * @param result the result of the callback
- */
- void after(RepeatContext context, RepeatStatus result);
-
- /**
- * Called once at the start of a complete batch, before any items are
- * processed. Implementers can use this method to acquire any resources that
- * might be needed during processing. Implementers can halt the current
- * operation by setting the complete flag on the context. To halt all
- * enclosing batches (the whole job), the would need to use the parent
- * context (recursively).
- *
- * @param context the current batch context
- */
- void open(RepeatContext context);
-
- /**
- * Called when a repeat callback fails by throwing an exception. There will
- * be one call to this method for each exception thrown during a repeat
- * operation (e.g. a chunk).
- *
- * There is no need to re-throw the exception here - that will be done by
- * the enclosing framework.
- *
- * @param context the current batch context
- * @param e the error that was encountered in an item callback.
- */
- void onError(RepeatContext context, Throwable e);
-
- /**
- * Called once at the end of a complete batch, after normal or abnormal
- * completion (i.e. even after an exception). Implementers can use this
- * method to clean up any resources.
- *
- * @param context the current batch context.
- */
- void close(RepeatContext context);
-}
diff --git a/src/main/java/org/springframework/repeat/RepeatOperations.java b/src/main/java/org/springframework/repeat/RepeatOperations.java
deleted file mode 100644
index c6a8965..0000000
--- a/src/main/java/org/springframework/repeat/RepeatOperations.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright 2006-2007 the original author or authors.
- *
- * 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 org.springframework.repeat;
-
-
-/**
- * The main interface providing access to batch operations. The batch client is
- * the {@link RepeatCallback}, where a single item or record is processed. The
- * batch behaviour, boundary conditions, transactions etc, are dealt with by the
- * {@link RepeatOperations} in such as way that the client does not need to know
- * about them. The client may have access to framework abstractions, like
- * template data sources, but these should work the same whether they are in a
- * batch or not.
- *
- * @author Dave Syer
- *
- */
-public interface RepeatOperations {
-
- /**
- * Execute the callback repeatedly, until a decision can be made to
- * complete. The decision about how many times to execute or when to
- * complete, and what to do in the case of an error is delegated to a
- * {@link CompletionPolicy}.
- *
- * @param callback the batch callback.
- * @return the aggregate of the result of all the callback operations. An
- * indication of whether the {@link RepeatOperations} can continue
- * processing if this method is called again.
- */
- RepeatStatus iterate(RepeatCallback callback) throws RepeatException;
-
-}
diff --git a/src/main/java/org/springframework/repeat/RepeatStatus.java b/src/main/java/org/springframework/repeat/RepeatStatus.java
deleted file mode 100644
index 7b41a51..0000000
--- a/src/main/java/org/springframework/repeat/RepeatStatus.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright 2006-2007 the original author or authors.
- *
- * 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 org.springframework.repeat;
-
-public enum RepeatStatus {
-
- /**
- * Indicates that processing can continue.
- */
- CONTINUABLE(true),
- /**
- * Indicates that processing is finished (either successful or unsuccessful)
- */
- FINISHED(false);
-
- private final boolean continuable;
-
- private RepeatStatus(boolean continuable) {
- this.continuable = continuable;
- }
-
- public static RepeatStatus continueIf(boolean continuable) {
- return continuable ? CONTINUABLE : FINISHED;
- }
-
- public boolean isContinuable() {
- return this == CONTINUABLE;
- }
-
- public RepeatStatus and(boolean value) {
- return value && continuable ? CONTINUABLE : FINISHED;
- }
-
-}
diff --git a/src/main/java/org/springframework/repeat/callback/NestedRepeatCallback.java b/src/main/java/org/springframework/repeat/callback/NestedRepeatCallback.java
deleted file mode 100644
index c5708fe..0000000
--- a/src/main/java/org/springframework/repeat/callback/NestedRepeatCallback.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright 2006-2007 the original author or authors.
- *
- * 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 org.springframework.repeat.callback;
-
-import org.springframework.repeat.RepeatCallback;
-import org.springframework.repeat.RepeatContext;
-import org.springframework.repeat.RepeatOperations;
-import org.springframework.repeat.RepeatStatus;
-
-/**
- * Callback that delegates to another callback, via a {@link RepeatOperations}
- * instance. Useful when nesting or composing batches in one another, e.g. for
- * breaking a batch down into chunks.
- *
- * @author Dave Syer
- *
- */
-public class NestedRepeatCallback implements RepeatCallback {
-
- private RepeatOperations template;
-
- private RepeatCallback callback;
-
- /**
- * Constructor setting mandatory fields.
- *
- * @param template the {@link RepeatOperations} to use when calling the
- * delegate callback
- * @param callback the {@link RepeatCallback} delegate
- */
- public NestedRepeatCallback(RepeatOperations template, RepeatCallback callback) {
- super();
- this.template = template;
- this.callback = callback;
- }
-
- /**
- * Simply calls template.execute(callback). Clients can use this to repeat a
- * batch process, or to break a process up into smaller chunks (e.g. to
- * change the transaction boundaries).
- *
- * @see org.springframework.repeat.RepeatCallback#doInIteration(RepeatContext)
- */
- public RepeatStatus doInIteration(RepeatContext context) throws Exception {
- return template.iterate(callback);
- }
-}
diff --git a/src/main/java/org/springframework/repeat/callback/package.html b/src/main/java/org/springframework/repeat/callback/package.html
deleted file mode 100644
index a25a6cf..0000000
--- a/src/main/java/org/springframework/repeat/callback/package.html
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-Infrastructure implementations of repeat callback concerns.
-
-
-
diff --git a/src/main/java/org/springframework/repeat/context/RepeatContextCounter.java b/src/main/java/org/springframework/repeat/context/RepeatContextCounter.java
deleted file mode 100644
index 9830607..0000000
--- a/src/main/java/org/springframework/repeat/context/RepeatContextCounter.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright 2006-2007 the original author or authors.
- *
- * 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 org.springframework.repeat.context;
-
-import java.util.concurrent.atomic.AtomicInteger;
-
-import org.springframework.repeat.RepeatContext;
-import org.springframework.util.Assert;
-
-/**
- * Helper class for policies that need to count the number of occurrences of
- * some event (e.g. an exception type in the context) in the scope of a batch.
- * The value of the counter can be stored between batches in a nested context,
- * so that the termination decision is based on the aggregate of a number of
- * sibling batches.
- *
- * @author Dave Syer
- *
- */
-public class RepeatContextCounter {
-
- final private String countKey;
-
- /**
- * Flag to indicate whether the count is stored at the level of the parent
- * context, or just local to the current context. Default value is false.
- */
- final private boolean useParent;
-
- final private RepeatContext context;
-
- /**
- * Increment the counter.
- *
- * @param delta the amount by which to increment the counter.
- */
- final public void increment(int delta) {
- AtomicInteger count = getCounter();
- count.addAndGet(delta);
- }
-
- /**
- * Increment by 1.
- */
- final public void increment() {
- increment(1);
- }
-
- /**
- * Convenience constructor with useParent=false.
- * @param context the current context.
- * @param countKey the key to use to store the counter in the context.
- */
- public RepeatContextCounter(RepeatContext context, String countKey) {
- this(context, countKey, false);
- }
-
- /**
- * Construct a new {@link RepeatContextCounter}.
- *
- * @param context the current context.
- * @param countKey the key to use to store the counter in the context.
- * @param useParent true if the counter is to be shared between siblings.
- * The state will be stored in the parent of the context (if it exists)
- * instead of the context itself.
- */
- public RepeatContextCounter(RepeatContext context, String countKey, boolean useParent) {
-
- super();
-
- Assert.notNull(context, "The context must be provided to initialize a counter");
-
- this.countKey = countKey;
- this.useParent = useParent;
-
- RepeatContext parent = context.getParent();
-
- if (this.useParent && parent != null) {
- this.context = parent;
- }
- else {
- this.context = context;
- }
- if (!this.context.hasAttribute(countKey)) {
- this.context.setAttribute(countKey, new AtomicInteger());
- }
-
- }
-
- /**
- * @return the current value of the counter
- */
- public int getCount() {
- return getCounter().intValue();
- }
-
- private AtomicInteger getCounter() {
- return ((AtomicInteger) context.getAttribute(countKey));
- }
-
-}
diff --git a/src/main/java/org/springframework/repeat/context/RepeatContextSupport.java b/src/main/java/org/springframework/repeat/context/RepeatContextSupport.java
deleted file mode 100644
index 8430b7a..0000000
--- a/src/main/java/org/springframework/repeat/context/RepeatContextSupport.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * Copyright 2006-2007 the original author or authors.
- *
- * 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 org.springframework.repeat.context;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.springframework.repeat.RepeatContext;
-
-public class RepeatContextSupport extends SynchronizedAttributeAccessor implements RepeatContext {
-
- private RepeatContext parent;
-
- private int count;
-
- private volatile boolean completeOnly;
-
- private volatile boolean terminateOnly;
-
- private Map> callbacks = new HashMap>();
-
- /**
- * Constructor for {@link RepeatContextSupport}. The parent can be null, but
- * should be set to the enclosing repeat context if there is one, e.g. if
- * this context is an inner loop.
- * @param parent
- */
- public RepeatContextSupport(RepeatContext parent) {
- super();
- this.parent = parent;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.springframework.batch.repeat.RepeatContext#isCompleteOnly()
- */
- public boolean isCompleteOnly() {
- return completeOnly;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.springframework.batch.repeat.RepeatContext#setCompleteOnly()
- */
- public void setCompleteOnly() {
- completeOnly = true;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.springframework.batch.repeat.RepeatContext#isTerminateOnly()
- */
- public boolean isTerminateOnly() {
- return terminateOnly;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.springframework.batch.repeat.RepeatContext#setTerminateOnly()
- */
- public void setTerminateOnly() {
- terminateOnly = true;
- setCompleteOnly();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.springframework.batch.repeat.RepeatContext#getParent()
- */
- public RepeatContext getParent() {
- return parent;
- }
-
- /**
- * Used by clients to increment the started count.
- */
- public synchronized void increment() {
- count++;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.springframework.batch.repeat.RepeatContext#getStartedCount()
- */
- public synchronized int getStartedCount() {
- return count;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * org.springframework.batch.repeat.RepeatContext#registerDestructionCallback
- * (java.lang.String, java.lang.Runnable)
- */
- public void registerDestructionCallback(String name, Runnable callback) {
- synchronized (callbacks) {
- Set set = callbacks.get(name);
- if (set == null) {
- set = new HashSet();
- callbacks.put(name, set);
- }
- set.add(callback);
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.springframework.batch.repeat.RepeatContext#close()
- */
- public void close() {
-
- List errors = new ArrayList();
-
- Set>> copy;
-
- synchronized (callbacks) {
- copy = new HashSet>>(callbacks.entrySet());
- }
-
- for (Map.Entry> entry : copy) {
-
- for (Runnable callback : entry.getValue()) {
- /*
- * Potentially we could check here if there is an attribute with
- * the given name - if it has been removed, maybe the callback
- * is invalid. On the other hand it is less surprising for the
- * callback register if it is always executed.
- */
- if (callback != null) {
- /*
- * The documentation of the interface says that these
- * callbacks must not throw exceptions, but we don't trust
- * them necessarily...
- */
- try {
- callback.run();
- }
- catch (RuntimeException t) {
- errors.add(t);
- }
- }
- }
- }
-
- if (errors.isEmpty()) {
- return;
- }
-
- throw (RuntimeException) errors.get(0);
- }
-
-}
diff --git a/src/main/java/org/springframework/repeat/context/SynchronizedAttributeAccessor.java b/src/main/java/org/springframework/repeat/context/SynchronizedAttributeAccessor.java
deleted file mode 100644
index f67b2b6..0000000
--- a/src/main/java/org/springframework/repeat/context/SynchronizedAttributeAccessor.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright 2006-2007 the original author or authors.
- *
- * 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 org.springframework.repeat.context;
-
-import org.springframework.core.AttributeAccessor;
-import org.springframework.core.AttributeAccessorSupport;
-
-/**
- * An {@link AttributeAccessor} that synchronizes on a mutex (not this) before
- * modifying or accessing the underlying attributes.
- *
- * @author Dave Syer
- *
- */
-public class SynchronizedAttributeAccessor implements AttributeAccessor {
-
- /**
- * All methods are delegated to this support object.
- */
- AttributeAccessorSupport support = new AttributeAccessorSupport() {
- /**
- * Generated serial UID.
- */
- private static final long serialVersionUID = -7664290016506582290L;
- };
-
- /*
- * (non-Javadoc)
- * @see org.springframework.core.AttributeAccessor#attributeNames()
- */
- public String[] attributeNames() {
- synchronized (support) {
- return support.attributeNames();
- }
- }
-
- /*
- * (non-Javadoc)
- * @see java.lang.Object#equals(java.lang.Object)
- */
- public boolean equals(Object other) {
- if (this == other) {
- return true;
- }
- AttributeAccessorSupport that;
- if (other instanceof SynchronizedAttributeAccessor) {
- that = ((SynchronizedAttributeAccessor) other).support;
- }
- else if (other instanceof AttributeAccessorSupport) {
- that = (AttributeAccessorSupport) other;
- }
- else {
- return false;
- }
- synchronized (support) {
- return support.equals(that);
- }
- }
-
- /*
- * (non-Javadoc)
- * @see org.springframework.core.AttributeAccessor#getAttribute(java.lang.String)
- */
- public Object getAttribute(String name) {
- synchronized (support) {
- return support.getAttribute(name);
- }
- }
-
- /*
- * (non-Javadoc)
- * @see org.springframework.core.AttributeAccessor#hasAttribute(java.lang.String)
- */
- public boolean hasAttribute(String name) {
- synchronized (support) {
- return support.hasAttribute(name);
- }
- }
-
- /*
- * (non-Javadoc)
- * @see java.lang.Object#hashCode()
- */
- public int hashCode() {
- return support.hashCode();
- }
-
- /*
- * (non-Javadoc)
- * @see org.springframework.core.AttributeAccessor#removeAttribute(java.lang.String)
- */
- public Object removeAttribute(String name) {
- synchronized (support) {
- return support.removeAttribute(name);
- }
- }
-
- /*
- * (non-Javadoc)
- * @see org.springframework.core.AttributeAccessor#setAttribute(java.lang.String,
- * java.lang.Object)
- */
- public void setAttribute(String name, Object value) {
- synchronized (support) {
- support.setAttribute(name, value);
- }
- }
-
- /**
- * Additional support for atomic put if absent.
- * @param name the key for the attribute name
- * @param value the value of the attribute
- * @return null if the attribute was not already set, the existing value
- * otherwise.
- */
- public Object setAttributeIfAbsent(String name, Object value) {
- synchronized (support) {
- Object old = getAttribute(name);
- if (old != null) {
- return old;
- }
- setAttribute(name, value);
- }
- return null;
- }
-
- /*
- * (non-Javadoc)
- * @see java.lang.Object#toString()
- */
- public String toString() {
- StringBuffer buffer = new StringBuffer("SynchronizedAttributeAccessor: [");
- synchronized (support) {
- String[] names = attributeNames();
- for (int i = 0; i < names.length; i++) {
- String name = names[i];
- buffer.append(names[i]).append("=").append(getAttribute(name));
- if (i < names.length - 1) {
- buffer.append(", ");
- }
- }
- buffer.append("]");
- return buffer.toString();
- }
- }
-
-}
diff --git a/src/main/java/org/springframework/repeat/context/package.html b/src/main/java/org/springframework/repeat/context/package.html
deleted file mode 100644
index 7bb43fa..0000000
--- a/src/main/java/org/springframework/repeat/context/package.html
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-Infrastructure implementations of repeat context concerns.
-
-
-
diff --git a/src/main/java/org/springframework/repeat/exception/CompositeExceptionHandler.java b/src/main/java/org/springframework/repeat/exception/CompositeExceptionHandler.java
deleted file mode 100644
index ba808ef..0000000
--- a/src/main/java/org/springframework/repeat/exception/CompositeExceptionHandler.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright 2006-2007 the original author or authors.
- *
- * 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 org.springframework.repeat.exception;
-
-import java.util.Arrays;
-
-import org.springframework.repeat.RepeatContext;
-
-/**
- * Composiste {@link ExceptionHandler} that loops though a list of delegates.
- *
- * @author Dave Syer
- *
- */
-public class CompositeExceptionHandler implements ExceptionHandler {
-
- private ExceptionHandler[] handlers = new ExceptionHandler[0];
-
- public void setHandlers(ExceptionHandler[] handlers) {
- this.handlers = Arrays.asList(handlers).toArray(new ExceptionHandler[handlers.length]);
- }
-
- /**
- * Iterate over the handlers delegating the call to each in turn. The chain
- * ends if an exception is thrown.
- *
- * @see ExceptionHandler#handleException(RepeatContext, Throwable)
- */
- public void handleException(RepeatContext context, Throwable throwable) throws Throwable {
- for (int i = 0; i < handlers.length; i++) {
- ExceptionHandler handler = handlers[i];
- handler.handleException(context, throwable);
- }
- }
-}
diff --git a/src/main/java/org/springframework/repeat/exception/DefaultExceptionHandler.java b/src/main/java/org/springframework/repeat/exception/DefaultExceptionHandler.java
deleted file mode 100644
index eb1ce51..0000000
--- a/src/main/java/org/springframework/repeat/exception/DefaultExceptionHandler.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright 2006-2007 the original author or authors.
- *
- * 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 org.springframework.repeat.exception;
-
-import org.springframework.repeat.RepeatContext;
-
-/**
- * Default implementation of {@link ExceptionHandler} - just re-throws the exception it encounters.
- *
- * @author Dave Syer
- *
- */
-public class DefaultExceptionHandler implements ExceptionHandler {
-
- /**
- * Re-throw the throwable.
- *
- * @see org.springframework.repeat.exception.ExceptionHandler#handleException(RepeatContext,
- * Throwable)
- */
- public void handleException(RepeatContext context, Throwable throwable) throws Throwable {
- throw throwable;
- }
-
-}
diff --git a/src/main/java/org/springframework/repeat/exception/ExceptionHandler.java b/src/main/java/org/springframework/repeat/exception/ExceptionHandler.java
deleted file mode 100644
index 0634952..0000000
--- a/src/main/java/org/springframework/repeat/exception/ExceptionHandler.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright 2006-2007 the original author or authors.
- *
- * 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 org.springframework.repeat.exception;
-
-import org.springframework.repeat.CompletionPolicy;
-import org.springframework.repeat.RepeatContext;
-
-/**
- * Handler to allow strategies for re-throwing exceptions. Normally a
- * {@link CompletionPolicy} will be used to decide whether to end a batch when
- * there is no exception, and the {@link ExceptionHandler} is used to signal an
- * abnormal ending - an abnormal ending would result in an
- * {@link ExceptionHandler} throwing an exception. The caller will catch and
- * re-throw it if necessary.
- *
- * @author Dave Syer
- * @author Robert Kasanicky
- *
- */
-public interface ExceptionHandler {
-
- /**
- * Deal with a Throwable during a batch - decide whether it should be
- * re-thrown in the first place.
- *
- * @param context the current {@link RepeatContext}. Can be used to store
- * state (via attributes), for example to count the number of occurrences of
- * a particular exception type and implement a threshold policy.
- * @param throwable an exception.
- * @throws Throwable implementations are free to re-throw the exception
- */
- void handleException(RepeatContext context, Throwable throwable) throws Throwable;
-
-}
diff --git a/src/main/java/org/springframework/repeat/exception/LogOrRethrowExceptionHandler.java b/src/main/java/org/springframework/repeat/exception/LogOrRethrowExceptionHandler.java
deleted file mode 100644
index 51f03d1..0000000
--- a/src/main/java/org/springframework/repeat/exception/LogOrRethrowExceptionHandler.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright 2006-2007 the original author or authors.
- *
- * 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 org.springframework.repeat.exception;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.springframework.classify.Classifier;
-import org.springframework.classify.ClassifierSupport;
-import org.springframework.repeat.RepeatContext;
-import org.springframework.repeat.RepeatException;
-
-/**
- * Implementation of {@link ExceptionHandler} based on an {@link Classifier}.
- * The classifier determines whether to log the exception or rethrow it. The
- * keys in the classifier must be the same as the static enum in this class.
- *
- * @author Dave Syer
- *
- */
-public class LogOrRethrowExceptionHandler implements ExceptionHandler {
-
- /**
- * Logging levels for the handler.
- *
- * @author Dave Syer
- *
- */
- public static enum Level {
-
- /**
- * Key for {@link Classifier} signalling that the throwable should be
- * rethrown. If the throwable is not a RuntimeException it is wrapped in
- * a {@link RepeatException}.
- */
- RETHROW,
-
- /**
- * Key for {@link Classifier} signalling that the throwable should be
- * logged at debug level.
- */
- DEBUG,
-
- /**
- * Key for {@link Classifier} signalling that the throwable should be
- * logged at warn level.
- */
- WARN,
-
- /**
- * Key for {@link Classifier} signalling that the throwable should be
- * logged at error level.
- */
- ERROR
-
- }
-
- protected final Log logger = LogFactory.getLog(LogOrRethrowExceptionHandler.class);
-
- private Classifier exceptionClassifier = new ClassifierSupport(Level.RETHROW);
-
- /**
- * Setter for the {@link Classifier} used by this handler. The default is to
- * map all throwable instances to {@link Level#RETHROW}.
- *
- * @param exceptionClassifier the ExceptionClassifier to use
- */
- public void setExceptionClassifier(Classifier exceptionClassifier) {
- this.exceptionClassifier = exceptionClassifier;
- }
-
- /**
- * Classify the throwables and decide whether to rethrow based on the
- * result. The context is not used.
- *
- * @throws Throwable
- *
- * @see ExceptionHandler#handleException(RepeatContext, Throwable)
- */
- public void handleException(RepeatContext context, Throwable throwable) throws Throwable {
-
- Level key = exceptionClassifier.classify(throwable);
- if (Level.ERROR.equals(key)) {
- logger.error("Exception encountered in batch repeat.", throwable);
- }
- else if (Level.WARN.equals(key)) {
- logger.warn("Exception encountered in batch repeat.", throwable);
- }
- else if (Level.DEBUG.equals(key) && logger.isDebugEnabled()) {
- logger.debug("Exception encountered in batch repeat.", throwable);
- }
- else if (Level.RETHROW.equals(key)) {
- throw throwable;
- }
-
- }
-
-}
diff --git a/src/main/java/org/springframework/repeat/exception/RethrowOnThresholdExceptionHandler.java b/src/main/java/org/springframework/repeat/exception/RethrowOnThresholdExceptionHandler.java
deleted file mode 100644
index 22b61a9..0000000
--- a/src/main/java/org/springframework/repeat/exception/RethrowOnThresholdExceptionHandler.java
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * Copyright 2006-2007 the original author or authors.
- *
- * 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 org.springframework.repeat.exception;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.springframework.classify.Classifier;
-import org.springframework.classify.SubclassClassifier;
-import org.springframework.repeat.RepeatContext;
-import org.springframework.repeat.context.RepeatContextCounter;
-import org.springframework.util.ObjectUtils;
-
-/**
- * Implementation of {@link ExceptionHandler} that rethrows when exceptions of a
- * given type reach a threshold. Requires an {@link Classifier} that maps
- * exception types to unique keys, and also a map from those keys to threshold
- * values (Integer type).
- *
- * @author Dave Syer
- *
- */
-public class RethrowOnThresholdExceptionHandler implements ExceptionHandler {
-
- protected static final IntegerHolder ZERO = new IntegerHolder(0);
-
- protected final Log logger = LogFactory.getLog(RethrowOnThresholdExceptionHandler.class);
-
- private Classifier super Throwable, IntegerHolder> exceptionClassifier = new Classifier() {
- public RethrowOnThresholdExceptionHandler.IntegerHolder classify(Throwable classifiable) {
- return ZERO;
- }
- };
-
- private boolean useParent = false;
-
- /**
- * Flag to indicate the the exception counters should be shared between
- * sibling contexts in a nested batch. Default is false.
- *
- * @param useParent true if the parent context should be used to store the
- * counters.
- */
- public void setUseParent(boolean useParent) {
- this.useParent = useParent;
- }
-
- /**
- * Set up the exception handler. Creates a default exception handler and
- * threshold that maps all exceptions to a threshold of 0 - all exceptions
- * are rethrown by default.
- */
- public RethrowOnThresholdExceptionHandler() {
- super();
- }
-
- /**
- * A map from exception classes to a threshold value of type Integer.
- *
- * @param thresholds the threshold value map.
- */
- public void setThresholds(Map, Integer> thresholds) {
- Map, IntegerHolder> typeMap = new HashMap, IntegerHolder>();
- for (Entry, Integer> entry : thresholds.entrySet()) {
- typeMap.put(entry.getKey(), new IntegerHolder(entry.getValue()));
- }
- exceptionClassifier = new SubclassClassifier(typeMap, ZERO);
- }
-
- /**
- * Classify the throwables and decide whether to re-throw based on the
- * result. The context is used to accumulate the number of exceptions of the
- * same type according to the classifier.
- *
- * @throws Throwable
- * @see ExceptionHandler#handleException(RepeatContext, Throwable)
- */
- public void handleException(RepeatContext context, Throwable throwable) throws Throwable {
-
- IntegerHolder key = exceptionClassifier.classify(throwable);
-
- RepeatContextCounter counter = getCounter(context, key);
- counter.increment();
- int count = counter.getCount();
- int threshold = key.getValue();
- if (count > threshold) {
- throw throwable;
- }
-
- }
-
- private RepeatContextCounter getCounter(RepeatContext context, IntegerHolder key) {
- String attribute = RethrowOnThresholdExceptionHandler.class.getName() + "." + key;
- // Creates a new counter and stores it in the correct context:
- return new RepeatContextCounter(context, attribute, useParent);
- }
-
- /**
- * @author Dave Syer
- *
- */
- private static class IntegerHolder {
-
- private final int value;
-
- /**
- * @param value
- */
- public IntegerHolder(int value) {
- this.value = value;
- }
-
- /**
- * Public getter for the value.
- * @return the value
- */
- public int getValue() {
- return value;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#toString()
- */
- @Override
- public String toString() {
- return ObjectUtils.getIdentityHexString(this) + "." + value;
- }
-
- }
-
-}
diff --git a/src/main/java/org/springframework/repeat/exception/SimpleLimitExceptionHandler.java b/src/main/java/org/springframework/repeat/exception/SimpleLimitExceptionHandler.java
deleted file mode 100644
index 1786091..0000000
--- a/src/main/java/org/springframework/repeat/exception/SimpleLimitExceptionHandler.java
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright 2006-2007 the original author or authors.
- *
- * 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 org.springframework.repeat.exception;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.springframework.beans.factory.InitializingBean;
-import org.springframework.repeat.RepeatContext;
-
-/**
- * Simple implementation of exception handler which looks for given exception
- * types. If one of the types is found then a counter is incremented and the
- * limit is checked to determine if it has been exceeded and the Throwable
- * should be re-thrown. Also allows to specify list of 'fatal' exceptions that
- * are never subject to counting, but are immediately re-thrown. The fatal list
- * has higher priority so the two lists needn't be exclusive.
- *
- * @author Dave Syer
- * @author Robert Kasanicky
- */
-public class SimpleLimitExceptionHandler implements ExceptionHandler, InitializingBean {
-
- private RethrowOnThresholdExceptionHandler delegate = new RethrowOnThresholdExceptionHandler();
-
- private Collection> exceptionClasses = Collections
- .> singleton(Exception.class);
-
- private Collection> fatalExceptionClasses = Collections
- .> singleton(Error.class);
-
- private int limit = 0;
-
- /**
- * Apply the provided properties to create a delegate handler.
- *
- * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
- */
- public void afterPropertiesSet() throws Exception {
- if (limit <= 0) {
- return;
- }
- Map, Integer> thresholds = new HashMap, Integer>();
- for (Class extends Throwable> type : exceptionClasses) {
- thresholds.put(type, limit);
- }
- // do the fatalExceptionClasses last so they override the others
- for (Class extends Throwable> type : fatalExceptionClasses) {
- thresholds.put(type, 0);
- }
- delegate.setThresholds(thresholds);
- }
-
- /**
- * Flag to indicate the the exception counters should be shared between
- * sibling contexts in a nested batch (i.e. inner loop). Default is false.
- * Set this flag to true if you want to count exceptions for the whole
- * (outer) loop in a typical container.
- *
- * @param useParent true if the parent context should be used to store the
- * counters.
- */
- public void setUseParent(boolean useParent) {
- delegate.setUseParent(useParent);
- }
-
- /**
- * Convenience constructor for the {@link SimpleLimitExceptionHandler} to
- * set the limit.
- *
- * @param limit the limit
- */
- public SimpleLimitExceptionHandler(int limit) {
- this();
- this.limit = limit;
- }
-
- /**
- * Default constructor for the {@link SimpleLimitExceptionHandler}.
- */
- public SimpleLimitExceptionHandler() {
- super();
- }
-
- /**
- * Rethrows only if the limit is breached for this context on the exception
- * type specified.
- *
- * @see #setExceptionClasses(Collection)
- * @see #setLimit(int)
- *
- * @see org.springframework.repeat.exception.ExceptionHandler#handleException(org.springframework.repeat.RepeatContext,
- * Throwable)
- */
- public void handleException(RepeatContext context, Throwable throwable) throws Throwable {
- delegate.handleException(context, throwable);
- }
-
- /**
- * The limit on the given exception type within a single context before it
- * is rethrown.
- *
- * @param limit the limit
- */
- public void setLimit(final int limit) {
- this.limit = limit;
- }
-
- /**
- * Setter for the exception classes that this handler counts. Defaults to
- * {@link Exception}. If more exceptionClasses are specified handler uses
- * single counter that is incremented when one of the recognized exception
- * exceptionClasses is handled.
- * @param classes exceptionClasses
- */
- public void setExceptionClasses(Collection> classes) {
- this.exceptionClasses = classes;
- }
-
- /**
- * Setter for the exception classes that shouldn't be counted, but rethrown
- * immediately. This list has higher priority than
- * {@link #setExceptionClasses(Collection)}.
- *
- * @param fatalExceptionClasses defaults to {@link Error}
- */
- public void setFatalExceptionClasses(Collection> fatalExceptionClasses) {
- this.fatalExceptionClasses = fatalExceptionClasses;
- }
-
-}
diff --git a/src/main/java/org/springframework/repeat/exception/package.html b/src/main/java/org/springframework/repeat/exception/package.html
deleted file mode 100644
index edbc051..0000000
--- a/src/main/java/org/springframework/repeat/exception/package.html
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-Infrastructure implementations of repeat exception handler concerns.
-
-
-
diff --git a/src/main/java/org/springframework/repeat/interceptor/RepeatOperationsInterceptor.java b/src/main/java/org/springframework/repeat/interceptor/RepeatOperationsInterceptor.java
deleted file mode 100644
index 37c5c3b..0000000
--- a/src/main/java/org/springframework/repeat/interceptor/RepeatOperationsInterceptor.java
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * Copyright 2006-2007 the original author or authors.
- *
- * 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 org.springframework.repeat.interceptor;
-
-import org.aopalliance.intercept.MethodInterceptor;
-import org.aopalliance.intercept.MethodInvocation;
-import org.springframework.aop.ProxyMethodInvocation;
-import org.springframework.repeat.RepeatCallback;
-import org.springframework.repeat.RepeatContext;
-import org.springframework.repeat.RepeatException;
-import org.springframework.repeat.RepeatOperations;
-import org.springframework.repeat.RepeatStatus;
-import org.springframework.repeat.support.RepeatTemplate;
-import org.springframework.util.Assert;
-
-/**
- * A {@link MethodInterceptor} that can be used to automatically repeat calls to
- * a method on a service. The injected {@link RepeatOperations} is used to
- * control the completion of the loop. Independent of the completion policy in
- * the {@link RepeatOperations} the loop will repeat until the target method
- * returns null or false. Be careful when injecting a bespoke
- * {@link RepeatOperations} that the loop will actually terminate, because the
- * default policy for a vanilla {@link RepeatTemplate} will never complete if
- * the return type of the target method is void (the value returned is always
- * not-null, representing the {@link Void#TYPE}).
- *
- * @author Dave Syer
- */
-public class RepeatOperationsInterceptor implements MethodInterceptor {
-
- private RepeatOperations repeatOperations = new RepeatTemplate();
-
- /**
- * Setter for the {@link RepeatOperations}.
- *
- * @param batchTempate
- * @throws IllegalArgumentException if the argument is null.
- */
- public void setRepeatOperations(RepeatOperations batchTempate) {
- Assert.notNull(batchTempate, "'repeatOperations' cannot be null.");
- this.repeatOperations = batchTempate;
- }
-
- /**
- * Invoke the proceeding method call repeatedly, according to the properties
- * of the injected {@link RepeatOperations}.
- *
- * @see org.aopalliance.intercept.MethodInterceptor#invoke(org.aopalliance.intercept.MethodInvocation)
- */
- public Object invoke(final MethodInvocation invocation) throws Throwable {
-
- final ResultHolder result = new ResultHolder();
- // Cache void return value if intercepted method returns void
- final boolean voidReturnType = Void.TYPE.equals(invocation.getMethod().getReturnType());
- if (voidReturnType) {
- // This will be ignored anyway, but we want it to be non-null for
- // convenience of checking that there is a result.
- result.setValue(new Object());
- }
-
- try {
- repeatOperations.iterate(new RepeatCallback() {
-
- public RepeatStatus doInIteration(RepeatContext context) throws Exception {
- try {
-
- MethodInvocation clone = invocation;
- if (invocation instanceof ProxyMethodInvocation) {
- clone = ((ProxyMethodInvocation) invocation).invocableClone();
- }
- else {
- throw new IllegalStateException(
- "MethodInvocation of the wrong type detected - this should not happen with Spring AOP, so please raise an issue if you see this exception");
- }
-
- Object value = clone.proceed();
- if (voidReturnType) {
- return RepeatStatus.CONTINUABLE;
- }
- if (!isComplete(value)) {
- // Save the last result
- result.setValue(value);
- return RepeatStatus.CONTINUABLE;
- }
- else {
- result.setFinalValue(value);
- return RepeatStatus.FINISHED;
- }
- }
- catch (Throwable e) {
- if (e instanceof Exception) {
- throw (Exception) e;
- }
- else {
- throw new RepeatOperationsInterceptorException("Unexpected error in batch interceptor", e);
- }
- }
- }
-
- });
- }
- catch (Throwable t) {
- // The repeat exception should be unwrapped by the template
- throw t;
- }
-
- if (result.isReady()) {
- return result.getValue();
- }
-
- // No result means something weird happened
- throw new IllegalStateException("No result available for attempted repeat call to " + invocation
- + ". The invocation was never called, so maybe there is a problem with the completion policy?");
- }
-
- /**
- * @param result
- * @return
- */
- private boolean isComplete(Object result) {
- return result == null || (result instanceof Boolean) && !((Boolean) result).booleanValue();
- }
-
- /**
- * Simple wrapper exception class to enable nasty errors to be passed out of
- * the scope of the repeat operations and handled by the caller.
- *
- * @author Dave Syer
- *
- */
- private static class RepeatOperationsInterceptorException extends RepeatException {
- /**
- * @param message
- * @param e
- */
- public RepeatOperationsInterceptorException(String message, Throwable e) {
- super(message, e);
- }
- }
-
- /**
- * Simple wrapper object for the result from a method invocation.
- *
- * @author Dave Syer
- *
- */
- private static class ResultHolder {
- private Object value = null;
-
- private boolean ready = false;
-
- /**
- * Public setter for the Object.
- * @param value the value to set
- */
- public void setValue(Object value) {
- this.ready = true;
- this.value = value;
- }
-
- /**
- * @param value
- */
- public void setFinalValue(Object value) {
- if (ready) {
- // Only set the value the last time if the last time was also
- // the first time
- return;
- }
- setValue(value);
- }
-
- /**
- * Public getter for the Object.
- * @return the value
- */
- public Object getValue() {
- return value;
- }
-
- /**
- * @return true if a value has been set
- */
- public boolean isReady() {
- return ready;
- }
- }
-
-}
diff --git a/src/main/java/org/springframework/repeat/interceptor/package.html b/src/main/java/org/springframework/repeat/interceptor/package.html
deleted file mode 100644
index bb348ce..0000000
--- a/src/main/java/org/springframework/repeat/interceptor/package.html
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-Infrastructure implementations of repeat aop concerns.
-
-
-
diff --git a/src/main/java/org/springframework/repeat/listener/CompositeRepeatListener.java b/src/main/java/org/springframework/repeat/listener/CompositeRepeatListener.java
deleted file mode 100644
index 57c3204..0000000
--- a/src/main/java/org/springframework/repeat/listener/CompositeRepeatListener.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright 2006-2007 the original author or authors.
- *
- * 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 org.springframework.repeat.listener;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import org.springframework.repeat.RepeatContext;
-import org.springframework.repeat.RepeatListener;
-import org.springframework.repeat.RepeatStatus;
-
-/**
- * @author Dave Syer
- *
- */
-public class CompositeRepeatListener implements RepeatListener {
-
- private List listeners = new ArrayList();
-
- /**
- * Public setter for the listeners.
- *
- * @param listeners
- */
- public void setListeners(RepeatListener[] listeners) {
- this.listeners = Arrays.asList(listeners);
- }
-
- /**
- * Register additional listener.
- *
- * @param listener
- */
- public void register(RepeatListener listener) {
- if (!listeners.contains(listener)) {
- listeners.add(listener);
- }
- }
-
- /* (non-Javadoc)
- * @see org.springframework.batch.repeat.RepeatListener#after(org.springframework.batch.repeat.RepeatContext, org.springframework.batch.repeat.ExitStatus)
- */
- public void after(RepeatContext context, RepeatStatus result) {
- for (RepeatListener listener : listeners) {
- listener.after(context, result);
- }
- }
-
- /* (non-Javadoc)
- * @see org.springframework.batch.repeat.RepeatListener#before(org.springframework.batch.repeat.RepeatContext)
- */
- public void before(RepeatContext context) {
- for (RepeatListener listener : listeners) {
- listener.before(context);
- }
- }
-
- /* (non-Javadoc)
- * @see org.springframework.batch.repeat.RepeatListener#close(org.springframework.batch.repeat.RepeatContext)
- */
- public void close(RepeatContext context) {
- for (RepeatListener listener : listeners) {
- listener.close(context);
- }
- }
-
- /* (non-Javadoc)
- * @see org.springframework.batch.repeat.RepeatListener#onError(org.springframework.batch.repeat.RepeatContext, java.lang.Throwable)
- */
- public void onError(RepeatContext context, Throwable e) {
- for (RepeatListener listener : listeners) {
- listener.onError(context, e);
- }
- }
-
- /* (non-Javadoc)
- * @see org.springframework.batch.repeat.RepeatListener#open(org.springframework.batch.repeat.RepeatContext)
- */
- public void open(RepeatContext context) {
- for (RepeatListener listener : listeners) {
- listener.open(context);
- }
- }
-
-}
diff --git a/src/main/java/org/springframework/repeat/listener/RepeatListenerSupport.java b/src/main/java/org/springframework/repeat/listener/RepeatListenerSupport.java
deleted file mode 100644
index 8335adb..0000000
--- a/src/main/java/org/springframework/repeat/listener/RepeatListenerSupport.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2006-2007 the original author or authors.
- *
- * 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 org.springframework.repeat.listener;
-
-import org.springframework.repeat.RepeatContext;
-import org.springframework.repeat.RepeatListener;
-import org.springframework.repeat.RepeatStatus;
-
-/**
- * Empty method implementation of {@link RepeatListener}.
- *
- * @author Dave Syer
- *
- */
-public class RepeatListenerSupport implements RepeatListener {
-
- public void before(RepeatContext context) {
- }
-
- public void after(RepeatContext context, RepeatStatus result) {
- }
-
- public void close(RepeatContext context) {
- }
-
- public void onError(RepeatContext context, Throwable e) {
- }
-
- public void open(RepeatContext context) {
- }
-
-}
diff --git a/src/main/java/org/springframework/repeat/listener/package.html b/src/main/java/org/springframework/repeat/listener/package.html
deleted file mode 100644
index 8a95d83..0000000
--- a/src/main/java/org/springframework/repeat/listener/package.html
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-Infrastructure implementations of repeat interceptor concerns.
-
-Infrastructure implementations of repeat concerns.
-
-
-
diff --git a/src/main/java/org/springframework/repeat/policy/CompletionPolicySupport.java b/src/main/java/org/springframework/repeat/policy/CompletionPolicySupport.java
deleted file mode 100644
index 952dfe9..0000000
--- a/src/main/java/org/springframework/repeat/policy/CompletionPolicySupport.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright 2006-2007 the original author or authors.
- *
- * 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 org.springframework.repeat.policy;
-
-import org.springframework.repeat.CompletionPolicy;
-import org.springframework.repeat.RepeatContext;
-import org.springframework.repeat.RepeatStatus;
-import org.springframework.repeat.context.RepeatContextSupport;
-
-/**
- * Very simple base class for {@link CompletionPolicy} implementations.
- *
- * @author Dave Syer
- *
- */
-public class CompletionPolicySupport implements CompletionPolicy {
-
- /**
- * If exit status is not continuable return true, otherwise
- * delegate to {@link #isComplete(RepeatContext)}.
- *
- * @see org.springframework.repeat.CompletionPolicy#isComplete(org.springframework.repeat.RepeatContext,
- * RepeatStatus)
- */
- public boolean isComplete(RepeatContext context, RepeatStatus result) {
- if (result != null && !result.isContinuable()) {
- return true;
- }
- else {
- return isComplete(context);
- }
- }
-
- /**
- * Always true.
- *
- * @see org.springframework.repeat.CompletionPolicy#isComplete(org.springframework.repeat.RepeatContext)
- */
- public boolean isComplete(RepeatContext context) {
- return true;
- }
-
- /**
- * Build a new {@link RepeatContextSupport} and return it.
- *
- * @see org.springframework.repeat.CompletionPolicy#start(RepeatContext)
- */
- public RepeatContext start(RepeatContext context) {
- return new RepeatContextSupport(context);
- }
-
- /**
- * Increment the context so the counter is up to date. Do nothing else.
- *
- * @see org.springframework.repeat.CompletionPolicy#update(org.springframework.repeat.RepeatContext)
- */
- public void update(RepeatContext context) {
- if (context instanceof RepeatContextSupport) {
- ((RepeatContextSupport) context).increment();
- }
- }
-
-}
diff --git a/src/main/java/org/springframework/repeat/policy/CompositeCompletionPolicy.java b/src/main/java/org/springframework/repeat/policy/CompositeCompletionPolicy.java
deleted file mode 100644
index 589c6ae..0000000
--- a/src/main/java/org/springframework/repeat/policy/CompositeCompletionPolicy.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright 2006-2007 the original author or authors.
- *
- * 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 org.springframework.repeat.policy;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import org.springframework.repeat.CompletionPolicy;
-import org.springframework.repeat.RepeatContext;
-import org.springframework.repeat.RepeatStatus;
-import org.springframework.repeat.context.RepeatContextSupport;
-
-/**
- * Composite policy that loops through a list of delegate policies and answers
- * calls by a concensus.
- *
- * @author Dave Syer
- *
- */
-public class CompositeCompletionPolicy implements CompletionPolicy {
-
- CompletionPolicy[] policies = new CompletionPolicy[0];
-
- /**
- * Setter for the policies.
- *
- * @param policies
- */
- public void setPolicies(CompletionPolicy[] policies) {
- this.policies = Arrays.asList(policies).toArray(new CompletionPolicy[policies.length]);
- }
-
- /**
- * This policy is complete if any of the composed policies is complete.
- *
- * @see org.springframework.repeat.CompletionPolicy#isComplete(org.springframework.repeat.RepeatContext,
- * RepeatStatus)
- */
- public boolean isComplete(RepeatContext context, RepeatStatus result) {
- RepeatContext[] contexts = ((CompositeBatchContext) context).contexts;
- CompletionPolicy[] policies = ((CompositeBatchContext) context).policies;
- for (int i = 0; i < policies.length; i++) {
- if (policies[i].isComplete(contexts[i], result)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * This policy is complete if any of the composed policies is complete.
- *
- * @see org.springframework.repeat.CompletionPolicy#isComplete(org.springframework.repeat.RepeatContext)
- */
- public boolean isComplete(RepeatContext context) {
- RepeatContext[] contexts = ((CompositeBatchContext) context).contexts;
- CompletionPolicy[] policies = ((CompositeBatchContext) context).policies;
- for (int i = 0; i < policies.length; i++) {
- if (policies[i].isComplete(contexts[i])) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Create a new composite context from all the available policies.
- *
- * @see org.springframework.repeat.CompletionPolicy#start(RepeatContext)
- */
- public RepeatContext start(RepeatContext context) {
- List list = new ArrayList();
- for (int i = 0; i < policies.length; i++) {
- list.add(policies[i].start(context));
- }
- return new CompositeBatchContext(context, list);
-
- }
-
- /**
- * Update all the composed contexts, and also increment the parent context.
- *
- * @see org.springframework.repeat.CompletionPolicy#update(org.springframework.repeat.RepeatContext)
- */
- public void update(RepeatContext context) {
- RepeatContext[] contexts = ((CompositeBatchContext) context).contexts;
- CompletionPolicy[] policies = ((CompositeBatchContext) context).policies;
- for (int i = 0; i < policies.length; i++) {
- policies[i].update(contexts[i]);
- }
- ((RepeatContextSupport) context).increment();
- }
-
- /**
- * Composite context that knows about the policies and contexts is was
- * created with.
- *
- * @author Dave Syer
- *
- */
- protected class CompositeBatchContext extends RepeatContextSupport {
-
- private RepeatContext[] contexts;
-
- // Save a reference to the policies when we were created - gives some
- // protection against reference changes (e.g. if the number of policies
- // change).
- private CompletionPolicy[] policies;
-
- public CompositeBatchContext(RepeatContext context, List contexts) {
- super(context);
- this.contexts = contexts.toArray(new RepeatContext[contexts.size()]);
- this.policies = CompositeCompletionPolicy.this.policies;
- }
-
- }
-
-}
diff --git a/src/main/java/org/springframework/repeat/policy/CountingCompletionPolicy.java b/src/main/java/org/springframework/repeat/policy/CountingCompletionPolicy.java
deleted file mode 100644
index 528a6c3..0000000
--- a/src/main/java/org/springframework/repeat/policy/CountingCompletionPolicy.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright 2006-2007 the original author or authors.
- *
- * 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 org.springframework.repeat.policy;
-
-import org.springframework.repeat.RepeatContext;
-import org.springframework.repeat.context.RepeatContextCounter;
-import org.springframework.repeat.context.RepeatContextSupport;
-
-/**
- * Abstract base class for policies that need to count the number of occurrences
- * of some event (e.g. an exception type in the context), and terminate based on
- * a limit for the counter. The value of the counter can be stored between
- * batches in a nested context, so that the termination decision is based on the
- * aggregate of a number of sibling batches.
- *
- * @author Dave Syer
- *
- */
-public abstract class CountingCompletionPolicy extends DefaultResultCompletionPolicy {
-
- /**
- * Session key for global counter.
- */
- public static final String COUNT = CountingCompletionPolicy.class.getName() + ".COUNT";
-
- private boolean useParent = false;
-
- private int maxCount = 0;
-
- /**
- * Flag to indicate whether the count is at the level of the parent context,
- * or just local to the context. If true then the count is aggregated among
- * siblings in a nested batch.
- *
- * @param useParent whether to use the parent context to cache the total
- * count. Default value is false.
- */
- public void setUseParent(boolean useParent) {
- this.useParent = useParent;
- }
-
- /**
- * Setter for maximum value of count before termination.
- *
- * @param maxCount the maximum number of counts before termination. Default
- * 0 so termination is immediate.
- */
- public void setMaxCount(int maxCount) {
- this.maxCount = maxCount;
- }
-
- /**
- * Extension point for subclasses. Obtain the value of the count in the
- * current context. Subclasses can count the number of attempts or
- * violations and store the result in their context. This policy base class
- * will take care of the termination contract and aggregating at the level
- * of the session if required.
- *
- * @param context the current context, specific to the subclass.
- * @return the value of the counter in the context.
- */
- protected abstract int getCount(RepeatContext context);
-
- /**
- * Extension point for subclasses. Inspect the context and update the state
- * of a counter in whatever way is appropriate. This will be added to the
- * session-level counter if {@link #setUseParent(boolean)} is true.
- *
- * @param context the current context.
- *
- * @return the change in the value of the counter (default 0).
- */
- protected int doUpdate(RepeatContext context) {
- return 0;
- }
-
- /*
- * (non-Javadoc)
- * @see org.springframework.batch.repeat.policy.CompletionPolicySupport#isComplete(org.springframework.batch.repeat.BatchContext)
- */
- final public boolean isComplete(RepeatContext context) {
- int count = ((CountingBatchContext) context).getCounter().getCount();
- return count >= maxCount;
- }
-
- /*
- * (non-Javadoc)
- * @see org.springframework.batch.repeat.policy.CompletionPolicySupport#start(org.springframework.batch.repeat.BatchContext)
- */
- public RepeatContext start(RepeatContext parent) {
- return new CountingBatchContext(parent);
- }
-
- /*
- * (non-Javadoc)
- * @see org.springframework.batch.repeat.policy.CompletionPolicySupport#update(org.springframework.batch.repeat.BatchContext)
- */
- final public void update(RepeatContext context) {
- super.update(context);
- int delta = doUpdate(context);
- ((CountingBatchContext) context).getCounter().increment(delta);
- }
-
- protected class CountingBatchContext extends RepeatContextSupport {
-
- RepeatContextCounter counter;
-
- public CountingBatchContext(RepeatContext parent) {
- super(parent);
- counter = new RepeatContextCounter(this, COUNT, useParent);
- }
-
- public RepeatContextCounter getCounter() {
- return counter;
- }
-
- }
-}
diff --git a/src/main/java/org/springframework/repeat/policy/DefaultResultCompletionPolicy.java b/src/main/java/org/springframework/repeat/policy/DefaultResultCompletionPolicy.java
deleted file mode 100644
index 782c7b7..0000000
--- a/src/main/java/org/springframework/repeat/policy/DefaultResultCompletionPolicy.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright 2006-2007 the original author or authors.
- *
- * 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 org.springframework.repeat.policy;
-
-import org.springframework.repeat.CompletionPolicy;
-import org.springframework.repeat.RepeatContext;
-import org.springframework.repeat.RepeatStatus;
-
-/**
- * Very simple {@link CompletionPolicy} that bases its decision on the result of
- * a batch operation. If the result is null or not continuable according to the
- * {@link RepeatStatus} the batch is complete, otherwise not.
- *
- * @author Dave Syer
- *
- */
-public class DefaultResultCompletionPolicy extends CompletionPolicySupport {
-
- /**
- * True if the result is null, or a {@link RepeatStatus} indicating
- * completion.
- *
- * @see org.springframework.repeat.CompletionPolicy#isComplete(org.springframework.repeat.RepeatContext,
- * RepeatStatus)
- */
- public boolean isComplete(RepeatContext context, RepeatStatus result) {
- return (result == null || !result.isContinuable());
- }
-
- /**
- * Always false.
- *
- * @see org.springframework.repeat.CompletionPolicy#isComplete(org.springframework.repeat.RepeatContext)
- */
- public boolean isComplete(RepeatContext context) {
- return false;
- }
-
-}
diff --git a/src/main/java/org/springframework/repeat/policy/SimpleCompletionPolicy.java b/src/main/java/org/springframework/repeat/policy/SimpleCompletionPolicy.java
deleted file mode 100644
index d0aa862..0000000
--- a/src/main/java/org/springframework/repeat/policy/SimpleCompletionPolicy.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright 2006-2007 the original author or authors.
- *
- * 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 org.springframework.repeat.policy;
-
-import org.springframework.repeat.RepeatContext;
-import org.springframework.repeat.RepeatStatus;
-import org.springframework.repeat.context.RepeatContextSupport;
-import org.springframework.repeat.support.RepeatTemplate;
-import org.springframework.util.ClassUtils;
-
-/**
- * Policy for terminating a batch after a fixed number of operations. Internal
- * state is maintained and a counter incremented, so successful use of this
- * policy requires that isComplete() is only called once per batch item. Using
- * the standard {@link RepeatTemplate} should ensure this contract is kept, but it needs
- * to be carefully monitored.
- *
- * @author Dave Syer
- *
- */
-public class SimpleCompletionPolicy extends DefaultResultCompletionPolicy {
-
- public static final int DEFAULT_CHUNK_SIZE = 5;
-
- int chunkSize = 0;
-
- public SimpleCompletionPolicy() {
- this(DEFAULT_CHUNK_SIZE);
- }
-
- public SimpleCompletionPolicy(int chunkSize) {
- super();
- this.chunkSize = chunkSize;
- }
-
- public void setChunkSize(int chunkSize) {
- this.chunkSize = chunkSize;
- }
-
- /**
- * Reset the counter.
- *
- * @see org.springframework.repeat.CompletionPolicy#start(RepeatContext)
- */
- public RepeatContext start(RepeatContext context) {
- return new SimpleTerminationContext(context);
- }
-
- /**
- * Terminate if the chunk size has been reached, or the result is null.
- *
- * @see org.springframework.repeat.CompletionPolicy#isComplete(RepeatContext,
- * RepeatStatus)
- * @throws RuntimeException (normally terminating the batch) if the result is
- * itself an exception.
- */
- public boolean isComplete(RepeatContext context, RepeatStatus result) {
- return super.isComplete(context, result) || ((SimpleTerminationContext) context).isComplete();
- }
-
- /**
- * Terminate if the chunk size has been reached.
- *
- * @see org.springframework.repeat.CompletionPolicy#isComplete(RepeatContext)
- */
- public boolean isComplete(RepeatContext context) {
- return ((SimpleTerminationContext) context).isComplete();
- }
-
- /**
- * Increment the counter in the context.
- *
- * @see org.springframework.repeat.CompletionPolicy#update(RepeatContext)
- */
- public void update(RepeatContext context) {
- ((SimpleTerminationContext) context).update();
- }
-
- protected class SimpleTerminationContext extends RepeatContextSupport {
-
- public SimpleTerminationContext(RepeatContext context) {
- super(context);
- }
-
- public void update() {
- increment();
- }
-
- public boolean isComplete() {
- return getStartedCount() >= chunkSize;
- }
- }
-
- /* (non-Javadoc)
- * @see java.lang.Object#toString()
- */
- public String toString() {
- return ClassUtils.getShortName(SimpleCompletionPolicy.class)+": chunkSize="+chunkSize;
- }
-
-}
diff --git a/src/main/java/org/springframework/repeat/policy/TimeoutTerminationPolicy.java b/src/main/java/org/springframework/repeat/policy/TimeoutTerminationPolicy.java
deleted file mode 100644
index daf6485..0000000
--- a/src/main/java/org/springframework/repeat/policy/TimeoutTerminationPolicy.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright 2006-2007 the original author or authors.
- *
- * 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 org.springframework.repeat.policy;
-
-import org.springframework.repeat.RepeatContext;
-import org.springframework.repeat.context.RepeatContextSupport;
-
-/**
- * Termination policy that times out after a fixed period. Allows graceful exit
- * from a batch if the latest result comes in after the timeout expires (i.e.
- * does not throw a timeout exception).
- *
- * N.B. It may often be the case that the batch governed by this policy will be
- * transactional, and the transaction might have its own timeout. In this case
- * the transaction might throw a timeout exception on commit if its timeout
- * threshold is lower than the termination policy.
- *
- * @author Dave Syer
- *
- */
-public class TimeoutTerminationPolicy extends CompletionPolicySupport {
-
- /**
- * Default timeout value in millisecs (the value equivalent to 30 seconds).
- */
- public static final long DEFAULT_TIMEOUT = 30000L;
-
- private long timeout = DEFAULT_TIMEOUT;
-
- /**
- * Default constructor.
- */
- public TimeoutTerminationPolicy() {
- super();
- }
-
- /**
- * Construct a {@link TimeoutTerminationPolicy} with the specified timeout
- * value (in milliseconds).
- *
- * @param timeout
- */
- public TimeoutTerminationPolicy(long timeout) {
- super();
- this.timeout = timeout;
- }
-
- /**
- * Check the timeout and complete gracefully if it has expires.
- *
- * @see org.springframework.repeat.CompletionPolicy#isComplete(org.springframework.repeat.RepeatContext)
- */
- @Override
- public boolean isComplete(RepeatContext context) {
- return ((TimeoutBatchContext) context).isComplete();
- }
-
- /**
- * Start the clock on the timeout.
- *
- * @see org.springframework.repeat.CompletionPolicy#start(RepeatContext)
- */
- @Override
- public RepeatContext start(RepeatContext context) {
- return new TimeoutBatchContext(context);
- }
-
- protected class TimeoutBatchContext extends RepeatContextSupport {
-
- private volatile long time = System.currentTimeMillis();
-
- private final long timeout = TimeoutTerminationPolicy.this.timeout;
-
- public TimeoutBatchContext(RepeatContext context) {
- super(context);
- }
-
- public boolean isComplete() {
- return (System.currentTimeMillis() - time) > timeout;
- }
-
- }
-
-}
diff --git a/src/main/java/org/springframework/repeat/policy/package.html b/src/main/java/org/springframework/repeat/policy/package.html
deleted file mode 100644
index e30f24f..0000000
--- a/src/main/java/org/springframework/repeat/policy/package.html
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-Infrastructure implementations of repeat policy concerns.
-
-
-
diff --git a/src/main/java/org/springframework/repeat/support/RepeatInternalState.java b/src/main/java/org/springframework/repeat/support/RepeatInternalState.java
deleted file mode 100644
index 7767048..0000000
--- a/src/main/java/org/springframework/repeat/support/RepeatInternalState.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright 2006-2007 the original author or authors.
- *
- * 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 org.springframework.repeat.support;
-
-import java.util.Collection;
-
-/**
- * Internal interface for extensions of {@link RepeatTemplate}.
- *
- * @author Dave Syer
- *
- */
-public interface RepeatInternalState {
-
- /**
- * Returns a mutable collection of exceptions that have occurred in the
- * current repeat context. Clients are expected to mutate this collection.
- *
- * @return the collection of exceptions being accumulated
- */
- Collection getThrowables();
-
-}
diff --git a/src/main/java/org/springframework/repeat/support/RepeatInternalStateSupport.java b/src/main/java/org/springframework/repeat/support/RepeatInternalStateSupport.java
deleted file mode 100644
index d4dc2c5..0000000
--- a/src/main/java/org/springframework/repeat/support/RepeatInternalStateSupport.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright 2006-2007 the original author or authors.
- *
- * 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 org.springframework.repeat.support;
-
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Set;
-
-public class RepeatInternalStateSupport implements RepeatInternalState {
-
- // Accumulation of failed results.
- private final Set throwables = new HashSet();
-
- /* (non-Javadoc)
- * @see org.springframework.batch.repeat.support.BatchInternalState#getThrowables()
- */
- public Collection getThrowables() {
- return throwables;
- }
-
-}
diff --git a/src/main/java/org/springframework/repeat/support/RepeatSynchronizationManager.java b/src/main/java/org/springframework/repeat/support/RepeatSynchronizationManager.java
deleted file mode 100644
index 33cdc32..0000000
--- a/src/main/java/org/springframework/repeat/support/RepeatSynchronizationManager.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright 2006-2007 the original author or authors.
- *
- * 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 org.springframework.repeat.support;
-
-import org.springframework.repeat.RepeatCallback;
-import org.springframework.repeat.RepeatContext;
-import org.springframework.repeat.RepeatOperations;
-
-/**
- * Global variable support for repeat clients. Normally it is not necessary for
- * clients to be aware of the surrounding environment because a
- * {@link RepeatCallback} can always use the context it is passed by the
- * enclosing {@link RepeatOperations}. But occasionally it might be helpful to
- * have lower level access to the ongoing {@link RepeatContext} so we provide a
- * global accessor here. The mutator methods ({@link #clear()} and
- * {@link #register(RepeatContext)} should not be used except internally by
- * {@link RepeatOperations} implementations.
- *
- * @author Dave Syer
- *
- */
-public final class RepeatSynchronizationManager {
-
- private static final ThreadLocal contextHolder = new ThreadLocal();
-
- private RepeatSynchronizationManager() {
- }
-
- /**
- * Getter for the current context. A context is shared by all items in the
- * batch, so this method is intended to return the same context object
- * independent of whether the callback is running synchronously or
- * asynchronously with the surrounding {@link RepeatOperations}.
- *
- * @return the current {@link RepeatContext} or null if there is none (if we
- * are not in a batch).
- */
- public static RepeatContext getContext() {
- return contextHolder.get();
- }
-
- /**
- * Convenience method to set the current repeat operation to complete if it
- * exists.
- */
- public static void setCompleteOnly() {
- RepeatContext context = getContext();
- if (context != null) {
- context.setCompleteOnly();
- }
- }
-
- /**
- * Method for registering a context - should only be used by
- * {@link RepeatOperations} implementations to ensure that
- * {@link #getContext()} always returns the correct value.
- *
- * @param context a new context at the start of a batch.
- * @return the old value if there was one.
- */
- public static RepeatContext register(RepeatContext context) {
- RepeatContext oldSession = getContext();
- RepeatSynchronizationManager.contextHolder.set(context);
- return oldSession;
- }
-
- /**
- * Clear the current context at the end of a batch - should only be used by
- * {@link RepeatOperations} implementations.
- *
- * @return the old value if there was one.
- */
- public static RepeatContext clear() {
- RepeatContext context = getContext();
- RepeatSynchronizationManager.contextHolder.set(null);
- return context;
- }
-
- /**
- * Set current session and all ancestors (via parent) to complete.,
- */
- public static void setAncestorsCompleteOnly() {
- RepeatContext context = getContext();
- while (context != null) {
- context.setCompleteOnly();
- context = context.getParent();
- }
- }
-
-}
diff --git a/src/main/java/org/springframework/repeat/support/RepeatTemplate.java b/src/main/java/org/springframework/repeat/support/RepeatTemplate.java
deleted file mode 100644
index 05a8d08..0000000
--- a/src/main/java/org/springframework/repeat/support/RepeatTemplate.java
+++ /dev/null
@@ -1,476 +0,0 @@
-/*
- * Copyright 2006-2007 the original author or authors.
- *
- * 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 org.springframework.repeat.support;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.springframework.repeat.CompletionPolicy;
-import org.springframework.repeat.RepeatCallback;
-import org.springframework.repeat.RepeatContext;
-import org.springframework.repeat.RepeatException;
-import org.springframework.repeat.RepeatListener;
-import org.springframework.repeat.RepeatOperations;
-import org.springframework.repeat.RepeatStatus;
-import org.springframework.repeat.exception.DefaultExceptionHandler;
-import org.springframework.repeat.exception.ExceptionHandler;
-import org.springframework.repeat.policy.DefaultResultCompletionPolicy;
-import org.springframework.util.Assert;
-
-/**
- * Simple implementation and base class for batch templates implementing
- * {@link RepeatOperations}. Provides a framework including interceptors and
- * policies. Subclasses just need to provide a method that gets the next result
- * and one that waits for all the results to be returned from concurrent
- * processes or threads.
- *
- * N.B. the template accumulates thrown exceptions during the iteration, and
- * they are all processed together when the main loop ends (i.e. finished
- * processing the items). Clients that do not want to stop execution when an
- * exception is thrown can use a specific {@link CompletionPolicy} that does not
- * finish when exceptions are received. This is not the default behaviour.
- *
- * Clients that want to take some business action when an exception is thrown by
- * the {@link RepeatCallback} can consider using a custom {@link RepeatListener}
- * instead of trying to customise the {@link CompletionPolicy}. This is
- * generally a friendlier interface to implement, and the
- * {@link RepeatListener#after(RepeatContext, RepeatStatus)} method is passed in
- * the result of the callback, which would be an instance of {@link Throwable}
- * if the business processing had thrown an exception. If the exception is not
- * to be propagated to the caller, then a non-default {@link CompletionPolicy}
- * needs to be provided as well, but that could be off the shelf, with the
- * business action implemented only in the interceptor.
- *
- * @author Dave Syer
- *
- */
-public class RepeatTemplate implements RepeatOperations {
-
- protected Log logger = LogFactory.getLog(getClass());
-
- private RepeatListener[] listeners = new RepeatListener[] {};
-
- private CompletionPolicy completionPolicy = new DefaultResultCompletionPolicy();
-
- private ExceptionHandler exceptionHandler = new DefaultExceptionHandler();
-
- /**
- * Set the listeners for this template, registering them for callbacks at
- * appropriate times in the iteration.
- *
- * @param listeners
- */
- public void setListeners(RepeatListener[] listeners) {
- this.listeners = Arrays.asList(listeners).toArray(new RepeatListener[listeners.length]);
- }
-
- /**
- * Register an additional listener.
- *
- * @param listener
- */
- public void registerListener(RepeatListener listener) {
- List list = new ArrayList(Arrays.asList(listeners));
- list.add(listener);
- listeners = (RepeatListener[]) list.toArray(new RepeatListener[list.size()]);
- }
-
- /**
- * Setter for exception handler strategy. The exception handler is called at
- * the end of a batch, after the {@link CompletionPolicy} has determined
- * that the batch is complete. By default all exceptions are re-thrown.
- *
- * @see ExceptionHandler
- * @see DefaultExceptionHandler
- * @see #setCompletionPolicy(CompletionPolicy)
- *
- * @param exceptionHandler the {@link ExceptionHandler} to use.
- */
- public void setExceptionHandler(ExceptionHandler exceptionHandler) {
- this.exceptionHandler = exceptionHandler;
- }
-
- /**
- * Setter for policy to decide when the batch is complete. The default is to
- * complete normally when the callback returns a {@link RepeatStatus} which
- * is not marked as continuable, and abnormally when the callback throws an
- * exception (but the decision to re-throw the exception is deferred to the
- * {@link ExceptionHandler}).
- *
- * @see #setExceptionHandler(ExceptionHandler)
- *
- * @param terminationPolicy a TerminationPolicy.
- * @throws IllegalArgumentException if the argument is null
- */
- public void setCompletionPolicy(CompletionPolicy terminationPolicy) {
- Assert.notNull(terminationPolicy);
- this.completionPolicy = terminationPolicy;
- }
-
- /**
- * Execute the batch callback until the completion policy decides that we
- * are finished. Wait for the whole batch to finish before returning even if
- * the task executor is asynchronous.
- *
- * @see org.springframework.repeat.RepeatOperations#iterate(org.springframework.repeat.RepeatCallback)
- */
- public RepeatStatus iterate(RepeatCallback callback) {
-
- RepeatContext outer = RepeatSynchronizationManager.getContext();
-
- RepeatStatus result = RepeatStatus.CONTINUABLE;
- try {
- // This works with an asynchronous TaskExecutor: the
- // interceptors have to wait for the child processes.
- result = executeInternal(callback);
- }
- finally {
- RepeatSynchronizationManager.clear();
- if (outer != null) {
- RepeatSynchronizationManager.register(outer);
- }
- }
-
- return result;
- }
-
- /**
- * Internal convenience method to loop over interceptors and batch
- * callbacks.
- *
- * @param callback the callback to process each element of the loop.
- *
- * @return the aggregate of {@link ContinuationPolicy#canContinue(Object)}
- * for all the results from the callback.
- *
- */
- private RepeatStatus executeInternal(final RepeatCallback callback) {
-
- // Reset the termination policy if there is one...
- RepeatContext context = start();
-
- // Make sure if we are already marked complete before we start then no
- // processing takes place.
- boolean running = !isMarkedComplete(context);
-
- for (int i = 0; i < listeners.length; i++) {
- RepeatListener interceptor = listeners[i];
- interceptor.open(context);
- running = running && !isMarkedComplete(context);
- if (!running)
- break;
- }
-
- // Return value, default is to allow continued processing.
- RepeatStatus result = RepeatStatus.CONTINUABLE;
-
- RepeatInternalState state = createInternalState(context);
- // This is the list of exceptions thrown by all active callbacks
- Collection throwables = state.getThrowables();
- // Keep a separate list of exceptions we handled that need to be
- // rethrown
- Collection deferred = new ArrayList();
-
- try {
-
- while (running) {
-
- /*
- * Run the before interceptors here, not in the task executor so
- * that they all happen in the same thread - it's easier for
- * tracking batch status, amongst other things.
- */
- for (int i = 0; i < listeners.length; i++) {
- RepeatListener interceptor = listeners[i];
- interceptor.before(context);
- // Allow before interceptors to veto the batch by setting
- // flag.
- running = running && !isMarkedComplete(context);
- }
-
- // Check that we are still running (should always be true) ...
- if (running) {
-
- try {
-
- result = getNextResult(context, callback, state);
- executeAfterInterceptors(context, result);
-
- }
- catch (Throwable throwable) {
- doHandle(throwable, context, deferred);
- }
-
- // N.B. the order may be important here:
- if (isComplete(context, result) || isMarkedComplete(context) || !deferred.isEmpty()) {
- running = false;
- }
-
- }
-
- }
-
- result = result.and(waitForResults(state));
- for (Throwable throwable : throwables) {
- doHandle(throwable, context, deferred);
- }
-
- // Explicitly drop any references to internal state...
- state = null;
-
- }
- /*
- * No need for explicit catch here - if the business processing threw an
- * exception it was already handled by the helper methods. An exception
- * here is necessarily fatal.
- */
- finally {
-
- try {
-
- if (!deferred.isEmpty()) {
- Throwable throwable = (Throwable) deferred.iterator().next();
- logger.debug("Handling fatal exception explicitly (rethrowing first of " + deferred.size() + "): "
- + throwable.getClass().getName() + ": " + throwable.getMessage());
- rethrow(throwable);
- }
-
- }
- finally {
-
- try {
- for (int i = listeners.length; i-- > 0;) {
- RepeatListener interceptor = listeners[i];
- interceptor.close(context);
- }
- }
- finally {
- context.close();
- }
-
- }
-
- }
-
- return result;
-
- }
-
- private void doHandle(Throwable throwable, RepeatContext context, Collection deferred) {
- // An exception alone is not sufficient grounds for not
- // continuing
- Throwable unwrappedThrowable = unwrapIfRethrown(throwable);
- try {
-
- for (int i = listeners.length; i-- > 0;) {
- RepeatListener interceptor = listeners[i];
- // This is not an error - only log at debug
- // level.
- logger.debug("Exception intercepted (" + (i + 1) + " of " + listeners.length + ")", unwrappedThrowable);
- interceptor.onError(context, unwrappedThrowable);
- }
-
- logger.debug("Handling exception: " + throwable.getClass().getName() + ", caused by: "
- + unwrappedThrowable.getClass().getName() + ": " + unwrappedThrowable.getMessage());
- exceptionHandler.handleException(context, unwrappedThrowable);
-
- }
- catch (Throwable handled) {
- deferred.add(handled);
- }
- }
-
- /**
- * Re-throws the original throwable if it is unchecked, wraps checked
- * exceptions into {@link RepeatException}.
- */
- private static void rethrow(Throwable throwable) throws RuntimeException {
- if (throwable instanceof Error) {
- throw (Error) throwable;
- }
- else if (throwable instanceof RuntimeException) {
- throw (RuntimeException) throwable;
- }
- else {
- throw new RepeatException("Exception in batch process", throwable);
- }
- }
-
- /**
- * Unwraps the throwable if it has been wrapped by
- * {@link #rethrow(Throwable)}.
- */
- private static Throwable unwrapIfRethrown(Throwable throwable) {
- if (throwable instanceof RepeatException) {
- return throwable.getCause();
- }
- else {
- return throwable;
- }
- }
-
- /**
- * Create an internal state object that is used to store data needed
- * internally in the scope of an iteration. Used by subclasses to manage the
- * queueing and retrieval of asynchronous results. The default just provides
- * an accumulation of Throwable instances for processing at the end of the
- * batch.
- *
- * @param context the current {@link RepeatContext}
- * @return a {@link RepeatInternalState} instance.
- *
- * @see RepeatTemplate#waitForResults(RepeatInternalState)
- */
- protected RepeatInternalState createInternalState(RepeatContext context) {
- return new RepeatInternalStateSupport();
- }
-
- /**
- * Get the next completed result, possibly executing several callbacks until
- * one finally finishes. Normally a subclass would have to override both
- * this method and {@link #createInternalState(RepeatContext)} because the
- * implementation of this method would rely on the details of the internal
- * state.
- *
- * @param context current BatchContext.
- * @param callback the callback to execute.
- * @param state maintained by the implementation.
- * @return a finished result.
- *
- * @see #isComplete(RepeatContext)
- * @see #createInternalState(RepeatContext)
- */
- protected RepeatStatus getNextResult(RepeatContext context, RepeatCallback callback, RepeatInternalState state)
- throws Throwable {
- update(context);
- if (logger.isDebugEnabled()) {
- logger.debug("Repeat operation about to start at count=" + context.getStartedCount());
- }
- return callback.doInIteration(context);
-
- }
-
- /**
- * If necessary, wait for results to come back from remote or concurrent
- * processes. By default does nothing and returns true.
- *
- * @param state the internal state.
- * @return true if {@link #canContinue(RepeatStatus)} is true for all
- * results retrieved.
- */
- protected boolean waitForResults(RepeatInternalState state) {
- // no-op by default
- return true;
- }
-
- /**
- * Check return value from batch operation.
- *
- * @param value the last callback result.
- * @return true if the value is {@link RepeatStatus#CONTINUABLE}.
- */
- protected final boolean canContinue(RepeatStatus value) {
- return ((RepeatStatus) value).isContinuable();
- }
-
- private boolean isMarkedComplete(RepeatContext context) {
- boolean complete = context.isCompleteOnly();
- if (context.getParent() != null) {
- complete = complete || isMarkedComplete(context.getParent());
- }
- if (complete) {
- logger.debug("Repeat is complete according to context alone.");
- }
- return complete;
-
- }
-
- /**
- * Convenience method to execute after interceptors on a callback result.
- *
- * @param context the current batch context.
- * @param value the result of the callback to process.
- */
- protected void executeAfterInterceptors(final RepeatContext context, RepeatStatus value) {
-
- // Don't re-throw exceptions here: let the exception handler deal with
- // that...
-
- if (value != null && value.isContinuable()) {
- for (int i = listeners.length; i-- > 0;) {
- RepeatListener interceptor = listeners[i];
- interceptor.after(context, value);
- }
-
- }
-
- }
-
- /**
- * Delegate to the {@link CompletionPolicy}.
- *
- * @see org.springframework.repeat.CompletionPolicy#isComplete(RepeatContext,
- * RepeatStatus)
- */
- protected boolean isComplete(RepeatContext context, RepeatStatus result) {
- boolean complete = completionPolicy.isComplete(context, result);
- if (complete) {
- logger.debug("Repeat is complete according to policy and result value.");
- }
- return complete;
- }
-
- /**
- * Delegate to {@link CompletionPolicy}.
- *
- * @see org.springframework.repeat.CompletionPolicy#isComplete(RepeatContext)
- */
- protected boolean isComplete(RepeatContext context) {
- boolean complete = completionPolicy.isComplete(context);
- if (complete) {
- logger.debug("Repeat is complete according to policy alone not including result.");
- }
- return complete;
- }
-
- /**
- * Delegate to the {@link CompletionPolicy}.
- *
- * @see org.springframework.repeat.CompletionPolicy#start(RepeatContext)
- */
- protected RepeatContext start() {
- RepeatContext parent = RepeatSynchronizationManager.getContext();
- RepeatContext context = completionPolicy.start(parent);
- RepeatSynchronizationManager.register(context);
- logger.debug("Starting repeat context.");
- return context;
- }
-
- /**
- * Delegate to the {@link CompletionPolicy}.
- *
- * @see org.springframework.repeat.CompletionPolicy#update(RepeatContext)
- */
- protected void update(RepeatContext context) {
- completionPolicy.update(context);
- }
-
-}
diff --git a/src/main/java/org/springframework/repeat/support/ResultHolder.java b/src/main/java/org/springframework/repeat/support/ResultHolder.java
deleted file mode 100644
index a2d73be..0000000
--- a/src/main/java/org/springframework/repeat/support/ResultHolder.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright 2006-2007 the original author or authors.
- *
- * 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 org.springframework.repeat.support;
-
-import org.springframework.repeat.RepeatContext;
-import org.springframework.repeat.RepeatStatus;
-
-/**
- * Interface for result holder.
- *
- * @author Dave Syer
- */
-interface ResultHolder {
- /**
- * Get the result for client from this holder. Does not block if none is
- * available yet.
- *
- * @return the result, or null if there is none.
- * @throws IllegalStateException
- */
- RepeatStatus getResult();
-
- /**
- * Get the error for client from this holder if any. Does not block if
- * none is available yet.
- *
- * @return the error, or null if there is none.
- * @throws IllegalStateException
- */
- Throwable getError();
-
- /**
- * Get the context in which the result evaluation is executing.
- *
- * @return the context of the result evaluation.
- */
- RepeatContext getContext();
-}
\ No newline at end of file
diff --git a/src/main/java/org/springframework/repeat/support/ResultHolderResultQueue.java b/src/main/java/org/springframework/repeat/support/ResultHolderResultQueue.java
deleted file mode 100644
index 3e16597..0000000
--- a/src/main/java/org/springframework/repeat/support/ResultHolderResultQueue.java
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Copyright 2002-2007 the original author or authors.
- *
- * 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 org.springframework.repeat.support;
-
-import java.util.Comparator;
-import java.util.NoSuchElementException;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.PriorityBlockingQueue;
-import java.util.concurrent.Semaphore;
-
-import org.springframework.repeat.RepeatStatus;
-
-/**
- * An implementation of the {@link ResultQueue} that throttles the number of
- * expected results, limiting it to a maximum at any given time.
- *
- * @author Dave Syer
- */
-public class ResultHolderResultQueue implements ResultQueue {
-
- // Accumulation of result objects as they finish.
- private final BlockingQueue results;
-
- // Accumulation of dummy objects flagging expected results in the future.
- private final Semaphore waits;
-
- private final Object lock = new Object();
-
- private volatile int count = 0;
-
- /**
- * @param throttleLimit the maximum number of results that can be expected
- * at any given time.
- */
- public ResultHolderResultQueue(int throttleLimit) {
- results = new PriorityBlockingQueue(throttleLimit, new ResultHolderComparator());
- waits = new Semaphore(throttleLimit);
- }
-
- public boolean isEmpty() {
- return results.isEmpty();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.springframework.batch.repeat.support.ResultQueue#isExpecting()
- */
- public boolean isExpecting() {
- // Base the decision about whether we expect more results on a
- // counter of the number of expected results actually collected.
- // Do not synchronize! Otherwise put and expect can deadlock.
- return count > 0;
- }
-
- /**
- * Tell the queue to expect one more result. Blocks until a new result is
- * available if already expecting too many (as determined by the throttle
- * limit).
- *
- * @see ResultQueue#expect()
- */
- public void expect() throws InterruptedException {
- waits.acquire();
- // Don't acquire the lock in a synchronized block - might deadlock
- synchronized (lock) {
- count++;
- }
- }
-
- public void put(ResultHolder holder) throws IllegalArgumentException {
- if (!isExpecting()) {
- throw new IllegalArgumentException("Not expecting a result. Call expect() before put().");
- }
- results.add(holder);
- // Take from the waits queue now to allow another result to
- // accumulate. But don't decrement the counter.
- waits.release();
- synchronized (lock) {
- lock.notifyAll();
- }
- }
-
- /**
- * Get the next result as soon as it becomes available.
- *
- * Release result immediately if:
- *
- *
There is a result that is continuable.
- *
- * Otherwise block if either:
- *
- *
There is no result (as per contract of {@link ResultQueue}).
- *
The number of results is less than the number expected.
- *
- * Error if either:
- *
- *
Not expecting.
- *
Interrupted.
- *
- *
- * @see ResultQueue#take()
- */
- public ResultHolder take() throws NoSuchElementException, InterruptedException {
- if (!isExpecting()) {
- throw new NoSuchElementException("Not expecting a result. Call expect() before take().");
- }
- ResultHolder value;
- synchronized (lock) {
- value = results.take();
- if (isContinuable(value)) {
- // Decrement the counter only when the result is collected.
- count--;
- return value;
- }
- }
- results.put(value);
- synchronized (lock) {
- while (count > results.size()) {
- lock.wait();
- }
- value = results.take();
- count--;
- }
- return value;
- }
-
- private boolean isContinuable(ResultHolder value) {
- return value.getResult() != null && value.getResult().isContinuable();
- }
-
- /**
- * Compares ResultHolders so that one that is continuable ranks lowest.
- *
- * @author Dave Syer
- *
- */
- private static class ResultHolderComparator implements Comparator {
- public int compare(ResultHolder h1, ResultHolder h2) {
- RepeatStatus result1 = h1.getResult();
- RepeatStatus result2 = h2.getResult();
- if (result1 == null && result2 == null) {
- return 0;
- }
- if (result1 == null) {
- return -1;
- }
- else if (result2 == null) {
- return 1;
- }
- if ((result1.isContinuable() && result2.isContinuable())
- || (!result1.isContinuable() && !result2.isContinuable())) {
- return 0;
- }
- if (result1.isContinuable()) {
- return -1;
- }
- return 1;
- }
- }
-
-}
diff --git a/src/main/java/org/springframework/repeat/support/ResultQueue.java b/src/main/java/org/springframework/repeat/support/ResultQueue.java
deleted file mode 100644
index 55a85d4..0000000
--- a/src/main/java/org/springframework/repeat/support/ResultQueue.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright 2002-2007 the original author or authors.
- *
- * 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 org.springframework.repeat.support;
-
-import java.util.NoSuchElementException;
-import java.util.concurrent.BlockingQueue;
-
-import org.springframework.core.task.TaskExecutor;
-
-/**
- * Abstraction for queue of {@link ResultHolder} objects. Acts a bit likeT a
- * {@link BlockingQueue} with the ability to count the number of items it
- * expects to ever hold. When clients schedule an item to be added they call
- * {@link #expect()}, and then collect the result later with {@link #take()}.
- * Result providers in another thread call {@link #put(Object)} to notify the
- * expecting client of a new result.
- *
- * @author Dave Syer
- * @author Ben Hale
- */
-interface ResultQueue {
-
- /**
- * In a master-slave pattern, the master calls this method paired with
- * {@link #take()} to manage the flow of items. Normally a task is submitted
- * for processing in another thread, at which point the master uses this
- * method to keep track of the number of expected results. It has the
- * personality of an counter increment, rather than a work queue, which is
- * usually managed elsewhere, e.g. by a {@link TaskExecutor}.
- * Implementations may choose to block here, if they need to limit the
- * number or rate of tasks being submitted.
- *
- * @throws InterruptedException if the call blocks and is then interrupted.
- */
- void expect() throws InterruptedException;
-
- /**
- * Once it is expecting a result, clients call this method to satisfy the
- * expectation. In a master-worker pattern, the workers call this method to
- * deposit the result of a finished task on the queue for collection.
- *
- * @param result the result for later collection.
- *
- * @throws IllegalArgumentException if the queue is not expecting a new
- * result
- */
- void put(T result) throws IllegalArgumentException;
-
- /**
- * Gets the next available result, blocking if there are none yet available.
- *
- * @return a result previously deposited
- *
- * @throws NoSuchElementException if there is no result expected
- * @throws InterruptedException if the operation is interrupted while
- * waiting
- */
- T take() throws NoSuchElementException, InterruptedException;
-
- /**
- * Used by master thread to verify that there are results available from
- * {@link #take()} without possibly having to block and wait.
- *
- * @return true if there are no results available
- */
- boolean isEmpty();
-
- /**
- * Check if any results are expected. Usually used by master thread to drain
- * queue when it is finished.
- *
- * @return true if more results are expected, but possibly not yet
- * available.
- */
- public boolean isExpecting();
-
-}
diff --git a/src/main/java/org/springframework/repeat/support/TaskExecutorRepeatTemplate.java b/src/main/java/org/springframework/repeat/support/TaskExecutorRepeatTemplate.java
deleted file mode 100644
index dc57b2b..0000000
--- a/src/main/java/org/springframework/repeat/support/TaskExecutorRepeatTemplate.java
+++ /dev/null
@@ -1,324 +0,0 @@
-/*
- * Copyright 2006-2007 the original author or authors.
- *
- * 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 org.springframework.repeat.support;
-
-import org.springframework.core.task.SyncTaskExecutor;
-import org.springframework.core.task.TaskExecutor;
-import org.springframework.repeat.RepeatCallback;
-import org.springframework.repeat.RepeatContext;
-import org.springframework.repeat.RepeatException;
-import org.springframework.repeat.RepeatOperations;
-import org.springframework.repeat.RepeatStatus;
-import org.springframework.util.Assert;
-
-/**
- * Provides {@link RepeatOperations} support including interceptors that can be
- * used to modify or monitor the behaviour at run time.
- *
- * This implementation is sufficient to be used to configure transactional
- * behaviour for each item by making the {@link RepeatCallback} transactional,
- * or for the whole batch by making the execute method transactional (but only
- * then if the task executor is synchronous).
- *
- * This class is thread safe if its collaborators are thread safe (interceptors,
- * terminationPolicy, callback). Normally this will be the case, but clients
- * need to be aware that if the task executor is asynchronous, then the other
- * collaborators should be also. In particular the {@link RepeatCallback} that
- * is wrapped in the execute method must be thread safe - often it is based on
- * some form of data source, which itself should be both thread safe and
- * transactional (multiple threads could be accessing it at any given time, and
- * each thread would have its own transaction).
- *
- * @author Dave Syer
- *
- */
-public class TaskExecutorRepeatTemplate extends RepeatTemplate {
-
- /**
- * Default limit for maximum number of concurrent unfinished results allowed
- * by the template.
- * {@link #getNextResult(RepeatContext, RepeatCallback, RepeatInternalState)}
- * .
- */
- public static final int DEFAULT_THROTTLE_LIMIT = 4;
-
- private int throttleLimit = DEFAULT_THROTTLE_LIMIT;
-
- private TaskExecutor taskExecutor = new SyncTaskExecutor();
-
- /**
- * Public setter for the throttle limit. The throttle limit is the largest
- * number of concurrent tasks that can be executing at one time - if a new
- * task arrives and the throttle limit is breached we wait for one of the
- * executing tasks to finish before submitting the new one to the
- * {@link TaskExecutor}. Default value is {@link #DEFAULT_THROTTLE_LIMIT}.
- * N.B. when used with a thread pooled {@link TaskExecutor} the thread pool
- * might prevent the throttle limit actually being reached (so make the core
- * pool size larger than the throttle limit if possible).
- *
- * @param throttleLimit the throttleLimit to set.
- */
- public void setThrottleLimit(int throttleLimit) {
- this.throttleLimit = throttleLimit;
- }
-
- /**
- * Setter for task executor to be used to run the individual item callbacks.
- *
- * @param taskExecutor a TaskExecutor
- * @throws IllegalArgumentException if the argument is null
- */
- public void setTaskExecutor(TaskExecutor taskExecutor) {
- Assert.notNull(taskExecutor);
- this.taskExecutor = taskExecutor;
- }
-
- /**
- * Use the {@link #setTaskExecutor(TaskExecutor)} to generate a result. The
- * internal state in this case is a queue of unfinished result holders of
- * type {@link ResultHolder}. The holder with the return value should not be
- * on the queue when this method exits. The queue is scoped in the calling
- * method so there is no need to synchronize access.
- *
- */
- protected RepeatStatus getNextResult(RepeatContext context, RepeatCallback callback, RepeatInternalState state)
- throws Throwable {
-
- ExecutingRunnable runnable = null;
-
- ResultQueue queue = ((ResultQueueInternalState) state).getResultQueue();
-
- do {
-
- /*
- * Wrap the callback in a runnable that will add its result to the
- * queue when it is ready.
- */
- runnable = new ExecutingRunnable(callback, context, queue);
-
- /**
- * Tell the runnable that it can expect a result. This could have
- * been in-lined with the constructor, but it might block, so it's
- * better to do it here, since we have the option (it's a private
- * class).
- */
- runnable.expect();
-
- /*
- * Start the task possibly concurrently / in the future.
- */
- taskExecutor.execute(runnable);
-
- /*
- * Allow termination policy to update its state. This must happen
- * immediately before or after the call to the task executor.
- */
- update(context);
-
- /*
- * Keep going until we get a result that is finished, or early
- * termination...
- */
- } while (queue.isEmpty() && !isComplete(context));
-
- /*
- * N.B. If the queue is empty then take() blocks until a result appears,
- * and there must be at least one because we just submitted one to the
- * task executor.
- */
- ResultHolder result = queue.take();
- if (result.getError() != null) {
- throw result.getError();
- }
- return result.getResult();
- }
-
- /**
- * Wait for all the results to appear on the queue and execute the after
- * interceptors for each one.
- *
- * @see org.springframework.repeat.support.RepeatTemplate#waitForResults(org.springframework.repeat.support.RepeatInternalState)
- */
- protected boolean waitForResults(RepeatInternalState state) {
-
- ResultQueue queue = ((ResultQueueInternalState) state).getResultQueue();
-
- boolean result = true;
-
- while (queue.isExpecting()) {
-
- /*
- * Careful that no runnables that are not going to finish ever get
- * onto the queue, else this may block forever.
- */
- ResultHolder future;
- try {
- future = (ResultHolder) queue.take();
- }
- catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- throw new RepeatException("InterruptedException while waiting for result.");
- }
-
- if (future.getError() != null) {
- state.getThrowables().add(future.getError());
- }
- else {
- RepeatStatus status = future.getResult();
- result = result && canContinue(status);
- executeAfterInterceptors(future.getContext(), status);
- }
-
- }
-
- Assert.state(queue.isEmpty(), "Future results queue should be empty at end of batch.");
-
- return result;
- }
-
- protected RepeatInternalState createInternalState(RepeatContext context) {
- // Queue of pending results:
- return new ResultQueueInternalState(throttleLimit);
- }
-
- /**
- * A runnable that puts its result on a queue when it is done.
- *
- * @author Dave Syer
- *
- */
- private class ExecutingRunnable implements Runnable, ResultHolder {
-
- private final RepeatCallback callback;
-
- private final RepeatContext context;
-
- private final ResultQueue queue;
-
- private volatile RepeatStatus result;
-
- private volatile Throwable error;
-
- public ExecutingRunnable(RepeatCallback callback, RepeatContext context, ResultQueue queue) {
-
- super();
-
- this.callback = callback;
- this.context = context;
- this.queue = queue;
-
- }
-
- /**
- * Tell the queue to expect a result.
- */
- public void expect() {
- try {
- queue.expect();
- }
- catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- throw new RepeatException("InterruptedException waiting for to acquire lock on input.");
- }
- }
-
- /**
- * Execute the batch callback, and store the result, or any exception
- * that is thrown for retrieval later by caller.
- *
- * @see java.lang.Runnable#run()
- */
- public void run() {
- boolean clearContext = false;
- try {
- if (RepeatSynchronizationManager.getContext() == null) {
- clearContext = true;
- RepeatSynchronizationManager.register(context);
- }
-
- if (logger.isDebugEnabled()) {
- logger.debug("Repeat operation about to start at count=" + context.getStartedCount());
- }
-
- result = callback.doInIteration(context);
-
- }
- catch (Exception e) {
- error = e;
- }
- finally {
-
- if (clearContext) {
- RepeatSynchronizationManager.clear();
- }
-
- queue.put(this);
-
- }
- }
-
- /**
- * Get the result - never blocks because the queue manages waiting for
- * the task to finish.
- */
- public RepeatStatus getResult() {
- return result;
- }
-
- /**
- * Get the error - never blocks because the queue manages waiting for
- * the task to finish.
- */
- public Throwable getError() {
- return error;
- }
-
- /**
- * Getter for the context.
- */
- public RepeatContext getContext() {
- return this.context;
- }
-
- }
-
- /**
- * @author Dave Syer
- *
- */
- private static class ResultQueueInternalState extends RepeatInternalStateSupport {
-
- private final ResultQueue results;
-
- /**
- * @param throttleLimit the throttle limit for the result queue
- */
- public ResultQueueInternalState(int throttleLimit) {
- super();
- this.results = new ResultHolderResultQueue(throttleLimit);
- }
-
- /**
- * @return the result queue
- */
- public ResultQueue getResultQueue() {
- return results;
- }
-
- }
-
-}
diff --git a/src/main/java/org/springframework/repeat/support/ThrottleLimitResultQueue.java b/src/main/java/org/springframework/repeat/support/ThrottleLimitResultQueue.java
deleted file mode 100644
index dc96536..0000000
--- a/src/main/java/org/springframework/repeat/support/ThrottleLimitResultQueue.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright 2002-2007 the original author or authors.
- *
- * 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 org.springframework.repeat.support;
-
-import java.util.NoSuchElementException;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.Semaphore;
-
-/**
- * An implementation of the {@link ResultQueue} that throttles the number of
- * expected results, limiting it to a maximum at any given time.
- *
- * @author Dave Syer
- */
-public class ThrottleLimitResultQueue implements ResultQueue {
-
- // Accumulation of result objects as they finish.
- private final BlockingQueue results;
-
- // Accumulation of dummy objects flagging expected results in the future.
- private final Semaphore waits;
-
- private final Object lock = new Object();
-
- private volatile int count = 0;
-
- /**
- * @param throttleLimit the maximum number of results that can be expected
- * at any given time.
- */
- public ThrottleLimitResultQueue(int throttleLimit) {
- results = new LinkedBlockingQueue();
- waits = new Semaphore(throttleLimit);
- }
-
- public boolean isEmpty() {
- return results.isEmpty();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.springframework.batch.repeat.support.ResultQueue#isExpecting()
- */
- public boolean isExpecting() {
- // Base the decision about whether we expect more results on a
- // counter of the number of expected results actually collected.
- // Do not synchronize! Otherwise put and expect can deadlock.
- return count > 0;
- }
-
- /**
- * Tell the queue to expect one more result. Blocks until a new result is
- * available if already expecting too many (as determined by the throttle
- * limit).
- *
- * @see ResultQueue#expect()
- */
- public void expect() throws InterruptedException {
- synchronized (lock) {
- waits.acquire();
- count++;
- }
- }
-
- public void put(T holder) throws IllegalArgumentException {
- if (!isExpecting()) {
- throw new IllegalArgumentException("Not expecting a result. Call expect() before put().");
- }
- // There should be no need to block here, or to use offer()
- results.add(holder);
- // Take from the waits queue now to allow another result to
- // accumulate. But don't decrement the counter.
- waits.release();
- }
-
- public T take() throws NoSuchElementException, InterruptedException {
- if (!isExpecting()) {
- throw new NoSuchElementException("Not expecting a result. Call expect() before take().");
- }
- T value;
- synchronized (lock) {
- value = results.take();
- // Decrement the counter only when the result is collected.
- count--;
- }
- return value;
- }
-
-}
diff --git a/src/main/java/org/springframework/repeat/support/package.html b/src/main/java/org/springframework/repeat/support/package.html
deleted file mode 100644
index 6e3f0ee..0000000
--- a/src/main/java/org/springframework/repeat/support/package.html
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-Infrastructure implementations of repeat support concerns.
-
-
-
diff --git a/src/main/java/org/springframework/retry/support/RetrySynchronizationManager.java b/src/main/java/org/springframework/retry/support/RetrySynchronizationManager.java
index bacef57..df696e8 100644
--- a/src/main/java/org/springframework/retry/support/RetrySynchronizationManager.java
+++ b/src/main/java/org/springframework/retry/support/RetrySynchronizationManager.java
@@ -16,7 +16,6 @@
package org.springframework.retry.support;
-import org.springframework.repeat.RepeatOperations;
import org.springframework.retry.RetryCallback;
import org.springframework.retry.RetryContext;
import org.springframework.retry.RetryOperations;
@@ -52,7 +51,7 @@ public final class RetrySynchronizationManager {
/**
* Method for registering a context - should only be used by
- * {@link RetryOperations} implementations to ensure that
+ * {@link org.springframework.repeat.RepeatOperations} implementations to ensure that
* {@link #getContext()} always returns the correct value.
*
* @param context the new context to register
diff --git a/src/main/java/org/springframework/retry/support/RetryTemplate.java b/src/main/java/org/springframework/retry/support/RetryTemplate.java
index ca0b11b..f191c9c 100644
--- a/src/main/java/org/springframework/retry/support/RetryTemplate.java
+++ b/src/main/java/org/springframework/retry/support/RetryTemplate.java
@@ -23,7 +23,6 @@ import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.springframework.repeat.RepeatException;
import org.springframework.retry.ExhaustedRetryException;
import org.springframework.retry.RecoveryCallback;
import org.springframework.retry.RetryCallback;
@@ -469,7 +468,7 @@ public class RetryTemplate implements RetryOperations {
/**
* Re-throws the original throwable if it is unchecked, wraps checked
- * exceptions into {@link RepeatException}.
+ * exceptions into {@link RetryException}.
*/
private static Exception wrapIfNecessary(Throwable throwable) {
if (throwable instanceof Error) {
diff --git a/src/test/java/org/springframework/repeat/AbstractExceptionTests.java b/src/test/java/org/springframework/repeat/AbstractExceptionTests.java
deleted file mode 100644
index 54d7f73..0000000
--- a/src/test/java/org/springframework/repeat/AbstractExceptionTests.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright 2006-2007 the original author or authors.
- *
- * 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 org.springframework.repeat;
-
-import junit.framework.TestCase;
-
-public abstract class AbstractExceptionTests extends TestCase {
-
- public void testExceptionString() throws Exception {
- Exception exception = getException("foo");
- assertEquals("foo", exception.getMessage());
- }
-
- public void testExceptionStringThrowable() throws Exception {
- Exception exception = getException("foo", new IllegalStateException());
- assertEquals("foo", exception.getMessage().substring(0, 3));
- }
-
- public abstract Exception getException(String msg) throws Exception;
-
- public abstract Exception getException(String msg, Throwable t) throws Exception;
-}
diff --git a/src/test/java/org/springframework/repeat/RepeatExceptionTests.java b/src/test/java/org/springframework/repeat/RepeatExceptionTests.java
deleted file mode 100644
index b26cd50..0000000
--- a/src/test/java/org/springframework/repeat/RepeatExceptionTests.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright 2006-2007 the original author or authors.
- *
- * 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 org.springframework.repeat;
-
-import org.springframework.repeat.RepeatException;
-
-public class RepeatExceptionTests extends AbstractExceptionTests {
-
- public Exception getException(String msg) throws Exception {
- return new RepeatException(msg);
- }
-
- public Exception getException(String msg, Throwable t) throws Exception {
- return new RepeatException(msg, t);
- }
-
- public void testNothing() throws Exception {
- // fool coverage tools...
- }
-}
diff --git a/src/test/java/org/springframework/repeat/callback/NestedRepeatCallbackTests.java b/src/test/java/org/springframework/repeat/callback/NestedRepeatCallbackTests.java
deleted file mode 100644
index 3562582..0000000
--- a/src/test/java/org/springframework/repeat/callback/NestedRepeatCallbackTests.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright 2006-2007 the original author or authors.
- *
- * 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 org.springframework.repeat.callback;
-
-import junit.framework.TestCase;
-
-import org.springframework.repeat.RepeatCallback;
-import org.springframework.repeat.RepeatContext;
-import org.springframework.repeat.RepeatStatus;
-import org.springframework.repeat.support.RepeatTemplate;
-
-public class NestedRepeatCallbackTests extends TestCase {
-
- int count = 0;
-
- public void testExecute() throws Exception {
- NestedRepeatCallback callback = new NestedRepeatCallback(new RepeatTemplate(), new RepeatCallback() {
- public RepeatStatus doInIteration(RepeatContext context) throws Exception {
- count++;
- return RepeatStatus.continueIf(count <= 1);
- }
- });
- RepeatStatus result = callback.doInIteration(null);
- assertEquals(2, count);
- assertFalse(result.isContinuable()); // False because processing has finished
- }
-}
diff --git a/src/test/java/org/springframework/repeat/context/RepeatContextCounterTests.java b/src/test/java/org/springframework/repeat/context/RepeatContextCounterTests.java
deleted file mode 100644
index d17373d..0000000
--- a/src/test/java/org/springframework/repeat/context/RepeatContextCounterTests.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright 2006-2007 the original author or authors.
- *
- * 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 org.springframework.repeat.context;
-
-import junit.framework.TestCase;
-
-import org.springframework.repeat.RepeatContext;
-
-public class RepeatContextCounterTests extends TestCase {
-
- RepeatContext parent = new RepeatContextSupport(null);
- RepeatContext context = new RepeatContextSupport(parent);
-
- public void testAttributeCreated() {
- new RepeatContextCounter(context, "FOO");
- assertTrue(context.hasAttribute("FOO"));
- }
-
- public void testAttributeCreatedWithNullParent() {
- new RepeatContextCounter(parent, "FOO", true);
- assertTrue(parent.hasAttribute("FOO"));
- }
-
- public void testVanillaIncrement() throws Exception {
- RepeatContextCounter counter = new RepeatContextCounter(context, "FOO");
- assertEquals(0, counter.getCount());
- counter.increment(1);
- assertEquals(1, counter.getCount());
- counter.increment(2);
- assertEquals(3, counter.getCount());
- }
-
- public void testAttributeCreatedInParent() throws Exception {
- new RepeatContextCounter(context, "FOO", true);
- assertFalse(context.hasAttribute("FOO"));
- assertTrue(parent.hasAttribute("FOO"));
- }
-
- public void testParentIncrement() throws Exception {
- RepeatContextCounter counter = new RepeatContextCounter(context, "FOO", true);
- assertEquals(0, counter.getCount());
- counter.increment(1);
- // now get new context with same parent
- counter = new RepeatContextCounter(new RepeatContextSupport(parent), "FOO", true);
- assertEquals(1, counter.getCount());
- counter.increment(2);
- assertEquals(3, counter.getCount());
- }
-
-}
diff --git a/src/test/java/org/springframework/repeat/context/RepeatContextSupportTests.java b/src/test/java/org/springframework/repeat/context/RepeatContextSupportTests.java
deleted file mode 100644
index d89d052..0000000
--- a/src/test/java/org/springframework/repeat/context/RepeatContextSupportTests.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright 2006-2007 the original author or authors.
- *
- * 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 org.springframework.repeat.context;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import junit.framework.TestCase;
-
-/**
- * @author dsyer
- *
- */
-public class RepeatContextSupportTests extends TestCase {
-
- private List list = new ArrayList();
-
- /**
- * Test method for {@link org.springframework.repeat.context.RepeatContextSupport#registerDestructionCallback(java.lang.String, java.lang.Runnable)}.
- */
- public void testDestructionCallbackSunnyDay() throws Exception {
- RepeatContextSupport context = new RepeatContextSupport(null);
- context.setAttribute("foo", "FOO");
- context.registerDestructionCallback("foo", new Runnable() {
- public void run() {
- list.add("bar");
- }
- });
- context.close();
- assertEquals(1, list.size());
- assertEquals("bar", list.get(0));
- }
-
- /**
- * Test method for {@link org.springframework.repeat.context.RepeatContextSupport#registerDestructionCallback(java.lang.String, java.lang.Runnable)}.
- */
- public void testDestructionCallbackMissingAttribute() throws Exception {
- RepeatContextSupport context = new RepeatContextSupport(null);
- context.registerDestructionCallback("foo", new Runnable() {
- public void run() {
- list.add("bar");
- }
- });
- context.close();
- // No check for the attribute before executing callback
- assertEquals(1, list.size());
- }
-
- /**
- * Test method for {@link org.springframework.repeat.context.RepeatContextSupport#registerDestructionCallback(java.lang.String, java.lang.Runnable)}.
- */
- public void testDestructionCallbackWithException() throws Exception {
- RepeatContextSupport context = new RepeatContextSupport(null);
- context.setAttribute("foo", "FOO");
- context.setAttribute("bar", "BAR");
- context.registerDestructionCallback("bar", new Runnable() {
- public void run() {
- list.add("spam");
- throw new RuntimeException("fail!");
- }
- });
- context.registerDestructionCallback("foo", new Runnable() {
- public void run() {
- list.add("bar");
- throw new RuntimeException("fail!");
- }
- });
- try {
- context.close();
- fail("Expected RuntimeException");
- } catch (RuntimeException e) {
- // We don't care which one was thrown...
- assertEquals("fail!", e.getMessage());
- }
- // ...but we do care that both were executed:
- assertEquals(2, list.size());
- assertTrue(list.contains("bar"));
- assertTrue(list.contains("spam"));
- }
-}
diff --git a/src/test/java/org/springframework/repeat/context/SynchronizedAttributeAccessorTests.java b/src/test/java/org/springframework/repeat/context/SynchronizedAttributeAccessorTests.java
deleted file mode 100644
index 3a94bfd..0000000
--- a/src/test/java/org/springframework/repeat/context/SynchronizedAttributeAccessorTests.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright 2006-2007 the original author or authors.
- *
- * 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 org.springframework.repeat.context;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-import junit.framework.TestCase;
-
-import org.springframework.core.AttributeAccessorSupport;
-
-public class SynchronizedAttributeAccessorTests extends TestCase {
-
- SynchronizedAttributeAccessor accessor = new SynchronizedAttributeAccessor();
-
- public void testHashCode() {
- SynchronizedAttributeAccessor another = new SynchronizedAttributeAccessor();
- accessor.setAttribute("foo", "bar");
- another.setAttribute("foo", "bar");
- assertEquals(accessor, another);
- assertEquals("Object.hashCode() contract broken", accessor.hashCode(), another.hashCode());
- }
-
- public void testToStringWithNoAttributes() throws Exception {
- assertNotNull(accessor.toString());
- }
-
- public void testToStringWithAttributes() throws Exception {
- accessor.setAttribute("foo", "bar");
- accessor.setAttribute("spam", "bucket");
- assertNotNull(accessor.toString());
- }
-
- public void testAttributeNames() {
- accessor.setAttribute("foo", "bar");
- accessor.setAttribute("spam", "bucket");
- List list = Arrays.asList(accessor.attributeNames());
- assertEquals(2, list.size());
- assertTrue(list.contains("foo"));
- }
-
- public void testEqualsSameType() {
- SynchronizedAttributeAccessor another = new SynchronizedAttributeAccessor();
- accessor.setAttribute("foo", "bar");
- another.setAttribute("foo", "bar");
- assertEquals(accessor, another);
- }
-
- public void testEqualsSelf() {
- accessor.setAttribute("foo", "bar");
- assertEquals(accessor, accessor);
- }
-
- public void testEqualsWrongType() {
- accessor.setAttribute("foo", "bar");
- Map another = Collections.singletonMap("foo", "bar");
- // Accessor and another are instances of unrelated classes, they should
- // never be equal...
- assertFalse(accessor.equals(another));
- }
-
- public void testEqualsSupport() {
- AttributeAccessorSupport another = new AttributeAccessorSupport() {
- };
- accessor.setAttribute("foo", "bar");
- another.setAttribute("foo", "bar");
- assertEquals(accessor, another);
- }
-
- public void testGetAttribute() {
- accessor.setAttribute("foo", "bar");
- assertEquals("bar", accessor.getAttribute("foo"));
- }
-
- public void testSetAttributeIfAbsentWhenAlreadyPresent() {
- accessor.setAttribute("foo", "bar");
- assertEquals("bar", accessor.setAttributeIfAbsent("foo", "spam"));
- }
-
- public void testSetAttributeIfAbsentWhenNotAlreadyPresent() {
- assertEquals(null, accessor.setAttributeIfAbsent("foo", "bar"));
- assertEquals("bar", accessor.getAttribute("foo"));
- }
-
- public void testHasAttribute() {
- accessor.setAttribute("foo", "bar");
- assertEquals(true, accessor.hasAttribute("foo"));
- }
-
- public void testRemoveAttribute() {
- accessor.setAttribute("foo", "bar");
- assertEquals("bar", accessor.getAttribute("foo"));
- accessor.removeAttribute("foo");
- assertEquals(null, accessor.getAttribute("foo"));
- }
-
-}
diff --git a/src/test/java/org/springframework/repeat/exception/CompositeExceptionHandlerTests.java b/src/test/java/org/springframework/repeat/exception/CompositeExceptionHandlerTests.java
deleted file mode 100644
index 54cd8c4..0000000
--- a/src/test/java/org/springframework/repeat/exception/CompositeExceptionHandlerTests.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright 2006-2007 the original author or authors.
- *
- * 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 org.springframework.repeat.exception;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import junit.framework.TestCase;
-
-import org.springframework.repeat.RepeatContext;
-import org.springframework.repeat.exception.CompositeExceptionHandler;
-import org.springframework.repeat.exception.ExceptionHandler;
-
-public class CompositeExceptionHandlerTests extends TestCase {
-
- private CompositeExceptionHandler handler = new CompositeExceptionHandler();
-
- public void testNewHandler() throws Throwable {
- try {
- handler.handleException(null, new RuntimeException());
- }
- catch (RuntimeException e) {
- fail("Unexpected RuntimeException");
- }
- }
-
- public void testDelegation() throws Throwable {
- final List list = new ArrayList();
- handler.setHandlers(new ExceptionHandler[] {
- new ExceptionHandler() {
- public void handleException(RepeatContext context, Throwable throwable) throws RuntimeException {
- list.add("1");
- }
- },
- new ExceptionHandler() {
- public void handleException(RepeatContext context, Throwable throwable) throws RuntimeException {
- list.add("2");
- }
- }
- });
- handler.handleException(null, new RuntimeException());
- assertEquals(2, list.size());
- assertEquals("1", list.get(0));
- assertEquals("2", list.get(1));
- }
-}
diff --git a/src/test/java/org/springframework/repeat/exception/DefaultExceptionHandlerTests.java b/src/test/java/org/springframework/repeat/exception/DefaultExceptionHandlerTests.java
deleted file mode 100644
index 820e9f9..0000000
--- a/src/test/java/org/springframework/repeat/exception/DefaultExceptionHandlerTests.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright 2006-2007 the original author or authors.
- *
- * 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 org.springframework.repeat.exception;
-
-import junit.framework.TestCase;
-
-import org.springframework.repeat.RepeatContext;
-
-public class DefaultExceptionHandlerTests extends TestCase {
-
- private DefaultExceptionHandler handler = new DefaultExceptionHandler();
- private RepeatContext context = null;
-
- public void testRuntimeException() throws Throwable {
- try {
- handler.handleException(context, new RuntimeException("Foo"));
- fail("Expected RuntimeException");
- } catch (RuntimeException e) {
- assertEquals("Foo", e.getMessage());
- }
- }
-
- public void testError() throws Throwable {
- try {
- handler.handleException(context, new Error("Foo"));
- fail("Expected Error");
- } catch (Error e) {
- assertEquals("Foo", e.getMessage());
- }
- }
-}
diff --git a/src/test/java/org/springframework/repeat/exception/LogOrRethrowExceptionHandlerTests.java b/src/test/java/org/springframework/repeat/exception/LogOrRethrowExceptionHandlerTests.java
deleted file mode 100644
index 5d98969..0000000
--- a/src/test/java/org/springframework/repeat/exception/LogOrRethrowExceptionHandlerTests.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright 2006-2007 the original author or authors.
- *
- * 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 org.springframework.repeat.exception;
-
-import java.io.StringWriter;
-
-import junit.framework.TestCase;
-
-import org.apache.log4j.Logger;
-import org.apache.log4j.SimpleLayout;
-import org.apache.log4j.WriterAppender;
-import org.springframework.classify.ClassifierSupport;
-import org.springframework.repeat.RepeatContext;
-import org.springframework.repeat.exception.LogOrRethrowExceptionHandler.Level;
-
-public class LogOrRethrowExceptionHandlerTests extends TestCase {
-
- private LogOrRethrowExceptionHandler handler = new LogOrRethrowExceptionHandler();
-
- private StringWriter writer;
-
- private RepeatContext context = null;
-
- protected void setUp() throws Exception {
- super.setUp();
- Logger logger = Logger.getLogger(LogOrRethrowExceptionHandler.class);
- logger.setLevel(org.apache.log4j.Level.DEBUG);
- writer = new StringWriter();
- logger.removeAllAppenders();
- logger.getParent().removeAllAppenders();
- logger.addAppender(new WriterAppender(new SimpleLayout(), writer));
- }
-
- public void testRuntimeException() throws Throwable {
- try {
- handler.handleException(context, new RuntimeException("Foo"));
- fail("Expected RuntimeException");
- }
- catch (RuntimeException e) {
- assertEquals("Foo", e.getMessage());
- }
- }
-
- public void testError() throws Throwable {
- try {
- handler.handleException(context, new Error("Foo"));
- fail("Expected Error");
- }
- catch (Error e) {
- assertEquals("Foo", e.getMessage());
- }
- }
-
- public void testNotRethrownErrorLevel() throws Throwable {
- handler.setExceptionClassifier(new ClassifierSupport(Level.RETHROW) {
- public Level classify(Throwable throwable) {
- return Level.ERROR;
- }
- });
- // No exception...
- handler.handleException(context, new Error("Foo"));
- assertNotNull(writer.toString());
- }
-
- public void testNotRethrownWarnLevel() throws Throwable {
- handler.setExceptionClassifier(new ClassifierSupport(Level.RETHROW) {
- public Level classify(Throwable throwable) {
- return Level.WARN;
- }
- });
- // No exception...
- handler.handleException(context, new Error("Foo"));
- assertNotNull(writer.toString());
- }
-
- public void testNotRethrownDebugLevel() throws Throwable {
- handler.setExceptionClassifier(new ClassifierSupport(Level.RETHROW) {
- public Level classify(Throwable throwable) {
- return Level.DEBUG;
- }
- });
- // No exception...
- handler.handleException(context, new Error("Foo"));
- assertNotNull(writer.toString());
- }
-
-}
diff --git a/src/test/java/org/springframework/repeat/exception/RethrowOnThresholdExceptionHandlerTests.java b/src/test/java/org/springframework/repeat/exception/RethrowOnThresholdExceptionHandlerTests.java
deleted file mode 100644
index 0ab51c8..0000000
--- a/src/test/java/org/springframework/repeat/exception/RethrowOnThresholdExceptionHandlerTests.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright 2006-2007 the original author or authors.
- *
- * 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 org.springframework.repeat.exception;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.fail;
-
-import java.util.Collections;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import org.junit.Test;
-import org.springframework.repeat.RepeatContext;
-import org.springframework.repeat.context.RepeatContextSupport;
-
-public class RethrowOnThresholdExceptionHandlerTests {
-
- private RethrowOnThresholdExceptionHandler handler = new RethrowOnThresholdExceptionHandler();
-
- private RepeatContext parent = new RepeatContextSupport(null);
-
- private RepeatContext context = new RepeatContextSupport(parent);
-
- @Test
- public void testRuntimeException() throws Throwable {
- try {
- handler.handleException(context, new RuntimeException("Foo"));
- fail("Expected RuntimeException");
- }
- catch (RuntimeException e) {
- assertEquals("Foo", e.getMessage());
- }
- }
-
- @Test
- public void testError() throws Throwable {
- try {
- handler.handleException(context, new Error("Foo"));
- fail("Expected Error");
- }
- catch (Error e) {
- assertEquals("Foo", e.getMessage());
- }
- }
-
- @Test
- public void testNotRethrownWithThreshold() throws Throwable {
- handler.setThresholds(Collections., Integer> singletonMap(Exception.class, 1));
- // No exception...
- handler.handleException(context, new RuntimeException("Foo"));
- AtomicInteger counter = (AtomicInteger) context.getAttribute(context.attributeNames()[0]);
- assertNotNull(counter);
- assertEquals(1, counter.get());
- }
-
- @Test
- public void testRethrowOnThreshold() throws Throwable {
- handler.setThresholds(Collections., Integer> singletonMap(Exception.class, 2));
- // No exception...
- handler.handleException(context, new RuntimeException("Foo"));
- handler.handleException(context, new RuntimeException("Foo"));
- try {
- handler.handleException(context, new RuntimeException("Foo"));
- fail("Expected RuntimeException");
- }
- catch (RuntimeException e) {
- assertEquals("Foo", e.getMessage());
- }
- }
-
- @Test
- public void testNotUseParent() throws Throwable {
- handler.setThresholds(Collections., Integer> singletonMap(Exception.class, 1));
- // No exception...
- handler.handleException(context, new RuntimeException("Foo"));
- context = new RepeatContextSupport(parent);
- try {
- // No exception again - context is changed...
- handler.handleException(context, new RuntimeException("Foo"));
- }
- catch (RuntimeException e) {
- fail("Unexpected Error");
- }
- }
-
- @Test
- public void testUseParent() throws Throwable {
- handler.setThresholds(Collections., Integer> singletonMap(Exception.class, 1));
- handler.setUseParent(true);
- // No exception...
- handler.handleException(context, new RuntimeException("Foo"));
- context = new RepeatContextSupport(parent);
- try {
- handler.handleException(context, new RuntimeException("Foo"));
- fail("Expected Error");
- }
- catch (RuntimeException e) {
- assertEquals("Foo", e.getMessage());
- }
- }
-
-}
diff --git a/src/test/java/org/springframework/repeat/exception/SimpleLimitExceptionHandlerTests.java b/src/test/java/org/springframework/repeat/exception/SimpleLimitExceptionHandlerTests.java
deleted file mode 100644
index 86bc3be..0000000
--- a/src/test/java/org/springframework/repeat/exception/SimpleLimitExceptionHandlerTests.java
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * Copyright 2006-2007 the original author or authors.
- *
- * 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 org.springframework.repeat.exception;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.springframework.repeat.context.RepeatContextSupport;
-
-/**
- * Unit tests for {@link SimpleLimitExceptionHandler}
- *
- * @author Robert Kasanicky
- * @author Dave Syer
- */
-public class SimpleLimitExceptionHandlerTests {
-
- // object under test
- private SimpleLimitExceptionHandler handler = new SimpleLimitExceptionHandler();
-
- @Before
- public void initializeHandler() throws Exception {
- handler.afterPropertiesSet();
- }
-
- @Test
- public void testInitializeWithNullContext() throws Throwable {
- try {
- handler.handleException(null, new RuntimeException("foo"));
- fail("Expected IllegalArgumentException");
- }
- catch (IllegalArgumentException e) {
- // expected
- }
- }
-
- @Test
- public void testInitializeWithNullContextAndNullException() throws Throwable {
- try {
- handler.handleException(null, null);
- }
- catch (IllegalArgumentException e) {
- // expected;
- }
- }
-
- @Test
- public void testDefaultBehaviour() throws Throwable {
- Throwable throwable = new RuntimeException("foo");
- try {
- handler.handleException(new RepeatContextSupport(null), throwable);
- fail("Exception was swallowed.");
- }
- catch (RuntimeException expected) {
- assertTrue("Exception is rethrown, ignoring the exception limit", true);
- assertSame(expected, throwable);
- }
- }
-
- /**
- * Other than nominated exception type should be rethrown, ignoring the
- * exception limit.
- *
- * @throws Exception
- */
- @Test
- public void testNormalExceptionThrown() throws Throwable {
- Throwable throwable = new RuntimeException("foo");
-
- final int MORE_THAN_ZERO = 1;
- handler.setLimit(MORE_THAN_ZERO);
- handler.setExceptionClasses(Collections.> singleton(IllegalArgumentException.class));
- handler.afterPropertiesSet();
-
- try {
- handler.handleException(new RepeatContextSupport(null), throwable);
- fail("Exception was swallowed.");
- }
- catch (RuntimeException expected) {
- assertTrue("Exception is rethrown, ignoring the exception limit", true);
- assertSame(expected, throwable);
- }
- }
-
- /**
- * TransactionInvalidException should only be rethrown below the exception
- * limit.
- *
- * @throws Exception
- */
- @Test
- public void testLimitedExceptionTypeNotThrown() throws Throwable {
- final int MORE_THAN_ZERO = 1;
- handler.setLimit(MORE_THAN_ZERO);
- handler.setExceptionClasses(Collections.> singleton(RuntimeException.class));
- handler.afterPropertiesSet();
-
- try {
- handler.handleException(new RepeatContextSupport(null), new RuntimeException("foo"));
- }
- catch (RuntimeException expected) {
- fail("Unexpected exception.");
- }
- }
-
- /**
- * TransactionInvalidException should only be rethrown below the exception
- * limit.
- *
- * @throws Exception
- */
- @Test
- public void testLimitedExceptionNotThrownFromSiblings() throws Throwable {
- Throwable throwable = new RuntimeException("foo");
-
- final int MORE_THAN_ZERO = 1;
- handler.setLimit(MORE_THAN_ZERO);
- handler.setExceptionClasses(Collections.> singleton(RuntimeException.class));
- handler.afterPropertiesSet();
-
- RepeatContextSupport parent = new RepeatContextSupport(null);
-
- try {
- RepeatContextSupport context = new RepeatContextSupport(parent);
- handler.handleException(context, throwable);
- context = new RepeatContextSupport(parent);
- handler.handleException(context, throwable);
- }
- catch (RuntimeException expected) {
- fail("Unexpected exception.");
- }
- }
-
- /**
- * TransactionInvalidException should only be rethrown below the exception
- * limit.
- *
- * @throws Exception
- */
- @Test
- public void testLimitedExceptionThrownFromSiblingsWhenUsingParent() throws Throwable {
- Throwable throwable = new RuntimeException("foo");
-
- final int MORE_THAN_ZERO = 1;
- handler.setLimit(MORE_THAN_ZERO);
- handler.setExceptionClasses(Collections.> singleton(RuntimeException.class));
- handler.setUseParent(true);
- handler.afterPropertiesSet();
-
- RepeatContextSupport parent = new RepeatContextSupport(null);
-
- try {
- RepeatContextSupport context = new RepeatContextSupport(parent);
- handler.handleException(context, throwable);
- context = new RepeatContextSupport(parent);
- handler.handleException(context, throwable);
- fail("Expected exception.");
- }
- catch (RuntimeException expected) {
- assertSame(throwable, expected);
- }
- }
-
- /**
- * Exceptions are swallowed until the exception limit is exceeded. After the
- * limit is exceeded exceptions are rethrown
- */
- @Test
- public void testExceptionNotThrownBelowLimit() throws Throwable {
-
- final int EXCEPTION_LIMIT = 3;
- handler.setLimit(EXCEPTION_LIMIT);
- handler.afterPropertiesSet();
-
- List throwables = new ArrayList() {
- {
- for (int i = 0; i < (EXCEPTION_LIMIT); i++) {
- add(new RuntimeException("below exception limit"));
- }
- }
- };
-
- RepeatContextSupport context = new RepeatContextSupport(null);
-
- try {
- for (Throwable throwable : throwables) {
-
- handler.handleException(context, throwable);
- assertTrue("exceptions up to limit are swallowed", true);
-
- }
- }
- catch (RuntimeException unexpected) {
- fail("exception rethrown although exception limit was not exceeded");
- }
-
- }
-
- /**
- * TransactionInvalidExceptions are swallowed until the exception limit is
- * exceeded. After the limit is exceeded exceptions are rethrown as
- * BatchCriticalExceptions
- */
- @Test
- public void testExceptionThrownAboveLimit() throws Throwable {
-
- final int EXCEPTION_LIMIT = 3;
- handler.setLimit(EXCEPTION_LIMIT);
- handler.afterPropertiesSet();
-
- List throwables = new ArrayList() {
- {
- for (int i = 0; i < (EXCEPTION_LIMIT); i++) {
- add(new RuntimeException("below exception limit"));
- }
- }
- };
-
- throwables.add(new RuntimeException("above exception limit"));
-
- RepeatContextSupport context = new RepeatContextSupport(null);
-
- try {
- for (Throwable throwable : throwables) {
-
- handler.handleException(context, throwable);
- assertTrue("exceptions up to limit are swallowed", true);
-
- }
- }
- catch (RuntimeException expected) {
- assertEquals("above exception limit", expected.getMessage());
- }
-
- // after reaching the limit, behaviour should be idempotent
- try {
- handler.handleException(context, new RuntimeException("foo"));
- assertTrue("exceptions up to limit are swallowed", true);
-
- }
- catch (RuntimeException expected) {
- assertEquals("foo", expected.getMessage());
- }
- }
-}
diff --git a/src/test/java/org/springframework/repeat/interceptor/RepeatOperationsInterceptorTests.java b/src/test/java/org/springframework/repeat/interceptor/RepeatOperationsInterceptorTests.java
deleted file mode 100644
index 125ba55..0000000
--- a/src/test/java/org/springframework/repeat/interceptor/RepeatOperationsInterceptorTests.java
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- * Copyright 2006-2007 the original author or authors.
- *
- * 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 org.springframework.repeat.interceptor;
-
-import java.lang.reflect.AccessibleObject;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.List;
-
-import junit.framework.TestCase;
-
-import org.aopalliance.intercept.MethodInterceptor;
-import org.aopalliance.intercept.MethodInvocation;
-import org.springframework.aop.framework.Advised;
-import org.springframework.aop.framework.ProxyFactory;
-import org.springframework.repeat.RepeatCallback;
-import org.springframework.repeat.RepeatException;
-import org.springframework.repeat.RepeatOperations;
-import org.springframework.repeat.RepeatStatus;
-import org.springframework.repeat.policy.SimpleCompletionPolicy;
-import org.springframework.repeat.support.RepeatTemplate;
-
-public class RepeatOperationsInterceptorTests extends TestCase {
-
- private RepeatOperationsInterceptor interceptor;
-
- private Service service;
-
- private ServiceImpl target;
-
- protected void setUp() throws Exception {
- super.setUp();
- interceptor = new RepeatOperationsInterceptor();
- target = new ServiceImpl();
- ProxyFactory factory = new ProxyFactory(RepeatOperations.class.getClassLoader());
- factory.setInterfaces(new Class[] { Service.class });
- factory.setTarget(target);
- service = (Service) factory.getProxy();
- }
-
- public void testDefaultInterceptorSunnyDay() throws Exception {
- ((Advised) service).addAdvice(interceptor);
- service.service();
- assertEquals(3, target.count);
- }
-
- public void testCompleteOnFirstInvocation() throws Exception {
- ((Advised) service).addAdvice(interceptor);
- target.setMaxService(0);
- service.service();
- assertEquals(1, target.count);
- }
-
- public void testSetTemplate() throws Exception {
- final List