diff --git a/spring-integration-core/src/main/java/org/springframework/integration/aggregator/MessageCountReleaseStrategy.java b/spring-integration-core/src/main/java/org/springframework/integration/aggregator/MessageCountReleaseStrategy.java
index 7f75aa063c..a195cdf713 100755
--- a/spring-integration-core/src/main/java/org/springframework/integration/aggregator/MessageCountReleaseStrategy.java
+++ b/spring-integration-core/src/main/java/org/springframework/integration/aggregator/MessageCountReleaseStrategy.java
@@ -1,52 +1,52 @@
-/*
- * Copyright 2002-2010 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.integration.aggregator;
-
-import org.springframework.integration.store.MessageGroup;
-
-/**
- * A {@link ReleaseStrategy} that releases only the first n messages, where n is a threshold.
- *
- * @author Dave Syer
- *
- */
-public class MessageCountReleaseStrategy implements ReleaseStrategy {
-
- private final int threshold;
-
- /**
- * @param threshold the number of messages to accept before releasing
- */
- public MessageCountReleaseStrategy(int threshold) {
- super();
- this.threshold = threshold;
- }
-
- /**
- * Convenient constructor is only one message is required (threshold=1).
- */
- public MessageCountReleaseStrategy() {
- this(1);
- }
-
- /**
- * Release the group if it has more messages than the threshold and has not previously been released. Previous
- * releases leave an imprint on the group in the form of marked messages. It is possible that more messages than the
- * threshold could be released, but only if multiple consumers receive messages from the same group concurrently.
- */
- public boolean canRelease(MessageGroup group) {
- return group.size() >= threshold && group.getMarked().size() == 0;
- }
-
-}
+/*
+ * Copyright 2002-2010 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.integration.aggregator;
+
+import org.springframework.integration.store.MessageGroup;
+
+/**
+ * A {@link ReleaseStrategy} that releases only the first n messages, where n is a threshold.
+ *
+ * @author Dave Syer
+ *
+ */
+public class MessageCountReleaseStrategy implements ReleaseStrategy {
+
+ private final int threshold;
+
+ /**
+ * @param threshold the number of messages to accept before releasing
+ */
+ public MessageCountReleaseStrategy(int threshold) {
+ super();
+ this.threshold = threshold;
+ }
+
+ /**
+ * Convenient constructor is only one message is required (threshold=1).
+ */
+ public MessageCountReleaseStrategy() {
+ this(1);
+ }
+
+ /**
+ * Release the group if it has more messages than the threshold and has not previously been released. Previous
+ * releases leave an imprint on the group in the form of marked messages. It is possible that more messages than the
+ * threshold could be released, but only if multiple consumers receive messages from the same group concurrently.
+ */
+ public boolean canRelease(MessageGroup group) {
+ return group.size() >= threshold && group.getMarked().size() == 0;
+ }
+
+}
diff --git a/spring-integration-core/src/main/java/org/springframework/integration/dispatcher/OrderedAwareLinkedHashSet.java b/spring-integration-core/src/main/java/org/springframework/integration/dispatcher/OrderedAwareLinkedHashSet.java
index 5e289c3a50..cd76ac8134 100644
--- a/spring-integration-core/src/main/java/org/springframework/integration/dispatcher/OrderedAwareLinkedHashSet.java
+++ b/spring-integration-core/src/main/java/org/springframework/integration/dispatcher/OrderedAwareLinkedHashSet.java
@@ -1,192 +1,192 @@
-/*
- * Copyright 2002-2009 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.integration.dispatcher;
-
-import java.util.Collection;
-import java.util.Comparator;
-import java.util.LinkedHashSet;
-import java.util.Set;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
-import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
-
-import org.springframework.core.OrderComparator;
-import org.springframework.core.Ordered;
-import org.springframework.core.annotation.Order;
-import org.springframework.util.Assert;
-import org.springframework.util.CollectionUtils;
-import org.springframework.util.StringUtils;
-
-/**
- * Special Set that maintains the following semantics:
- * All elements that are un-ordered (do not implement {@link Ordered} interface or annotated
- * {@link Order} annotation) will be stored in the order in which they were added, maintaining the
- * semantics of the {@link LinkedHashSet}. However, for all {@link Ordered} elements a
- * {@link Comparator} (instantiated by default) for this implementation of {@link Set}, will be
- * used. Those elements will have precedence over un-ordered elements. If elements have the same
- * order but themselves do not equal to one another the more recent addition will be placed to the
- * right of (appended next to) the existing element with the same order, thus preserving the order
- * of the insertion and maintaining {@link LinkedHashSet} semantics for the un-ordered elements.
- *
- * The class is package-protected and only intended for use by the AbstractDispatcher. It
- * must enforce safe concurrent access for all usage by the dispatcher.
- *
- * @author Oleg Zhurakousky
- * @author Mark Fisher
- * @since 1.0.3
- */
-@SuppressWarnings({"unchecked", "serial"})
-class OrderedAwareLinkedHashSet extends LinkedHashSet {
-
- private final OrderComparator comparator = new OrderComparator();
-
- private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
-
- private final ReadLock readLock = rwl.readLock();
-
- private final WriteLock writeLock = rwl.writeLock();
-
-
- /**
- * Every time an Ordered element is added via this method this
- * Set will be re-sorted, otherwise the element is simply added
- * to the end. Added element must not be null.
- */
- public boolean add(E o) {
- Assert.notNull(o,"Can not add NULL object");
- writeLock.lock();
- try {
- boolean present = false;
- if (o instanceof Ordered){
- present = this.addOrderedElement((Ordered) o);
- }
- else {
- present = super.add(o);
- }
- return present;
- }
- finally {
- writeLock.unlock();
- }
- }
-
- /**
- * Adds all elements in this Collection.
- */
- public boolean addAll(Collection extends E> c) {
- Assert.notNull(c,"Can not merge with NULL set");
- writeLock.lock();
- try {
- for (E object : c) {
- this.add(object);
- }
- return true;
- }
- finally {
- writeLock.unlock();
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean remove(Object o) {
- writeLock.lock();
- try {
- return super.remove(o);
- }
- finally {
- writeLock.unlock();
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean removeAll(Collection> c){
- if (CollectionUtils.isEmpty(c)){
- return false;
- }
- writeLock.lock();
- try {
- return super.removeAll(c);
- }
- finally {
- writeLock.unlock();
- }
- }
-
- @Override
- public T[] toArray(T[] a) {
- readLock.lock();
- try {
- return super.toArray(a);
- }
- finally {
- readLock.unlock();
- }
- }
-
- @Override
- public String toString() {
- readLock.lock();
- try {
- return StringUtils.collectionToCommaDelimitedString(this);
- }
- finally {
- readLock.unlock();
- }
- }
-
- private boolean addOrderedElement(Ordered adding) {
- boolean added = false;
- E[] tempUnorderedElements = (E[]) this.toArray();
- if (super.contains(adding)) {
- return false;
- }
- super.clear();
-
- if (tempUnorderedElements.length == 0) {
- added = super.add((E) adding);
- }
- else {
- Set tempSet = new LinkedHashSet();
- for (E current : tempUnorderedElements) {
- if (current instanceof Ordered) {
- if (this.comparator.compare(adding, current) < 0) {
- added = super.add((E) adding);
- super.add(current);
- }
- else {
- super.add(current);
- }
- }
- else {
- tempSet.add(current);
- }
- }
- if (!added) {
- added = super.add((E) adding);
- }
- for (Object object : tempSet) {
- super.add((E) object);
- }
- }
- return added;
- }
-
-}
+/*
+ * Copyright 2002-2009 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.integration.dispatcher;
+
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.LinkedHashSet;
+import java.util.Set;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
+
+import org.springframework.core.OrderComparator;
+import org.springframework.core.Ordered;
+import org.springframework.core.annotation.Order;
+import org.springframework.util.Assert;
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.StringUtils;
+
+/**
+ * Special Set that maintains the following semantics:
+ * All elements that are un-ordered (do not implement {@link Ordered} interface or annotated
+ * {@link Order} annotation) will be stored in the order in which they were added, maintaining the
+ * semantics of the {@link LinkedHashSet}. However, for all {@link Ordered} elements a
+ * {@link Comparator} (instantiated by default) for this implementation of {@link Set}, will be
+ * used. Those elements will have precedence over un-ordered elements. If elements have the same
+ * order but themselves do not equal to one another the more recent addition will be placed to the
+ * right of (appended next to) the existing element with the same order, thus preserving the order
+ * of the insertion and maintaining {@link LinkedHashSet} semantics for the un-ordered elements.
+ *
+ * The class is package-protected and only intended for use by the AbstractDispatcher. It
+ * must enforce safe concurrent access for all usage by the dispatcher.
+ *
+ * @author Oleg Zhurakousky
+ * @author Mark Fisher
+ * @since 1.0.3
+ */
+@SuppressWarnings({"unchecked", "serial"})
+class OrderedAwareLinkedHashSet extends LinkedHashSet {
+
+ private final OrderComparator comparator = new OrderComparator();
+
+ private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
+
+ private final ReadLock readLock = rwl.readLock();
+
+ private final WriteLock writeLock = rwl.writeLock();
+
+
+ /**
+ * Every time an Ordered element is added via this method this
+ * Set will be re-sorted, otherwise the element is simply added
+ * to the end. Added element must not be null.
+ */
+ public boolean add(E o) {
+ Assert.notNull(o,"Can not add NULL object");
+ writeLock.lock();
+ try {
+ boolean present = false;
+ if (o instanceof Ordered){
+ present = this.addOrderedElement((Ordered) o);
+ }
+ else {
+ present = super.add(o);
+ }
+ return present;
+ }
+ finally {
+ writeLock.unlock();
+ }
+ }
+
+ /**
+ * Adds all elements in this Collection.
+ */
+ public boolean addAll(Collection extends E> c) {
+ Assert.notNull(c,"Can not merge with NULL set");
+ writeLock.lock();
+ try {
+ for (E object : c) {
+ this.add(object);
+ }
+ return true;
+ }
+ finally {
+ writeLock.unlock();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean remove(Object o) {
+ writeLock.lock();
+ try {
+ return super.remove(o);
+ }
+ finally {
+ writeLock.unlock();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean removeAll(Collection> c){
+ if (CollectionUtils.isEmpty(c)){
+ return false;
+ }
+ writeLock.lock();
+ try {
+ return super.removeAll(c);
+ }
+ finally {
+ writeLock.unlock();
+ }
+ }
+
+ @Override
+ public T[] toArray(T[] a) {
+ readLock.lock();
+ try {
+ return super.toArray(a);
+ }
+ finally {
+ readLock.unlock();
+ }
+ }
+
+ @Override
+ public String toString() {
+ readLock.lock();
+ try {
+ return StringUtils.collectionToCommaDelimitedString(this);
+ }
+ finally {
+ readLock.unlock();
+ }
+ }
+
+ private boolean addOrderedElement(Ordered adding) {
+ boolean added = false;
+ E[] tempUnorderedElements = (E[]) this.toArray();
+ if (super.contains(adding)) {
+ return false;
+ }
+ super.clear();
+
+ if (tempUnorderedElements.length == 0) {
+ added = super.add((E) adding);
+ }
+ else {
+ Set tempSet = new LinkedHashSet();
+ for (E current : tempUnorderedElements) {
+ if (current instanceof Ordered) {
+ if (this.comparator.compare(adding, current) < 0) {
+ added = super.add((E) adding);
+ super.add(current);
+ }
+ else {
+ super.add(current);
+ }
+ }
+ else {
+ tempSet.add(current);
+ }
+ }
+ if (!added) {
+ added = super.add((E) adding);
+ }
+ for (Object object : tempSet) {
+ super.add((E) object);
+ }
+ }
+ return added;
+ }
+
+}
diff --git a/spring-integration-core/src/main/java/org/springframework/integration/store/AbstractMessageGroupStore.java b/spring-integration-core/src/main/java/org/springframework/integration/store/AbstractMessageGroupStore.java
index c307cb8ff8..5733373851 100644
--- a/spring-integration-core/src/main/java/org/springframework/integration/store/AbstractMessageGroupStore.java
+++ b/spring-integration-core/src/main/java/org/springframework/integration/store/AbstractMessageGroupStore.java
@@ -1,93 +1,93 @@
-/*
- * Copyright 2002-2010 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.integration.store;
-
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.LinkedHashSet;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-/**
- * @author Dave Syer
- *
- * @since 2.0
- *
- */
-public abstract class AbstractMessageGroupStore implements MessageGroupStore, Iterable {
-
- protected final Log logger = LogFactory.getLog(getClass());
-
- private Collection expiryCallbacks = new LinkedHashSet();
-
- /**
- *
- */
- public AbstractMessageGroupStore() {
- super();
- }
-
- /**
- * Convenient injection point for expiry callbacks in the message store. Each of the callbacks provided will simply
- * be registered with the store using {@link #registerMessageGroupExpiryCallback(MessageGroupCallback)}.
- *
- * @param expiryCallbacks the expiry callbacks to add
- */
- public void setExpiryCallbacks(Collection expiryCallbacks) {
- for (MessageGroupCallback callback : expiryCallbacks) {
- registerMessageGroupExpiryCallback(callback);
- }
- }
-
- public void registerMessageGroupExpiryCallback(MessageGroupCallback callback) {
- expiryCallbacks.add(callback);
- }
-
- public int expireMessageGroups(long timeout) {
- int count = 0;
- long threshold = System.currentTimeMillis() - timeout;
- for (MessageGroup group : this) {
- if (group.getTimestamp() < threshold) {
- count++;
- expire(group);
- }
- }
- return count;
- }
-
- public abstract Iterator iterator();
-
- private void expire(MessageGroup group) {
-
- RuntimeException exception = null;
-
- for (MessageGroupCallback callback : expiryCallbacks) {
- try {
- callback.execute(this, group);
- } catch (RuntimeException e) {
- if (exception == null) {
- exception = e;
- }
- logger.error("Exception in expiry callback", e);
- }
- }
-
- if (exception != null) {
- throw exception;
- }
-
- }
-
+/*
+ * Copyright 2002-2010 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.integration.store;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * @author Dave Syer
+ *
+ * @since 2.0
+ *
+ */
+public abstract class AbstractMessageGroupStore implements MessageGroupStore, Iterable {
+
+ protected final Log logger = LogFactory.getLog(getClass());
+
+ private Collection expiryCallbacks = new LinkedHashSet();
+
+ /**
+ *
+ */
+ public AbstractMessageGroupStore() {
+ super();
+ }
+
+ /**
+ * Convenient injection point for expiry callbacks in the message store. Each of the callbacks provided will simply
+ * be registered with the store using {@link #registerMessageGroupExpiryCallback(MessageGroupCallback)}.
+ *
+ * @param expiryCallbacks the expiry callbacks to add
+ */
+ public void setExpiryCallbacks(Collection expiryCallbacks) {
+ for (MessageGroupCallback callback : expiryCallbacks) {
+ registerMessageGroupExpiryCallback(callback);
+ }
+ }
+
+ public void registerMessageGroupExpiryCallback(MessageGroupCallback callback) {
+ expiryCallbacks.add(callback);
+ }
+
+ public int expireMessageGroups(long timeout) {
+ int count = 0;
+ long threshold = System.currentTimeMillis() - timeout;
+ for (MessageGroup group : this) {
+ if (group.getTimestamp() < threshold) {
+ count++;
+ expire(group);
+ }
+ }
+ return count;
+ }
+
+ public abstract Iterator iterator();
+
+ private void expire(MessageGroup group) {
+
+ RuntimeException exception = null;
+
+ for (MessageGroupCallback callback : expiryCallbacks) {
+ try {
+ callback.execute(this, group);
+ } catch (RuntimeException e) {
+ if (exception == null) {
+ exception = e;
+ }
+ logger.error("Exception in expiry callback", e);
+ }
+ }
+
+ if (exception != null) {
+ throw exception;
+ }
+
+ }
+
}
\ No newline at end of file
diff --git a/spring-integration-core/src/main/java/org/springframework/integration/store/MessageGroupCallback.java b/spring-integration-core/src/main/java/org/springframework/integration/store/MessageGroupCallback.java
index 02cfc158d2..672dfd714d 100755
--- a/spring-integration-core/src/main/java/org/springframework/integration/store/MessageGroupCallback.java
+++ b/spring-integration-core/src/main/java/org/springframework/integration/store/MessageGroupCallback.java
@@ -1,26 +1,26 @@
-/*
- * Copyright 2002-2010 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.integration.store;
-
-/**
- * @author Dave Syer
- *
- * @since 2.0
- *
- */
-public interface MessageGroupCallback {
-
- void execute(MessageGroupStore messageGroupStore, MessageGroup group);
-
-}
+/*
+ * Copyright 2002-2010 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.integration.store;
+
+/**
+ * @author Dave Syer
+ *
+ * @since 2.0
+ *
+ */
+public interface MessageGroupCallback {
+
+ void execute(MessageGroupStore messageGroupStore, MessageGroup group);
+
+}
diff --git a/spring-integration-core/src/main/java/org/springframework/integration/store/MessageGroupStoreReaper.java b/spring-integration-core/src/main/java/org/springframework/integration/store/MessageGroupStoreReaper.java
index 51a613903a..4ee8c7ad0d 100644
--- a/spring-integration-core/src/main/java/org/springframework/integration/store/MessageGroupStoreReaper.java
+++ b/spring-integration-core/src/main/java/org/springframework/integration/store/MessageGroupStoreReaper.java
@@ -1,100 +1,100 @@
-/*
- * Copyright 2002-2010 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.integration.store;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.springframework.beans.factory.DisposableBean;
-import org.springframework.beans.factory.InitializingBean;
-import org.springframework.context.ApplicationContext;
-import org.springframework.util.Assert;
-
-/**
- * Convenient configurable component to allow explicit timed expiry of {@link MessageGroup} instances in a
- * {@link MessageGroupStore}. This component provides a no-args {@link #run()} method that is useful for remote or timed
- * execution and a {@link #destroy()} method that can optionally be called on shutdown.
- *
- * @author Dave Syer
- *
- */
-public class MessageGroupStoreReaper implements Runnable, DisposableBean, InitializingBean {
-
- private static Log logger = LogFactory.getLog(MessageGroupStoreReaper.class);
-
- private MessageGroupStore messageGroupStore;
- private boolean expireOnDestroy = false;
- private long timeout = -1;
-
- public MessageGroupStoreReaper(MessageGroupStore messageGroupStore) {
- this.messageGroupStore = messageGroupStore;
- }
-
- public MessageGroupStoreReaper() {
- }
-
- /**
- * Flag to indicate that the stores should be expired when this component is destroyed (i.e. usuually when its
- * enclosing {@link ApplicationContext} is closed).
- *
- * @param expireOnDestroy the flag value to set
- */
- public void setExpireOnDestroy(boolean expireOnDestroy) {
- this.expireOnDestroy = expireOnDestroy;
- }
-
- /**
- * Timeout in milliseconds (default -1). If negative then no groups ever time out. If greater than zero then all
- * groups older than that value are expired when this component is {@link #run()}.
- *
- * @param timeout the timeout to set
- */
- public void setTimeout(long timeout) {
- this.timeout = timeout;
- }
-
- /**
- * A message group store to expire according the the other configurations.
- *
- * @param messageGroupStore the {@link MessageGroupStore} to set
- */
- public void setMessageGroupStore(MessageGroupStore messageGroupStore) {
- this.messageGroupStore = messageGroupStore;
- }
-
- public void afterPropertiesSet() throws Exception {
- Assert.state(messageGroupStore != null, "A MessageGroupStore must be provided");
- }
-
- public void destroy() throws Exception {
- if (expireOnDestroy) {
- logger.info("Expiring all messages from message group store: " + messageGroupStore);
- messageGroupStore.expireMessageGroups(0);
- }
- }
-
- /**
- * Expire all message groups older than the {@link #setTimeout(long) timeout} provided. Normally this method would
- * be executed by a scheduled task.
- */
- public void run() {
- if (timeout >= 0) {
- if (logger.isDebugEnabled()) {
- logger.debug("Expiring all messages older than timeout=" + timeout + " from message group store: "
- + messageGroupStore);
- }
- messageGroupStore.expireMessageGroups(timeout);
- }
- }
-
-}
+/*
+ * Copyright 2002-2010 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.integration.store;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.factory.DisposableBean;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.context.ApplicationContext;
+import org.springframework.util.Assert;
+
+/**
+ * Convenient configurable component to allow explicit timed expiry of {@link MessageGroup} instances in a
+ * {@link MessageGroupStore}. This component provides a no-args {@link #run()} method that is useful for remote or timed
+ * execution and a {@link #destroy()} method that can optionally be called on shutdown.
+ *
+ * @author Dave Syer
+ *
+ */
+public class MessageGroupStoreReaper implements Runnable, DisposableBean, InitializingBean {
+
+ private static Log logger = LogFactory.getLog(MessageGroupStoreReaper.class);
+
+ private MessageGroupStore messageGroupStore;
+ private boolean expireOnDestroy = false;
+ private long timeout = -1;
+
+ public MessageGroupStoreReaper(MessageGroupStore messageGroupStore) {
+ this.messageGroupStore = messageGroupStore;
+ }
+
+ public MessageGroupStoreReaper() {
+ }
+
+ /**
+ * Flag to indicate that the stores should be expired when this component is destroyed (i.e. usuually when its
+ * enclosing {@link ApplicationContext} is closed).
+ *
+ * @param expireOnDestroy the flag value to set
+ */
+ public void setExpireOnDestroy(boolean expireOnDestroy) {
+ this.expireOnDestroy = expireOnDestroy;
+ }
+
+ /**
+ * Timeout in milliseconds (default -1). If negative then no groups ever time out. If greater than zero then all
+ * groups older than that value are expired when this component is {@link #run()}.
+ *
+ * @param timeout the timeout to set
+ */
+ public void setTimeout(long timeout) {
+ this.timeout = timeout;
+ }
+
+ /**
+ * A message group store to expire according the the other configurations.
+ *
+ * @param messageGroupStore the {@link MessageGroupStore} to set
+ */
+ public void setMessageGroupStore(MessageGroupStore messageGroupStore) {
+ this.messageGroupStore = messageGroupStore;
+ }
+
+ public void afterPropertiesSet() throws Exception {
+ Assert.state(messageGroupStore != null, "A MessageGroupStore must be provided");
+ }
+
+ public void destroy() throws Exception {
+ if (expireOnDestroy) {
+ logger.info("Expiring all messages from message group store: " + messageGroupStore);
+ messageGroupStore.expireMessageGroups(0);
+ }
+ }
+
+ /**
+ * Expire all message groups older than the {@link #setTimeout(long) timeout} provided. Normally this method would
+ * be executed by a scheduled task.
+ */
+ public void run() {
+ if (timeout >= 0) {
+ if (logger.isDebugEnabled()) {
+ logger.debug("Expiring all messages older than timeout=" + timeout + " from message group store: "
+ + messageGroupStore);
+ }
+ messageGroupStore.expireMessageGroups(timeout);
+ }
+ }
+
+}
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/aggregator/integration/AnnotationAggregatorTests.java b/spring-integration-core/src/test/java/org/springframework/integration/aggregator/integration/AnnotationAggregatorTests.java
index 522abd3a49..5bd0ae304a 100644
--- a/spring-integration-core/src/test/java/org/springframework/integration/aggregator/integration/AnnotationAggregatorTests.java
+++ b/spring-integration-core/src/test/java/org/springframework/integration/aggregator/integration/AnnotationAggregatorTests.java
@@ -1,80 +1,80 @@
-/*
- * Copyright 2002-2010 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.integration.aggregator.integration;
-
-import static org.junit.Assert.assertTrue;
-
-import java.util.List;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.integration.Message;
-import org.springframework.integration.annotation.Aggregator;
-import org.springframework.integration.annotation.CorrelationStrategy;
-import org.springframework.integration.annotation.ReleaseStrategy;
-import org.springframework.integration.channel.DirectChannel;
-import org.springframework.integration.core.MessageBuilder;
-import org.springframework.integration.core.PollableChannel;
-import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
-
-/**
- * @author Mark Fisher
- */
-@ContextConfiguration
-@RunWith(SpringJUnit4ClassRunner.class)
-public class AnnotationAggregatorTests {
-
- @Autowired
- DirectChannel input;
-
- @Autowired
- PollableChannel output;
-
-
- @Test
- public void testAggregationWithAnnotationStrategies() {
- input.send(MessageBuilder.withPayload("a").build());
- input.send(MessageBuilder.withPayload("b").build());
- @SuppressWarnings("unchecked")
- Message result = (Message) output.receive();
- String payload = result.getPayload();
- assertTrue("Wrong payload: "+payload, payload.contains("Payload=a"));
- assertTrue("Wrong payload: "+payload, payload.contains("Payload=b"));
- }
-
- @SuppressWarnings("unused")
- private static class TestAggregator {
-
- @Aggregator
- public Message> aggregate(final List> messages) {
- return MessageBuilder.withPayload(messages.toString()).build();
- }
-
- @ReleaseStrategy
- public boolean release(final List> messages) {
- return messages.size()>1;
- }
-
- @CorrelationStrategy
- public Object getKey(Message> message) {
- return "1";
- }
- }
-
-}
+/*
+ * Copyright 2002-2010 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.integration.aggregator.integration;
+
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.integration.Message;
+import org.springframework.integration.annotation.Aggregator;
+import org.springframework.integration.annotation.CorrelationStrategy;
+import org.springframework.integration.annotation.ReleaseStrategy;
+import org.springframework.integration.channel.DirectChannel;
+import org.springframework.integration.core.MessageBuilder;
+import org.springframework.integration.core.PollableChannel;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+/**
+ * @author Mark Fisher
+ */
+@ContextConfiguration
+@RunWith(SpringJUnit4ClassRunner.class)
+public class AnnotationAggregatorTests {
+
+ @Autowired
+ DirectChannel input;
+
+ @Autowired
+ PollableChannel output;
+
+
+ @Test
+ public void testAggregationWithAnnotationStrategies() {
+ input.send(MessageBuilder.withPayload("a").build());
+ input.send(MessageBuilder.withPayload("b").build());
+ @SuppressWarnings("unchecked")
+ Message result = (Message) output.receive();
+ String payload = result.getPayload();
+ assertTrue("Wrong payload: "+payload, payload.contains("Payload=a"));
+ assertTrue("Wrong payload: "+payload, payload.contains("Payload=b"));
+ }
+
+ @SuppressWarnings("unused")
+ private static class TestAggregator {
+
+ @Aggregator
+ public Message> aggregate(final List> messages) {
+ return MessageBuilder.withPayload(messages.toString()).build();
+ }
+
+ @ReleaseStrategy
+ public boolean release(final List> messages) {
+ return messages.size()>1;
+ }
+
+ @CorrelationStrategy
+ public Object getKey(Message> message) {
+ return "1";
+ }
+ }
+
+}
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/aggregator/integration/MethodInvokingAggregatorReturningMessageTests-context.xml b/spring-integration-core/src/test/java/org/springframework/integration/aggregator/integration/MethodInvokingAggregatorReturningMessageTests-context.xml
index 9c0452da3d..82de024d28 100644
--- a/spring-integration-core/src/test/java/org/springframework/integration/aggregator/integration/MethodInvokingAggregatorReturningMessageTests-context.xml
+++ b/spring-integration-core/src/test/java/org/springframework/integration/aggregator/integration/MethodInvokingAggregatorReturningMessageTests-context.xml
@@ -1,28 +1,28 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/channel/config/AutoGeneratedChannelTests-context.xml b/spring-integration-core/src/test/java/org/springframework/integration/channel/config/AutoGeneratedChannelTests-context.xml
index 21194ef98c..6d0def4d9e 100644
--- a/spring-integration-core/src/test/java/org/springframework/integration/channel/config/AutoGeneratedChannelTests-context.xml
+++ b/spring-integration-core/src/test/java/org/springframework/integration/channel/config/AutoGeneratedChannelTests-context.xml
@@ -1,11 +1,11 @@
-
+ http://www.springframework.org/schema/integration/spring-integration.xsd">
-
+ http://www.springframework.org/schema/integration/spring-integration.xsd">
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/channel/config/DispatchingChannelParserTests-context.xml b/spring-integration-core/src/test/java/org/springframework/integration/channel/config/DispatchingChannelParserTests-context.xml
index c3144d15cf..63c66021bb 100644
--- a/spring-integration-core/src/test/java/org/springframework/integration/channel/config/DispatchingChannelParserTests-context.xml
+++ b/spring-integration-core/src/test/java/org/springframework/integration/channel/config/DispatchingChannelParserTests-context.xml
@@ -7,7 +7,7 @@
http://www.springframework.org/schema/integration/spring-integration.xsd">
-
+
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/channel/config/channelInterceptorParserTests.xml b/spring-integration-core/src/test/java/org/springframework/integration/channel/config/channelInterceptorParserTests.xml
index 5ff14b01b0..b2230679d5 100644
--- a/spring-integration-core/src/test/java/org/springframework/integration/channel/config/channelInterceptorParserTests.xml
+++ b/spring-integration-core/src/test/java/org/springframework/integration/channel/config/channelInterceptorParserTests.xml
@@ -1,11 +1,11 @@
-
+ http://www.springframework.org/schema/integration/spring-integration.xsd">
@@ -26,5 +26,5 @@
-
+
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/channel/config/channelParserTests.xml b/spring-integration-core/src/test/java/org/springframework/integration/channel/config/channelParserTests.xml
index 03ae820db5..70c80bd907 100644
--- a/spring-integration-core/src/test/java/org/springframework/integration/channel/config/channelParserTests.xml
+++ b/spring-integration-core/src/test/java/org/springframework/integration/channel/config/channelParserTests.xml
@@ -11,7 +11,7 @@
-
+
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/channel/config/channelWithoutId.xml b/spring-integration-core/src/test/java/org/springframework/integration/channel/config/channelWithoutId.xml
index b3c0852e30..c04607fd46 100644
--- a/spring-integration-core/src/test/java/org/springframework/integration/channel/config/channelWithoutId.xml
+++ b/spring-integration-core/src/test/java/org/springframework/integration/channel/config/channelWithoutId.xml
@@ -1,11 +1,11 @@
-
+ http://www.springframework.org/schema/integration/spring-integration.xsd">
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/channel/config/priorityChannelParserTests.xml b/spring-integration-core/src/test/java/org/springframework/integration/channel/config/priorityChannelParserTests.xml
index fd8d30ab19..9952f4c162 100644
--- a/spring-integration-core/src/test/java/org/springframework/integration/channel/config/priorityChannelParserTests.xml
+++ b/spring-integration-core/src/test/java/org/springframework/integration/channel/config/priorityChannelParserTests.xml
@@ -1,11 +1,11 @@
-
+ http://www.springframework.org/schema/integration/spring-integration.xsd">
@@ -21,5 +21,5 @@
-
+
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/channel/config/rendezvousChannelParserTests.xml b/spring-integration-core/src/test/java/org/springframework/integration/channel/config/rendezvousChannelParserTests.xml
index 835833d9a4..c2c31f3bba 100644
--- a/spring-integration-core/src/test/java/org/springframework/integration/channel/config/rendezvousChannelParserTests.xml
+++ b/spring-integration-core/src/test/java/org/springframework/integration/channel/config/rendezvousChannelParserTests.xml
@@ -1,11 +1,11 @@
-
+ http://www.springframework.org/schema/integration/spring-integration.xsd">
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/channel/directChannelParserTests.xml b/spring-integration-core/src/test/java/org/springframework/integration/channel/directChannelParserTests.xml
index be034c0e12..b32bfb1b30 100644
--- a/spring-integration-core/src/test/java/org/springframework/integration/channel/directChannelParserTests.xml
+++ b/spring-integration-core/src/test/java/org/springframework/integration/channel/directChannelParserTests.xml
@@ -1,11 +1,11 @@
-
+ http://www.springframework.org/schema/integration/spring-integration.xsd">
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/config/AggregatorWithMessageStoreParserTests-context.xml b/spring-integration-core/src/test/java/org/springframework/integration/config/AggregatorWithMessageStoreParserTests-context.xml
index 2e3a2eb1ed..8a2781a4e0 100644
--- a/spring-integration-core/src/test/java/org/springframework/integration/config/AggregatorWithMessageStoreParserTests-context.xml
+++ b/spring-integration-core/src/test/java/org/springframework/integration/config/AggregatorWithMessageStoreParserTests-context.xml
@@ -1,23 +1,23 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/config/ChannelAdapterParserTests-context.xml b/spring-integration-core/src/test/java/org/springframework/integration/config/ChannelAdapterParserTests-context.xml
index 9510341478..db85a343eb 100644
--- a/spring-integration-core/src/test/java/org/springframework/integration/config/ChannelAdapterParserTests-context.xml
+++ b/spring-integration-core/src/test/java/org/springframework/integration/config/ChannelAdapterParserTests-context.xml
@@ -1,12 +1,12 @@
-
-
+
@@ -24,5 +24,5 @@
-
+
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/config/FilterParserTests-context.xml b/spring-integration-core/src/test/java/org/springframework/integration/config/FilterParserTests-context.xml
index 79fa610dfc..b2978426dd 100644
--- a/spring-integration-core/src/test/java/org/springframework/integration/config/FilterParserTests-context.xml
+++ b/spring-integration-core/src/test/java/org/springframework/integration/config/FilterParserTests-context.xml
@@ -1,7 +1,7 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/config/annotation/AnnotatedEndpointActivationTests-context.xml b/spring-integration-core/src/test/java/org/springframework/integration/config/annotation/AnnotatedEndpointActivationTests-context.xml
index 054b17cf1e..5eecbc6a13 100644
--- a/spring-integration-core/src/test/java/org/springframework/integration/config/annotation/AnnotatedEndpointActivationTests-context.xml
+++ b/spring-integration-core/src/test/java/org/springframework/integration/config/annotation/AnnotatedEndpointActivationTests-context.xml
@@ -1,11 +1,11 @@
-
+ http://www.springframework.org/schema/integration/spring-integration.xsd">
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/config/annotation/messageParameterAnnotatedEndpointTests.xml b/spring-integration-core/src/test/java/org/springframework/integration/config/annotation/messageParameterAnnotatedEndpointTests.xml
index da477ddc25..0c0bb408d0 100644
--- a/spring-integration-core/src/test/java/org/springframework/integration/config/annotation/messageParameterAnnotatedEndpointTests.xml
+++ b/spring-integration-core/src/test/java/org/springframework/integration/config/annotation/messageParameterAnnotatedEndpointTests.xml
@@ -1,11 +1,11 @@
-
+ http://www.springframework.org/schema/integration/spring-integration.xsd">
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/config/annotation/serviceActivatorAnnotationPostProcessorTests.xml b/spring-integration-core/src/test/java/org/springframework/integration/config/annotation/serviceActivatorAnnotationPostProcessorTests.xml
index 5ccb3386bc..1e9f702254 100644
--- a/spring-integration-core/src/test/java/org/springframework/integration/config/annotation/serviceActivatorAnnotationPostProcessorTests.xml
+++ b/spring-integration-core/src/test/java/org/springframework/integration/config/annotation/serviceActivatorAnnotationPostProcessorTests.xml
@@ -1,11 +1,11 @@
-
+ http://www.springframework.org/schema/integration/spring-integration.xsd">
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/config/annotation/simpleAnnotatedEndpointTests.xml b/spring-integration-core/src/test/java/org/springframework/integration/config/annotation/simpleAnnotatedEndpointTests.xml
index 85660a3fad..96984dccc9 100644
--- a/spring-integration-core/src/test/java/org/springframework/integration/config/annotation/simpleAnnotatedEndpointTests.xml
+++ b/spring-integration-core/src/test/java/org/springframework/integration/config/annotation/simpleAnnotatedEndpointTests.xml
@@ -1,11 +1,11 @@
-
+ http://www.springframework.org/schema/integration/spring-integration.xsd">
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/config/annotation/typeConvertingEndpointTests.xml b/spring-integration-core/src/test/java/org/springframework/integration/config/annotation/typeConvertingEndpointTests.xml
index 40cc548e3a..16f9abd373 100644
--- a/spring-integration-core/src/test/java/org/springframework/integration/config/annotation/typeConvertingEndpointTests.xml
+++ b/spring-integration-core/src/test/java/org/springframework/integration/config/annotation/typeConvertingEndpointTests.xml
@@ -1,11 +1,11 @@
-
+ http://www.springframework.org/schema/integration/spring-integration.xsd">
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/config/messageBusWithAsyncEventMulticaster.xml b/spring-integration-core/src/test/java/org/springframework/integration/config/messageBusWithAsyncEventMulticaster.xml
index 8857f305e9..81b670ae7f 100644
--- a/spring-integration-core/src/test/java/org/springframework/integration/config/messageBusWithAsyncEventMulticaster.xml
+++ b/spring-integration-core/src/test/java/org/springframework/integration/config/messageBusWithAsyncEventMulticaster.xml
@@ -1,11 +1,11 @@
-
+ http://www.springframework.org/schema/integration/spring-integration.xsd">
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/config/messageBusWithDefaults.xml b/spring-integration-core/src/test/java/org/springframework/integration/config/messageBusWithDefaults.xml
index a5cd9c1a0c..4db2000b82 100644
--- a/spring-integration-core/src/test/java/org/springframework/integration/config/messageBusWithDefaults.xml
+++ b/spring-integration-core/src/test/java/org/springframework/integration/config/messageBusWithDefaults.xml
@@ -1,11 +1,11 @@
-
+ http://www.springframework.org/schema/integration/spring-integration.xsd">
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/config/messageBusWithErrorChannel.xml b/spring-integration-core/src/test/java/org/springframework/integration/config/messageBusWithErrorChannel.xml
index 72f8efaa33..a942fc52e0 100644
--- a/spring-integration-core/src/test/java/org/springframework/integration/config/messageBusWithErrorChannel.xml
+++ b/spring-integration-core/src/test/java/org/springframework/integration/config/messageBusWithErrorChannel.xml
@@ -1,11 +1,11 @@
-
+ http://www.springframework.org/schema/integration/spring-integration.xsd">
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/config/messageBusWithTaskScheduler.xml b/spring-integration-core/src/test/java/org/springframework/integration/config/messageBusWithTaskScheduler.xml
index 6c8b8c717c..0088cca99d 100644
--- a/spring-integration-core/src/test/java/org/springframework/integration/config/messageBusWithTaskScheduler.xml
+++ b/spring-integration-core/src/test/java/org/springframework/integration/config/messageBusWithTaskScheduler.xml
@@ -1,11 +1,11 @@
-
+ http://www.springframework.org/schema/integration/spring-integration.xsd">
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/config/messageBusWithoutAsyncEventMulticaster.xml b/spring-integration-core/src/test/java/org/springframework/integration/config/messageBusWithoutAsyncEventMulticaster.xml
index f4c10f8738..4db2000b82 100644
--- a/spring-integration-core/src/test/java/org/springframework/integration/config/messageBusWithoutAsyncEventMulticaster.xml
+++ b/spring-integration-core/src/test/java/org/springframework/integration/config/messageBusWithoutAsyncEventMulticaster.xml
@@ -1,7 +1,7 @@
-
-
-
+
@@ -20,5 +20,5 @@
-
+
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/config/xml/HeaderEnricherMethodInvokingTests-context.xml b/spring-integration-core/src/test/java/org/springframework/integration/config/xml/HeaderEnricherMethodInvokingTests-context.xml
index a86fed97cf..0ba0aa1e18 100644
--- a/spring-integration-core/src/test/java/org/springframework/integration/config/xml/HeaderEnricherMethodInvokingTests-context.xml
+++ b/spring-integration-core/src/test/java/org/springframework/integration/config/xml/HeaderEnricherMethodInvokingTests-context.xml
@@ -1,11 +1,11 @@
-
+ http://www.springframework.org/schema/integration/spring-integration.xsd">
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/config/xml/HeaderFilterParserTests-context.xml b/spring-integration-core/src/test/java/org/springframework/integration/config/xml/HeaderFilterParserTests-context.xml
index 1c3b26f6e1..ea47fddb25 100644
--- a/spring-integration-core/src/test/java/org/springframework/integration/config/xml/HeaderFilterParserTests-context.xml
+++ b/spring-integration-core/src/test/java/org/springframework/integration/config/xml/HeaderFilterParserTests-context.xml
@@ -1,11 +1,11 @@
-
+ http://www.springframework.org/schema/integration/spring-integration.xsd">
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/config/xml/NestedChainParserTests-context.xml b/spring-integration-core/src/test/java/org/springframework/integration/config/xml/NestedChainParserTests-context.xml
index 4584cee9be..ac98046813 100644
--- a/spring-integration-core/src/test/java/org/springframework/integration/config/xml/NestedChainParserTests-context.xml
+++ b/spring-integration-core/src/test/java/org/springframework/integration/config/xml/NestedChainParserTests-context.xml
@@ -1,11 +1,11 @@
-
+ http://www.springframework.org/schema/integration/spring-integration.xsd">
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/config/xml/ObjectToStringTransformerParserTests-context.xml b/spring-integration-core/src/test/java/org/springframework/integration/config/xml/ObjectToStringTransformerParserTests-context.xml
index a3d6c75617..20e1f1646e 100644
--- a/spring-integration-core/src/test/java/org/springframework/integration/config/xml/ObjectToStringTransformerParserTests-context.xml
+++ b/spring-integration-core/src/test/java/org/springframework/integration/config/xml/ObjectToStringTransformerParserTests-context.xml
@@ -1,11 +1,11 @@
-
+ http://www.springframework.org/schema/integration/spring-integration.xsd">
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/config/xml/PayloadDeserializingTransformerParserTests-context.xml b/spring-integration-core/src/test/java/org/springframework/integration/config/xml/PayloadDeserializingTransformerParserTests-context.xml
index 8d53ce85ad..fa96090e1b 100644
--- a/spring-integration-core/src/test/java/org/springframework/integration/config/xml/PayloadDeserializingTransformerParserTests-context.xml
+++ b/spring-integration-core/src/test/java/org/springframework/integration/config/xml/PayloadDeserializingTransformerParserTests-context.xml
@@ -1,11 +1,11 @@
-
+ http://www.springframework.org/schema/integration/spring-integration.xsd">
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/config/xml/PayloadSerializingTransformerParserTests-context.xml b/spring-integration-core/src/test/java/org/springframework/integration/config/xml/PayloadSerializingTransformerParserTests-context.xml
index 128f6ea1f5..57c67b7d97 100644
--- a/spring-integration-core/src/test/java/org/springframework/integration/config/xml/PayloadSerializingTransformerParserTests-context.xml
+++ b/spring-integration-core/src/test/java/org/springframework/integration/config/xml/PayloadSerializingTransformerParserTests-context.xml
@@ -1,11 +1,11 @@
-
+ http://www.springframework.org/schema/integration/spring-integration.xsd">
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/config/xml/defaultPollerWithId.xml b/spring-integration-core/src/test/java/org/springframework/integration/config/xml/defaultPollerWithId.xml
index 0fa35c7858..1525366a5a 100644
--- a/spring-integration-core/src/test/java/org/springframework/integration/config/xml/defaultPollerWithId.xml
+++ b/spring-integration-core/src/test/java/org/springframework/integration/config/xml/defaultPollerWithId.xml
@@ -1,11 +1,11 @@
-
+ http://www.springframework.org/schema/integration/spring-integration.xsd">
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/config/xml/defaultPollerWithoutId.xml b/spring-integration-core/src/test/java/org/springframework/integration/config/xml/defaultPollerWithoutId.xml
index 8b06e0f03c..7d55d492ca 100644
--- a/spring-integration-core/src/test/java/org/springframework/integration/config/xml/defaultPollerWithoutId.xml
+++ b/spring-integration-core/src/test/java/org/springframework/integration/config/xml/defaultPollerWithoutId.xml
@@ -1,11 +1,11 @@
-
+ http://www.springframework.org/schema/integration/spring-integration.xsd">
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/config/xml/gatewayParserTests.xml b/spring-integration-core/src/test/java/org/springframework/integration/config/xml/gatewayParserTests.xml
index c6b64624ae..9deaafe3b3 100644
--- a/spring-integration-core/src/test/java/org/springframework/integration/config/xml/gatewayParserTests.xml
+++ b/spring-integration-core/src/test/java/org/springframework/integration/config/xml/gatewayParserTests.xml
@@ -1,11 +1,11 @@
-
+ http://www.springframework.org/schema/integration/spring-integration.xsd">
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/config/xml/multipleDefaultPollers.xml b/spring-integration-core/src/test/java/org/springframework/integration/config/xml/multipleDefaultPollers.xml
index 9273edb8c1..e258177cd7 100644
--- a/spring-integration-core/src/test/java/org/springframework/integration/config/xml/multipleDefaultPollers.xml
+++ b/spring-integration-core/src/test/java/org/springframework/integration/config/xml/multipleDefaultPollers.xml
@@ -1,11 +1,11 @@
-
+ http://www.springframework.org/schema/integration/spring-integration.xsd">
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/config/xml/pollerWithAdviceChain.xml b/spring-integration-core/src/test/java/org/springframework/integration/config/xml/pollerWithAdviceChain.xml
index 7d6dc1680d..4428d7226c 100644
--- a/spring-integration-core/src/test/java/org/springframework/integration/config/xml/pollerWithAdviceChain.xml
+++ b/spring-integration-core/src/test/java/org/springframework/integration/config/xml/pollerWithAdviceChain.xml
@@ -1,11 +1,11 @@
-
+ http://www.springframework.org/schema/integration/spring-integration.xsd">
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/config/xml/pollerWithReceiveTimeout.xml b/spring-integration-core/src/test/java/org/springframework/integration/config/xml/pollerWithReceiveTimeout.xml
index b8ee2498f3..864b812e57 100644
--- a/spring-integration-core/src/test/java/org/springframework/integration/config/xml/pollerWithReceiveTimeout.xml
+++ b/spring-integration-core/src/test/java/org/springframework/integration/config/xml/pollerWithReceiveTimeout.xml
@@ -1,11 +1,11 @@
-
+ http://www.springframework.org/schema/integration/spring-integration.xsd">
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/config/xml/topLevelPollerWithoutId.xml b/spring-integration-core/src/test/java/org/springframework/integration/config/xml/topLevelPollerWithoutId.xml
index 18ff48f018..946dc8528c 100644
--- a/spring-integration-core/src/test/java/org/springframework/integration/config/xml/topLevelPollerWithoutId.xml
+++ b/spring-integration-core/src/test/java/org/springframework/integration/config/xml/topLevelPollerWithoutId.xml
@@ -1,7 +1,7 @@
-
-
+ http://www.springframework.org/schema/integration/spring-integration.xsd">
@@ -33,5 +33,5 @@
-
+
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/dispatcher/propagationNotSupportedTests.xml b/spring-integration-core/src/test/java/org/springframework/integration/dispatcher/propagationNotSupportedTests.xml
index 5700856390..72c88a03cf 100644
--- a/spring-integration-core/src/test/java/org/springframework/integration/dispatcher/propagationNotSupportedTests.xml
+++ b/spring-integration-core/src/test/java/org/springframework/integration/dispatcher/propagationNotSupportedTests.xml
@@ -1,11 +1,11 @@
-
+ http://www.springframework.org/schema/integration/spring-integration.xsd">
@@ -29,5 +29,5 @@
-
+
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/dispatcher/propagationRequiredTests.xml b/spring-integration-core/src/test/java/org/springframework/integration/dispatcher/propagationRequiredTests.xml
index 6a334d6e45..937ab4083d 100644
--- a/spring-integration-core/src/test/java/org/springframework/integration/dispatcher/propagationRequiredTests.xml
+++ b/spring-integration-core/src/test/java/org/springframework/integration/dispatcher/propagationRequiredTests.xml
@@ -1,11 +1,11 @@
-
+ http://www.springframework.org/schema/integration/spring-integration.xsd">
@@ -28,6 +28,6 @@
-
+
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/dispatcher/propagationRequiresNewTests.xml b/spring-integration-core/src/test/java/org/springframework/integration/dispatcher/propagationRequiresNewTests.xml
index f42ad90785..4bd68226fb 100644
--- a/spring-integration-core/src/test/java/org/springframework/integration/dispatcher/propagationRequiresNewTests.xml
+++ b/spring-integration-core/src/test/java/org/springframework/integration/dispatcher/propagationRequiresNewTests.xml
@@ -1,11 +1,11 @@
-
+ http://www.springframework.org/schema/integration/spring-integration.xsd">
@@ -29,5 +29,5 @@
-
+
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/dispatcher/propagationSupportsTests.xml b/spring-integration-core/src/test/java/org/springframework/integration/dispatcher/propagationSupportsTests.xml
index f3bb30d005..43f93f3cab 100644
--- a/spring-integration-core/src/test/java/org/springframework/integration/dispatcher/propagationSupportsTests.xml
+++ b/spring-integration-core/src/test/java/org/springframework/integration/dispatcher/propagationSupportsTests.xml
@@ -1,11 +1,11 @@
-
+ http://www.springframework.org/schema/integration/spring-integration.xsd">
@@ -29,5 +29,5 @@
-
+
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/dispatcher/transactionTests.xml b/spring-integration-core/src/test/java/org/springframework/integration/dispatcher/transactionTests.xml
index 845e32d3eb..f5a03ea67b 100644
--- a/spring-integration-core/src/test/java/org/springframework/integration/dispatcher/transactionTests.xml
+++ b/spring-integration-core/src/test/java/org/springframework/integration/dispatcher/transactionTests.xml
@@ -1,11 +1,11 @@
-
+ http://www.springframework.org/schema/integration/spring-integration.xsd">
@@ -42,5 +42,5 @@
-
+
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/endpoint/pollingEndpointErrorHandlingTests.xml b/spring-integration-core/src/test/java/org/springframework/integration/endpoint/pollingEndpointErrorHandlingTests.xml
index f49f51b4e1..546ea72356 100644
--- a/spring-integration-core/src/test/java/org/springframework/integration/endpoint/pollingEndpointErrorHandlingTests.xml
+++ b/spring-integration-core/src/test/java/org/springframework/integration/endpoint/pollingEndpointErrorHandlingTests.xml
@@ -5,7 +5,7 @@
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
- http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd">
+ http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd">
@@ -15,6 +15,6 @@
-
+
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/endpoint/returnAddressTests.xml b/spring-integration-core/src/test/java/org/springframework/integration/endpoint/returnAddressTests.xml
index db55873a1d..f15ac7515f 100644
--- a/spring-integration-core/src/test/java/org/springframework/integration/endpoint/returnAddressTests.xml
+++ b/spring-integration-core/src/test/java/org/springframework/integration/endpoint/returnAddressTests.xml
@@ -1,11 +1,11 @@
-
+ http://www.springframework.org/schema/integration/spring-integration.xsd">
@@ -30,5 +30,5 @@
-
+
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/filter/filterContextTests.xml b/spring-integration-core/src/test/java/org/springframework/integration/filter/filterContextTests.xml
index bd3edc2350..7f6f573463 100644
--- a/spring-integration-core/src/test/java/org/springframework/integration/filter/filterContextTests.xml
+++ b/spring-integration-core/src/test/java/org/springframework/integration/filter/filterContextTests.xml
@@ -1,12 +1,12 @@
-
-
+
@@ -19,5 +19,5 @@
output-channel="output"/>
-
+
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/gateway/gatewayAutowiring.xml b/spring-integration-core/src/test/java/org/springframework/integration/gateway/gatewayAutowiring.xml
index b67629a3c8..e14c1f6844 100644
--- a/spring-integration-core/src/test/java/org/springframework/integration/gateway/gatewayAutowiring.xml
+++ b/spring-integration-core/src/test/java/org/springframework/integration/gateway/gatewayAutowiring.xml
@@ -7,7 +7,7 @@
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
-
+
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/gateway/gatewayWithRendezvousChannel.xml b/spring-integration-core/src/test/java/org/springframework/integration/gateway/gatewayWithRendezvousChannel.xml
index f607a73934..596456ad47 100644
--- a/spring-integration-core/src/test/java/org/springframework/integration/gateway/gatewayWithRendezvousChannel.xml
+++ b/spring-integration-core/src/test/java/org/springframework/integration/gateway/gatewayWithRendezvousChannel.xml
@@ -1,11 +1,11 @@
-
+ http://www.springframework.org/schema/integration/spring-integration.xsd">
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/gateway/gatewayWithResponseCorrelator.xml b/spring-integration-core/src/test/java/org/springframework/integration/gateway/gatewayWithResponseCorrelator.xml
index ada93a204f..086a88cd50 100644
--- a/spring-integration-core/src/test/java/org/springframework/integration/gateway/gatewayWithResponseCorrelator.xml
+++ b/spring-integration-core/src/test/java/org/springframework/integration/gateway/gatewayWithResponseCorrelator.xml
@@ -1,11 +1,11 @@
-
+ http://www.springframework.org/schema/integration/spring-integration.xsd">
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/router/config/routerParserTests.xml b/spring-integration-core/src/test/java/org/springframework/integration/router/config/routerParserTests.xml
index 869fef041b..3f640ea451 100644
--- a/spring-integration-core/src/test/java/org/springframework/integration/router/config/routerParserTests.xml
+++ b/spring-integration-core/src/test/java/org/springframework/integration/router/config/routerParserTests.xml
@@ -1,11 +1,11 @@
-
+ http://www.springframework.org/schema/integration/spring-integration.xsd">
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/router/config/splitterAggregatorTests.xml b/spring-integration-core/src/test/java/org/springframework/integration/router/config/splitterAggregatorTests.xml
index 3950d94cc1..7941af2805 100644
--- a/spring-integration-core/src/test/java/org/springframework/integration/router/config/splitterAggregatorTests.xml
+++ b/spring-integration-core/src/test/java/org/springframework/integration/router/config/splitterAggregatorTests.xml
@@ -1,11 +1,11 @@
-
+ http://www.springframework.org/schema/integration/spring-integration.xsd">
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/router/config/splitterParserTests.xml b/spring-integration-core/src/test/java/org/springframework/integration/router/config/splitterParserTests.xml
index 190a41014b..c03a7044f3 100644
--- a/spring-integration-core/src/test/java/org/springframework/integration/router/config/splitterParserTests.xml
+++ b/spring-integration-core/src/test/java/org/springframework/integration/router/config/splitterParserTests.xml
@@ -1,11 +1,11 @@
-
+ http://www.springframework.org/schema/integration/spring-integration.xsd">
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/store/MessageStoreReaperTests-context.xml b/spring-integration-core/src/test/java/org/springframework/integration/store/MessageStoreReaperTests-context.xml
index 8f1299d6d0..a244141c78 100644
--- a/spring-integration-core/src/test/java/org/springframework/integration/store/MessageStoreReaperTests-context.xml
+++ b/spring-integration-core/src/test/java/org/springframework/integration/store/MessageStoreReaperTests-context.xml
@@ -1,26 +1,26 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/transformer/transformerContextTests.xml b/spring-integration-core/src/test/java/org/springframework/integration/transformer/transformerContextTests.xml
index 5679865023..39a13fba35 100644
--- a/spring-integration-core/src/test/java/org/springframework/integration/transformer/transformerContextTests.xml
+++ b/spring-integration-core/src/test/java/org/springframework/integration/transformer/transformerContextTests.xml
@@ -1,12 +1,12 @@
-
-
+
@@ -16,5 +16,5 @@
-
+
diff --git a/spring-integration-file/src/main/java/org/springframework/integration/file/AbstractInboundRemoteFileSystemSychronizer.java b/spring-integration-file/src/main/java/org/springframework/integration/file/AbstractInboundRemoteFileSystemSychronizer.java
new file mode 100644
index 0000000000..2f4ce15ab4
--- /dev/null
+++ b/spring-integration-file/src/main/java/org/springframework/integration/file/AbstractInboundRemoteFileSystemSychronizer.java
@@ -0,0 +1,148 @@
+package org.springframework.integration.file;
+
+import org.springframework.core.io.Resource;
+import org.springframework.integration.endpoint.AbstractEndpoint;
+import org.springframework.integration.file.entries.AcceptAllEntryListFilter;
+import org.springframework.integration.file.entries.EntryListFilter;
+import org.springframework.scheduling.Trigger;
+import org.springframework.util.Assert;
+
+import java.util.concurrent.ScheduledFuture;
+
+
+/**
+ * This handles a lot of the common ground in our approach for synchronizing a remote file system locally
+ *
+ * @author Josh Long
+ */
+public abstract class AbstractInboundRemoteFileSystemSychronizer extends AbstractEndpoint {
+ /**
+ * Should we delete the source file?
+ * For an FTP server, for example, this would delete the original FTPFile instance
+ *
+ * At the moment I can simply see this triggering the setting
+ */
+ protected boolean shouldDeleteSourceFile;
+
+ /**
+ * the directory we're writing our synchronizations to
+ */
+ protected volatile Resource localDirectory;
+
+ /**
+ * a {@link org.springframework.integration.file.entries.EntryListFilter} that we're running against the remote file system view!
+ */
+ protected volatile EntryListFilter filter = new AcceptAllEntryListFilter();
+
+ /**
+ * the {@link java.util.concurrent.ScheduledFuture} instance we get when we schedule our {@link AbstractInboundRemoteFileSystemSychronizer.SynchronizeTask}
+ */
+ protected ScheduledFuture> scheduledFuture;
+
+ /**
+ * Used to store the {@link org.springframework.integration.file.AbstractInboundRemoteFileSystemSychronizer.EntryAcknowledgmentStrategy} implementation
+ */
+ protected EntryAcknowledgmentStrategy entryAcknowledgmentStrategy;
+
+ /**
+ * Obviously thread safe - simply provides a NOOP impl so we don't have to keep dancing around NPE's
+ */
+ private EntryAcknowledgmentStrategy noOpEntryAcknowledgmentStrategy = new EntryAcknowledgmentStrategy() {
+ public void acknowledge(Object o, T msg) {
+ }
+ };
+
+ public void setEntryAcknowledgmentStrategy(EntryAcknowledgmentStrategy entryAcknowledgmentStrategy) {
+ this.entryAcknowledgmentStrategy = entryAcknowledgmentStrategy;
+ }
+
+ public void setShouldDeleteSourceFile(boolean shouldDeleteSourceFile) {
+ this.shouldDeleteSourceFile = shouldDeleteSourceFile;
+ }
+
+ public void setLocalDirectory(Resource localDirectory) {
+ this.localDirectory = localDirectory;
+ }
+
+ public void setFilter(EntryListFilter filter) {
+ this.filter = filter;
+ }
+
+ /**
+ * @param usefulContextOrClientData
+ * @param t leverages strategy implementations to enable different behavior. It's a hook to the entry ({@link T}) after it's been successfully downloaded.
+ * Conceptually, you might delete the remote one or rename it or something
+ * @throws Throwable
+ */
+ protected void acknowledge(Object usefulContextOrClientData, T t)
+ throws Throwable {
+ Assert.notNull(this.entryAcknowledgmentStrategy != null, "entryAcknowledgmentStrategy can't be null!");
+ this.entryAcknowledgmentStrategy.acknowledge(usefulContextOrClientData, t);
+ }
+
+ /**
+ * This is the callback where we need the implementation to do some specific work
+ */
+ protected abstract void syncRemoteToLocalFileSystem()
+ throws Exception ;
+
+ /**
+ * {@inheritDoc}
+ */
+ protected void doStop() {
+ Assert.notNull(this.scheduledFuture, "the 'scheduledFuture' can't be null!");
+ this.scheduledFuture.cancel(true);
+ }
+
+ /**
+ * Returns a value in millis dictating how frequently the trigger should fire
+ *
+ * @return a {@link org.springframework.scheduling.Trigger} implementation (likely,
+ * {@link org.springframework.scheduling.support.PeriodicTrigger})
+ */
+ protected abstract Trigger getTrigger();
+
+ /**
+ * {@inheritDoc}
+ */
+ protected void doStart() {
+ if (this.entryAcknowledgmentStrategy == null) {
+ this.entryAcknowledgmentStrategy = noOpEntryAcknowledgmentStrategy;
+ }
+
+ this.scheduledFuture = this.getTaskScheduler().schedule(new SynchronizeTask(), this.getTrigger());
+ }
+
+ /**
+ * Strategy interface to expose a hook for dispatching, moving, or deleting the file once it's been delivered
+ *
+ * @author Josh Long
+ * @param the entry type (file, sftp, ftp, ...)
+ */
+ public static interface EntryAcknowledgmentStrategy {
+ /**
+ * Semantics are simple. You get a pointer to the entry just processed and any kind of helper data you could ask for. Since the strategy is a
+ * singleton and the clients you might ask for as context data are pooled, it's not recommended that you try to cache them.
+ *
+ * @param useful any context data
+ * @param msg the data / file / entry you want to process -- specific to sublcasses
+ * @throws Exception thrown for any old reason
+ */
+ void acknowledge(Object useful, T msg) throws Exception;
+ }
+
+ /**
+ * This {@link Runnable} is launched as a background thread and is used to babysit the
+ * {@link org.springframework.integration.file.AbstractInboundRemoteFileSystemSychronizer#localDirectory},
+ * queueing and delivering accumulated files as possible.
+ */
+ class SynchronizeTask implements Runnable {
+ public void run() {
+ try {
+ syncRemoteToLocalFileSystem();
+ } catch (Exception e) {
+ throw new RuntimeException(e) ;
+ }
+ }
+ }
+}
diff --git a/spring-integration-file/src/main/java/org/springframework/integration/file/AbstractInboundRemoteFileSystemSynchronizingMessageSource.java b/spring-integration-file/src/main/java/org/springframework/integration/file/AbstractInboundRemoteFileSystemSynchronizingMessageSource.java
new file mode 100644
index 0000000000..235b69ecbd
--- /dev/null
+++ b/spring-integration-file/src/main/java/org/springframework/integration/file/AbstractInboundRemoteFileSystemSynchronizingMessageSource.java
@@ -0,0 +1,112 @@
+package org.springframework.integration.file;
+
+import org.springframework.core.io.FileSystemResource;
+import org.springframework.core.io.Resource;
+
+import org.springframework.integration.Message;
+import org.springframework.integration.core.MessageSource;
+import org.springframework.integration.endpoint.AbstractEndpoint;
+import org.springframework.integration.file.entries.*;
+
+import org.springframework.util.Assert;
+
+import java.io.File;
+
+import java.util.regex.Pattern;
+
+
+/**
+ * Ultimately, this factors out a lot of the common logic between the FTP and SFTP adapters
+ *
+ * @author Josh Long
+ */
+public abstract class AbstractInboundRemoteFileSystemSynchronizingMessageSource> extends AbstractEndpoint implements MessageSource {
+ /**
+ * Extension used when downloading files. We change it right after we know it's downloaded
+ */
+ public static final String INCOMPLETE_EXTENSION = ".INCOMPLETE";
+
+ /**
+ * Should the endpoint attempt to create the local directory and / or the remote directory?
+ */
+ protected volatile boolean autoCreateDirectories = true;
+
+ /**
+ * An implementation that will handle the chores of actually syncing up the remote FS
+ */
+ protected volatile T synchronizer;
+
+ /**
+ * What directory should things be synced to locally ?
+ */
+ protected volatile Resource localDirectory;
+
+ /**
+ * The actual {@link FileReadingMessageSource} that we continue to trust to do the job monitoring the filesystem once files are moved down
+ */
+ protected volatile FileReadingMessageSource fileSource;
+
+ /**
+ * The predicate to use in scanning the remote Fs for downloads
+ */
+ protected EntryListFilter remotePredicate;
+
+ public void setAutoCreateDirectories(boolean autoCreateDirectories) {
+ this.autoCreateDirectories = autoCreateDirectories;
+ }
+
+ public void setSynchronizer(T synchronizer) {
+ this.synchronizer = synchronizer;
+ }
+
+ public void setLocalDirectory(Resource localDirectory) {
+ this.localDirectory = localDirectory;
+ }
+
+ public void setRemotePredicate(EntryListFilter remotePredicate) {
+ this.remotePredicate = remotePredicate;
+ }
+
+ private EntryListFilter buildFilter() {
+ FileEntryNamer fileEntryNamer = new FileEntryNamer();
+ Pattern completePattern = Pattern.compile("^.*(?(new AcceptOnceEntryFileListFilter(), new PatternMatchingEntryListFilter(fileEntryNamer, completePattern));
+ }
+
+ @Override
+ protected void onInit() throws Exception {
+ if (this.remotePredicate != null) {
+ this.synchronizer.setFilter(this.remotePredicate);
+ }
+
+ if (this.autoCreateDirectories) {
+
+
+
+ if((this.localDirectory != null) && !this.localDirectory.exists() && this.localDirectory.getFile().mkdirs())
+ logger.debug( "the localDirectory " + this.localDirectory + " doesn't exist");
+ }
+
+ /**
+ * Handles making sure the remote files get here in one piece
+ */
+ this.synchronizer.setLocalDirectory(this.localDirectory);
+ this.synchronizer.setTaskScheduler(this.getTaskScheduler());
+ this.synchronizer.setBeanFactory(this.getBeanFactory());
+ this.synchronizer.setPhase(this.getPhase());
+ this.synchronizer.setBeanName(this.getComponentName());
+
+ /**
+ * Handles forwarding files once they ultimately appear in the {@link #localDirectory}
+ */
+ this.fileSource = new FileReadingMessageSource();
+ this.fileSource.setFilter(buildFilter());
+ this.fileSource.setDirectory(this.localDirectory.getFile());
+ this.fileSource.afterPropertiesSet();
+ this.synchronizer.afterPropertiesSet();
+ }
+
+ public Message receive() {
+ return this.fileSource.receive();
+ }
+}
diff --git a/spring-integration-file/src/main/java/org/springframework/integration/file/DefaultDirectoryScanner.java b/spring-integration-file/src/main/java/org/springframework/integration/file/DefaultDirectoryScanner.java
index 27580bbbfa..aff9f362ec 100644
--- a/spring-integration-file/src/main/java/org/springframework/integration/file/DefaultDirectoryScanner.java
+++ b/spring-integration-file/src/main/java/org/springframework/integration/file/DefaultDirectoryScanner.java
@@ -13,14 +13,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.integration.file;
import org.springframework.integration.MessagingException;
+import org.springframework.integration.file.entries.AcceptOnceEntryFileListFilter;
+import org.springframework.integration.file.entries.EntryListFilter;
import java.io.File;
+
import java.util.List;
+
/**
* Default directory scanner and base class for other directory scanners. It takes care of the default interrelations
* between filtering, scanning and locking.
@@ -29,16 +32,17 @@ import java.util.List;
* @since 2.0
*/
public class DefaultDirectoryScanner implements DirectoryScanner {
- private FileListFilter filter = new AcceptOnceFileListFilter();
+ private EntryListFilter filter = new AcceptOnceEntryFileListFilter();
private FileLocker locker;
public final List listFiles(File directory) throws IllegalArgumentException {
File[] files = listEligibleFiles(directory);
+
if (files == null) {
- throw new MessagingException("The path [" + directory
- + "] does not denote a properly accessible directory.");
+ throw new MessagingException("The path [" + directory + "] does not denote a properly accessible directory.");
}
- return this.filter.filterFiles(files);
+
+ return this.filter.filterEntries(files);
}
/**
@@ -52,10 +56,7 @@ public class DefaultDirectoryScanner implements DirectoryScanner {
return directory.listFiles();
}
- /**
- * {@inheritDoc}
- */
- public final void setFilter(FileListFilter filter) {
+ public void setFilter(EntryListFilter filter) {
this.filter = filter;
}
@@ -65,7 +66,7 @@ public class DefaultDirectoryScanner implements DirectoryScanner {
* This class takes the minimal implementation and merely delegates to the locker if set.
*/
public final boolean tryClaim(File file) {
- return locker != null ? locker.lock(file) : true;
+ return (locker == null) || locker.lock(file);
}
/**
diff --git a/spring-integration-file/src/main/java/org/springframework/integration/file/DirectoryScanner.java b/spring-integration-file/src/main/java/org/springframework/integration/file/DirectoryScanner.java
index a194998c61..bcd3d69396 100644
--- a/spring-integration-file/src/main/java/org/springframework/integration/file/DirectoryScanner.java
+++ b/spring-integration-file/src/main/java/org/springframework/integration/file/DirectoryScanner.java
@@ -16,13 +16,15 @@
package org.springframework.integration.file;
+import org.springframework.integration.file.entries.EntryListFilter;
+
import java.io.File;
import java.util.List;
/**
* Strategy for scanning directories. Implementations may select all children and grandchildren of the scanned directory
* in any order. This interface is intended to enable the customization of selection, locking and ordering of files in a
- * directory like RecursiveDirectoryScanner. If the only requirement is to ignore certain files a FileListFilter
+ * directory like RecursiveDirectoryScanner. If the only requirement is to ignore certain files a EntryListFilter
* implementation should suffice.
*
*
@@ -37,6 +39,7 @@ public interface DirectoryScanner {
*
* @param directory the directory to scan for files
* @return a list of files representing the content of the directory
+ * @throws IllegalArgumentException thrown if the input is incorrect
*/
List listFiles(File directory) throws IllegalArgumentException;
@@ -47,7 +50,7 @@ public interface DirectoryScanner {
*
* @param filter the custom filter to be used
*/
- void setFilter(FileListFilter filter);
+ void setFilter(EntryListFilter filter);
/**
diff --git a/spring-integration-file/src/main/java/org/springframework/integration/file/FileReadingMessageSource.java b/spring-integration-file/src/main/java/org/springframework/integration/file/FileReadingMessageSource.java
index 85d71be275..d20b346079 100644
--- a/spring-integration-file/src/main/java/org/springframework/integration/file/FileReadingMessageSource.java
+++ b/spring-integration-file/src/main/java/org/springframework/integration/file/FileReadingMessageSource.java
@@ -13,33 +13,38 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.integration.file;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+
import org.springframework.beans.factory.InitializingBean;
+
import org.springframework.integration.Message;
import org.springframework.integration.MessagingException;
import org.springframework.integration.aggregator.ResequencingMessageGroupProcessor;
import org.springframework.integration.core.MessageBuilder;
import org.springframework.integration.core.MessageSource;
+import org.springframework.integration.file.entries.EntryListFilter;
+
import org.springframework.util.Assert;
import java.io.File;
+
import java.util.*;
import java.util.concurrent.PriorityBlockingQueue;
+
/**
* {@link MessageSource} that creates messages from a file system directory. To prevent messages for certain files, you
- * may supply a {@link FileListFilter}. By default, an {@link AcceptOnceFileListFilter} is used. It ensures files are
+ * may supply a {@link org.springframework.integration.file.filters.FileListFilter}. By default, an {@link org.springframework.integration.file.filters.AcceptOnceFileListFilter} is used. It ensures files are
* picked up only once from the directory.
*
* A common problem with reading files is that a file may be detected before it is ready. The default {@link
- * AcceptOnceFileListFilter} does not prevent this. In most cases, this can be prevented if the file-writing process
+ * org.springframework.integration.file.filters.AcceptOnceFileListFilter} does not prevent this. In most cases, this can be prevented if the file-writing process
* renames each file as soon as it is ready for reading. A pattern-matching filter that accepts only files that are
- * ready (e.g. based on a known suffix), composed with the default {@link AcceptOnceFileListFilter} would allow for
- * this. See {@link org.springframework.integration.file.CompositeFileListFilter} for a way to do this.
+ * ready (e.g. based on a known suffix), composed with the default {@link org.springframework.integration.file.filters.AcceptOnceFileListFilter} would allow for
+ * this. See {@link org.springframework.integration.file.filters.CompositeFileListFilter} for a way to do this.
*
* A {@link Comparator} can be used to ensure internal ordering of the Files in a {@link PriorityBlockingQueue}. This
* does not provide the same guarantees as a {@link ResequencingMessageGroupProcessor}, but in cases where writing files and failure
@@ -51,18 +56,11 @@ import java.util.concurrent.PriorityBlockingQueue;
* @author Iwein Fuld
* @author Mark Fisher
*/
-public class FileReadingMessageSource implements MessageSource,
- InitializingBean {
-
+public class FileReadingMessageSource implements MessageSource, InitializingBean {
private static final int DEFAULT_INTERNAL_QUEUE_CAPACITY = 5;
-
- private static final Log logger = LogFactory
- .getLog(FileReadingMessageSource.class);
-
+ private static final Log logger = LogFactory.getLog(FileReadingMessageSource.class);
private volatile File directory;
-
private volatile DirectoryScanner scanner = new DefaultDirectoryScanner();
-
private volatile boolean autoCreateDirectory = true;
/*
@@ -70,7 +68,6 @@ public class FileReadingMessageSource implements MessageSource,
* There is no locking around the queue, so there is also no iteration.
*/
private final Queue toBeReceived;
-
private boolean scanEachPoll = false;
/**
@@ -92,7 +89,7 @@ public class FileReadingMessageSource implements MessageSource,
*/
public FileReadingMessageSource(int internalQueueCapacity) {
this(null);
- Assert.isTrue(internalQueueCapacity>0, "Cannot create a queue with non positive capacity");
+ Assert.isTrue(internalQueueCapacity > 0, "Cannot create a queue with non positive capacity");
this.setScanner(new HeadDirectoryScanner(internalQueueCapacity));
}
@@ -108,8 +105,7 @@ public class FileReadingMessageSource implements MessageSource,
* @param receptionOrderComparator the comparator to be used to order the files in the internal queue
*/
public FileReadingMessageSource(Comparator receptionOrderComparator) {
- toBeReceived = new PriorityBlockingQueue(DEFAULT_INTERNAL_QUEUE_CAPACITY,
- receptionOrderComparator);
+ toBeReceived = new PriorityBlockingQueue(DEFAULT_INTERNAL_QUEUE_CAPACITY, receptionOrderComparator);
}
/**
@@ -137,13 +133,13 @@ public class FileReadingMessageSource implements MessageSource,
}
/**
- * Sets a {@link FileListFilter}. By default a {@link AcceptOnceFileListFilter} with no bounds is used. In most
- * cases a customized {@link FileListFilter} will be needed to deal with modification and duplication concerns. If
- * multiple filters are required a {@link CompositeFileListFilter} can be used to group them together.
+ * Sets a {@link org.springframework.integration.file.filters.FileListFilter}. By default a {@link org.springframework.integration.file.filters.AcceptOnceFileListFilter} with no bounds is used. In most
+ * cases a customized {@link org.springframework.integration.file.filters.FileListFilter} will be needed to deal with modification and duplication concerns. If
+ * multiple filters are required a {@link org.springframework.integration.file.filters.CompositeFileListFilter} can be used to group them together.
*
* The supplied filter must be thread safe..
*/
- public void setFilter(FileListFilter filter) {
+ public void setFilter(EntryListFilter filter) {
Assert.notNull(filter, "'filter' must not be null");
this.scanner.setFilter(filter);
}
@@ -175,43 +171,50 @@ public class FileReadingMessageSource implements MessageSource,
public final void afterPropertiesSet() {
Assert.notNull(directory, "'directory' must not be set before initialization");
+
if (!this.directory.exists() && this.autoCreateDirectory) {
this.directory.mkdirs();
}
- Assert.isTrue(this.directory.exists(), "Source directory ["
- + directory + "] does not exist.");
- Assert.isTrue(this.directory.isDirectory(), "Source path ["
- + this.directory + "] does not point to a directory.");
- Assert.isTrue(this.directory.canRead(), "Source directory ["
- + this.directory + "] is not readable.");
+
+ Assert.isTrue(this.directory.exists(), "Source directory [" + directory + "] does not exist.");
+ Assert.isTrue(this.directory.isDirectory(), "Source path [" + this.directory + "] does not point to a directory.");
+ Assert.isTrue(this.directory.canRead(), "Source directory [" + this.directory + "] is not readable.");
}
public Message receive() throws MessagingException {
Message message = null;
+
// rescan only if needed or explicitly configured
if (scanEachPoll || toBeReceived.isEmpty()) {
scanInputDirectory();
}
+
File file = toBeReceived.poll();
+
// file == null means the queue was empty
// we can't rely on isEmpty for concurrency reasons
- while (file != null && !scanner.tryClaim(file)) {
+ while ((file != null) && !scanner.tryClaim(file)) {
file = toBeReceived.poll();
}
+
if (file != null) {
message = MessageBuilder.withPayload(file).build();
+
if (logger.isInfoEnabled()) {
logger.info("Created message: [" + message + "]");
}
}
+
return message;
}
private void scanInputDirectory() {
List filteredFiles = scanner.listFiles(directory);
Set freshFiles = new HashSet(filteredFiles);
+
if (!freshFiles.isEmpty()) {
toBeReceived.addAll(freshFiles);
+
if (logger.isDebugEnabled()) {
logger.debug("Added to queue: " + freshFiles);
}
@@ -225,6 +228,7 @@ public class FileReadingMessageSource implements MessageSource,
if (logger.isWarnEnabled()) {
logger.warn("Failed to send: " + failedMessage);
}
+
toBeReceived.offer(failedMessage.getPayload());
}
diff --git a/spring-integration-file/src/main/java/org/springframework/integration/file/HeadDirectoryScanner.java b/spring-integration-file/src/main/java/org/springframework/integration/file/HeadDirectoryScanner.java
index 7f761687cd..6a3c291b24 100644
--- a/spring-integration-file/src/main/java/org/springframework/integration/file/HeadDirectoryScanner.java
+++ b/spring-integration-file/src/main/java/org/springframework/integration/file/HeadDirectoryScanner.java
@@ -13,13 +13,16 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.integration.file;
+import org.springframework.integration.file.entries.EntryListFilter;
+
import java.io.File;
+
import java.util.Arrays;
import java.util.List;
+
/**
* A custom scanner that only returns the first maxNumberOfFiles elements from a directory listing. This is
* useful to limit the number of File objects in memory and therefore mutually exclusive with AcceptOnceFileListFilter.
@@ -28,19 +31,18 @@ import java.util.List;
* @since 2.0.0
*/
public class HeadDirectoryScanner extends DefaultDirectoryScanner {
-
public HeadDirectoryScanner(int maxNumberOfFiles) {
this.setFilter(new HeadFilter(maxNumberOfFiles));
}
- private class HeadFilter implements FileListFilter {
+ private class HeadFilter implements EntryListFilter {
private final int maxNumberOfFiles;
public HeadFilter(int maxNumberOfFiles) {
this.maxNumberOfFiles = maxNumberOfFiles;
}
- public List filterFiles(File[] files) {
+ public List filterEntries(File[] files) {
return Arrays.asList(files).subList(0, Math.min(files.length, maxNumberOfFiles));
}
}
diff --git a/spring-integration-file/src/main/java/org/springframework/integration/file/config/FileListFilterFactoryBean.java b/spring-integration-file/src/main/java/org/springframework/integration/file/config/FileListFilterFactoryBean.java
index fa98a9bc0c..f88ff7a6ff 100644
--- a/spring-integration-file/src/main/java/org/springframework/integration/file/config/FileListFilterFactoryBean.java
+++ b/spring-integration-file/src/main/java/org/springframework/integration/file/config/FileListFilterFactoryBean.java
@@ -13,110 +13,114 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.integration.file.config;
+import org.springframework.beans.factory.FactoryBean;
+
+import org.springframework.integration.file.entries.*;
+
import java.io.File;
+
+import java.util.Collection;
import java.util.regex.Pattern;
-import org.springframework.beans.factory.FactoryBean;
-import org.springframework.integration.file.AbstractFileListFilter;
-import org.springframework.integration.file.AcceptOnceFileListFilter;
-import org.springframework.integration.file.CompositeFileListFilter;
-import org.springframework.integration.file.FileListFilter;
-import org.springframework.integration.file.PatternMatchingFileListFilter;
/**
* @author Mark Fisher
* @since 1.0.3
*/
-public class FileListFilterFactoryBean implements FactoryBean {
+public class FileListFilterFactoryBean implements FactoryBean> {
+ private volatile EntryListFilter fileListFilter;
+ private volatile EntryListFilter filterReference;
+ private volatile Pattern filenamePattern;
+ private volatile Boolean preventDuplicates;
+ private final Object monitor = new Object();
+ private volatile Collection> filterReferences;
+ private FileEntryNamer fileNamer = new FileEntryNamer();
- private volatile FileListFilter fileListFilter;
+ public void setFilterReferences(Collection> filterReferences) {
+ this.filterReferences = filterReferences;
+ }
- private volatile FileListFilter filterReference;
+ public void setFilterReference(EntryListFilter filterReference) {
+ this.filterReference = filterReference;
+ }
- private volatile Pattern filenamePattern;
+ public void setFilenamePattern(Pattern filenamePattern) {
+ this.filenamePattern = filenamePattern;
+ }
- private volatile Boolean preventDuplicates;
+ public void setPreventDuplicates(Boolean preventDuplicates) {
+ this.preventDuplicates = preventDuplicates;
+ }
- private final Object monitor = new Object();
+ public EntryListFilter getObject() throws Exception {
+ if (this.fileListFilter == null) {
+ synchronized (this.monitor) {
+ this.intializeFileListFilter();
+ }
+ }
+ return this.fileListFilter;
+ }
- public void setFilterReference(FileListFilter filterReference) {
- this.filterReference = filterReference;
- }
+ public Class> getObjectType() {
+ return (this.fileListFilter != null) ? this.fileListFilter.getClass() : EntryListFilter.class;
+ }
- public void setFilenamePattern(Pattern filenamePattern) {
- this.filenamePattern = filenamePattern;
- }
+ public boolean isSingleton() {
+ return true;
+ }
- public void setPreventDuplicates(Boolean preventDuplicates) {
- this.preventDuplicates = preventDuplicates;
- }
+ private void intializeFileListFilter() {
+ if (this.fileListFilter != null) {
+ return;
+ }
- public FileListFilter getObject() throws Exception {
- if (this.fileListFilter == null) {
- synchronized (this.monitor) {
- this.intializeFileListFilter();
- }
- }
- return this.fileListFilter;
- }
+ EntryListFilter flf=null;
- public Class> getObjectType() {
- return (this.fileListFilter != null)
- ? this.fileListFilter.getClass() : FileListFilter.class;
- }
+ if ((this.filterReference != null) && (this.filenamePattern != null)) {
+ throw new IllegalArgumentException("The 'filter' reference and " + "'filename-pattern' attributes are mutually exclusive.");
+ }
- public boolean isSingleton() {
- return true;
- }
+ if (this.filterReference != null) {
+ if (Boolean.TRUE.equals(this.preventDuplicates)) {
+ flf = this.createCompositeWithAcceptOnceFilter(this.filterReference);
+ } else { // preventDuplicates is either FALSE or NULL
+ flf = this.filterReference;
+ }
+ } else if (this.filenamePattern != null) {
+ PatternMatchingEntryListFilter patternFilter = new PatternMatchingEntryListFilter(fileNamer, this.filenamePattern);
- private void intializeFileListFilter() {
- if (this.fileListFilter != null) {
- return;
- }
- FileListFilter flf = null;
- if (this.filterReference != null && this.filenamePattern != null) {
- throw new IllegalArgumentException("The 'filter' reference and " +
- "'filename-pattern' attributes are mutually exclusive.");
- }
- if (this.filterReference != null) {
- if (Boolean.TRUE.equals(this.preventDuplicates)) {
- flf = this.createCompositeWithAcceptOnceFilter(this.filterReference);
- }
- else { // preventDuplicates is either FALSE or NULL
- flf = this.filterReference;
- }
- }
- else if (this.filenamePattern != null) {
- PatternMatchingFileListFilter patternFilter = new PatternMatchingFileListFilter(this.filenamePattern);
- if (Boolean.FALSE.equals(this.preventDuplicates)) {
- flf = patternFilter;
- }
- else { // preventDuplicates is either TRUE or NULL
- flf = this.createCompositeWithAcceptOnceFilter(patternFilter);
- }
- }
- else if (Boolean.FALSE.equals(this.preventDuplicates)) {
- flf = new AbstractFileListFilter() {
- @Override
- protected boolean accept(File file) {
- return true;
- }
- };
- }
- else { // preventDuplicates is either TRUE or NULL
- flf = new AcceptOnceFileListFilter();
- }
- this.fileListFilter = flf;
- }
+ if (Boolean.FALSE.equals(this.preventDuplicates)) {
+ flf = patternFilter;
+ } else { // preventDuplicates is either TRUE or NULL
+ flf = this.createCompositeWithAcceptOnceFilter(patternFilter);
+ }
+ } else if (Boolean.FALSE.equals(this.preventDuplicates)) {
+ flf = new AcceptAllEntryListFilter();
+ } else { // preventDuplicates is either TRUE or NULL
+ flf = new AcceptOnceEntryFileListFilter();
+ }
- private FileListFilter createCompositeWithAcceptOnceFilter(FileListFilter otherFilter) {
- CompositeFileListFilter compositeFilter = new CompositeFileListFilter();
- compositeFilter.addFilter(new AcceptOnceFileListFilter(), otherFilter);
- return compositeFilter;
- }
+ // finally, it might be that they simply want a {@link CompositeEntryListFilter}
+ if ((this.filterReferences != null) && (this.filterReferences.size() > 0) ) {
+ CompositeEntryListFilter flfc = new CompositeEntryListFilter();
+ for (EntryListFilter ff : filterReferences)
+ flfc.addFilter(ff);
+
+ flf = flfc;
+ }
+ if( flf== null)flf =new CompositeEntryListFilter();
+
+ this.fileListFilter = flf;
+ }
+
+ private CompositeEntryListFilter createCompositeWithAcceptOnceFilter(EntryListFilter otherFilter) {
+ CompositeEntryListFilter compositeFilter = new CompositeEntryListFilter();
+ compositeFilter.addFilter(new AcceptOnceEntryFileListFilter(), otherFilter);
+
+ return compositeFilter;
+ }
}
diff --git a/spring-integration-file/src/main/java/org/springframework/integration/file/config/FileReadingMessageSourceFactoryBean.java b/spring-integration-file/src/main/java/org/springframework/integration/file/config/FileReadingMessageSourceFactoryBean.java
index 09d5cfab4f..aa0c41b79e 100644
--- a/spring-integration-file/src/main/java/org/springframework/integration/file/config/FileReadingMessageSourceFactoryBean.java
+++ b/spring-integration-file/src/main/java/org/springframework/integration/file/config/FileReadingMessageSourceFactoryBean.java
@@ -19,10 +19,10 @@ package org.springframework.integration.file.config;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.FactoryBean;
-import org.springframework.integration.file.CompositeFileListFilter;
import org.springframework.integration.file.DirectoryScanner;
-import org.springframework.integration.file.FileListFilter;
import org.springframework.integration.file.FileReadingMessageSource;
+import org.springframework.integration.file.entries.CompositeEntryListFilter;
+import org.springframework.integration.file.entries.EntryListFilter;
import org.springframework.integration.file.locking.AbstractFileLockerFilter;
import java.io.File;
@@ -41,7 +41,7 @@ public class FileReadingMessageSourceFactoryBean implements FactoryBean filter;
private volatile AbstractFileLockerFilter locker;
@@ -69,7 +69,7 @@ public class FileReadingMessageSourceFactoryBean implements FactoryBean filter) {
if (filter instanceof AbstractFileLockerFilter && this.locker == null) {
this.setLocker((AbstractFileLockerFilter) filter);
}
@@ -133,7 +133,7 @@ public class FileReadingMessageSourceFactoryBean implements FactoryBean(this.filter, this.locker));
this.source.setLocker(locker);
}
}
diff --git a/spring-integration-file/src/main/java/org/springframework/integration/file/entries/AbstractEntryListFilter.java b/spring-integration-file/src/main/java/org/springframework/integration/file/entries/AbstractEntryListFilter.java
index 3f00a62660..87239b84b2 100644
--- a/spring-integration-file/src/main/java/org/springframework/integration/file/entries/AbstractEntryListFilter.java
+++ b/spring-integration-file/src/main/java/org/springframework/integration/file/entries/AbstractEntryListFilter.java
@@ -13,16 +13,26 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.integration.file.entries;
+import org.springframework.beans.factory.InitializingBean;
+
import java.util.ArrayList;
import java.util.List;
-public abstract class AbstractEntryListFilter implements EntryListFilter {
- protected abstract boolean accept(T t);
+/**
+ * A convenience base class for any {@link EntryListFilter} whose criteria can be
+ * evaluated against each File in isolation. If the entire List of files is
+ * required for evaluation, implement the {@link EntryListFilter} interface directly.
+ *
+ * @author Mark Fisher
+ * @author Iwein Fuld
+ * @author Josh Long
+ */
+public abstract class AbstractEntryListFilter implements InitializingBean, EntryListFilter {
+ public abstract boolean accept(T t);
public List filterEntries(T[] entries) {
List accepted = new ArrayList();
@@ -37,4 +47,8 @@ public abstract class AbstractEntryListFilter implements EntryListFilter {
return accepted;
}
+
+ public void afterPropertiesSet() throws Exception {
+ // its all you!
+ }
}
diff --git a/spring-integration-file/src/main/java/org/springframework/integration/file/entries/AcceptAllEntryListFilter.java b/spring-integration-file/src/main/java/org/springframework/integration/file/entries/AcceptAllEntryListFilter.java
new file mode 100644
index 0000000000..87cbe8d847
--- /dev/null
+++ b/spring-integration-file/src/main/java/org/springframework/integration/file/entries/AcceptAllEntryListFilter.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2002-2008 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.integration.file.entries;
+
+
+/**
+ * Simple NOOP implementation for {@link org.springframework.integration.file.entries.EntryListFilter} implementation.
+ * Suitable as a default in implementations.
+ *
+ * @author Josh Long
+ * @param
+ */
+public class AcceptAllEntryListFilter extends AbstractEntryListFilter {
+ @Override
+ public boolean accept(T t) {
+ return true;
+ }
+}
diff --git a/spring-integration-file/src/main/java/org/springframework/integration/file/entries/AcceptOnceEntryFileListFilter.java b/spring-integration-file/src/main/java/org/springframework/integration/file/entries/AcceptOnceEntryFileListFilter.java
index 789c8c00a5..cc37ee7197 100644
--- a/spring-integration-file/src/main/java/org/springframework/integration/file/entries/AcceptOnceEntryFileListFilter.java
+++ b/spring-integration-file/src/main/java/org/springframework/integration/file/entries/AcceptOnceEntryFileListFilter.java
@@ -13,20 +13,29 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.integration.file.entries;
-
import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;
+
+/**
+ * {@link EntryListFilter} that passes files only one time. This can
+ * conveniently be used to prevent duplication of files, as is done in
+ * {@link org.springframework.integration.file.FileReadingMessageSource}.
+ *
+ * This implementation is thread safe.
+ *
+ * @author Iwein Fuld
+ * @since 1.0.0
+ */
public class AcceptOnceEntryFileListFilter extends AbstractEntryListFilter {
private final Queue seen;
private final Object monitor = new Object();
/**
- * Creates an AcceptOnceFileFilter that is based on a bounded queue. If the
+ * Creates an {@link org.springframework.integration.file.entries.AcceptOnceEntryFileListFilter} that is based on a bounded queue. If the
* queue overflows, files that fall out will be passed through this filter
* again if passed to the {@link #filterEntries(Object[])} method.
*
@@ -44,7 +53,7 @@ public class AcceptOnceEntryFileListFilter extends AbstractEntryListFilter
this.seen = new LinkedBlockingQueue();
}
- protected boolean accept(T pathname) {
+ public boolean accept(T pathname) {
synchronized (this.monitor) {
if (seen.contains(pathname)) {
return false;
diff --git a/spring-integration-file/src/main/java/org/springframework/integration/file/entries/CompositeEntryListFilter.java b/spring-integration-file/src/main/java/org/springframework/integration/file/entries/CompositeEntryListFilter.java
index 82ecdc00e8..9dd9d8933e 100644
--- a/spring-integration-file/src/main/java/org/springframework/integration/file/entries/CompositeEntryListFilter.java
+++ b/spring-integration-file/src/main/java/org/springframework/integration/file/entries/CompositeEntryListFilter.java
@@ -13,32 +13,37 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.integration.file.entries;
+import org.springframework.beans.factory.InitializingBean;
+
import org.springframework.util.Assert;
+
import java.util.*;
public class CompositeEntryListFilter implements EntryListFilter {
- private final Set fileFilters;
+ private final Set> fileFilters;
- public CompositeEntryListFilter(EntryListFilter... fileFilters) {
- this.fileFilters = new LinkedHashSet(Arrays.asList(fileFilters));
+ public CompositeEntryListFilter(EntryListFilter... fileFilters) {
+ this.fileFilters = new LinkedHashSet>(Arrays.asList(fileFilters));
}
- public CompositeEntryListFilter(Collection fileFilters) {
- this.fileFilters = new LinkedHashSet(fileFilters);
+ public CompositeEntryListFilter(Collection extends EntryListFilter> fileFilters) {
+ this.fileFilters = new LinkedHashSet>(fileFilters);
}
@SuppressWarnings("unchecked")
public List filterEntries(T[] entries) {
Assert.notNull(entries, "'files' should not be null");
- List leftOver = Arrays.asList(entries);
- for (EntryListFilter fileFilter : this.fileFilters) {
- T[] ts =(T[]) leftOver.toArray();
+
+ List leftOver = Arrays.asList(entries);
+
+ for (EntryListFilter fileFilter : this.fileFilters) {
+ T[] ts = (T[]) leftOver.toArray();
leftOver = fileFilter.filterEntries(ts);
}
+
return leftOver;
}
@@ -47,7 +52,7 @@ public class CompositeEntryListFilter implements EntryListFilter {
* @return this CompositeFileFilter instance with the added filters
* @see #addFilters(Collection)
*/
- public CompositeEntryListFilter addFilter(EntryListFilter... filters) {
+ public CompositeEntryListFilter addFilter(EntryListFilter... filters) {
return addFilters(Arrays.asList(filters));
}
@@ -59,7 +64,16 @@ public class CompositeEntryListFilter implements EntryListFilter {
* @param filtersToAdd a list of filters to add
* @return this CompositeEntryListFilter instance with the added filters
*/
- public CompositeEntryListFilter addFilters(Collection filtersToAdd) {
+ public CompositeEntryListFilter addFilters(Collection> filtersToAdd) {
+ for (EntryListFilter elf : filtersToAdd)
+ if (elf instanceof InitializingBean) {
+ try {
+ ((InitializingBean) elf).afterPropertiesSet();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
this.fileFilters.addAll(filtersToAdd);
return this;
diff --git a/spring-integration-file/src/main/java/org/springframework/integration/file/entries/EntryListFilter.java b/spring-integration-file/src/main/java/org/springframework/integration/file/entries/EntryListFilter.java
index 8ab82e15cc..076fca83a8 100644
--- a/spring-integration-file/src/main/java/org/springframework/integration/file/entries/EntryListFilter.java
+++ b/spring-integration-file/src/main/java/org/springframework/integration/file/entries/EntryListFilter.java
@@ -18,6 +18,19 @@ package org.springframework.integration.file.entries;
import java.util.List;
-public interface EntryListFilter {
- List filterEntries(T [] entries );
+/**
+ * Strategy interface for filtering a group of entries / files.
+ *
+ * {@link EntryListFilter} that passes file entries only one time. This can
+ * conveniently be used to prevent duplication of files, as is done in
+ * {@link org.springframework.integration.file.FileReadingMessageSource}.
+ *
+ * This implementation is thread safe.
+ *
+ * @author Iwein Fuld
+ * @author Josh Long
+ * @since 1.0.0
+ */
+public interface EntryListFilter {
+ List filterEntries(T[] entries);
}
diff --git a/spring-integration-file/src/main/java/org/springframework/integration/file/entries/EntryNamer.java b/spring-integration-file/src/main/java/org/springframework/integration/file/entries/EntryNamer.java
index 1bc181cb42..fde16e3a34 100644
--- a/spring-integration-file/src/main/java/org/springframework/integration/file/entries/EntryNamer.java
+++ b/spring-integration-file/src/main/java/org/springframework/integration/file/entries/EntryNamer.java
@@ -15,6 +15,21 @@
*/
package org.springframework.integration.file.entries;
+/**
+ * Responsible for coercing a String identification out of the {@link T} entry.
+ * @param the type of entry (there's an implementation for FTP, SFTP, and plain-old java.io.Files)
+ *
+ * @author Josh Long
+ */
public interface EntryNamer {
+
+ /**
+ * This is the one place I couldn't spackle over the interface differences between an FTPFile (FTP adapter), File (File adapter), and LsEntry (SFTP adapter)
+ * with generics alone. So we have a typed strategy implementation for accessing a property ....
+ *
+ *
+ * @param entry the entry in a file system listing
+ * @return the String name that might be used to reference that entry or to do regular expression checks against
+ */
String nameOf(T entry);
}
diff --git a/spring-integration-file/src/main/java/org/springframework/integration/file/entries/FileEntryNamer.java b/spring-integration-file/src/main/java/org/springframework/integration/file/entries/FileEntryNamer.java
new file mode 100644
index 0000000000..23de52ac76
--- /dev/null
+++ b/spring-integration-file/src/main/java/org/springframework/integration/file/entries/FileEntryNamer.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2002-2008 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.integration.file.entries;
+
+import java.io.File;
+
+
+/**
+ * {@link java.io.File} implementation of the {@link org.springframework.integration.file.entries.EntryNamer} strategy.
+ *
+ * This part feels a little over-engineered...
+ *
+ * @author Josh Long
+ *
+ */
+public class FileEntryNamer implements EntryNamer {
+ public String nameOf(File entry) {
+ return (entry != null) ? entry.getName() : null;
+ }
+}
diff --git a/spring-integration-file/src/main/java/org/springframework/integration/file/entries/PatternMatchingEntryListFilter.java b/spring-integration-file/src/main/java/org/springframework/integration/file/entries/PatternMatchingEntryListFilter.java
index 1d9d604b06..1e29c1d2cb 100644
--- a/spring-integration-file/src/main/java/org/springframework/integration/file/entries/PatternMatchingEntryListFilter.java
+++ b/spring-integration-file/src/main/java/org/springframework/integration/file/entries/PatternMatchingEntryListFilter.java
@@ -24,16 +24,29 @@ import java.util.regex.Pattern;
/**
- * experimental
+ * experimental
+ *
+ * Filters a listing of entries (T) by qualifying their 'name' (as determined by {@link org.springframework.integration.file.entries.EntryNamer})
+ * against a regular expression (an instance of {@link java.util.regex.Pattern})
*
* @author Josh Long
* @param the type of entry
*/
-public abstract class PatternMatchingEntryListFilter extends AbstractEntryListFilter implements InitializingBean {
+public class PatternMatchingEntryListFilter extends AbstractEntryListFilter implements InitializingBean {
private Pattern pattern;
private String patternExpression;
private EntryNamer entryNamer;
+ public PatternMatchingEntryListFilter(EntryNamer en, String p) {
+ this.entryNamer = en;
+ this.patternExpression = p;
+ }
+
+ public PatternMatchingEntryListFilter(EntryNamer en, Pattern p) {
+ this.entryNamer = en;
+ this.pattern = p;
+ }
+
public void setPattern(Pattern pattern) {
this.pattern = pattern;
}
@@ -46,13 +59,12 @@ public abstract class PatternMatchingEntryListFilter extends AbstractEntryLis
if (StringUtils.hasText(this.patternExpression) && (pattern == null)) {
this.pattern = Pattern.compile(this.patternExpression);
}
-
- Assert.notNull(this.entryNamer,"'entryNamer' must not be null!");
+ Assert.notNull(this.entryNamer, "'entryNamer' must not be null!");
Assert.notNull(this.pattern, "'pattern' mustn't be null!");
}
-
+
@Override
- protected boolean accept(T t) {
+ public boolean accept(T t) {
return (t != null) && this.pattern.matcher(this.entryNamer.nameOf(t)).matches();
}
diff --git a/spring-integration-file/src/main/java/org/springframework/integration/file/entries/SingleEntryAdaptingEntryListFilter.java b/spring-integration-file/src/main/java/org/springframework/integration/file/entries/SingleEntryAdaptingEntryListFilter.java
new file mode 100644
index 0000000000..0842b6e027
--- /dev/null
+++ b/spring-integration-file/src/main/java/org/springframework/integration/file/entries/SingleEntryAdaptingEntryListFilter.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2002-2008 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.integration.file.entries;
+
+import org.springframework.util.Assert;
+
+
+/**
+ * this simply takes an {@link org.springframework.integration.file.entries.EntryListFilter}
+ * and produces an object that can field just one argument instea of an array
+ *
+ * @author Josh Long
+ */
+public class SingleEntryAdaptingEntryListFilter extends AbstractEntryListFilter {
+
+ /**
+ * the {@link org.springframework.integration.file.entries.EntryListFilter} that you'd like to delegate to
+ */
+ private volatile EntryListFilter entryFilter;
+
+ public SingleEntryAdaptingEntryListFilter(EntryListFilter ef) {
+ this.entryFilter = ef;
+ Assert.notNull(this.entryFilter, "the entryFilter can't be null");
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public boolean accept(T t) {
+ T[] ts = (T[]) new Object[] { t };
+ return this.entryFilter.filterEntries(ts).size() == 1;
+ }
+}
diff --git a/spring-integration-file/src/main/java/org/springframework/integration/file/AbstractFileListFilter.java b/spring-integration-file/src/main/java/org/springframework/integration/file/filters/AbstractFileListFilter.java
similarity index 96%
rename from spring-integration-file/src/main/java/org/springframework/integration/file/AbstractFileListFilter.java
rename to spring-integration-file/src/main/java/org/springframework/integration/file/filters/AbstractFileListFilter.java
index 23fcda4766..2d05371b8d 100644
--- a/spring-integration-file/src/main/java/org/springframework/integration/file/AbstractFileListFilter.java
+++ b/spring-integration-file/src/main/java/org/springframework/integration/file/filters/AbstractFileListFilter.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package org.springframework.integration.file;
+package org.springframework.integration.file.filters;
import java.io.File;
import java.util.ArrayList;
diff --git a/spring-integration-file/src/main/java/org/springframework/integration/file/AcceptOnceFileListFilter.java b/spring-integration-file/src/main/java/org/springframework/integration/file/filters/AcceptOnceFileListFilter.java
similarity index 92%
rename from spring-integration-file/src/main/java/org/springframework/integration/file/AcceptOnceFileListFilter.java
rename to spring-integration-file/src/main/java/org/springframework/integration/file/filters/AcceptOnceFileListFilter.java
index 576d168726..1abf68d4d1 100644
--- a/spring-integration-file/src/main/java/org/springframework/integration/file/AcceptOnceFileListFilter.java
+++ b/spring-integration-file/src/main/java/org/springframework/integration/file/filters/AcceptOnceFileListFilter.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package org.springframework.integration.file;
+package org.springframework.integration.file.filters;
import java.io.File;
import java.util.Queue;
@@ -23,13 +23,13 @@ import java.util.concurrent.LinkedBlockingQueue;
/**
* {@link FileListFilter} that passes files only one time. This can
* conveniently be used to prevent duplication of files, as is done in
- * {@link FileReadingMessageSource}.
+ * {@link org.springframework.integration.file.FileReadingMessageSource}.
*
* This implementation is thread safe.
*
* @author Iwein Fuld
* @since 1.0.0
- */
+ */ @Deprecated
public class AcceptOnceFileListFilter extends AbstractFileListFilter {
private final Queue seen;
diff --git a/spring-integration-file/src/main/java/org/springframework/integration/file/CompositeFileListFilter.java b/spring-integration-file/src/main/java/org/springframework/integration/file/filters/CompositeFileListFilter.java
similarity index 96%
rename from spring-integration-file/src/main/java/org/springframework/integration/file/CompositeFileListFilter.java
rename to spring-integration-file/src/main/java/org/springframework/integration/file/filters/CompositeFileListFilter.java
index a1ea42ee71..b1e876145a 100644
--- a/spring-integration-file/src/main/java/org/springframework/integration/file/CompositeFileListFilter.java
+++ b/spring-integration-file/src/main/java/org/springframework/integration/file/filters/CompositeFileListFilter.java
@@ -13,8 +13,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+package org.springframework.integration.file.filters;
+
+import java.util.Set;
-package org.springframework.integration.file;
import org.springframework.util.Assert;
@@ -22,13 +24,14 @@ import java.io.File;
import java.io.FileFilter;
import java.util.*;
+
/**
* Composition that delegates to multiple {@link FileFilter}s. The composition is AND based, meaning that a file must
* pass through each filter's {@link #filterFiles(java.io.File[])} method in order to be accepted by the composite.
*
* @author Iwein Fuld
* @author Mark Fisher
- */
+ */ @Deprecated
public class CompositeFileListFilter implements FileListFilter {
private final Set fileFilters;
diff --git a/spring-integration-file/src/main/java/org/springframework/integration/file/FileListFilter.java b/spring-integration-file/src/main/java/org/springframework/integration/file/filters/FileListFilter.java
similarity index 92%
rename from spring-integration-file/src/main/java/org/springframework/integration/file/FileListFilter.java
rename to spring-integration-file/src/main/java/org/springframework/integration/file/filters/FileListFilter.java
index 615f57b129..3ed8bc7a47 100644
--- a/spring-integration-file/src/main/java/org/springframework/integration/file/FileListFilter.java
+++ b/spring-integration-file/src/main/java/org/springframework/integration/file/filters/FileListFilter.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package org.springframework.integration.file;
+package org.springframework.integration.file.filters;
import java.io.File;
import java.util.List;
@@ -23,7 +23,7 @@ import java.util.List;
* Strategy interface for filtering a group of files.
*
* @author Iwein Fuld
- */
+ */ @Deprecated
public interface FileListFilter {
/**
diff --git a/spring-integration-file/src/main/java/org/springframework/integration/file/PatternMatchingFileListFilter.java b/spring-integration-file/src/main/java/org/springframework/integration/file/filters/PatternMatchingFileListFilter.java
similarity index 95%
rename from spring-integration-file/src/main/java/org/springframework/integration/file/PatternMatchingFileListFilter.java
rename to spring-integration-file/src/main/java/org/springframework/integration/file/filters/PatternMatchingFileListFilter.java
index 3dac0f7629..786477c454 100644
--- a/spring-integration-file/src/main/java/org/springframework/integration/file/PatternMatchingFileListFilter.java
+++ b/spring-integration-file/src/main/java/org/springframework/integration/file/filters/PatternMatchingFileListFilter.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package org.springframework.integration.file;
+package org.springframework.integration.file.filters;
import java.io.File;
import java.util.regex.Pattern;
@@ -26,6 +26,7 @@ import org.springframework.util.Assert;
*
* @author Mark Fisher
*/
+@Deprecated
public class PatternMatchingFileListFilter extends AbstractFileListFilter {
private final Pattern pattern;
diff --git a/spring-integration-file/src/main/java/org/springframework/integration/file/locking/AbstractFileLockerFilter.java b/spring-integration-file/src/main/java/org/springframework/integration/file/locking/AbstractFileLockerFilter.java
index 7804468f75..71fff4aac8 100644
--- a/spring-integration-file/src/main/java/org/springframework/integration/file/locking/AbstractFileLockerFilter.java
+++ b/spring-integration-file/src/main/java/org/springframework/integration/file/locking/AbstractFileLockerFilter.java
@@ -16,8 +16,8 @@
package org.springframework.integration.file.locking;
-import org.springframework.integration.file.AbstractFileListFilter;
import org.springframework.integration.file.FileLocker;
+import org.springframework.integration.file.entries.AbstractEntryListFilter;
import java.io.File;
@@ -29,9 +29,10 @@ import java.io.File;
* @since 2.0
*
*/
-public abstract class AbstractFileLockerFilter extends AbstractFileListFilter implements FileLocker {
+public abstract class AbstractFileLockerFilter extends AbstractEntryListFilter implements FileLocker {
- protected final boolean accept(File file) {
- return isLockable(file);
+ @Override
+ public boolean accept(File file) {
+ return this.isLockable(file);
}
-}
\ No newline at end of file
+}
diff --git a/spring-integration-file/src/main/java/org/springframework/integration/file/monitors/AbstractEventDrivenFileMonitor.java b/spring-integration-file/src/main/java/org/springframework/integration/file/monitors/AbstractEventDrivenFileMonitor.java
new file mode 100644
index 0000000000..4d47ca5186
--- /dev/null
+++ b/spring-integration-file/src/main/java/org/springframework/integration/file/monitors/AbstractEventDrivenFileMonitor.java
@@ -0,0 +1,261 @@
+package org.springframework.integration.file.monitors;
+
+import org.springframework.core.task.SimpleAsyncTaskExecutor;
+
+import org.springframework.integration.context.IntegrationObjectSupport;
+import org.springframework.integration.file.entries.*;
+
+import org.springframework.util.Assert;
+
+import java.io.File;
+
+import java.util.concurrent.Executor;
+import java.util.concurrent.LinkedBlockingQueue;
+
+
+/**
+ * This component will support event-based (not poller based) notifications of files from a file system.
+ * Immediate implementations will center around supporting other adapters's delivery of files once they've been synced from a remote system.
+ * Potential future expansions for consumer consumption might be a push / event-based file adapter based on either native code
+ * or Java 7's NIO.2 WaterService or other third party implementations.
+ *
+ * In the meantime, this provides us with a base class for building event driven file adapters quickly. The two cases I see are:
+ *
+ *
+ *
+ *
+ *
+ *
+ * @author Josh Long
+ */
+public abstract class AbstractEventDrivenFileMonitor extends IntegrationObjectSupport implements EventDrivenDirectoryMonitor {
+ /**
+ * when this component starts up, we can perform a scan of the folder this first time and to pre-seed the #additions queue
+ */
+ private boolean scanDirectoryOnLoad;
+
+ /**
+ * How many files we'll support in the backlog at a time
+ */
+ private volatile int maxQueueSize = 100;
+
+ /**
+ * the backlog
+ */
+ private volatile LinkedBlockingQueue additions;
+
+ /**
+ * An {@link java.util.concurrent.Executor} implementation. Default is {@link org.springframework.core.task.SimpleAsyncTaskExecutor}
+ */
+ private volatile Executor executor;
+
+ /**
+ * Should the director be automatically created?
+ */
+ private volatile boolean autoCreateDirectory;
+
+ /**
+ * The directory to monitor (a {@link java.io.File})
+ */
+ private volatile File directoryToMonitorCached;
+
+ /**
+ * A {@link org.springframework.integration.file.entries.EntryListFilter} reference
+ */
+ private volatile SingleEntryAdaptingEntryListFilter filter;
+
+ /**
+ * state guard (extra for post-init state)
+ */
+ private final Object guard = new Object();
+
+ public void setScanDirectoryOnLoad(boolean scanDirectoryOnLoad) {
+ this.scanDirectoryOnLoad = scanDirectoryOnLoad;
+ }
+
+ /**
+ * installs directory, and then kicks of an event pump
+ *
+ * @param directory the directory to start watching from. Unspecified if this implies recursion or not.
+ * @param fileAdditionListener the callback
+ * @throws Exception
+ */
+ public void monitor(File directory, FileAdditionListener fileAdditionListener)
+ throws Exception {
+ this.installDirectoryIfRequired(directory);
+ this.prescan();
+ this.executor.execute(new FileDeliveryPump(fileAdditionListener));
+ }
+
+ public void setMaxQueueSize(int maxQueueSize) {
+ this.maxQueueSize = maxQueueSize;
+ }
+
+ public void setFilter(EntryListFilter filter) {
+ this.filter = new SingleEntryAdaptingEntryListFilter(filter);
+ }
+
+ public void setExecutor(Executor executor) {
+ this.executor = executor;
+ }
+
+ public void setAutoCreateDirectory(boolean autoCreateDirectory) {
+ this.autoCreateDirectory = autoCreateDirectory;
+ }
+
+ protected void publishNewFileReceived(String path) {
+ this.publishNewFileReceived(new File(path));
+ }
+
+ protected void publishNewFileReceived(File file) {
+ this.additions.add(file);
+ }
+
+ /**
+ * Obviously, we're trying to keep away from scanning, but this may be necessary at startup to catch up the backlog
+ */
+ protected void prescan() {
+ synchronized (this.guard) {
+ if (this.scanDirectoryOnLoad) {
+ for (File f : this.directoryToMonitorCached.listFiles())
+ this.publishNewFileReceived(f);
+ }
+ }
+ }
+
+ /**
+ * Handles ensuring that the directory we're monitroring exists or can be created
+ *
+ * @param directoryToMonitor the directory to monitor
+ * @throws Exception
+ */
+ protected void installDirectoryIfRequired(File directoryToMonitor)
+ throws Exception {
+ synchronized (this.guard) {
+ this.directoryToMonitorCached = directoryToMonitor;
+ Assert.state(null != this.directoryToMonitorCached, "the directory to monitor can't be null");
+
+ boolean directoryIsReady = this.directoryToMonitorCached.exists();
+
+ if (!directoryIsReady) {
+ if (!directoryToMonitorCached.exists()) {
+ if (this.autoCreateDirectory) {
+ Assert.state(directoryToMonitorCached.mkdirs() && directoryToMonitorCached.exists(),
+ String.format("Couldn't create the directory %s", directoryToMonitorCached.getAbsolutePath()));
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Custom initialization hook - override at your discretion
+ *
+ * @throws Exception
+ */
+ protected void start() throws Exception{
+ // noop
+ }
+
+ @Override
+ protected void onInit() throws Exception {
+ additions = new LinkedBlockingQueue(this.maxQueueSize);
+
+ if (this.executor == null) {
+ this.executor = new SimpleAsyncTaskExecutor();
+ }
+
+ if (this.filter == null) {
+ this.filter = new SingleEntryAdaptingEntryListFilter(new AcceptAllEntryListFilter());
+ }
+
+ Assert.notNull(this.filter, "the filter can't be null");
+
+ this.start();
+ }
+
+ /**
+ * a way to remove the responsibility of reacting to the file system from implementations while still being thread safe and handling backlog
+ *
+ * @author Josh Long
+ */
+ class FileDeliveryPump implements Runnable {
+ private volatile FileAdditionListener fileAdditionListener;
+
+ public FileDeliveryPump(FileAdditionListener fileAdditionListener) {
+ this.fileAdditionListener = fileAdditionListener;
+ Assert.notNull(this.fileAdditionListener, "the FileAdditionListener can't be null");
+ }
+
+ public void run() {
+ do {
+ try {
+ File taken = additions.take();
+
+ if (filter.accept(taken)) {
+ fileAdditionListener.fileAdded(taken);
+ }
+ } catch (Throwable th) {
+ throw new RuntimeException(th);
+ }
+ } while (true);
+ }
+ }
+}
+/*
+
+
+class MyEDFRM extends AbstractEventDrivenFileMonitor {
+ @Override
+ protected void start() throws Exception {
+ System.out.println("start()");
+ }
+
+ public void addToHeap(File file) {
+ this.publishNewFileReceived(file);
+ }
+
+ public static void main(String[] args) throws Throwable {
+ SimpleAsyncTaskExecutor simpleAsyncTaskExecutor = new SimpleAsyncTaskExecutor();
+
+ final MyEDFRM myEDFRM = new MyEDFRM();
+ myEDFRM.setExecutor(simpleAsyncTaskExecutor);
+ myEDFRM.setAutoCreateDirectory(true);
+ myEDFRM.afterPropertiesSet();
+
+ AcceptOnceEntryFileListFilter acceptOnceEntryFileListFilter=new AcceptOnceEntryFileListFilter() ;
+ acceptOnceEntryFileListFilter.afterPropertiesSet();
+ PatternMatchingEntryListFilter patternMatchingEntryListFilter=
+ new PatternMatchingEntryListFilter(new FileEntryNamer(), ".*?jpg");
+ patternMatchingEntryListFilter.afterPropertiesSet();
+
+ Collection extends EntryListFilter> l=Arrays.asList( acceptOnceEntryFileListFilter, patternMatchingEntryListFilter);
+ CompositeEntryListFilter compositeEntryListFilter = new CompositeEntryListFilter(l );
+
+
+ myEDFRM.setFilter(compositeEntryListFilter);
+
+ final File desktop = new File(System.getProperty("user.home"), "Desktop");
+ myEDFRM.monitor(desktop, new FileAdditionListener() {
+ public void fileAdded(File f) {
+ System.out.println("Got one! " + f.getAbsolutePath());
+ }
+ });
+ System.out.println("enjoying the world");
+ simpleAsyncTaskExecutor.execute(new Runnable() {
+ public void run() {
+ while (true) {
+ try {
+ Thread.sleep(1000 * 10);
+
+ for (File f : desktop.listFiles())
+ myEDFRM.addToHeap(f);
+ } catch (InterruptedException e) {
+ //
+ }
+ }
+ }
+ });
+ }
+}
+*/
diff --git a/spring-integration-file/src/main/java/org/springframework/integration/file/monitors/DirectedEventDrivenFileMonitor.java b/spring-integration-file/src/main/java/org/springframework/integration/file/monitors/DirectedEventDrivenFileMonitor.java
new file mode 100644
index 0000000000..c116762b43
--- /dev/null
+++ b/spring-integration-file/src/main/java/org/springframework/integration/file/monitors/DirectedEventDrivenFileMonitor.java
@@ -0,0 +1,15 @@
+package org.springframework.integration.file.monitors;
+
+import java.io.File;
+
+
+/**
+ * simply takes a hint and publishes an event as appropriate
+ *
+ * @author Josh Long
+ */
+public class DirectedEventDrivenFileMonitor extends AbstractEventDrivenFileMonitor {
+ public void directlyNotifyOfNewFile(File file) {
+ this.publishNewFileReceived(file);
+ }
+}
diff --git a/spring-integration-file/src/main/java/org/springframework/integration/file/monitors/EventDrivenDirectoryMonitor.java b/spring-integration-file/src/main/java/org/springframework/integration/file/monitors/EventDrivenDirectoryMonitor.java
new file mode 100644
index 0000000000..718486a8f7
--- /dev/null
+++ b/spring-integration-file/src/main/java/org/springframework/integration/file/monitors/EventDrivenDirectoryMonitor.java
@@ -0,0 +1,21 @@
+package org.springframework.integration.file.monitors;
+
+import java.io.File;
+
+
+/**
+ * Defines an interface for a component that reacts to file system events
+ *
+ * @author Josh Long
+ */
+public interface EventDrivenDirectoryMonitor {
+ /**
+ * the implementation should know how to publish events on the {@link FileAdditionListener}
+ * for a given #directory
+ *
+ * @param directory the directory to start watching from. Unspecified if this implies recursion or not.
+ * @param fileAdditionListener the callback
+ * @throws Exception if anything should go wrong
+ */
+ void monitor(File directory, FileAdditionListener fileAdditionListener) throws Exception;
+}
diff --git a/spring-integration-file/src/main/java/org/springframework/integration/file/monitors/FileAdditionListener.java b/spring-integration-file/src/main/java/org/springframework/integration/file/monitors/FileAdditionListener.java
new file mode 100644
index 0000000000..f32860346a
--- /dev/null
+++ b/spring-integration-file/src/main/java/org/springframework/integration/file/monitors/FileAdditionListener.java
@@ -0,0 +1,19 @@
+package org.springframework.integration.file.monitors;
+
+import java.io.File;
+
+/**
+ * A generic hook into the arrival of a new {@link java.io.File}
+ *
+ * @author Josh Long
+ * @see org.springframework.integration.file.monitors.MessageSendingFileAdditionListener
+ */
+public interface FileAdditionListener {
+
+ /**
+ * a callback method that's invoked when a new {@link java.io.File} is detected.
+ *
+ * @param f the {@link java.io.File} that was detected
+ */
+ void fileAdded(File f);
+}
diff --git a/spring-integration-file/src/main/java/org/springframework/integration/file/monitors/MessageSendingFileAdditionListener.java b/spring-integration-file/src/main/java/org/springframework/integration/file/monitors/MessageSendingFileAdditionListener.java
new file mode 100644
index 0000000000..3ae9b649a7
--- /dev/null
+++ b/spring-integration-file/src/main/java/org/springframework/integration/file/monitors/MessageSendingFileAdditionListener.java
@@ -0,0 +1,47 @@
+package org.springframework.integration.file.monitors;
+
+import org.springframework.integration.Message;
+import org.springframework.integration.context.IntegrationObjectSupport;
+import org.springframework.integration.core.MessageBuilder;
+import org.springframework.integration.core.MessageChannel;
+import org.springframework.integration.core.MessagingTemplate;
+
+import org.springframework.transaction.PlatformTransactionManager;
+
+import org.springframework.util.Assert;
+
+import java.io.File;
+
+
+/**
+ * Supports propagating a {@link org.springframework.integration.Message} on the receipt of a new {@link java.io.File}
+ *
+ * @author Josh Long
+ */
+public class MessageSendingFileAdditionListener extends IntegrationObjectSupport implements FileAdditionListener {
+ private MessagingTemplate messagingTemplate = new MessagingTemplate();
+ private MessageChannel channel;
+ private PlatformTransactionManager platformTransactionManager;
+
+ public void setChannel(MessageChannel channel) {
+ this.channel = channel;
+ }
+
+ @Override
+ protected void onInit() throws Exception {
+ Assert.notNull(this.channel, "'channel' can't be null!");
+
+ if (this.platformTransactionManager != null) {
+ this.messagingTemplate.setTransactionManager(platformTransactionManager);
+ }
+ }
+
+ public void setPlatformTransactionManager(PlatformTransactionManager platformTransactionManager) {
+ this.platformTransactionManager = platformTransactionManager;
+ }
+
+ public void fileAdded(File f) {
+ Message fileMsg = MessageBuilder.withPayload(f).build();
+ this.messagingTemplate.send(fileMsg);
+ }
+}
diff --git a/spring-integration-file/src/main/resources/org/springframework/integration/file/config/spring-integration-file-1.0.xsd b/spring-integration-file/src/main/resources/org/springframework/integration/file/config/spring-integration-file-1.0.xsd
index c2c89f3aa6..3753122ea1 100644
--- a/spring-integration-file/src/main/resources/org/springframework/integration/file/config/spring-integration-file-1.0.xsd
+++ b/spring-integration-file/src/main/resources/org/springframework/integration/file/config/spring-integration-file-1.0.xsd
@@ -53,7 +53,7 @@
-
+
diff --git a/spring-integration-file/src/main/resources/org/springframework/integration/file/config/spring-integration-file-2.0.xsd b/spring-integration-file/src/main/resources/org/springframework/integration/file/config/spring-integration-file-2.0.xsd
index cf960a43d2..f00a15167c 100644
--- a/spring-integration-file/src/main/resources/org/springframework/integration/file/config/spring-integration-file-2.0.xsd
+++ b/spring-integration-file/src/main/resources/org/springframework/integration/file/config/spring-integration-file-2.0.xsd
@@ -56,7 +56,7 @@
-
+
diff --git a/spring-integration-file/src/test/java/org/springframework/integration/file/CompositeFileListFilterTests.java b/spring-integration-file/src/test/java/org/springframework/integration/file/CompositeFileListFilterTests.java
index e3de58346b..ae44c96b44 100644
--- a/spring-integration-file/src/test/java/org/springframework/integration/file/CompositeFileListFilterTests.java
+++ b/spring-integration-file/src/test/java/org/springframework/integration/file/CompositeFileListFilterTests.java
@@ -26,13 +26,15 @@ import java.util.Arrays;
import java.util.List;
import org.junit.Test;
+import org.springframework.integration.file.filters.CompositeFileListFilter;
+import org.springframework.integration.file.filters.FileListFilter;
/**
* @author Iwein Fuld
*/
public class CompositeFileListFilterTests {
- private FileListFilter fileFilterMock1 = mock(FileListFilter.class);
+ private FileListFilter fileFilterMock1 = mock( FileListFilter.class);
private FileListFilter fileFilterMock2 = mock(FileListFilter.class);
@@ -51,7 +53,8 @@ public class CompositeFileListFilterTests {
@Test
public void forwardedToAddedFilters() throws Exception {
- CompositeFileListFilter compositeFileFilter = new CompositeFileListFilter().addFilter(fileFilterMock1, fileFilterMock2);
+ CompositeFileListFilter compositeFileFilter = new CompositeFileListFilter();
+ compositeFileFilter.addFilter(fileFilterMock1, fileFilterMock2);
List returnedFiles = Arrays.asList(new File[] { fileMock });
when(fileFilterMock1.filterFiles(isA(File[].class))).thenReturn(returnedFiles);
when(fileFilterMock2.filterFiles(isA(File[].class))).thenReturn(returnedFiles);
diff --git a/spring-integration-file/src/test/java/org/springframework/integration/file/FileReadingMessageSourceIntegrationTests-context.xml b/spring-integration-file/src/test/java/org/springframework/integration/file/FileReadingMessageSourceIntegrationTests-context.xml
index f6c205b022..f0336e1452 100644
--- a/spring-integration-file/src/test/java/org/springframework/integration/file/FileReadingMessageSourceIntegrationTests-context.xml
+++ b/spring-integration-file/src/test/java/org/springframework/integration/file/FileReadingMessageSourceIntegrationTests-context.xml
@@ -1,28 +1,49 @@
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:p="http://www.springframework.org/schema/p" xmlns:util="http://www.springframework.org/schema/util"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans
+ http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.0.xsd">
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
-
+
+
-
\ No newline at end of file
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spring-integration-file/src/test/java/org/springframework/integration/file/FileReadingMessageSourceIntegrationTests.java b/spring-integration-file/src/test/java/org/springframework/integration/file/FileReadingMessageSourceIntegrationTests.java
index 44ae3e5845..76fcdc620f 100644
--- a/spring-integration-file/src/test/java/org/springframework/integration/file/FileReadingMessageSourceIntegrationTests.java
+++ b/spring-integration-file/src/test/java/org/springframework/integration/file/FileReadingMessageSourceIntegrationTests.java
@@ -80,7 +80,8 @@ public class FileReadingMessageSourceIntegrationTests {
@Test
public void getFiles() throws Exception {
Message received1 = pollableFileSource.receive();
- assertNotNull("This should return the first message", received1);
+ System.out.println( "getfiels() round 1");
+ assertNotNull("This should return the first message", received1);
pollableFileSource.onSend(received1);
Message received2 = pollableFileSource.receive();
assertNotNull(received2);
@@ -154,12 +155,13 @@ public class FileReadingMessageSourceIntegrationTests {
/**
* Convenience method to run part of a test concurrently in multiple threads
*
- * @param numberOfThreads
- * @param todo the runnable that should be run by all the threads
+ * @param numberOfThreads how many threads to spawn
+ * @param runnable the runnable that should be run by all the threads
+ * @param start the {@link java.util.concurrent.CountDownLatch} instance telling it when to assume everything works
* @return a latch that will be counted down once all threads have run their
* runnable.
*/
- private CountDownLatch doConcurrently(int numberOfThreads, final Runnable todo, final CountDownLatch start) {
+ private CountDownLatch doConcurrently(int numberOfThreads, final Runnable runnable, final CountDownLatch start) {
final CountDownLatch started = new CountDownLatch(numberOfThreads);
final CountDownLatch done = new CountDownLatch(numberOfThreads);
for (int i = 0; i < numberOfThreads; i++) {
@@ -174,7 +176,7 @@ public class FileReadingMessageSourceIntegrationTests {
catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
- todo.run();
+ runnable.run();
done.countDown();
}
}).start();
diff --git a/spring-integration-file/src/test/java/org/springframework/integration/file/FileToChannelIntegrationTests-context.xml b/spring-integration-file/src/test/java/org/springframework/integration/file/FileToChannelIntegrationTests-context.xml
index a342db3147..0462c2fb0f 100644
--- a/spring-integration-file/src/test/java/org/springframework/integration/file/FileToChannelIntegrationTests-context.xml
+++ b/spring-integration-file/src/test/java/org/springframework/integration/file/FileToChannelIntegrationTests-context.xml
@@ -1,46 +1,48 @@
+ http://www.springframework.org/schema/integration/file/spring-integration-file.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.0.xsd">
-
-
+
+
-
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
+
-
\ No newline at end of file
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spring-integration-file/src/test/java/org/springframework/integration/file/PatternMatchingFileListFilterTests.java b/spring-integration-file/src/test/java/org/springframework/integration/file/PatternMatchingFileListFilterTests.java
index c86e12b9d5..8970b8a484 100644
--- a/spring-integration-file/src/test/java/org/springframework/integration/file/PatternMatchingFileListFilterTests.java
+++ b/spring-integration-file/src/test/java/org/springframework/integration/file/PatternMatchingFileListFilterTests.java
@@ -27,6 +27,8 @@ import org.junit.Test;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.context.support.ClassPathXmlApplicationContext;
+import org.springframework.integration.file.filters.FileListFilter;
+import org.springframework.integration.file.filters.PatternMatchingFileListFilter;
/**
* @author Mark Fisher
diff --git a/spring-integration-file/src/test/java/org/springframework/integration/file/TestFileListFilter.java b/spring-integration-file/src/test/java/org/springframework/integration/file/TestFileListFilter.java
index 88d4ad9d24..4b3b1bb6b8 100644
--- a/spring-integration-file/src/test/java/org/springframework/integration/file/TestFileListFilter.java
+++ b/spring-integration-file/src/test/java/org/springframework/integration/file/TestFileListFilter.java
@@ -16,6 +16,8 @@
package org.springframework.integration.file;
+import org.springframework.integration.file.entries.EntryListFilter;
+
import java.io.File;
import java.util.Arrays;
import java.util.List;
@@ -23,10 +25,8 @@ import java.util.List;
/**
* @author Iwein Fuld
*/
-public class TestFileListFilter implements FileListFilter {
-
- public List filterFiles(File[] files) {
- return Arrays.asList(files);
- }
-
+public class TestFileListFilter implements EntryListFilter {
+ public List filterEntries(File[] entries) {
+ return Arrays.asList(entries);
+ }
}
diff --git a/spring-integration-file/src/test/java/org/springframework/integration/file/config/FileInboundChannelAdapterParserTests-context.xml b/spring-integration-file/src/test/java/org/springframework/integration/file/config/FileInboundChannelAdapterParserTests-context.xml
index 1bf152ea65..242960f054 100644
--- a/spring-integration-file/src/test/java/org/springframework/integration/file/config/FileInboundChannelAdapterParserTests-context.xml
+++ b/spring-integration-file/src/test/java/org/springframework/integration/file/config/FileInboundChannelAdapterParserTests-context.xml
@@ -20,15 +20,19 @@
-
+
+
+
+
-
\ No newline at end of file
+
diff --git a/spring-integration-file/src/test/java/org/springframework/integration/file/config/FileInboundChannelAdapterParserTests.java b/spring-integration-file/src/test/java/org/springframework/integration/file/config/FileInboundChannelAdapterParserTests.java
index 764b47afb2..bfa36f7f77 100644
--- a/spring-integration-file/src/test/java/org/springframework/integration/file/config/FileInboundChannelAdapterParserTests.java
+++ b/spring-integration-file/src/test/java/org/springframework/integration/file/config/FileInboundChannelAdapterParserTests.java
@@ -32,7 +32,9 @@ import org.springframework.beans.DirectFieldAccessor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.integration.channel.AbstractMessageChannel;
-import org.springframework.integration.file.CompositeFileListFilter;
+import org.springframework.integration.file.entries.AcceptOnceEntryFileListFilter;
+import org.springframework.integration.file.entries.CompositeEntryListFilter;
+import org.springframework.integration.file.filters.CompositeFileListFilter;
import org.springframework.integration.file.DefaultDirectoryScanner;
import org.springframework.integration.file.FileReadingMessageSource;
import org.springframework.test.context.ContextConfiguration;
@@ -77,8 +79,9 @@ public class FileInboundChannelAdapterParserTests {
public void filter() throws Exception {
DefaultDirectoryScanner scanner = (DefaultDirectoryScanner) accessor.getPropertyValue("scanner");
DirectFieldAccessor scannerAccessor = new DirectFieldAccessor(scanner);
- assertTrue("'filter' should be set",
- scannerAccessor.getPropertyValue("filter") instanceof CompositeFileListFilter);
+ Object filter = scannerAccessor.getPropertyValue("filter");
+ assertTrue("'filter' should be set",
+ filter instanceof AcceptOnceEntryFileListFilter);
}
@Test
diff --git a/spring-integration-file/src/test/java/org/springframework/integration/file/config/FileInboundChannelAdapterWithPatternParserTests.java b/spring-integration-file/src/test/java/org/springframework/integration/file/config/FileInboundChannelAdapterWithPatternParserTests.java
index 5bdc482781..dfefdf467d 100644
--- a/spring-integration-file/src/test/java/org/springframework/integration/file/config/FileInboundChannelAdapterWithPatternParserTests.java
+++ b/spring-integration-file/src/test/java/org/springframework/integration/file/config/FileInboundChannelAdapterWithPatternParserTests.java
@@ -34,11 +34,15 @@ import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.integration.channel.AbstractMessageChannel;
import org.springframework.integration.endpoint.AbstractEndpoint;
-import org.springframework.integration.file.AcceptOnceFileListFilter;
-import org.springframework.integration.file.CompositeFileListFilter;
-import org.springframework.integration.file.FileListFilter;
+import org.springframework.integration.file.entries.AcceptOnceEntryFileListFilter;
+import org.springframework.integration.file.entries.CompositeEntryListFilter;
+import org.springframework.integration.file.entries.EntryListFilter;
+import org.springframework.integration.file.entries.PatternMatchingEntryListFilter;
+import org.springframework.integration.file.filters.AcceptOnceFileListFilter;
+import org.springframework.integration.file.filters.*;
import org.springframework.integration.file.FileReadingMessageSource;
-import org.springframework.integration.file.PatternMatchingFileListFilter;
+import org.springframework.integration.file.filters.PatternMatchingFileListFilter;
+import org.springframework.integration.file.filters.FileListFilter;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@@ -88,7 +92,7 @@ public class FileInboundChannelAdapterWithPatternParserTests {
@Test
public void compositeFilterType() {
DirectFieldAccessor scannerAccessor = new DirectFieldAccessor(accessor.getPropertyValue("scanner"));
- assertTrue(scannerAccessor.getPropertyValue("filter") instanceof CompositeFileListFilter);
+ assertTrue(scannerAccessor.getPropertyValue("filter") instanceof CompositeEntryListFilter);
}
@Test
@@ -106,11 +110,11 @@ public class FileInboundChannelAdapterWithPatternParserTests {
public void acceptOnceFilter() {
DirectFieldAccessor scannerAccessor = new DirectFieldAccessor(accessor.getPropertyValue("scanner"));
- Set filters = (Set) new DirectFieldAccessor(
+ Set> filters = (Set>) new DirectFieldAccessor(
scannerAccessor.getPropertyValue("filter")).getPropertyValue("fileFilters");
boolean hasAcceptOnceFilter = false;
- for (FileListFilter filter : filters) {
- if (filter instanceof AcceptOnceFileListFilter) {
+ for (EntryListFilter filter : filters) {
+ if (filter instanceof AcceptOnceEntryFileListFilter) {
hasAcceptOnceFilter = true;
}
}
@@ -122,11 +126,11 @@ public class FileInboundChannelAdapterWithPatternParserTests {
public void patternFilter() {
DirectFieldAccessor scannerAccessor = new DirectFieldAccessor(accessor.getPropertyValue("scanner"));
- Set filters = (Set) new DirectFieldAccessor(
+ Set filters = (Set) new DirectFieldAccessor(
scannerAccessor.getPropertyValue("filter")).getPropertyValue("fileFilters");
Pattern pattern = null;
- for (FileListFilter filter : filters) {
- if (filter instanceof PatternMatchingFileListFilter) {
+ for (EntryListFilter filter : filters) {
+ if (filter instanceof PatternMatchingEntryListFilter) {
pattern = (Pattern) new DirectFieldAccessor(filter).getPropertyValue("pattern");
}
}
diff --git a/spring-integration-file/src/test/java/org/springframework/integration/file/config/FileInboundChannelAdapterWithPreventDuplicatesFlagTests.java b/spring-integration-file/src/test/java/org/springframework/integration/file/config/FileInboundChannelAdapterWithPreventDuplicatesFlagTests.java
index d8b2b677c6..87d96d8922 100644
--- a/spring-integration-file/src/test/java/org/springframework/integration/file/config/FileInboundChannelAdapterWithPreventDuplicatesFlagTests.java
+++ b/spring-integration-file/src/test/java/org/springframework/integration/file/config/FileInboundChannelAdapterWithPreventDuplicatesFlagTests.java
@@ -23,6 +23,14 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.integration.file.*;
+import org.springframework.integration.file.entries.AcceptOnceEntryFileListFilter;
+import org.springframework.integration.file.entries.CompositeEntryListFilter;
+import org.springframework.integration.file.entries.EntryListFilter;
+import org.springframework.integration.file.entries.PatternMatchingEntryListFilter;
+import org.springframework.integration.file.filters.AcceptOnceFileListFilter;
+import org.springframework.integration.file.filters.CompositeFileListFilter;
+import org.springframework.integration.file.filters.FileListFilter;
+import org.springframework.integration.file.filters.PatternMatchingFileListFilter;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@@ -50,95 +58,95 @@ public class FileInboundChannelAdapterWithPreventDuplicatesFlagTests {
@Test
public void filterAndNull() {
- FileListFilter filter = this.extractFilter("filterAndNull");
- assertFalse(filter instanceof CompositeFileListFilter);
+ EntryListFilter filter = this.extractFilter("filterAndNull");
+ assertFalse(filter instanceof CompositeEntryListFilter);
assertSame(testFilter, filter);
}
@Test
@SuppressWarnings("unchecked")
public void filterAndTrue() {
- FileListFilter filter = this.extractFilter("filterAndTrue");
- assertTrue(filter instanceof CompositeFileListFilter);
+ EntryListFilter filter = this.extractFilter("filterAndTrue");
+ assertTrue(filter instanceof CompositeEntryListFilter);
Collection filters = (Collection) new DirectFieldAccessor(filter).getPropertyValue("fileFilters");
- assertTrue(filters.iterator().next() instanceof AcceptOnceFileListFilter);
+ assertTrue(filters.iterator().next() instanceof AcceptOnceEntryFileListFilter);
assertTrue(filters.contains(testFilter));
}
@Test
public void filterAndFalse() throws Exception {
- FileListFilter filter = this.extractFilter("filterAndFalse");
- assertFalse(filter instanceof CompositeFileListFilter);
+ EntryListFilter filter = this.extractFilter("filterAndFalse");
+ assertFalse(filter instanceof CompositeEntryListFilter);
assertSame(testFilter, filter);
}
@Test
@SuppressWarnings("unchecked")
public void patternAndNull() throws Exception {
- FileListFilter filter = this.extractFilter("patternAndNull");
- assertTrue(filter instanceof CompositeFileListFilter);
+ EntryListFilter filter = this.extractFilter("patternAndNull");
+ assertTrue(filter instanceof CompositeEntryListFilter);
Collection filters = (Collection) new DirectFieldAccessor(filter).getPropertyValue("fileFilters");
Iterator iterator = filters.iterator();
- assertTrue(iterator.next() instanceof AcceptOnceFileListFilter);
- assertTrue(iterator.next() instanceof PatternMatchingFileListFilter);
+ assertTrue(iterator.next() instanceof AcceptOnceEntryFileListFilter);
+ assertTrue(iterator.next() instanceof PatternMatchingEntryListFilter);
}
@Test
@SuppressWarnings("unchecked")
public void patternAndTrue() throws Exception {
- FileListFilter filter = this.extractFilter("patternAndTrue");
- assertTrue(filter instanceof CompositeFileListFilter);
+ EntryListFilter filter = this.extractFilter("patternAndTrue");
+ assertTrue(filter instanceof CompositeEntryListFilter);
Collection filters = (Collection) new DirectFieldAccessor(filter).getPropertyValue("fileFilters");
Iterator iterator = filters.iterator();
- assertTrue(iterator.next() instanceof AcceptOnceFileListFilter);
- assertTrue(iterator.next() instanceof PatternMatchingFileListFilter);
+ assertTrue(iterator.next() instanceof AcceptOnceEntryFileListFilter);
+ assertTrue(iterator.next() instanceof PatternMatchingEntryListFilter);
}
@Test
public void patternAndFalse() throws Exception {
- FileListFilter filter = this.extractFilter("patternAndFalse");
- assertFalse(filter instanceof CompositeFileListFilter);
- assertTrue(filter instanceof PatternMatchingFileListFilter);
+ EntryListFilter filter = this.extractFilter("patternAndFalse");
+ assertFalse(filter instanceof CompositeEntryListFilter);
+ assertTrue(filter instanceof PatternMatchingEntryListFilter);
}
@Test
public void defaultAndNull() throws Exception {
- FileListFilter filter = this.extractFilter("defaultAndNull");
+ EntryListFilter filter = this.extractFilter("defaultAndNull");
assertNotNull(filter);
- assertFalse(filter instanceof CompositeFileListFilter);
- assertTrue(filter instanceof AcceptOnceFileListFilter);
+ assertFalse(filter instanceof CompositeEntryListFilter);
+ assertTrue(filter instanceof AcceptOnceEntryFileListFilter);
File testFile = new File("test");
File[] files = new File[]{testFile, testFile, testFile};
- List result = filter.filterFiles(files);
- assertEquals(1, result.size());
+ List result = filter.filterEntries(files);
+ assertEquals(1 , result.size());
}
@Test
public void defaultAndTrue() throws Exception {
- FileListFilter filter = this.extractFilter("defaultAndTrue");
- assertFalse(filter instanceof CompositeFileListFilter);
- assertTrue(filter instanceof AcceptOnceFileListFilter);
+ EntryListFilter filter = this.extractFilter("defaultAndTrue");
+ assertFalse(filter instanceof CompositeEntryListFilter);
+ assertTrue(filter instanceof AcceptOnceEntryFileListFilter);
File testFile = new File("test");
File[] files = new File[]{testFile, testFile, testFile};
- List result = filter.filterFiles(files);
+ List result = filter.filterEntries(files);
assertEquals(1, result.size());
}
@Test
public void defaultAndFalse() throws Exception {
- FileListFilter filter = this.extractFilter("defaultAndFalse");
+ EntryListFilter filter = this.extractFilter("defaultAndFalse");
assertNotNull(filter);
- assertFalse(filter instanceof CompositeFileListFilter);
- assertFalse(filter instanceof AcceptOnceFileListFilter);
+ assertFalse(filter instanceof CompositeEntryListFilter);
+ assertFalse(filter instanceof AcceptOnceEntryFileListFilter);
File testFile = new File("test");
File[] files = new File[]{testFile, testFile, testFile};
- List result = filter.filterFiles(files);
+ List result = filter.filterEntries(files);
assertEquals(3, result.size());
}
- private FileListFilter extractFilter(String beanName) {
- return (FileListFilter) new DirectFieldAccessor(
+ private EntryListFilter extractFilter(String beanName) {
+ return (EntryListFilter) new DirectFieldAccessor(
new DirectFieldAccessor(
new DirectFieldAccessor(context.getBean(beanName))
.getPropertyValue("source"))
diff --git a/spring-integration-file/src/test/java/org/springframework/integration/file/config/FileInboundChannelAdapterWithQueueSizeTests-context.xml b/spring-integration-file/src/test/java/org/springframework/integration/file/config/FileInboundChannelAdapterWithQueueSizeTests-context.xml
index 62aa45c0e5..333cf41e1b 100644
--- a/spring-integration-file/src/test/java/org/springframework/integration/file/config/FileInboundChannelAdapterWithQueueSizeTests-context.xml
+++ b/spring-integration-file/src/test/java/org/springframework/integration/file/config/FileInboundChannelAdapterWithQueueSizeTests-context.xml
@@ -35,8 +35,9 @@
+
-
+
@@ -47,4 +48,4 @@
-
\ No newline at end of file
+
diff --git a/spring-integration-file/src/test/java/org/springframework/integration/file/config/FileListFilterFactoryBeanTests.java b/spring-integration-file/src/test/java/org/springframework/integration/file/config/FileListFilterFactoryBeanTests.java
index be9424c178..23ed447554 100644
--- a/spring-integration-file/src/test/java/org/springframework/integration/file/config/FileListFilterFactoryBeanTests.java
+++ b/spring-integration-file/src/test/java/org/springframework/integration/file/config/FileListFilterFactoryBeanTests.java
@@ -18,7 +18,8 @@ package org.springframework.integration.file.config;
import org.junit.Test;
import org.springframework.beans.DirectFieldAccessor;
-import org.springframework.integration.file.*;
+import org.springframework.integration.file.entries.*;
+import org.springframework.integration.file.filters.*;
import java.io.File;
import java.util.Collection;
@@ -45,7 +46,7 @@ public class FileListFilterFactoryBeanTests {
FileListFilterFactoryBean factory = new FileListFilterFactoryBean();
TestFilter testFilter = new TestFilter();
factory.setFilterReference(testFilter);
- FileListFilter result = factory.getObject();
+ EntryListFilter result = factory.getObject();
assertFalse(result instanceof CompositeFileListFilter);
assertSame(testFilter, result);
}
@@ -57,10 +58,10 @@ public class FileListFilterFactoryBeanTests {
TestFilter testFilter = new TestFilter();
factory.setFilterReference(testFilter);
factory.setPreventDuplicates(Boolean.TRUE);
- FileListFilter result = factory.getObject();
- assertTrue(result instanceof CompositeFileListFilter);
+ EntryListFilter result = factory.getObject();
+ assertTrue(result instanceof CompositeEntryListFilter);
Collection filters = (Collection) new DirectFieldAccessor(result).getPropertyValue("fileFilters");
- assertTrue(filters.iterator().next() instanceof AcceptOnceFileListFilter);
+ assertTrue(filters.iterator().next() instanceof AcceptOnceEntryFileListFilter);
assertTrue(filters.contains(testFilter));
}
@@ -70,8 +71,8 @@ public class FileListFilterFactoryBeanTests {
TestFilter testFilter = new TestFilter();
factory.setFilterReference(testFilter);
factory.setPreventDuplicates(Boolean.FALSE);
- FileListFilter result = factory.getObject();
- assertFalse(result instanceof CompositeFileListFilter);
+ EntryListFilter result = factory.getObject();
+ assertFalse(result instanceof CompositeEntryListFilter);
assertSame(testFilter, result);
}
@@ -80,12 +81,12 @@ public class FileListFilterFactoryBeanTests {
public void filenamePatternAndPreventDuplicatesNull() throws Exception {
FileListFilterFactoryBean factory = new FileListFilterFactoryBean();
factory.setFilenamePattern(Pattern.compile("foo"));
- FileListFilter result = factory.getObject();
- assertTrue(result instanceof CompositeFileListFilter);
+ EntryListFilter result = factory.getObject();
+ assertTrue(result instanceof CompositeEntryListFilter);
Collection filters = (Collection) new DirectFieldAccessor(result).getPropertyValue("fileFilters");
- Iterator iterator = filters.iterator();
- assertTrue(iterator.next() instanceof AcceptOnceFileListFilter);
- assertTrue(iterator.next() instanceof PatternMatchingFileListFilter);
+ Iterator iterator = filters.iterator();
+ assertTrue(iterator.next() instanceof AcceptOnceEntryFileListFilter);
+ assertTrue(iterator.next() instanceof PatternMatchingEntryListFilter);
}
@Test
@@ -94,12 +95,12 @@ public class FileListFilterFactoryBeanTests {
FileListFilterFactoryBean factory = new FileListFilterFactoryBean();
factory.setFilenamePattern(Pattern.compile("foo"));
factory.setPreventDuplicates(Boolean.TRUE);
- FileListFilter result = factory.getObject();
- assertTrue(result instanceof CompositeFileListFilter);
+ EntryListFilter result = factory.getObject();
+ assertTrue(result instanceof CompositeEntryListFilter);
Collection filters = (Collection) new DirectFieldAccessor(result).getPropertyValue("fileFilters");
- Iterator iterator = filters.iterator();
- assertTrue(iterator.next() instanceof AcceptOnceFileListFilter);
- assertTrue(iterator.next() instanceof PatternMatchingFileListFilter);
+ Iterator iterator = filters.iterator();
+ assertTrue(iterator.next() instanceof AcceptOnceEntryFileListFilter);
+ assertTrue(iterator.next() instanceof PatternMatchingEntryListFilter);
}
@Test
@@ -107,18 +108,18 @@ public class FileListFilterFactoryBeanTests {
FileListFilterFactoryBean factory = new FileListFilterFactoryBean();
factory.setFilenamePattern(Pattern.compile("foo"));
factory.setPreventDuplicates(Boolean.FALSE);
- FileListFilter result = factory.getObject();
- assertFalse(result instanceof CompositeFileListFilter);
- assertTrue(result instanceof PatternMatchingFileListFilter);
+ EntryListFilter result = factory.getObject();
+ assertFalse(result instanceof CompositeEntryListFilter);;
+// CompositeEntryListFilter
+ assertTrue(result instanceof PatternMatchingEntryListFilter ) ;
}
- private static class TestFilter extends AbstractFileListFilter {
-
- @Override
- protected boolean accept(File file) {
- return true;
- }
- }
+ private static class TestFilter extends AbstractEntryListFilter {
+ @Override
+ public boolean accept(File file) {
+ return true;
+ }
+ }
}
diff --git a/spring-integration-file/src/test/java/org/springframework/integration/file/invalidPatternMatchingFileListFilterTests.xml b/spring-integration-file/src/test/java/org/springframework/integration/file/invalidPatternMatchingFileListFilterTests.xml
index 3401588dcd..b1499bf518 100644
--- a/spring-integration-file/src/test/java/org/springframework/integration/file/invalidPatternMatchingFileListFilterTests.xml
+++ b/spring-integration-file/src/test/java/org/springframework/integration/file/invalidPatternMatchingFileListFilterTests.xml
@@ -4,7 +4,7 @@
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
-
+
diff --git a/spring-integration-file/src/test/java/org/springframework/integration/file/locking/FileLockingNamespaceTests.java b/spring-integration-file/src/test/java/org/springframework/integration/file/locking/FileLockingNamespaceTests.java
index 28f74dd6bd..5d43e31b22 100644
--- a/spring-integration-file/src/test/java/org/springframework/integration/file/locking/FileLockingNamespaceTests.java
+++ b/spring-integration-file/src/test/java/org/springframework/integration/file/locking/FileLockingNamespaceTests.java
@@ -22,7 +22,8 @@ import org.springframework.beans.DirectFieldAccessor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.integration.endpoint.SourcePollingChannelAdapter;
-import org.springframework.integration.file.CompositeFileListFilter;
+import org.springframework.integration.file.entries.CompositeEntryListFilter;
+import org.springframework.integration.file.filters.CompositeFileListFilter;
import org.springframework.integration.file.FileReadingMessageSource;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@@ -64,7 +65,7 @@ public class FileLockingNamespaceTests {
@Test
public void shouldSetCustomLockerProperly() {
assertThat(extractFromScanner("locker", customLockingSource), is(StubLocker.class));
- assertThat(extractFromScanner("filter", customLockingSource), is(CompositeFileListFilter.class));
+ assertThat(extractFromScanner("filter", customLockingSource), is(CompositeEntryListFilter.class));
}
private Object extractFromScanner(String propertyName, FileReadingMessageSource source) {
@@ -74,7 +75,7 @@ public class FileLockingNamespaceTests {
@Test
public void shouldSetNioLockerProperly() {
assertThat(extractFromScanner("locker", nioLockingSource), is(NioFileLocker.class));
- assertThat(extractFromScanner("filter", nioLockingSource), is(CompositeFileListFilter.class));
+ assertThat(extractFromScanner("filter", nioLockingSource), is(CompositeEntryListFilter.class));
}
public static class StubLocker extends AbstractFileLockerFilter {
diff --git a/spring-integration-file/src/test/java/org/springframework/integration/file/locking/NioFileLockerTests.java b/spring-integration-file/src/test/java/org/springframework/integration/file/locking/NioFileLockerTests.java
index 46b427da68..1e38e3ff9b 100644
--- a/spring-integration-file/src/test/java/org/springframework/integration/file/locking/NioFileLockerTests.java
+++ b/spring-integration-file/src/test/java/org/springframework/integration/file/locking/NioFileLockerTests.java
@@ -18,7 +18,7 @@ package org.springframework.integration.file.locking;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
-import org.springframework.integration.file.FileListFilter;
+import org.springframework.integration.file.entries.EntryListFilter;
import java.io.File;
import java.io.IOException;
@@ -49,20 +49,20 @@ public class NioFileLockerTests {
NioFileLocker filter = new NioFileLocker();
File testFile = new File(workdir, "test0");
testFile.createNewFile();
- assertThat(filter.filterFiles(workdir.listFiles()).get(0), is(testFile));
+ assertThat(filter.filterEntries(workdir.listFiles()).get(0), is(testFile));
filter.lock(testFile);
- assertThat(filter.filterFiles(workdir.listFiles()).get(0), is(testFile));
+ assertThat(filter.filterEntries(workdir.listFiles()).get(0), is(testFile));
}
@Test
public void fileNotListedWhenLockedByOtherFilter() throws IOException {
NioFileLocker filter1 = new NioFileLocker();
- FileListFilter filter2 = new NioFileLocker();
+ EntryListFilter filter2 = new NioFileLocker();
File testFile = new File(workdir, "test1");
testFile.createNewFile();
- assertThat(filter1.filterFiles(workdir.listFiles()).get(0), is(testFile));
+ assertThat(filter1.filterEntries(workdir.listFiles()).get(0), is(testFile));
filter1.lock(testFile);
- assertThat(filter2.filterFiles(workdir.listFiles()), is((List)new ArrayList()));
+ assertThat(filter2.filterEntries(workdir.listFiles()), is((List)new ArrayList()));
}
-}
\ No newline at end of file
+}
diff --git a/spring-integration-file/src/test/java/org/springframework/integration/file/patternMatchingFileListFilterTests.xml b/spring-integration-file/src/test/java/org/springframework/integration/file/patternMatchingFileListFilterTests.xml
index ddd5f8f965..bc8239e3c2 100644
--- a/spring-integration-file/src/test/java/org/springframework/integration/file/patternMatchingFileListFilterTests.xml
+++ b/spring-integration-file/src/test/java/org/springframework/integration/file/patternMatchingFileListFilterTests.xml
@@ -4,7 +4,7 @@
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
-
+
diff --git a/spring-integration-file/template.mf b/spring-integration-file/template.mf
index 8a4ea705bb..cc7dd1ef9b 100644
--- a/spring-integration-file/template.mf
+++ b/spring-integration-file/template.mf
@@ -10,4 +10,6 @@ Import-Template:
org.springframework.core.*;version="[3.0.0, 4.0.0)",
org.springframework.util;version="[3.0.0, 4.0.0)",
org.springframework.util.xml;version="[3.0.0, 4.0.0)",
+ org.springframework.scheduling.*;version="[3.0.0, 4.0.0)",
+ org.springframework.transaction.*;version="[3.0.0, 4.0.0)",
org.w3c.dom.*;version="0"
diff --git a/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/AbstractFtpFileListFilter.java b/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/AbstractFtpFileListFilter.java
deleted file mode 100644
index 7eb08590c5..0000000000
--- a/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/AbstractFtpFileListFilter.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package org.springframework.integration.ftp;
-
-import org.apache.commons.net.ftp.FTPFile;
-
-import java.util.ArrayList;
-import java.util.List;
-
-
-/**
- * Convenience implementation patterned off {@link org.springframework.integration.file.FileListFilter}
- *
- * @author Josh Long
- */
-public abstract class AbstractFtpFileListFilter implements FtpFileListFilter {
- /**
- * {@inheritDoc}
- */
- abstract public boolean accept(FTPFile ftpFile);
-
- public List filterFiles(FTPFile[] files) {
- List accepted = new ArrayList();
-
- if (files != null) {
- for (FTPFile f : files) {
- if (this.accept(f)) {
- accepted.add(f);
- }
- }
- }
-
- return accepted;
- }
-}
diff --git a/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/CompositeFtpFileListFilter.java b/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/CompositeFtpFileListFilter.java
deleted file mode 100644
index acb844fdc7..0000000000
--- a/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/CompositeFtpFileListFilter.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package org.springframework.integration.ftp;
-
-import org.apache.commons.net.ftp.FTPFile;
-import org.springframework.util.Assert;
-
-import java.util.*;
-
-
-/**
- * Patterned very much on the {@link org.springframework.integration.file.CompositeFileListFilter}
- *
- * @author Josh Long
- */
-public class CompositeFtpFileListFilter implements FtpFileListFilter {
- private Set filters;
-
- public CompositeFtpFileListFilter(FtpFileListFilter... ftpFileListFilter) {
- this.filters = new LinkedHashSet(Arrays.asList(ftpFileListFilter));
- }
-
- public CompositeFtpFileListFilter(Collection ftpFileListFilter) {
- this.filters = new LinkedHashSet(ftpFileListFilter);
- }
- public void addFilter( FtpFileListFilter ftpFileListFilter ) {
- this.filters.add(ftpFileListFilter);
- }
- public List filterFiles(FTPFile[] files) {
- Assert.notNull(files, "files[] can't be null!");
-
- List leftOver = Arrays.asList(files);
-
- for (FtpFileListFilter ff : this.filters)
- leftOver = ff.filterFiles(leftOver.toArray(new FTPFile[leftOver.size()]));
-
- return leftOver;
- }
-}
diff --git a/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/FtpFileEntryNamer.java b/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/FtpFileEntryNamer.java
new file mode 100644
index 0000000000..e511efac4d
--- /dev/null
+++ b/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/FtpFileEntryNamer.java
@@ -0,0 +1,17 @@
+package org.springframework.integration.ftp;
+
+import org.apache.commons.net.ftp.FTPFile;
+
+import org.springframework.integration.file.entries.EntryNamer;
+
+
+/**
+ * A {@link org.springframework.integration.file.entries.EntryNamer} for {@link org.apache.commons.net.ftp.FTPFile} objects
+ *
+ * @author Josh Long
+ */
+public class FtpFileEntryNamer implements EntryNamer {
+ public String nameOf(FTPFile entry) {
+ return entry.getName();
+ }
+}
diff --git a/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/FtpFileListFilter.java b/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/FtpFileListFilter.java
deleted file mode 100644
index bb92725a99..0000000000
--- a/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/FtpFileListFilter.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package org.springframework.integration.ftp;
-
-import org.apache.commons.net.ftp.FTPFile;
-
-import java.util.List;
-
-/**
- * Filters out all the FTPFiles taken in a scan of the remote mount o
- *
- * @author Josh Long
- */
-public interface FtpFileListFilter {
- List filterFiles (FTPFile [] files);
-}
diff --git a/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/FtpFileSource.java b/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/FtpFileSource.java
index 44cb3cb13b..da4b44e693 100644
--- a/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/FtpFileSource.java
+++ b/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/FtpFileSource.java
@@ -20,10 +20,8 @@ import org.springframework.context.Lifecycle;
import org.springframework.core.io.Resource;
import org.springframework.integration.Message;
import org.springframework.integration.core.MessageSource;
-import org.springframework.integration.file.AcceptOnceFileListFilter;
-import org.springframework.integration.file.CompositeFileListFilter;
import org.springframework.integration.file.FileReadingMessageSource;
-import org.springframework.integration.file.PatternMatchingFileListFilter;
+import org.springframework.integration.file.entries.*;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.Trigger;
@@ -37,10 +35,11 @@ import java.util.regex.Pattern;
*
* @author Iwein Fuld
*/
+@Deprecated
public class FtpFileSource implements MessageSource, InitializingBean, Lifecycle {
private FileReadingMessageSource fileSource;
private FtpInboundSynchronizer synchronizer;
-
+ private EntryNamer fileEntryName = new FileEntryNamer();
public FtpFileSource() {
this(new FileReadingMessageSource(), new FtpInboundSynchronizer());
}
@@ -48,9 +47,12 @@ public class FtpFileSource implements MessageSource, InitializingBean, Lif
public FtpFileSource(FileReadingMessageSource fileSource, FtpInboundSynchronizer synchronizer) {
this.fileSource = fileSource;
this.synchronizer = synchronizer;
-
Pattern completePattern = Pattern.compile("^.*(? f =new CompositeEntryListFilter(new AcceptOnceEntryFileListFilter(),
+ new PatternMatchingEntryListFilter(fileEntryName,completePattern));
+
+ fileSource.setFilter(f);
}
public void setFileSource(FileReadingMessageSource fileSource) {
@@ -63,10 +65,10 @@ public class FtpFileSource implements MessageSource, InitializingBean, Lif
public void setLocalWorkingDirectory(Resource localWorkingDirectory) {
this.synchronizer.setLocalDirectory(localWorkingDirectory);
-
try {
this.fileSource.setDirectory(localWorkingDirectory.getFile());
} catch (IOException e) {
+ // oops
}
}
diff --git a/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/FtpMessageSourceFactoryBean.java b/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/FtpFileSourceFactoryBean.java
similarity index 85%
rename from spring-integration-ftp/src/main/java/org/springframework/integration/ftp/FtpMessageSourceFactoryBean.java
rename to spring-integration-ftp/src/main/java/org/springframework/integration/ftp/FtpFileSourceFactoryBean.java
index c13ace9d46..cb6200c741 100644
--- a/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/FtpMessageSourceFactoryBean.java
+++ b/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/FtpFileSourceFactoryBean.java
@@ -2,6 +2,7 @@ package org.springframework.integration.ftp;
import org.apache.commons.lang.SystemUtils;
import org.apache.commons.net.ftp.FTPClient;
+import org.apache.commons.net.ftp.FTPFile;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.AbstractFactoryBean;
import org.springframework.context.ApplicationContext;
@@ -11,6 +12,9 @@ import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceEditor;
import org.springframework.core.io.ResourceLoader;
import org.springframework.integration.file.FileReadingMessageSource;
+import org.springframework.integration.file.entries.CompositeEntryListFilter;
+import org.springframework.integration.file.entries.EntryListFilter;
+import org.springframework.integration.file.entries.PatternMatchingEntryListFilter;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.util.Assert;
@@ -19,15 +23,15 @@ import org.springframework.util.StringUtils;
import java.io.File;
import java.util.Map;
-import java.util.regex.Pattern;
/**
- * Makes it easier to assemble the moving pieces involved in standing up an {@link FtpMessageSourceFactoryBean}
+ * Makes it easier to assemble the moving pieces involved in standing up an {@link org.springframework.integration.ftp.FtpFileSource}
*
* @author Josh Long
*/
-public class FtpMessageSourceFactoryBean extends AbstractFactoryBean implements ResourceLoaderAware, ApplicationContextAware {
+@Deprecated
+public class FtpFileSourceFactoryBean extends AbstractFactoryBean implements ResourceLoaderAware, ApplicationContextAware {
private int port;
private boolean autoCreateDirectories;
private String filenamePattern;
@@ -47,7 +51,7 @@ public class FtpMessageSourceFactoryBean extends AbstractFactoryBean filter;
public void setFilenamePattern(String filenamePattern) {
this.filenamePattern = filenamePattern;
@@ -98,10 +102,11 @@ public class FtpMessageSourceFactoryBean extends AbstractFactoryBean filter) {
this.filter = filter;
}
+ private FtpFileEntryNamer ftpFileEntryNamer =new FtpFileEntryNamer();
@Override
protected FtpFileSource createInstance() throws Exception {
// setup local dir
@@ -120,17 +125,15 @@ public class FtpMessageSourceFactoryBean extends AbstractFactoryBean compositeFtpFileListFilter = new CompositeEntryListFilter() ;
+ if( StringUtils.hasText( this.filenamePattern)){
+ PatternMatchingEntryListFilter ftpFilePatternMatchingEntryListFilter = new PatternMatchingEntryListFilter(ftpFileEntryNamer,filenamePattern) ;
+ compositeFtpFileListFilter.addFilter( ftpFilePatternMatchingEntryListFilter);
- if (StringUtils.hasText(this.filenamePattern)) {
- PatternMatchingFtpFileListFilter patternMatchingFTPFileListFilter = new PatternMatchingFtpFileListFilter();
- patternMatchingFTPFileListFilter.setPattern(Pattern.compile(this.filenamePattern));
- compositeFtpFileListFilter.addFilter(patternMatchingFTPFileListFilter);
}
+ if(this.filter != null)
+ compositeFtpFileListFilter.addFilter( this.filter);
- if (this.filter != null) {
- compositeFtpFileListFilter.addFilter(this.filter);
- }
this.ftpInboundSynchronizer.setFilter(compositeFtpFileListFilter);
diff --git a/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/FtpInboundSynchronizer.java b/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/FtpInboundSynchronizer.java
index 36c33731d2..86abdead21 100644
--- a/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/FtpInboundSynchronizer.java
+++ b/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/FtpInboundSynchronizer.java
@@ -23,6 +23,8 @@ import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.Lifecycle;
import org.springframework.core.io.Resource;
import org.springframework.integration.MessagingException;
+import org.springframework.integration.file.entries.AcceptAllEntryListFilter;
+import org.springframework.integration.file.entries.EntryListFilter;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.Trigger;
import org.springframework.scheduling.support.PeriodicTrigger;
@@ -44,6 +46,7 @@ import java.util.concurrent.ScheduledFuture;
*
* @author Iwein Fuld
*/
+@Deprecated
public class FtpInboundSynchronizer implements InitializingBean, Lifecycle {
private static final Log logger = LogFactory.getLog(FtpInboundSynchronizer.class);
static final String INCOMPLETE_EXTENSION = ".INCOMPLETE";
@@ -54,14 +57,10 @@ public class FtpInboundSynchronizer implements InitializingBean, Lifecycle {
private volatile Resource localDirectory;
private boolean running = false;
private ScheduledFuture> scheduledFuture;
- private FtpFileListFilter filter;
- private FtpFileListFilter acceptAllFtpFileListFilter = new FtpFileListFilter() {
- public List filterFiles(FTPFile[] files) {
- return Arrays.asList(files);
- }
- };
+ private EntryListFilter filter;
+ private EntryListFilter acceptAllFtpFileListFilter = new AcceptAllEntryListFilter();
- public void setFilter(FtpFileListFilter filter) {
+ public void setFilter(EntryListFilter filter) {
this.filter = filter;
}
@@ -94,7 +93,7 @@ public class FtpInboundSynchronizer implements InitializingBean, Lifecycle {
FTPClient client = this.clientPool.getClient();
Assert.state(client != null, FtpClientPool.class.getSimpleName() + " returned 'null' client this most likely a bug in the pool implementation.");
- Collection fileList = this.filter.filterFiles(client.listFiles());
+ Collection fileList = this.filter.filterEntries(client.listFiles());
try {
for (FTPFile ftpFile : fileList) {
diff --git a/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/PatternMatchingFtpFileListFilter.java b/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/PatternMatchingFtpFileListFilter.java
deleted file mode 100644
index feab1f1d0f..0000000000
--- a/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/PatternMatchingFtpFileListFilter.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package org.springframework.integration.ftp;
-
-import org.apache.commons.lang.builder.ToStringBuilder;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.commons.net.ftp.FTPFile;
-import org.springframework.beans.factory.InitializingBean;
-import org.springframework.util.Assert;
-import org.springframework.util.StringUtils;
-
-import java.util.regex.Pattern;
-
-
-/**
- * Validates {@link org.apache.commons.net.ftp.FTPFile}s against a {@link java.util.regex.Pattern}.
- * Patterned very much like {@link org.springframework.integration.file.PatternMatchingFileListFilter}.
- *
- * @author Josh Long
- */
-public class PatternMatchingFtpFileListFilter extends AbstractFtpFileListFilter implements InitializingBean {
-
- private Log logger = LogFactory.getLog(getClass());
-
- private Pattern pattern;
- private String patternExpression;
-
- public void setPattern(Pattern pattern) {
- this.pattern = pattern;
- }
-
- public void setPatternExpression(String patternExpression) {
- this.patternExpression = patternExpression;
- }
-
- @Override
- public boolean accept(FTPFile ftpFile) {
- if (logger.isDebugEnabled()) {
- logger.debug("testing: " + ToStringBuilder.reflectionToString(ftpFile));
- }
-
- return (ftpFile != null) && this.pattern.matcher(ftpFile.getName()).matches();
- }
-
- public void afterPropertiesSet() throws Exception {
- if (StringUtils.hasText(this.patternExpression) && (this.pattern == null)) {
- this.pattern = Pattern.compile(this.patternExpression);
- }
-
- Assert.notNull(this.pattern, "the pattern must not be null");
- }
-}
diff --git a/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/config/FtpNamespaceHandler.java b/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/config/FtpNamespaceHandler.java
index d72823110a..9ca93523b0 100644
--- a/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/config/FtpNamespaceHandler.java
+++ b/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/config/FtpNamespaceHandler.java
@@ -23,6 +23,8 @@ import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.config.xml.AbstractOutboundChannelAdapterParser;
import org.springframework.integration.config.xml.AbstractPollingInboundChannelAdapterParser;
import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
+import org.springframework.integration.ftp.FtpSendingMessageHandlerFactoryBean;
+import org.springframework.integration.ftp.impl.FtpRemoteFileSystemSynchronizingMessageSourceFactoryBean;
import org.w3c.dom.Element;
import java.util.HashMap;
@@ -57,7 +59,7 @@ public class FtpNamespaceHandler extends NamespaceHandlerSupport {
private static class FTPMessageSendingConsumerBeanDefinitionParser extends AbstractOutboundChannelAdapterParser {
@Override
protected AbstractBeanDefinition parseConsumer(Element element, ParserContext parserContext) {
- BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(PACKAGE_NAME + ".FtpSendingMessageHandlerFactoryBean");
+ BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(FtpSendingMessageHandlerFactoryBean.class.getName());
for (String p : "auto-create-directories,username,port,password,host,key-file,key-file-password,remote-directory".split(",")) {
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, p);
@@ -79,17 +81,20 @@ public class FtpNamespaceHandler extends NamespaceHandlerSupport {
@Override
@SuppressWarnings("unused")
protected String parseSource(Element element, ParserContext parserContext) {
- BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(PACKAGE_NAME + ".FtpMessageSourceFactoryBean");
- // reference
+ BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(
+ FtpRemoteFileSystemSynchronizingMessageSourceFactoryBean.class.getName());
+
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element,"filter");
- for (String p : ("filename-pattern,auto-create-directories,username,password,host,port," + "remote-directory,local-working-directory").split(",")) {
+ for (String p : ("auto-delete-remote-files-on-sync,filename-pattern,auto-create-directories,username,password,host,port," +
+ "remote-directory,local-working-directory").split(",")) {
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, p);
}
int clientMode = CLIENT_MODES.get(element.getAttribute("client-mode"));
builder.addPropertyValue("clientMode", clientMode);
+
return BeanDefinitionReaderUtils.registerWithGeneratedName(builder.getBeanDefinition(), parserContext.getRegistry());
}
}
diff --git a/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/impl/FtpInboundRemoteFileSystemSynchronizer.java b/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/impl/FtpInboundRemoteFileSystemSynchronizer.java
new file mode 100644
index 0000000000..301d2fa0ac
--- /dev/null
+++ b/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/impl/FtpInboundRemoteFileSystemSynchronizer.java
@@ -0,0 +1,126 @@
+package org.springframework.integration.ftp.impl;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.commons.net.ftp.FTPClient;
+import org.apache.commons.net.ftp.FTPFile;
+
+import org.springframework.core.io.Resource;
+
+import org.springframework.integration.MessagingException;
+import org.springframework.integration.file.AbstractInboundRemoteFileSystemSychronizer;
+import org.springframework.integration.file.AbstractInboundRemoteFileSystemSynchronizingMessageSource;
+import org.springframework.integration.ftp.FtpClientPool;
+
+import org.springframework.scheduling.Trigger;
+import org.springframework.scheduling.support.PeriodicTrigger;
+
+import org.springframework.util.Assert;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import java.util.Collection;
+import java.util.logging.Logger;
+
+
+/**
+ * An FTP-adapter implementation of {@link org.springframework.integration.file.AbstractInboundRemoteFileSystemSychronizer}
+ *
+ * @author Josh Long
+ */
+public class FtpInboundRemoteFileSystemSynchronizer extends AbstractInboundRemoteFileSystemSychronizer {
+ protected FtpClientPool clientPool;
+
+ @Override
+ protected void onInit() throws Exception {
+ Assert.notNull(this.clientPool, "clientPool can't be null");
+
+ if (this.shouldDeleteSourceFile) {
+ this.entryAcknowledgmentStrategy = new DeletionEntryAcknowledgmentStrategy();
+ }
+ }
+
+ /**
+ * The {@link org.springframework.integration.ftp.FtpClientPool} that holds references to {@link org.apache.commons.net.ftp.FTPClient} instances
+ *
+ * @param clientPool the {@link org.springframework.integration.ftp.FtpClientPool}
+ */
+ public void setClientPool(FtpClientPool clientPool) {
+ this.clientPool = clientPool;
+ }
+
+ protected boolean copyFileToLocalDirectory(FTPClient client, FTPFile ftpFile, Resource localDirectory)
+ throws IOException, FileNotFoundException {
+ String remoteFileName = ftpFile.getName();
+ String localFileName = localDirectory.getFile().getPath() + "/" + remoteFileName;
+ File localFile = new File(localFileName);
+
+ if (!localFile.exists()) {
+ String tempFileName = localFileName + AbstractInboundRemoteFileSystemSynchronizingMessageSource.INCOMPLETE_EXTENSION;
+ File file = new File(tempFileName);
+ FileOutputStream fos = new FileOutputStream(file);
+
+ try {
+ client.retrieveFile(remoteFileName, fos);
+
+ // Perhaps we have some dispatch of hte source file to do?
+ acknowledge(client, ftpFile);
+ } catch (Throwable th) {
+ throw new RuntimeException(th);
+ } finally {
+ fos.close();
+ }
+
+ file.renameTo(localFile);
+
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ protected void syncRemoteToLocalFileSystem() {
+ try {
+ FTPClient client = this.clientPool.getClient();
+ Assert.state(client != null, FtpClientPool.class.getSimpleName() + " returned a 'null' client. " + "This most likely a bug in the pool implementation.");
+
+ Collection fileList = this.filter.filterEntries(client.listFiles());
+
+ try {
+ for (FTPFile ftpFile : fileList) {
+ if ((ftpFile != null) && ftpFile.isFile()) {
+ copyFileToLocalDirectory(client, ftpFile, this.localDirectory);
+ }
+ }
+ } finally {
+ this.clientPool.releaseClient(client);
+ }
+ } catch (IOException e) {
+ throw new MessagingException("Problem occurred while synchronizing remote to local directory", e);
+ }
+ }
+
+ @Override
+ protected Trigger getTrigger() {
+ return new PeriodicTrigger(10 * 1000);
+ }
+
+ /**
+ * An ackowledgment strategy that deletes
+ */
+ class DeletionEntryAcknowledgmentStrategy implements AbstractInboundRemoteFileSystemSychronizer.EntryAcknowledgmentStrategy {
+ public void acknowledge(Object useful, FTPFile msg)
+ throws Exception {
+ FTPClient ftpClient = (FTPClient) useful;
+ if ((msg != null) && ftpClient.deleteFile(msg.getName())) {
+ if (logger.isDebugEnabled()) {
+ logger.debug("deleted " + msg.getName());
+ }
+ }
+ }
+ }
+}
diff --git a/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/impl/FtpInboundRemoteFileSystemSynchronizingMessageSource.java b/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/impl/FtpInboundRemoteFileSystemSynchronizingMessageSource.java
new file mode 100644
index 0000000000..42505532e8
--- /dev/null
+++ b/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/impl/FtpInboundRemoteFileSystemSynchronizingMessageSource.java
@@ -0,0 +1,38 @@
+package org.springframework.integration.ftp.impl;
+
+import org.apache.commons.net.ftp.FTPFile;
+
+import org.springframework.integration.file.AbstractInboundRemoteFileSystemSynchronizingMessageSource;
+import org.springframework.integration.ftp.FtpClientPool;
+
+
+/**
+ * a {@link org.springframework.integration.core.MessageSource} implementation for FTP
+ *
+ * @author Josh Long
+ */
+public class FtpInboundRemoteFileSystemSynchronizingMessageSource extends AbstractInboundRemoteFileSystemSynchronizingMessageSource {
+ private volatile FtpClientPool clientPool;
+
+ public void setClientPool(FtpClientPool clientPool) {
+ this.clientPool = clientPool;
+ }
+
+ @Override
+ protected void doStart() {
+ this.synchronizer.start();
+ }
+
+ @Override
+ protected void doStop() {
+ this.synchronizer.stop();
+ }
+
+ @Override
+ protected void onInit() throws Exception {
+ super.onInit();
+ this.synchronizer.setClientPool(this.clientPool);
+
+
+ }
+}
diff --git a/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/impl/FtpRemoteFileSystemSynchronizingMessageSourceFactoryBean.java b/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/impl/FtpRemoteFileSystemSynchronizingMessageSourceFactoryBean.java
new file mode 100644
index 0000000000..3dba5340ca
--- /dev/null
+++ b/spring-integration-ftp/src/main/java/org/springframework/integration/ftp/impl/FtpRemoteFileSystemSynchronizingMessageSourceFactoryBean.java
@@ -0,0 +1,170 @@
+package org.springframework.integration.ftp.impl;
+
+import org.apache.commons.lang.SystemUtils;
+import org.apache.commons.net.ftp.FTPClient;
+import org.apache.commons.net.ftp.FTPFile;
+
+import org.springframework.beans.factory.config.AbstractFactoryBean;
+
+import org.springframework.context.ResourceLoaderAware;
+
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.ResourceEditor;
+import org.springframework.core.io.ResourceLoader;
+
+import org.springframework.integration.file.AbstractInboundRemoteFileSystemSychronizer;
+import org.springframework.integration.file.entries.CompositeEntryListFilter;
+import org.springframework.integration.file.entries.EntryListFilter;
+import org.springframework.integration.file.entries.PatternMatchingEntryListFilter;
+import org.springframework.integration.ftp.DefaultFtpClientFactory;
+import org.springframework.integration.ftp.FtpFileEntryNamer;
+import org.springframework.integration.ftp.QueuedFtpClientPool;
+
+import org.springframework.util.StringUtils;
+
+import java.io.File;
+
+
+/**
+ * Factory to make building the namespace easier
+ *
+ * @author Josh Long
+ */
+public class FtpRemoteFileSystemSynchronizingMessageSourceFactoryBean extends AbstractFactoryBean implements ResourceLoaderAware {
+ private volatile String port;
+ private volatile String autoCreateDirectories;
+ private volatile String filenamePattern;
+ private volatile String username;
+ private volatile String password;
+ private volatile String host;
+ private volatile String remoteDirectory;
+ private volatile String localWorkingDirectory;
+ private volatile ResourceLoader resourceLoader;
+ private volatile Resource localDirectoryResource;
+ private volatile EntryListFilter filter;
+ private volatile int clientMode = FTPClient.ACTIVE_LOCAL_DATA_CONNECTION_MODE;
+ private volatile String autoDeleteRemoteFilesOnSync;
+
+ public void setAutoDeleteRemoteFilesOnSync(String autoDeleteRemoteFilesOnSync) {
+ this.autoDeleteRemoteFilesOnSync = autoDeleteRemoteFilesOnSync;
+ }
+
+ @Override
+ public Class> getObjectType() {
+ return FtpInboundRemoteFileSystemSynchronizingMessageSource.class;
+ }
+
+ private Resource fromText(String path) {
+ ResourceEditor resourceEditor = new ResourceEditor(this.resourceLoader);
+ resourceEditor.setAsText(path);
+ return (Resource) resourceEditor.getValue();
+ }
+
+ private DefaultFtpClientFactory defaultFtpClientFactory() {
+ DefaultFtpClientFactory defaultFtpClientFactory = new DefaultFtpClientFactory();
+ defaultFtpClientFactory.setHost(this.host);
+ defaultFtpClientFactory.setPassword(this.password);
+ defaultFtpClientFactory.setPort(Integer.parseInt(this.port));
+ defaultFtpClientFactory.setRemoteWorkingDirectory(this.remoteDirectory);
+ defaultFtpClientFactory.setUsername(this.username);
+ defaultFtpClientFactory.setClientMode(this.clientMode);
+
+ return defaultFtpClientFactory;
+ }
+
+ @Override
+ protected FtpInboundRemoteFileSystemSynchronizingMessageSource createInstance()
+ throws Exception {
+ boolean autoCreatDirs = Boolean.parseBoolean(this.autoCreateDirectories);
+ boolean ackRemoteDir = Boolean.parseBoolean(this.autoDeleteRemoteFilesOnSync);
+
+ FtpInboundRemoteFileSystemSynchronizingMessageSource ftpRemoteFileSystemSynchronizingMessageSource = new FtpInboundRemoteFileSystemSynchronizingMessageSource();
+ ftpRemoteFileSystemSynchronizingMessageSource.setAutoCreateDirectories(autoCreatDirs);
+
+ if (!StringUtils.hasText(this.localWorkingDirectory)) {
+ File tmp = new File(SystemUtils.getJavaIoTmpDir(), "ftpInbound");
+ this.localWorkingDirectory = "file://" + tmp.getAbsolutePath();
+ }
+
+ this.localDirectoryResource = this.fromText(this.localWorkingDirectory);
+
+ FtpFileEntryNamer ftpFileEntryNamer = new FtpFileEntryNamer();
+ CompositeEntryListFilter compositeFtpFileListFilter = new CompositeEntryListFilter();
+
+ if (StringUtils.hasText(this.filenamePattern)) {
+ PatternMatchingEntryListFilter ftpFilePatternMatchingEntryListFilter = new PatternMatchingEntryListFilter(ftpFileEntryNamer, filenamePattern);
+ compositeFtpFileListFilter.addFilter(ftpFilePatternMatchingEntryListFilter);
+ }
+
+ if (this.filter != null) {
+ compositeFtpFileListFilter.addFilter(this.filter);
+ }
+
+ QueuedFtpClientPool queuedFtpClientPool = new QueuedFtpClientPool(15, defaultFtpClientFactory());
+
+ FtpInboundRemoteFileSystemSynchronizer ftpRemoteFileSystemSynchronizer = new FtpInboundRemoteFileSystemSynchronizer();
+ ftpRemoteFileSystemSynchronizer.setClientPool(queuedFtpClientPool);
+ ftpRemoteFileSystemSynchronizer.setLocalDirectory(this.localDirectoryResource);
+ ftpRemoteFileSystemSynchronizer.setShouldDeleteSourceFile(ackRemoteDir);
+
+ if (compositeFtpFileListFilter != null) {
+ ftpRemoteFileSystemSynchronizer.setFilter(compositeFtpFileListFilter);
+ ftpRemoteFileSystemSynchronizingMessageSource.setRemotePredicate(compositeFtpFileListFilter);
+ }
+
+ ftpRemoteFileSystemSynchronizingMessageSource.setSynchronizer(ftpRemoteFileSystemSynchronizer);
+ ftpRemoteFileSystemSynchronizingMessageSource.setClientPool(queuedFtpClientPool);
+
+ ftpRemoteFileSystemSynchronizingMessageSource.setLocalDirectory(this.localDirectoryResource);
+ ftpRemoteFileSystemSynchronizingMessageSource.setBeanFactory(this.getBeanFactory());
+ ftpRemoteFileSystemSynchronizingMessageSource.setAutoStartup(true);
+ ftpRemoteFileSystemSynchronizingMessageSource.afterPropertiesSet();
+ ftpRemoteFileSystemSynchronizingMessageSource.start();
+
+ return ftpRemoteFileSystemSynchronizingMessageSource;
+ }
+
+ public void setPort(String port) {
+ this.port = port;
+ }
+
+ public void setAutoCreateDirectories(String autoCreateDirectories) {
+ this.autoCreateDirectories = autoCreateDirectories;
+ }
+
+ public void setFilenamePattern(String filenamePattern) {
+ this.filenamePattern = filenamePattern;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public void setHost(String host) {
+ this.host = host;
+ }
+
+ public void setRemoteDirectory(String remoteDirectory) {
+ this.remoteDirectory = remoteDirectory;
+ }
+
+ public void setLocalWorkingDirectory(String localWorkingDirectory) {
+ this.localWorkingDirectory = localWorkingDirectory;
+ }
+
+ public void setFilter(EntryListFilter filter) {
+ this.filter = filter;
+ }
+
+ public void setClientMode(int clientMode) {
+ this.clientMode = clientMode;
+ }
+
+ public void setResourceLoader(ResourceLoader resourceLoader) {
+ this.resourceLoader = resourceLoader;
+ }
+}
diff --git a/spring-integration-ftp/src/main/resources/org/springframework/integration/ftp/config/spring-integration-ftp-2.0.xsd b/spring-integration-ftp/src/main/resources/org/springframework/integration/ftp/config/spring-integration-ftp-2.0.xsd
index cf4dbc9fb2..391b4d7522 100644
--- a/spring-integration-ftp/src/main/resources/org/springframework/integration/ftp/config/spring-integration-ftp-2.0.xsd
+++ b/spring-integration-ftp/src/main/resources/org/springframework/integration/ftp/config/spring-integration-ftp-2.0.xsd
@@ -138,7 +138,7 @@
-
+
diff --git a/spring-integration-ftp/src/test/java/org/springframework/integration/ftp/InboundFtpFileServiceActivator.java b/spring-integration-ftp/src/test/java/org/springframework/integration/ftp/InboundFtpFileServiceActivator.java
index 75ad88642e..48544076e1 100644
--- a/spring-integration-ftp/src/test/java/org/springframework/integration/ftp/InboundFtpFileServiceActivator.java
+++ b/spring-integration-ftp/src/test/java/org/springframework/integration/ftp/InboundFtpFileServiceActivator.java
@@ -29,5 +29,6 @@ public class InboundFtpFileServiceActivator {
public static void main(String[] args) throws Throwable {
ClassPathXmlApplicationContext classPathXmlApplicationContext =
new ClassPathXmlApplicationContext("inbound-ftp-context.xml");
+ classPathXmlApplicationContext.start();
}
}
diff --git a/spring-integration-ftp/src/test/resources/inbound-ftp-context.xml b/spring-integration-ftp/src/test/resources/inbound-ftp-context.xml
index 355348baaf..aa937e6a32 100644
--- a/spring-integration-ftp/src/test/resources/inbound-ftp-context.xml
+++ b/spring-integration-ftp/src/test/resources/inbound-ftp-context.xml
@@ -20,7 +20,7 @@
filename-pattern=".*?jpg"
>
-
+
diff --git a/spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/config/JdbcMessageHandlerParser.java b/spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/config/JdbcMessageHandlerParser.java
index ecd81ba4db..aea695afac 100644
--- a/spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/config/JdbcMessageHandlerParser.java
+++ b/spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/config/JdbcMessageHandlerParser.java
@@ -1,72 +1,72 @@
-/*
- * Copyright 2002-2010 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.integration.jdbc.config;
-
-import org.springframework.beans.factory.BeanCreationException;
-import org.springframework.beans.factory.support.AbstractBeanDefinition;
-import org.springframework.beans.factory.support.BeanDefinitionBuilder;
-import org.springframework.beans.factory.xml.ParserContext;
-import org.springframework.integration.config.xml.AbstractOutboundChannelAdapterParser;
-import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
-import org.springframework.util.StringUtils;
-import org.w3c.dom.Element;
-
-/**
- * @author Dave Syer
- * @since 2.0
- *
- */
-public class JdbcMessageHandlerParser extends AbstractOutboundChannelAdapterParser {
-
- protected boolean shouldGenerateId() {
- return false;
- }
-
- protected boolean shouldGenerateIdAsFallback() {
- return true;
- }
-
- @Override
- protected AbstractBeanDefinition parseConsumer(Element element, ParserContext parserContext) {
- Object source = parserContext.extractSource(element);
- BeanDefinitionBuilder builder = BeanDefinitionBuilder
- .genericBeanDefinition("org.springframework.integration.jdbc.JdbcMessageHandler");
- String dataSourceRef = element.getAttribute("data-source");
- String jdbcOperationsRef = element.getAttribute("jdbc-operations");
- boolean refToDataSourceSet = StringUtils.hasText(dataSourceRef);
- boolean refToJdbcOperationsSet = StringUtils.hasText(jdbcOperationsRef);
- if ((refToDataSourceSet && refToJdbcOperationsSet)
- || (!refToDataSourceSet && !refToJdbcOperationsSet)) {
- parserContext.getReaderContext().error(
- "Exactly one of the attributes data-source or "
- + "simple-jdbc-operations should be set for the JDBC outbound-channel-adapter", source);
- }
- String query = IntegrationNamespaceUtils.getTextFromAttributeOrNestedElement(element, "query", parserContext);
- if (!StringUtils.hasText(query)) {
- throw new BeanCreationException("The query attrbitue is required");
- }
- if (!StringUtils.hasText(query)) {
- throw new BeanCreationException("The query attrbitue is required");
- }
- if (refToDataSourceSet) {
- builder.addConstructorArgReference(dataSourceRef);
- } else {
- builder.addConstructorArgReference(jdbcOperationsRef);
- }
- IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "sql-parameter-source-factory");
- builder.addConstructorArgValue(query);
- return builder.getBeanDefinition();
- }
-
-}
+/*
+ * Copyright 2002-2010 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.integration.jdbc.config;
+
+import org.springframework.beans.factory.BeanCreationException;
+import org.springframework.beans.factory.support.AbstractBeanDefinition;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.springframework.integration.config.xml.AbstractOutboundChannelAdapterParser;
+import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
+import org.springframework.util.StringUtils;
+import org.w3c.dom.Element;
+
+/**
+ * @author Dave Syer
+ * @since 2.0
+ *
+ */
+public class JdbcMessageHandlerParser extends AbstractOutboundChannelAdapterParser {
+
+ protected boolean shouldGenerateId() {
+ return false;
+ }
+
+ protected boolean shouldGenerateIdAsFallback() {
+ return true;
+ }
+
+ @Override
+ protected AbstractBeanDefinition parseConsumer(Element element, ParserContext parserContext) {
+ Object source = parserContext.extractSource(element);
+ BeanDefinitionBuilder builder = BeanDefinitionBuilder
+ .genericBeanDefinition("org.springframework.integration.jdbc.JdbcMessageHandler");
+ String dataSourceRef = element.getAttribute("data-source");
+ String jdbcOperationsRef = element.getAttribute("jdbc-operations");
+ boolean refToDataSourceSet = StringUtils.hasText(dataSourceRef);
+ boolean refToJdbcOperationsSet = StringUtils.hasText(jdbcOperationsRef);
+ if ((refToDataSourceSet && refToJdbcOperationsSet)
+ || (!refToDataSourceSet && !refToJdbcOperationsSet)) {
+ parserContext.getReaderContext().error(
+ "Exactly one of the attributes data-source or "
+ + "simple-jdbc-operations should be set for the JDBC outbound-channel-adapter", source);
+ }
+ String query = IntegrationNamespaceUtils.getTextFromAttributeOrNestedElement(element, "query", parserContext);
+ if (!StringUtils.hasText(query)) {
+ throw new BeanCreationException("The query attrbitue is required");
+ }
+ if (!StringUtils.hasText(query)) {
+ throw new BeanCreationException("The query attrbitue is required");
+ }
+ if (refToDataSourceSet) {
+ builder.addConstructorArgReference(dataSourceRef);
+ } else {
+ builder.addConstructorArgReference(jdbcOperationsRef);
+ }
+ IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "sql-parameter-source-factory");
+ builder.addConstructorArgValue(query);
+ return builder.getBeanDefinition();
+ }
+
+}
diff --git a/spring-integration-jdbc/src/main/sql/sqlserver.properties b/spring-integration-jdbc/src/main/sql/sqlserver.properties
index 60b6aa24e2..3796c21341 100644
--- a/spring-integration-jdbc/src/main/sql/sqlserver.properties
+++ b/spring-integration-jdbc/src/main/sql/sqlserver.properties
@@ -1,11 +1,11 @@
-# SQL language oddities
-BIGINT = BIGINT
-IDENTITY =
-GENERATED =
-DOUBLE = DOUBLE PRECISION
-BLOB = IMAGE
-CLOB = TEXT
-TIMESTAMP = DATETIME
-VARCHAR = VARCHAR
-# for generating drop statements...
-SEQUENCE = TABLE
+# SQL language oddities
+BIGINT = BIGINT
+IDENTITY =
+GENERATED =
+DOUBLE = DOUBLE PRECISION
+BLOB = IMAGE
+CLOB = TEXT
+TIMESTAMP = DATETIME
+VARCHAR = VARCHAR
+# for generating drop statements...
+SEQUENCE = TABLE
diff --git a/spring-integration-jdbc/src/main/sql/sybase.properties b/spring-integration-jdbc/src/main/sql/sybase.properties
index 78adc66a1c..f9dc6e9a8f 100644
--- a/spring-integration-jdbc/src/main/sql/sybase.properties
+++ b/spring-integration-jdbc/src/main/sql/sybase.properties
@@ -1,12 +1,12 @@
-# SQL language oddities
-BIGINT = BIGINT
-IDENTITY =
-GENERATED =
-DOUBLE = DOUBLE PRECISION
-BLOB = IMAGE
-CLOB = TEXT
-TIMESTAMP = DATETIME
-VARCHAR = VARCHAR
-NULL = NULL
-# for generating drop statements...
-SEQUENCE = TABLE
+# SQL language oddities
+BIGINT = BIGINT
+IDENTITY =
+GENERATED =
+DOUBLE = DOUBLE PRECISION
+BLOB = IMAGE
+CLOB = TEXT
+TIMESTAMP = DATETIME
+VARCHAR = VARCHAR
+NULL = NULL
+# for generating drop statements...
+SEQUENCE = TABLE
diff --git a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/JdbcMessageStoreTests-context.xml b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/JdbcMessageStoreTests-context.xml
index a11f031e2e..7f33a0fd3d 100644
--- a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/JdbcMessageStoreTests-context.xml
+++ b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/JdbcMessageStoreTests-context.xml
@@ -1,26 +1,26 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/defaultJdbcMessageStore.xml b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/defaultJdbcMessageStore.xml
index 705a2846ae..73f7dd023f 100644
--- a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/defaultJdbcMessageStore.xml
+++ b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/defaultJdbcMessageStore.xml
@@ -1,14 +1,14 @@
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
diff --git a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/jdbcOperationsJdbcMessageStore.xml b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/jdbcOperationsJdbcMessageStore.xml
index 494e36d2f7..b2185fb792 100644
--- a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/jdbcOperationsJdbcMessageStore.xml
+++ b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/jdbcOperationsJdbcMessageStore.xml
@@ -1,18 +1,18 @@
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/soupedUpJdbcMessageStore.xml b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/soupedUpJdbcMessageStore.xml
index 6ba45f2f1d..4adf642f40 100644
--- a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/soupedUpJdbcMessageStore.xml
+++ b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/soupedUpJdbcMessageStore.xml
@@ -1,16 +1,16 @@
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
diff --git a/spring-integration-mail/src/test/java/org/springframework/integration/mail/config/mailToStringTransformerParserTests.xml b/spring-integration-mail/src/test/java/org/springframework/integration/mail/config/mailToStringTransformerParserTests.xml
index c2d8cfc91a..57e2ecef47 100644
--- a/spring-integration-mail/src/test/java/org/springframework/integration/mail/config/mailToStringTransformerParserTests.xml
+++ b/spring-integration-mail/src/test/java/org/springframework/integration/mail/config/mailToStringTransformerParserTests.xml
@@ -8,7 +8,7 @@
http://www.springframework.org/schema/integration
http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/mail
- http://www.springframework.org/schema/integration/mail/spring-integration-mail.xsd">
+ http://www.springframework.org/schema/integration/mail/spring-integration-mail.xsd">
diff --git a/spring-integration-mail/src/test/java/org/springframework/integration/mail/config/mailToStringTransformerWithinChain.xml b/spring-integration-mail/src/test/java/org/springframework/integration/mail/config/mailToStringTransformerWithinChain.xml
index eb0b38c755..a0e991a064 100644
--- a/spring-integration-mail/src/test/java/org/springframework/integration/mail/config/mailToStringTransformerWithinChain.xml
+++ b/spring-integration-mail/src/test/java/org/springframework/integration/mail/config/mailToStringTransformerWithinChain.xml
@@ -8,7 +8,7 @@
http://www.springframework.org/schema/integration
http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/mail
- http://www.springframework.org/schema/integration/mail/spring-integration-mail.xsd">
+ http://www.springframework.org/schema/integration/mail/spring-integration-mail.xsd">
diff --git a/spring-integration-security/src/test/java/org/springframework/integration/security/config/SecuredChannelsParserTests-context.xml b/spring-integration-security/src/test/java/org/springframework/integration/security/config/SecuredChannelsParserTests-context.xml
index c861948b3f..1d7615ab08 100644
--- a/spring-integration-security/src/test/java/org/springframework/integration/security/config/SecuredChannelsParserTests-context.xml
+++ b/spring-integration-security/src/test/java/org/springframework/integration/security/config/SecuredChannelsParserTests-context.xml
@@ -14,8 +14,8 @@
http://www.springframework.org/schema/integration/security
http://www.springframework.org/schema/integration/security/spring-integration-security.xsd
http://www.springframework.org/schema/context
- http://www.springframework.org/schema/context/spring-context.xsd">
-
+ http://www.springframework.org/schema/context/spring-context.xsd">
+
diff --git a/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/AbstractSftpFileListFilter.java b/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/AbstractSftpFileListFilter.java
index cc5d1b8691..c50333ae39 100644
--- a/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/AbstractSftpFileListFilter.java
+++ b/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/AbstractSftpFileListFilter.java
@@ -22,10 +22,10 @@ import java.util.List;
/**
- * Convenience implementation patterned off {@link org.springframework.integration.file.FileListFilter}
+ * Convenience implementation patterned off {@link org.springframework.integration.file.filters.FileListFilter}
*
* @author Josh Long
- */
+ */ @Deprecated
public abstract class AbstractSftpFileListFilter implements SftpFileListFilter {
abstract public boolean accept(ChannelSftp.LsEntry lsEntry);
diff --git a/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/CompositeFtpFileListFilter.java b/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/CompositeFtpFileListFilter.java
index 4d2d0b54a3..f3c26e5edd 100644
--- a/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/CompositeFtpFileListFilter.java
+++ b/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/CompositeFtpFileListFilter.java
@@ -22,10 +22,10 @@ import java.util.*;
/**
- * Patterned very much on the {@link org.springframework.integration.file.CompositeFileListFilter}
+ * Patterned very much on the {@link org.springframework.integration.file.filters.CompositeFileListFilter}
*
* @author Josh Long
- */
+ */ @Deprecated
public class CompositeFtpFileListFilter implements SftpFileListFilter {
private Set filters;
diff --git a/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/PatternMatchingSftpFileListFilter.java b/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/PatternMatchingSftpFileListFilter.java
index c79f1d9a0c..b9c21f5d15 100644
--- a/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/PatternMatchingSftpFileListFilter.java
+++ b/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/PatternMatchingSftpFileListFilter.java
@@ -28,10 +28,10 @@ import java.util.regex.Pattern;
/**
* Validates {@link com.jcraft.jsch.ChannelSftp.LsEntry}s against a {@link java.util.regex.Pattern}.
- * Patterned very much like {@link org.springframework.integration.file.PatternMatchingFileListFilter}.
+ * Patterned very much like {@link org.springframework.integration.file.filters.PatternMatchingFileListFilter}.
*
* @author Josh Long
- */
+ */ @Deprecated
public class PatternMatchingSftpFileListFilter extends AbstractSftpFileListFilter implements InitializingBean {
private Log logger = LogFactory.getLog(getClass());
diff --git a/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/SftpEntryNamer.java b/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/SftpEntryNamer.java
new file mode 100644
index 0000000000..404c93510b
--- /dev/null
+++ b/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/SftpEntryNamer.java
@@ -0,0 +1,16 @@
+package org.springframework.integration.sftp;
+
+import com.jcraft.jsch.ChannelSftp;
+import org.springframework.integration.file.entries.EntryNamer;
+
+/**
+ * Knows how to name a {@link com.jcraft.jsch.ChannelSftp.LsEntry} instance
+ *
+ * @author Josh Long
+ */
+public class SftpEntryNamer implements EntryNamer{
+
+ public String nameOf(ChannelSftp.LsEntry entry) {
+ return entry.getFilename() ;
+ }
+}
diff --git a/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/SftpFileListFilter.java b/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/SftpFileListFilter.java
index 98a14fc56d..f5bc8925d2 100644
--- a/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/SftpFileListFilter.java
+++ b/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/SftpFileListFilter.java
@@ -24,7 +24,7 @@ import java.util.List;
* and returns the balance. These are then sync'd to the local directory.
*
* @author Josh Long
- */
+ */ @Deprecated
public interface SftpFileListFilter {
List filterFiles (ChannelSftp.LsEntry [] files);
}
diff --git a/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/SftpInboundSynchronizer.java b/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/SftpInboundSynchronizer.java
index fe04a7e3ff..676eab8389 100644
--- a/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/SftpInboundSynchronizer.java
+++ b/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/SftpInboundSynchronizer.java
@@ -44,7 +44,7 @@ import java.util.concurrent.ScheduledFuture;
*
* @author Josh Long
* @author Mario Gray
- */
+ */ @Deprecated
public class SftpInboundSynchronizer implements InitializingBean {
private static final long DEFAULT_REFRESH_RATE = 10 * 1000; // 10 seconds
diff --git a/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/SftpMessageSource.java b/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/SftpMessageSource.java
index 3d418ba1e6..33d66dec17 100644
--- a/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/SftpMessageSource.java
+++ b/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/SftpMessageSource.java
@@ -13,23 +13,28 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.springframework.integration.sftp;
+import com.jcraft.jsch.ChannelSftp;
+
import org.springframework.beans.factory.InitializingBean;
+
import org.springframework.context.Lifecycle;
+
import org.springframework.core.io.Resource;
+
import org.springframework.integration.Message;
import org.springframework.integration.core.MessageSource;
-import org.springframework.integration.file.AcceptOnceFileListFilter;
-import org.springframework.integration.file.CompositeFileListFilter;
import org.springframework.integration.file.FileReadingMessageSource;
-import org.springframework.integration.file.PatternMatchingFileListFilter;
+import org.springframework.integration.file.entries.CompositeEntryListFilter;
+import org.springframework.integration.file.entries.PatternMatchingEntryListFilter;
+
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.Trigger;
import java.io.File;
import java.io.IOException;
+
import java.util.regex.Pattern;
@@ -46,13 +51,21 @@ public class SftpMessageSource implements MessageSource, InitializingBean,
private SftpInboundSynchronizer synchronizer;
private TaskScheduler taskScheduler;
private Trigger trigger;
+ private SftpEntryNamer lsEntryEntryNamer = new SftpEntryNamer();
public SftpMessageSource(FileReadingMessageSource fileSource, SftpInboundSynchronizer synchronizer) {
this.fileReadingMessageSource = fileSource;
this.synchronizer = synchronizer;
Pattern completePattern = Pattern.compile("^.*(? filePatternMatchingEntryListFilter = new PatternMatchingEntryListFilter(lsEntryEntryNamer, completePattern);
+ PatternMatchingEntryListFilter lsEntryPatternMatchingEntryListFilter = new PatternMatchingEntryListFilter(this.lsEntryEntryNamer, completePattern);
+
+ CompositeEntryListFilter fileCompositeEntryListFilter = new CompositeEntryListFilter(filePatternMatchingEntryListFilter,
+ lsEntryPatternMatchingEntryListFilter);
+ // todo this.fileReadingMessageSource.setFilter( fileCompositeEntryListFilter);
+
+ //fileReadingMessageSource.setFilter( (completePattern)));
}
public void afterPropertiesSet() throws Exception {
@@ -94,11 +107,12 @@ public class SftpMessageSource implements MessageSource, InitializingBean,
public void setLocalDirectory(final Resource localDirectory) {
this.localDirectory = localDirectory;
+
try {
this.fileReadingMessageSource.setDirectory(localDirectory.getFile());
} catch (IOException e) {
-
}
+
this.synchronizer.setLocalDirectory(localDirectory);
}
diff --git a/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/config/SftpNamespaceHandler.java b/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/config/SftpNamespaceHandler.java
index 8d3e3b83e0..ec2cc9aada 100644
--- a/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/config/SftpNamespaceHandler.java
+++ b/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/config/SftpNamespaceHandler.java
@@ -23,6 +23,8 @@ import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.config.xml.AbstractOutboundChannelAdapterParser;
import org.springframework.integration.config.xml.AbstractPollingInboundChannelAdapterParser;
import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
+import org.springframework.integration.sftp.impl.SftpInboundRemoteFileSystemSynchronizingMessageSource;
+import org.springframework.integration.sftp.impl.SftpRemoteFileSystemSynchronizingMessageSourceFactoryBean;
import org.w3c.dom.Element;
@@ -63,7 +65,8 @@ public class SftpNamespaceHandler extends NamespaceHandlerSupport {
private static class SFTPMessageSourceBeanDefinitionParser extends AbstractPollingInboundChannelAdapterParser {
@Override
protected String parseSource(Element element, ParserContext parserContext) {
- BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition( SftpMessageSourceFactoryBean.class.getName());
+ BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(
+ SftpRemoteFileSystemSynchronizingMessageSourceFactoryBean.class.getName());
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "filter");
diff --git a/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/impl/SftpInboundRemoteFileSystemSynchronizer.java b/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/impl/SftpInboundRemoteFileSystemSynchronizer.java
new file mode 100644
index 0000000000..b323e703ac
--- /dev/null
+++ b/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/impl/SftpInboundRemoteFileSystemSynchronizer.java
@@ -0,0 +1,141 @@
+package org.springframework.integration.sftp.impl;
+
+import com.jcraft.jsch.ChannelSftp;
+import org.apache.commons.io.IOUtils;
+import org.springframework.beans.factory.annotation.Required;
+import org.springframework.core.io.Resource;
+import org.springframework.integration.MessagingException;
+import org.springframework.integration.file.AbstractInboundRemoteFileSystemSychronizer;
+import org.springframework.integration.file.AbstractInboundRemoteFileSystemSynchronizingMessageSource;
+import org.springframework.integration.sftp.SftpSession;
+import org.springframework.integration.sftp.SftpSessionPool;
+import org.springframework.scheduling.Trigger;
+import org.springframework.scheduling.support.PeriodicTrigger;
+import org.springframework.util.Assert;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collection;
+
+
+/**
+ * This handles the synchronization between a remote SFTP endpoint and a local mount
+ *
+ * @author Josh Long
+ */
+public class SftpInboundRemoteFileSystemSynchronizer extends AbstractInboundRemoteFileSystemSychronizer {
+ /**
+ * the path on te remote mount
+ */
+ private volatile String remotePath;
+
+ /**
+ * the pool of {@link org.springframework.integration.sftp.SftpSessionPool} SFTP sessions
+ */
+ private volatile SftpSessionPool clientPool;
+
+ public void setRemotePath(String remotePath) {
+ this.remotePath = remotePath;
+ }
+
+ @Override
+ protected void onInit() throws Exception {
+ Assert.notNull(this.clientPool, "clientPool can't be null");
+
+ if (this.shouldDeleteSourceFile) {
+ this.entryAcknowledgmentStrategy = new DeletionEntryAcknowledgmentStrategy();
+ }
+ }
+
+ @Required
+ public void setClientPool(SftpSessionPool clientPool) {
+ this.clientPool = clientPool;
+ }
+
+ @SuppressWarnings("ignored")
+ private boolean copyFromRemoteToLocalDirectory(SftpSession sftpSession, ChannelSftp.LsEntry entry, Resource localDir)
+ throws Exception {
+ File fileForLocalDir = localDir.getFile();
+
+ File localFile = new File(fileForLocalDir, entry.getFilename());
+
+ if (!localFile.exists()) {
+ InputStream in = null;
+ FileOutputStream fileOutputStream = null;
+
+ try {
+ File tmpLocalTarget = new File(localFile.getAbsolutePath() + AbstractInboundRemoteFileSystemSynchronizingMessageSource.INCOMPLETE_EXTENSION);
+
+ fileOutputStream = new FileOutputStream(tmpLocalTarget);
+
+ String remoteFqPath = this.remotePath + "/" + entry.getFilename();
+ in = sftpSession.getChannel().get(remoteFqPath);
+ IOUtils.copy(in, fileOutputStream);
+
+ if (tmpLocalTarget.renameTo(localFile)) {
+ // last step
+ this.acknowledge(sftpSession, entry);
+ }
+
+ return true;
+ } catch (Throwable th) {
+ IOUtils.closeQuietly(in);
+ IOUtils.closeQuietly(fileOutputStream);
+ }
+ } else {
+ return true;
+ }
+
+ return false;
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ protected void syncRemoteToLocalFileSystem() throws Exception {
+ SftpSession session = null;
+
+ try {
+ session = clientPool.getSession();
+ session.start();
+
+ ChannelSftp channelSftp = session.getChannel();
+ Collection beforeFilter = channelSftp.ls(remotePath);
+ ChannelSftp.LsEntry[] entries = (beforeFilter == null) ? new ChannelSftp.LsEntry[0] : beforeFilter.toArray(new ChannelSftp.LsEntry[beforeFilter.size()]);
+ Collection files = this.filter.filterEntries(entries);
+
+ for (ChannelSftp.LsEntry lsEntry : files) {
+ if ((lsEntry != null) && !lsEntry.getAttrs().isDir() && !lsEntry.getAttrs().isLink()) {
+ copyFromRemoteToLocalDirectory(session, lsEntry, this.localDirectory);
+ }
+ }
+ } catch (IOException e) {
+ throw new MessagingException("couldn't synchronize remote to local directory", e);
+ } finally {
+ if ((session != null) && (clientPool != null)) {
+ clientPool.release(session);
+ }
+ }
+ }
+
+ @Override
+ protected Trigger getTrigger() {
+ return new PeriodicTrigger(10 * 1000);
+ }
+
+ class DeletionEntryAcknowledgmentStrategy implements AbstractInboundRemoteFileSystemSychronizer.EntryAcknowledgmentStrategy {
+ public void acknowledge(Object useful, ChannelSftp.LsEntry msg)
+ throws Exception {
+ SftpSession sftpSession = (SftpSession) useful;
+
+ String remoteFqPath = remotePath + "/" + msg.getFilename();
+
+ sftpSession.getChannel().rm(remoteFqPath);
+
+ if (logger.isDebugEnabled()) {
+ logger.debug("deleted " + msg.getFilename());
+ }
+ }
+ }
+}
diff --git a/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/impl/SftpInboundRemoteFileSystemSynchronizingMessageSource.java b/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/impl/SftpInboundRemoteFileSystemSynchronizingMessageSource.java
new file mode 100644
index 0000000000..f45177b690
--- /dev/null
+++ b/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/impl/SftpInboundRemoteFileSystemSynchronizingMessageSource.java
@@ -0,0 +1,101 @@
+package org.springframework.integration.sftp.impl;
+
+import com.jcraft.jsch.ChannelSftp;
+import com.jcraft.jsch.SftpATTRS;
+
+import org.springframework.integration.file.AbstractInboundRemoteFileSystemSynchronizingMessageSource;
+import org.springframework.integration.sftp.SftpSession;
+import org.springframework.integration.sftp.SftpSessionPool;
+
+import org.springframework.util.Assert;
+
+
+/**
+ * a {@link org.springframework.integration.core.MessageSource} implementation for SFTP
+ *
+ * @author Josh Long
+ */
+public class SftpInboundRemoteFileSystemSynchronizingMessageSource extends AbstractInboundRemoteFileSystemSynchronizingMessageSource {
+ /**
+ * the pool of sessions
+ */
+ private volatile SftpSessionPool clientPool;
+
+
+ /**
+ * the remote path on teh server
+ */
+ private volatile String remotePath;
+
+ public void setClientPool(SftpSessionPool clientPool) {
+ this.clientPool = clientPool;
+ }
+
+ public void setRemotePath(String remotePath) {
+ this.remotePath = remotePath;
+ }
+
+ @Override
+ protected void doStart() {
+ this.synchronizer.start();
+ }
+
+ @Override
+ protected void doStop() {
+ this.synchronizer.stop();
+ }
+
+ /**
+ * there be dragons this way ... This method will check to ensure that the remote directory exists. If the directory
+ * doesnt exist, and autoCreatePath is 'true,' then this method makes a few reasonably sane attempts
+ * to create it. Otherwise, it fails fast.
+ *
+ * @param remotePath the path on the remote SSH / SFTP server to create.
+ * @return whether or not the directory is there (regardless of whether we created it in this method or it already
+ * existed.)
+ */
+ private boolean checkThatRemotePathExists(String remotePath) {
+ SftpSession session = null;
+ ChannelSftp channelSftp = null;
+
+ try {
+ session = this.clientPool.getSession();
+ Assert.state(session != null, "session as returned from the pool should not be null. " + "If it is, it is most likely an error in the pool implementation. ");
+ session.start();
+ channelSftp = session.getChannel();
+
+ SftpATTRS attrs = channelSftp.stat(remotePath);
+ assert (attrs != null) && attrs.isDir() : "attrs can't be null, and should indicate that it's a directory!";
+
+ return true;
+ } catch (Throwable th) {
+ if (this.autoCreateDirectories && (this.clientPool != null) && (session != null)) {
+ try {
+ if (channelSftp != null) {
+ channelSftp.mkdir(remotePath);
+
+ if (channelSftp.stat(remotePath).isDir()) {
+ return true;
+ }
+ }
+ } catch (Throwable t) {
+ return false;
+ }
+ }
+ } finally {
+ if ((clientPool != null) && (session != null)) {
+ clientPool.release(session);
+ }
+ }
+
+ return false;
+ }
+
+ @Override
+ protected void onInit() throws Exception {
+ super.onInit();
+
+ this.checkThatRemotePathExists(this.remotePath);
+ this.synchronizer.setClientPool(this.clientPool);
+ }
+}
diff --git a/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/impl/SftpRemoteFileSystemSynchronizingMessageSourceFactoryBean.java b/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/impl/SftpRemoteFileSystemSynchronizingMessageSourceFactoryBean.java
new file mode 100644
index 0000000000..98fa75ea7e
--- /dev/null
+++ b/spring-integration-sftp/src/main/java/org/springframework/integration/sftp/impl/SftpRemoteFileSystemSynchronizingMessageSourceFactoryBean.java
@@ -0,0 +1,195 @@
+package org.springframework.integration.sftp.impl;
+
+import com.jcraft.jsch.ChannelSftp;
+
+import org.apache.commons.lang.SystemUtils;
+
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.config.AbstractFactoryBean;
+
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.context.ResourceLoaderAware;
+
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.ResourceEditor;
+import org.springframework.core.io.ResourceLoader;
+
+import org.springframework.integration.file.FileReadingMessageSource;
+import org.springframework.integration.file.entries.CompositeEntryListFilter;
+import org.springframework.integration.file.entries.EntryListFilter;
+import org.springframework.integration.file.entries.PatternMatchingEntryListFilter;
+import org.springframework.integration.sftp.*;
+import org.springframework.integration.sftp.config.SftpSessionUtils;
+
+import org.springframework.scheduling.TaskScheduler;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
+
+import org.springframework.util.ErrorHandler;
+import org.springframework.util.StringUtils;
+
+import java.io.File;
+
+import java.util.Map;
+
+
+/**
+ * a factory bean to hide the fairly complex configuration possibilities for an SFTP endpoint
+ *
+ * @author Josh Long
+ */
+public class SftpRemoteFileSystemSynchronizingMessageSourceFactoryBean extends
+ AbstractFactoryBean implements ResourceLoaderAware {
+ /**
+ * injected by the container
+ */
+ private volatile ResourceLoader resourceLoader;
+ private volatile Resource localDirectoryResource;
+ private volatile String localDirectoryPath;
+ private volatile String autoCreateDirectories;
+ private volatile String autoDeleteRemoteFilesOnSync;
+ private volatile String filenamePattern;
+ private volatile EntryListFilter filter;
+ private int port = 22;
+
+ public void setLocalDirectoryResource(Resource localDirectoryResource) {
+ this.localDirectoryResource = localDirectoryResource;
+ }
+
+ public void setLocalDirectoryPath(String localDirectoryPath) {
+ this.localDirectoryPath = localDirectoryPath;
+ }
+
+ public void setAutoCreateDirectories(String autoCreateDirectories) {
+ this.autoCreateDirectories = autoCreateDirectories;
+ }
+
+ public void setAutoDeleteRemoteFilesOnSync(String autoDeleteRemoteFilesOnSync) {
+ this.autoDeleteRemoteFilesOnSync = autoDeleteRemoteFilesOnSync;
+ }
+
+ public void setFilenamePattern(String filenamePattern) {
+ this.filenamePattern = filenamePattern;
+ }
+
+ public void setFilter(EntryListFilter filter) {
+ this.filter = filter;
+ }
+
+ public void setPort(int port) {
+ this.port = port;
+ }
+
+ public void setHost(String host) {
+ this.host = host;
+ }
+
+ public void setKeyFile(String keyFile) {
+ this.keyFile = keyFile;
+ }
+
+ public void setKeyFilePassword(String keyFilePassword) {
+ this.keyFilePassword = keyFilePassword;
+ }
+
+ public void setLocalWorkingDirectory(String localWorkingDirectory) {
+ this.localWorkingDirectory = localWorkingDirectory;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public void setRemoteDirectory(String remoteDirectory) {
+ this.remoteDirectory = remoteDirectory;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ private String host;
+ private String keyFile;
+ private String keyFilePassword;
+ private String localWorkingDirectory;
+ private String password;
+ private String remoteDirectory;
+ private String username;
+
+ public void setResourceLoader(ResourceLoader resourceLoader) {
+ this.resourceLoader = resourceLoader;
+ }
+
+ @Override
+ public Class> getObjectType() {
+ return SftpRemoteFileSystemSynchronizingMessageSourceFactoryBean.class;
+ }
+
+ @Override
+ protected SftpInboundRemoteFileSystemSynchronizingMessageSource createInstance()
+ throws Exception {
+ boolean autoCreatDirs = Boolean.parseBoolean(this.autoCreateDirectories);
+ boolean ackRemoteDir = Boolean.parseBoolean(this.autoDeleteRemoteFilesOnSync);
+
+ SftpInboundRemoteFileSystemSynchronizingMessageSource sftpMsgSrc = new SftpInboundRemoteFileSystemSynchronizingMessageSource();
+ sftpMsgSrc.setAutoCreateDirectories(autoCreatDirs);
+
+ // local directories
+ if ((this.localDirectoryResource == null) || !StringUtils.hasText(this.localDirectoryPath)) {
+ File tmp = SystemUtils.getJavaIoTmpDir();
+ File sftpTmp = new File(tmp, "sftpInbound");
+ this.localDirectoryPath = "file://" + sftpTmp.getAbsolutePath();
+ }
+
+ this.localDirectoryResource = this.fromText(localDirectoryPath);
+
+ // remote predicates
+ SftpEntryNamer sftpEntryNamer = new SftpEntryNamer();
+ CompositeEntryListFilter compositeFtpFileListFilter = new CompositeEntryListFilter();
+
+ if (StringUtils.hasText(this.filenamePattern)) {
+ PatternMatchingEntryListFilter ftpFilePatternMatchingEntryListFilter = new PatternMatchingEntryListFilter(sftpEntryNamer, filenamePattern);
+ compositeFtpFileListFilter.addFilter(ftpFilePatternMatchingEntryListFilter);
+ }
+
+ if (this.filter != null) {
+ compositeFtpFileListFilter.addFilter(this.filter);
+ }
+
+ this.filter = compositeFtpFileListFilter;
+
+ // pools
+ SftpSessionFactory sessionFactory = SftpSessionUtils.buildSftpSessionFactory(
+ this.host, this.password, this.username, this.keyFile, this.keyFilePassword, this.port);
+
+ QueuedSftpSessionPool pool = new QueuedSftpSessionPool(15, sessionFactory);
+ pool.afterPropertiesSet();
+
+ SftpInboundRemoteFileSystemSynchronizer sftpSync = new SftpInboundRemoteFileSystemSynchronizer();
+ sftpSync.setClientPool(pool);
+ sftpSync.setLocalDirectory(this.localDirectoryResource);
+ sftpSync.setShouldDeleteSourceFile(ackRemoteDir);
+ sftpSync.setFilter(compositeFtpFileListFilter);
+ sftpSync.afterPropertiesSet();// todo is this correct ?
+ sftpSync.start();//todo
+
+ sftpMsgSrc.setRemotePredicate(compositeFtpFileListFilter);
+ sftpMsgSrc.setSynchronizer(sftpSync);
+ sftpMsgSrc.setClientPool( pool);
+ sftpMsgSrc.setRemotePath( this.remoteDirectory);
+ sftpMsgSrc.setLocalDirectory(this.localDirectoryResource);
+ sftpMsgSrc.setBeanFactory(this.getBeanFactory());
+ sftpMsgSrc.setAutoStartup(true);
+ sftpMsgSrc.afterPropertiesSet();
+ sftpMsgSrc.start();
+
+ return sftpMsgSrc;
+ }
+
+ private Resource fromText(String path) {
+ ResourceEditor resourceEditor = new ResourceEditor(this.resourceLoader);
+ resourceEditor.setAsText(path);
+ return (Resource) resourceEditor.getValue();
+ }
+
+}
diff --git a/spring-integration-sftp/src/test/java/org/springframework/integration/sftp/TestSftpReceipt.java b/spring-integration-sftp/src/test/java/org/springframework/integration/sftp/TestSftpReceipt.java
index 325651015e..71242c1c3a 100644
--- a/spring-integration-sftp/src/test/java/org/springframework/integration/sftp/TestSftpReceipt.java
+++ b/spring-integration-sftp/src/test/java/org/springframework/integration/sftp/TestSftpReceipt.java
@@ -19,7 +19,7 @@ import java.util.logging.Logger;
* @author Josh Long
*/
public class TestSftpReceipt {
-
+/*
private static final Logger logger = Logger.getLogger(TestSftpReceipt.class.getName());
private SftpSessionFactory sftpSessionFactory;
private String host;
@@ -104,5 +104,5 @@ public class TestSftpReceipt {
sftpSessionFactory.afterPropertiesSet();
return sftpSessionFactory;
- }
+ }*/
}
diff --git a/spring-integration-sftp/src/test/resources/TestInboundSftp.xml b/spring-integration-sftp/src/test/resources/TestInboundSftp.xml
index 6ef7076255..aa6efb21db 100644
--- a/spring-integration-sftp/src/test/resources/TestInboundSftp.xml
+++ b/spring-integration-sftp/src/test/resources/TestInboundSftp.xml
@@ -34,6 +34,7 @@
http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-3.0.xsd
http://www.springframework.org/schema/integration/sftp http://www.springframework.org/schema/integration/sftp/spring-integration-sftp-2.0.xsd">
+
diff --git a/src/docbkx/file.xml b/src/docbkx/file.xml
index f5a57ff030..e4b6aa6662 100644
--- a/src/docbkx/file.xml
+++ b/src/docbkx/file.xml
@@ -54,11 +54,11 @@
class="org.springframework.integration.file.FileReadingMessageSource"
p:inputDirectory="file:${input.directory}"
p:filter-ref="compositeFilter"/>
-
+
-
-
+
+
@@ -225,4 +225,4 @@
-
\ No newline at end of file
+
diff --git a/src/main/resources/license.txt b/src/main/resources/license.txt
index 29f81d812f..261eeb9e9f 100644
--- a/src/main/resources/license.txt
+++ b/src/main/resources/license.txt
@@ -1,201 +1,201 @@
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- 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.
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
diff --git a/src/main/resources/notice.txt b/src/main/resources/notice.txt
index 6394b12401..f62045a212 100644
--- a/src/main/resources/notice.txt
+++ b/src/main/resources/notice.txt
@@ -1,21 +1,21 @@
- ========================================================================
- == NOTICE file corresponding to section 4 d of the Apache License, ==
- == Version 2.0, in this case for the Spring Integration distribution. ==
- ========================================================================
-
- This product includes software developed by
- the Apache Software Foundation (http://www.apache.org).
-
- The end-user documentation included with a redistribution, if any,
- must include the following acknowledgement:
-
- "This product includes software developed by the Spring Framework
- Project (http://www.springframework.org)."
-
- Alternatively, this acknowledgement may appear in the software itself,
- if and wherever such third-party acknowledgements normally appear.
-
- The names "Spring", "Spring Framework", and "Spring Integration" must
- not be used to endorse or promote products derived from this software
- without prior written permission. For written permission, please contact
- enquiries@springsource.com.
+ ========================================================================
+ == NOTICE file corresponding to section 4 d of the Apache License, ==
+ == Version 2.0, in this case for the Spring Integration distribution. ==
+ ========================================================================
+
+ This product includes software developed by
+ the Apache Software Foundation (http://www.apache.org).
+
+ The end-user documentation included with a redistribution, if any,
+ must include the following acknowledgement:
+
+ "This product includes software developed by the Spring Framework
+ Project (http://www.springframework.org)."
+
+ Alternatively, this acknowledgement may appear in the software itself,
+ if and wherever such third-party acknowledgements normally appear.
+
+ The names "Spring", "Spring Framework", and "Spring Integration" must
+ not be used to endorse or promote products derived from this software
+ without prior written permission. For written permission, please contact
+ enquiries@springsource.com.