initial commit of my work to make building filesystem based adapters more consistent, cleaner.
This commit is contained in:
@@ -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 <code>n</code> messages, where <code>n</code> 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 <code>n</code> messages, where <code>n</code> 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
* <p>
|
||||
* The class is package-protected and only intended for use by the AbstractDispatcher. It
|
||||
* <emphasis>must</emphasis> 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<E> extends LinkedHashSet<E> {
|
||||
|
||||
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> 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.
|
||||
* <p>
|
||||
* The class is package-protected and only intended for use by the AbstractDispatcher. It
|
||||
* <emphasis>must</emphasis> 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<E> extends LinkedHashSet<E> {
|
||||
|
||||
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> 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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<MessageGroup> {
|
||||
|
||||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
private Collection<MessageGroupCallback> expiryCallbacks = new LinkedHashSet<MessageGroupCallback>();
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
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<MessageGroupCallback> 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<MessageGroup> 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<MessageGroup> {
|
||||
|
||||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
private Collection<MessageGroupCallback> expiryCallbacks = new LinkedHashSet<MessageGroupCallback>();
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
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<MessageGroupCallback> 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<MessageGroup> 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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<String> result = (Message<String>) 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<Message<?>> messages) {
|
||||
return MessageBuilder.withPayload(messages.toString()).build();
|
||||
}
|
||||
|
||||
@ReleaseStrategy
|
||||
public boolean release(final List<Message<?>> 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<String> result = (Message<String>) 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<Message<?>> messages) {
|
||||
return MessageBuilder.withPayload(messages.toString()).build();
|
||||
}
|
||||
|
||||
@ReleaseStrategy
|
||||
public boolean release(final List<Message<?>> messages) {
|
||||
return messages.size()>1;
|
||||
}
|
||||
|
||||
@CorrelationStrategy
|
||||
public Object getKey(Message<?> message) {
|
||||
return "1";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<channel id="pojoOutput">
|
||||
<queue/>
|
||||
</channel>
|
||||
|
||||
<channel id="defaultOutput">
|
||||
<queue/>
|
||||
</channel>
|
||||
|
||||
<splitter input-channel="pojoInput" output-channel="pojoAggregator"/>
|
||||
|
||||
<aggregator input-channel="pojoAggregator" output-channel="pojoOutput" method="aggregate">
|
||||
<beans:bean class="org.springframework.integration.aggregator.integration.MethodInvokingAggregatorReturningMessageTests$TestAggregator"/>
|
||||
</aggregator>
|
||||
|
||||
<splitter input-channel="defaultInput" output-channel="defaultAggregator"/>
|
||||
|
||||
<aggregator input-channel="defaultAggregator" output-channel="defaultOutput"/>
|
||||
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<channel id="pojoOutput">
|
||||
<queue/>
|
||||
</channel>
|
||||
|
||||
<channel id="defaultOutput">
|
||||
<queue/>
|
||||
</channel>
|
||||
|
||||
<splitter input-channel="pojoInput" output-channel="pojoAggregator"/>
|
||||
|
||||
<aggregator input-channel="pojoAggregator" output-channel="pojoOutput" method="aggregate">
|
||||
<beans:bean class="org.springframework.integration.aggregator.integration.MethodInvokingAggregatorReturningMessageTests$TestAggregator"/>
|
||||
</aggregator>
|
||||
|
||||
<splitter input-channel="defaultInput" output-channel="defaultAggregator"/>
|
||||
|
||||
<aggregator input-channel="defaultAggregator" output-channel="defaultOutput"/>
|
||||
|
||||
</beans:beans>
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<transformer id="transformer"
|
||||
input-channel="input"
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xsi:schemaLocation="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.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<context:property-placeholder
|
||||
location="/org/springframework/integration/channel/config/ChannelCapacityPlaceholderTests.properties"/>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<channel id="dispatcherAttribute" dispatcher="failover"/>
|
||||
|
||||
|
||||
<channel id="taskExecutorOnly">
|
||||
<dispatcher task-executor="taskExecutor"/>
|
||||
</channel>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<channel id="channelWithInterceptorRef">
|
||||
<queue capacity="5"/>
|
||||
@@ -26,5 +26,5 @@
|
||||
</channel>
|
||||
|
||||
<beans:bean id="interceptor" class="org.springframework.integration.config.TestChannelInterceptor"/>
|
||||
|
||||
|
||||
</beans:beans>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
</channel>
|
||||
|
||||
<channel id="defaultChannel" />
|
||||
|
||||
|
||||
<channel id="channelWithFailoverAttribute" dispatcher="failover"/>
|
||||
|
||||
<channel id="channelWithCustomQueue">
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:integration="http://www.springframework.org/schema/integration"
|
||||
xmlns:integration="http://www.springframework.org/schema/integration"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<integration:channel/>
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<channel id="priorityChannelWithDefaultComparator">
|
||||
<priority-queue capacity="10"/>
|
||||
@@ -21,5 +21,5 @@
|
||||
|
||||
<beans:bean id="payloadComparator"
|
||||
class="org.springframework.integration.channel.MessagePayloadTestComparator"/>
|
||||
|
||||
|
||||
</beans:beans>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<channel id="channel">
|
||||
<rendezvous-queue/>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<channel id="channel"/>
|
||||
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<channel id="output">
|
||||
<queue capacity="5" />
|
||||
</channel>
|
||||
|
||||
<channel id="input" />
|
||||
|
||||
<aggregator id="aggregator" ref="aggregatorBean"
|
||||
input-channel="input" output-channel="output" message-store="messageStore" send-partial-result-on-expiry="true"/>
|
||||
|
||||
<beans:bean id="messageStore" class="org.springframework.integration.store.SimpleMessageStore"/>
|
||||
|
||||
<beans:bean id="aggregatorBean"
|
||||
class="org.springframework.integration.config.TestAggregatorBean" />
|
||||
|
||||
</beans:beans>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<channel id="output">
|
||||
<queue capacity="5" />
|
||||
</channel>
|
||||
|
||||
<channel id="input" />
|
||||
|
||||
<aggregator id="aggregator" ref="aggregatorBean"
|
||||
input-channel="input" output-channel="output" message-store="messageStore" send-partial-result-on-expiry="true"/>
|
||||
|
||||
<beans:bean id="messageStore" class="org.springframework.integration.store.SimpleMessageStore"/>
|
||||
|
||||
<beans:bean id="aggregatorBean"
|
||||
class="org.springframework.integration.config.TestAggregatorBean" />
|
||||
|
||||
</beans:beans>
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
|
||||
<channel id="queueChannel">
|
||||
<queue capacity="1"/>
|
||||
</channel>
|
||||
@@ -24,5 +24,5 @@
|
||||
<beans:bean id="consumer" class="org.springframework.integration.config.TestConsumer"/>
|
||||
|
||||
<beans:bean id="testBean" class="org.springframework.integration.config.TestBean"/>
|
||||
|
||||
|
||||
</beans:beans>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
|
||||
@@ -1,73 +1,73 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<channel id="outputChannel">
|
||||
<queue capacity="5"/>
|
||||
</channel>
|
||||
<channel id="discardChannel">
|
||||
<queue capacity="5"/>
|
||||
</channel>
|
||||
|
||||
<channel id="aggregatorWithReferenceInput"/>
|
||||
<aggregator id="aggregatorWithReference" ref="aggregatorBean"
|
||||
input-channel="aggregatorWithReferenceInput" output-channel="outputChannel"/>
|
||||
|
||||
<channel id="completelyDefinedAggregatorInput"/>
|
||||
<aggregator id="completelyDefinedAggregator"
|
||||
input-channel="completelyDefinedAggregatorInput"
|
||||
output-channel="outputChannel"
|
||||
discard-channel="discardChannel"
|
||||
ref="aggregatorBean"
|
||||
release-strategy="releaseStrategy"
|
||||
correlation-strategy="correlationStrategy"
|
||||
send-timeout="86420000"
|
||||
send-partial-result-on-expiry="true"/>
|
||||
|
||||
<channel id="aggregatorWithExpressionsInput"/>
|
||||
<channel id="aggregatorWithExpressionsOutput"/>
|
||||
<aggregator id="aggregatorWithExpressions"
|
||||
input-channel="aggregatorWithExpressionsInput"
|
||||
output-channel="aggregatorWithExpressionsOutput"
|
||||
expression="?[payload.startsWith('1')].![payload]"
|
||||
release-strategy-expression="#root.size()>2"
|
||||
correlation-strategy-expression="headers['foo']"/>
|
||||
|
||||
<channel id="aggregatorWithReferenceAndMethodInput"/>
|
||||
<aggregator id="aggregatorWithReferenceAndMethod"
|
||||
ref="adderBean"
|
||||
method="add"
|
||||
input-channel="aggregatorWithReferenceAndMethodInput"
|
||||
output-channel="outputChannel"/>
|
||||
|
||||
<channel id="aggregatorWithPojoReleaseStrategyInput"/>
|
||||
<aggregator id="aggregatorWithPojoReleaseStrategy"
|
||||
input-channel="aggregatorWithPojoReleaseStrategyInput"
|
||||
output-channel="outputChannel"
|
||||
ref="adderBean"
|
||||
method="add"
|
||||
release-strategy="pojoReleaseStrategy"
|
||||
release-strategy-method="checkCompleteness"/>
|
||||
|
||||
<beans:bean id="aggregatorBean"
|
||||
class="org.springframework.integration.config.TestAggregatorBean" />
|
||||
|
||||
<beans:bean id="adderBean"
|
||||
class="org.springframework.integration.config.Adder" />
|
||||
|
||||
<beans:bean id="releaseStrategy"
|
||||
class="org.springframework.integration.config.TestReleaseStrategy" />
|
||||
|
||||
<beans:bean id="correlationStrategy" class="org.springframework.integration.config.TestCorrelationStrategy"/>
|
||||
|
||||
<beans:bean id="pojoReleaseStrategy"
|
||||
class="org.springframework.integration.config.MaxValueReleaseStrategy">
|
||||
<beans:constructor-arg value="10" />
|
||||
</beans:bean>
|
||||
|
||||
</beans:beans>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<channel id="outputChannel">
|
||||
<queue capacity="5"/>
|
||||
</channel>
|
||||
<channel id="discardChannel">
|
||||
<queue capacity="5"/>
|
||||
</channel>
|
||||
|
||||
<channel id="aggregatorWithReferenceInput"/>
|
||||
<aggregator id="aggregatorWithReference" ref="aggregatorBean"
|
||||
input-channel="aggregatorWithReferenceInput" output-channel="outputChannel"/>
|
||||
|
||||
<channel id="completelyDefinedAggregatorInput"/>
|
||||
<aggregator id="completelyDefinedAggregator"
|
||||
input-channel="completelyDefinedAggregatorInput"
|
||||
output-channel="outputChannel"
|
||||
discard-channel="discardChannel"
|
||||
ref="aggregatorBean"
|
||||
release-strategy="releaseStrategy"
|
||||
correlation-strategy="correlationStrategy"
|
||||
send-timeout="86420000"
|
||||
send-partial-result-on-expiry="true"/>
|
||||
|
||||
<channel id="aggregatorWithExpressionsInput"/>
|
||||
<channel id="aggregatorWithExpressionsOutput"/>
|
||||
<aggregator id="aggregatorWithExpressions"
|
||||
input-channel="aggregatorWithExpressionsInput"
|
||||
output-channel="aggregatorWithExpressionsOutput"
|
||||
expression="?[payload.startsWith('1')].![payload]"
|
||||
release-strategy-expression="#root.size()>2"
|
||||
correlation-strategy-expression="headers['foo']"/>
|
||||
|
||||
<channel id="aggregatorWithReferenceAndMethodInput"/>
|
||||
<aggregator id="aggregatorWithReferenceAndMethod"
|
||||
ref="adderBean"
|
||||
method="add"
|
||||
input-channel="aggregatorWithReferenceAndMethodInput"
|
||||
output-channel="outputChannel"/>
|
||||
|
||||
<channel id="aggregatorWithPojoReleaseStrategyInput"/>
|
||||
<aggregator id="aggregatorWithPojoReleaseStrategy"
|
||||
input-channel="aggregatorWithPojoReleaseStrategyInput"
|
||||
output-channel="outputChannel"
|
||||
ref="adderBean"
|
||||
method="add"
|
||||
release-strategy="pojoReleaseStrategy"
|
||||
release-strategy-method="checkCompleteness"/>
|
||||
|
||||
<beans:bean id="aggregatorBean"
|
||||
class="org.springframework.integration.config.TestAggregatorBean" />
|
||||
|
||||
<beans:bean id="adderBean"
|
||||
class="org.springframework.integration.config.Adder" />
|
||||
|
||||
<beans:bean id="releaseStrategy"
|
||||
class="org.springframework.integration.config.TestReleaseStrategy" />
|
||||
|
||||
<beans:bean id="correlationStrategy" class="org.springframework.integration.config.TestCorrelationStrategy"/>
|
||||
|
||||
<beans:bean id="pojoReleaseStrategy"
|
||||
class="org.springframework.integration.config.MaxValueReleaseStrategy">
|
||||
<beans:constructor-arg value="10" />
|
||||
</beans:bean>
|
||||
|
||||
</beans:beans>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<annotation-config/>
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:integration="http://www.springframework.org/schema/integration"
|
||||
xmlns:integration="http://www.springframework.org/schema/integration"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<integration:annotation-config/>
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<annotation-config/>
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:integration="http://www.springframework.org/schema/integration"
|
||||
xmlns:integration="http://www.springframework.org/schema/integration"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<integration:annotation-config/>
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:integration="http://www.springframework.org/schema/integration"
|
||||
xmlns:integration="http://www.springframework.org/schema/integration"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<integration:annotation-config/>
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<application-event-multicaster/>
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<channel id="test"/>
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<channel id="errorChannel"/>
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<channel id="test"/>
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
|
||||
<channel id="testChannel">
|
||||
<queue capacity="50"/>
|
||||
</channel>
|
||||
@@ -20,5 +20,5 @@
|
||||
<beans:bean id="testHandler" class="org.springframework.integration.config.TestHandler">
|
||||
<beans:constructor-arg value="1"/>
|
||||
</beans:bean>
|
||||
|
||||
|
||||
</beans:beans>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<header-enricher input-channel="input" ref="testBean" method="enrich">
|
||||
<header name="other" value="zzz"/>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<header-filter input-channel="input" header-names="a,d, c"/>
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<beans:bean id="abstractParent" class="org.springframework.integration.config.xml.NestedChainParserTests$ParentTestBean" abstract="true">
|
||||
<beans:property name="chain">
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<channel id="directInput"/>
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<channel id="directInput"/>
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<channel id="directInput"/>
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<poller id="defaultPollerWithId" default="true">
|
||||
<interval-trigger interval="5000"/>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<poller default="true">
|
||||
<interval-trigger interval="5000"/>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<channel id="requestChannel">
|
||||
<queue capacity="100"/>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<poller id="defaultPoller1" default="true">
|
||||
<interval-trigger interval="3000"/>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<poller id="poller">
|
||||
<interval-trigger interval="5000"/>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<poller id="poller" receive-timeout="1234">
|
||||
<interval-trigger interval="5" time-unit="SECONDS"/>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<channel id="input">
|
||||
<queue capacity="1"/>
|
||||
@@ -33,5 +33,5 @@
|
||||
<beans:bean id="testBean" class="org.springframework.integration.dispatcher.TestBean"/>
|
||||
|
||||
<beans:bean id="txManager" class="org.springframework.integration.util.TestTransactionManager"/>
|
||||
|
||||
|
||||
</beans:beans>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<channel id="input">
|
||||
<queue capacity="1"/>
|
||||
@@ -29,5 +29,5 @@
|
||||
<beans:bean id="testBean" class="org.springframework.integration.dispatcher.TestBean"/>
|
||||
|
||||
<beans:bean id="txManager" class="org.springframework.integration.util.TestTransactionManager"/>
|
||||
|
||||
|
||||
</beans:beans>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<channel id="input">
|
||||
<queue capacity="1"/>
|
||||
@@ -28,6 +28,6 @@
|
||||
|
||||
<beans:bean id="testBean" class="org.springframework.integration.dispatcher.TestBean"/>
|
||||
|
||||
<beans:bean id="txManager" class="org.springframework.integration.util.TestTransactionManager"/>
|
||||
<beans:bean id="txManager" class="org.springframework.integration.util.TestTransactionManager"/>
|
||||
|
||||
</beans:beans>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<channel id="input">
|
||||
<queue capacity="1"/>
|
||||
@@ -29,5 +29,5 @@
|
||||
<beans:bean id="testBean" class="org.springframework.integration.dispatcher.TestBean"/>
|
||||
|
||||
<beans:bean id="txManager" class="org.springframework.integration.util.TestTransactionManager"/>
|
||||
|
||||
|
||||
</beans:beans>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<channel id="input">
|
||||
<queue capacity="1"/>
|
||||
@@ -29,5 +29,5 @@
|
||||
<beans:bean id="testBean" class="org.springframework.integration.dispatcher.TestBean"/>
|
||||
|
||||
<beans:bean id="txManager" class="org.springframework.integration.util.TestTransactionManager"/>
|
||||
|
||||
|
||||
</beans:beans>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<channel id="badInput">
|
||||
<queue capacity="1"/>
|
||||
@@ -42,5 +42,5 @@
|
||||
<beans:bean id="testBean" class="org.springframework.integration.dispatcher.TestBean"/>
|
||||
|
||||
<beans:bean id="txManager" class="org.springframework.integration.util.TestTransactionManager"/>
|
||||
|
||||
|
||||
</beans:beans>
|
||||
|
||||
@@ -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">
|
||||
|
||||
<si:channel id="errorChannel">
|
||||
<si:queue capacity="10"/>
|
||||
@@ -15,6 +15,6 @@
|
||||
<property name="taskExecutor" ref="taskExecutor"/>
|
||||
</bean>
|
||||
|
||||
<task:executor id="taskExecutor" pool-size="1" rejection-policy="CALLER_RUNS"/>
|
||||
<task:executor id="taskExecutor" pool-size="1" rejection-policy="CALLER_RUNS"/>
|
||||
|
||||
</beans>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:si="http://www.springframework.org/schema/integration"
|
||||
xmlns:si="http://www.springframework.org/schema/integration"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<si:poller id="poller" default="true">
|
||||
<si:interval-trigger interval="50"/>
|
||||
@@ -30,5 +30,5 @@
|
||||
<si:service-activator input-channel="channel4" ref="testBean" method="duplicate" output-channel="replyChannel"/>
|
||||
|
||||
<bean id="testBean" class="org.springframework.integration.endpoint.TestBean"/>
|
||||
|
||||
|
||||
</beans>
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
|
||||
<channel id="input"/>
|
||||
|
||||
<channel id="output">
|
||||
@@ -19,5 +19,5 @@
|
||||
output-channel="output"/>
|
||||
|
||||
<beans:bean id="testBean" class="org.springframework.integration.filter.TestBean"/>
|
||||
|
||||
|
||||
</beans:beans>
|
||||
|
||||
@@ -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">
|
||||
|
||||
<context:annotation-config/>
|
||||
<context:annotation-config/>
|
||||
|
||||
<beans:bean id="testClient" class="org.springframework.integration.gateway.GatewayProxyFactoryBeanTests$TestClient"/>
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<channel id="requestChannel"/>
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<channel id="requestChannel"/>
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<channel id="input"/>
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<channel id="numbers"/>
|
||||
<channel id="splits"/>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<channel id="output">
|
||||
<queue capacity="10"/>
|
||||
|
||||
@@ -1,26 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:task="http://www.springframework.org/schema/task"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
|
||||
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd">
|
||||
|
||||
|
||||
<bean id="messageStore" class="org.springframework.integration.store.SimpleMessageStore">
|
||||
<property name="expiryCallbacks">
|
||||
<bean class="org.springframework.integration.store.MessageStoreReaperTests$ExpiryCallback"/>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="reaper" class="org.springframework.integration.store.MessageGroupStoreReaper">
|
||||
<property name="messageGroupStore" ref="messageStore"/>
|
||||
<property name="timeout" value="10"/>
|
||||
</bean>
|
||||
|
||||
<task:scheduled-tasks scheduler="scheduler">
|
||||
<task:scheduled ref="reaper" method="run" fixed-rate="100"/>
|
||||
</task:scheduled-tasks>
|
||||
|
||||
<task:scheduler id="scheduler"/>
|
||||
|
||||
</beans>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:task="http://www.springframework.org/schema/task"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
|
||||
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd">
|
||||
|
||||
|
||||
<bean id="messageStore" class="org.springframework.integration.store.SimpleMessageStore">
|
||||
<property name="expiryCallbacks">
|
||||
<bean class="org.springframework.integration.store.MessageStoreReaperTests$ExpiryCallback"/>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="reaper" class="org.springframework.integration.store.MessageGroupStoreReaper">
|
||||
<property name="messageGroupStore" ref="messageStore"/>
|
||||
<property name="timeout" value="10"/>
|
||||
</bean>
|
||||
|
||||
<task:scheduled-tasks scheduler="scheduler">
|
||||
<task:scheduled ref="reaper" method="run" fixed-rate="100"/>
|
||||
</task:scheduled-tasks>
|
||||
|
||||
<task:scheduler id="scheduler"/>
|
||||
|
||||
</beans>
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
|
||||
<channel id="input"/>
|
||||
|
||||
<channel id="output">
|
||||
@@ -16,5 +16,5 @@
|
||||
<transformer input-channel="input" ref="testBean" method="upperCase" output-channel="output"/>
|
||||
|
||||
<beans:bean id="testBean" class="org.springframework.integration.transformer.TestBean"/>
|
||||
|
||||
|
||||
</beans:beans>
|
||||
|
||||
@@ -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<T> extends AbstractEndpoint {
|
||||
/**
|
||||
* Should we <emphasis>delete</emphasis> the <b>source</b> file?
|
||||
* For an FTP server, for example, this would delete the original FTPFile instance
|
||||
* <p/>
|
||||
* 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 <emphasis>remote</emphasis> file system view!
|
||||
*/
|
||||
protected volatile EntryListFilter<T> filter = new AcceptAllEntryListFilter<T>();
|
||||
|
||||
/**
|
||||
* 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<T> entryAcknowledgmentStrategy;
|
||||
|
||||
/**
|
||||
* Obviously thread safe - simply provides a NOOP impl so we don't have to keep dancing around NPE's
|
||||
*/
|
||||
private EntryAcknowledgmentStrategy<T> noOpEntryAcknowledgmentStrategy = new EntryAcknowledgmentStrategy<T>() {
|
||||
public void acknowledge(Object o, T msg) {
|
||||
}
|
||||
};
|
||||
|
||||
public void setEntryAcknowledgmentStrategy(EntryAcknowledgmentStrategy<T> entryAcknowledgmentStrategy) {
|
||||
this.entryAcknowledgmentStrategy = entryAcknowledgmentStrategy;
|
||||
}
|
||||
|
||||
public void setShouldDeleteSourceFile(boolean shouldDeleteSourceFile) {
|
||||
this.shouldDeleteSourceFile = shouldDeleteSourceFile;
|
||||
}
|
||||
|
||||
public void setLocalDirectory(Resource localDirectory) {
|
||||
this.localDirectory = localDirectory;
|
||||
}
|
||||
|
||||
public void setFilter(EntryListFilter<T> 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 <T> the entry type (file, sftp, ftp, ...)
|
||||
*/
|
||||
public static interface EntryAcknowledgmentStrategy<T> {
|
||||
/**
|
||||
* 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) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<Y, T extends AbstractInboundRemoteFileSystemSychronizer<Y>> extends AbstractEndpoint implements MessageSource<File> {
|
||||
/**
|
||||
* 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<Y> 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<Y> remotePredicate) {
|
||||
this.remotePredicate = remotePredicate;
|
||||
}
|
||||
|
||||
private EntryListFilter<File> buildFilter() {
|
||||
FileEntryNamer fileEntryNamer = new FileEntryNamer();
|
||||
Pattern completePattern = Pattern.compile("^.*(?<!" + INCOMPLETE_EXTENSION + ")$");
|
||||
return new CompositeEntryListFilter<File>(new AcceptOnceEntryFileListFilter<File>(), new PatternMatchingEntryListFilter<File>(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<File> receive() {
|
||||
return this.fileSource.receive();
|
||||
}
|
||||
}
|
||||
@@ -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<File> filter = new AcceptOnceEntryFileListFilter<File>();
|
||||
private FileLocker locker;
|
||||
|
||||
public final List<File> 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<File> 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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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<File> 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<File> filter);
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -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.
|
||||
* <p/>
|
||||
* 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.
|
||||
* <p/>
|
||||
* 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<File>,
|
||||
InitializingBean {
|
||||
|
||||
public class FileReadingMessageSource implements MessageSource<File>, 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<File>,
|
||||
* There is no locking around the queue, so there is also no iteration.
|
||||
*/
|
||||
private final Queue<File> toBeReceived;
|
||||
|
||||
private boolean scanEachPoll = false;
|
||||
|
||||
/**
|
||||
@@ -92,7 +89,7 @@ public class FileReadingMessageSource implements MessageSource<File>,
|
||||
*/
|
||||
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<File>,
|
||||
* @param receptionOrderComparator the comparator to be used to order the files in the internal queue
|
||||
*/
|
||||
public FileReadingMessageSource(Comparator<File> receptionOrderComparator) {
|
||||
toBeReceived = new PriorityBlockingQueue<File>(DEFAULT_INTERNAL_QUEUE_CAPACITY,
|
||||
receptionOrderComparator);
|
||||
toBeReceived = new PriorityBlockingQueue<File>(DEFAULT_INTERNAL_QUEUE_CAPACITY, receptionOrderComparator);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -137,13 +133,13 @@ public class FileReadingMessageSource implements MessageSource<File>,
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* <p/>
|
||||
* <b>The supplied filter must be thread safe.</b>.
|
||||
*/
|
||||
public void setFilter(FileListFilter filter) {
|
||||
public void setFilter(EntryListFilter<File> filter) {
|
||||
Assert.notNull(filter, "'filter' must not be null");
|
||||
this.scanner.setFilter(filter);
|
||||
}
|
||||
@@ -175,43 +171,50 @@ public class FileReadingMessageSource implements MessageSource<File>,
|
||||
|
||||
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<File> receive() throws MessagingException {
|
||||
Message<File> 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<File> filteredFiles = scanner.listFiles(directory);
|
||||
Set<File> freshFiles = new HashSet<File>(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<File>,
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn("Failed to send: " + failedMessage);
|
||||
}
|
||||
|
||||
toBeReceived.offer(failedMessage.getPayload());
|
||||
}
|
||||
|
||||
|
||||
@@ -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 <code>maxNumberOfFiles</code> 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<File> {
|
||||
private final int maxNumberOfFiles;
|
||||
|
||||
public HeadFilter(int maxNumberOfFiles) {
|
||||
this.maxNumberOfFiles = maxNumberOfFiles;
|
||||
}
|
||||
|
||||
public List<File> filterFiles(File[] files) {
|
||||
public List<File> filterEntries(File[] files) {
|
||||
return Arrays.asList(files).subList(0, Math.min(files.length, maxNumberOfFiles));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<FileListFilter> {
|
||||
public class FileListFilterFactoryBean implements FactoryBean<EntryListFilter<File>> {
|
||||
private volatile EntryListFilter<File> fileListFilter;
|
||||
private volatile EntryListFilter<File> filterReference;
|
||||
private volatile Pattern filenamePattern;
|
||||
private volatile Boolean preventDuplicates;
|
||||
private final Object monitor = new Object();
|
||||
private volatile Collection<EntryListFilter<File>> filterReferences;
|
||||
private FileEntryNamer fileNamer = new FileEntryNamer();
|
||||
|
||||
private volatile FileListFilter fileListFilter;
|
||||
public void setFilterReferences(Collection<EntryListFilter<File>> filterReferences) {
|
||||
this.filterReferences = filterReferences;
|
||||
}
|
||||
|
||||
private volatile FileListFilter filterReference;
|
||||
public void setFilterReference(EntryListFilter<File> 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<File> 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<File> 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<File> patternFilter = new PatternMatchingEntryListFilter<File>(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<File>();
|
||||
} else { // preventDuplicates is either TRUE or NULL
|
||||
flf = new AcceptOnceEntryFileListFilter<File>();
|
||||
}
|
||||
|
||||
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<File> flfc = new CompositeEntryListFilter<File>();
|
||||
|
||||
for (EntryListFilter<File> ff : filterReferences)
|
||||
flfc.addFilter(ff);
|
||||
|
||||
flf = flfc;
|
||||
}
|
||||
if( flf== null)flf =new CompositeEntryListFilter<File>();
|
||||
|
||||
this.fileListFilter = flf;
|
||||
}
|
||||
|
||||
private CompositeEntryListFilter<File> createCompositeWithAcceptOnceFilter(EntryListFilter<File> otherFilter) {
|
||||
CompositeEntryListFilter<File> compositeFilter = new CompositeEntryListFilter<File>();
|
||||
compositeFilter.addFilter(new AcceptOnceEntryFileListFilter<File>(), otherFilter);
|
||||
|
||||
return compositeFilter;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<FileRead
|
||||
|
||||
private volatile File directory;
|
||||
|
||||
private volatile FileListFilter filter;
|
||||
private volatile EntryListFilter<File> filter;
|
||||
|
||||
private volatile AbstractFileLockerFilter locker;
|
||||
|
||||
@@ -69,7 +69,7 @@ public class FileReadingMessageSourceFactoryBean implements FactoryBean<FileRead
|
||||
this.scanner = scanner;
|
||||
}
|
||||
|
||||
public void setFilter(FileListFilter filter) {
|
||||
public void setFilter(EntryListFilter<File> filter) {
|
||||
if (filter instanceof AbstractFileLockerFilter && this.locker == null) {
|
||||
this.setLocker((AbstractFileLockerFilter) filter);
|
||||
}
|
||||
@@ -133,7 +133,7 @@ public class FileReadingMessageSourceFactoryBean implements FactoryBean<FileRead
|
||||
if (this.locker == null) {
|
||||
this.source.setFilter(this.filter);
|
||||
} else {
|
||||
this.source.setFilter(new CompositeFileListFilter(this.filter, this.locker));
|
||||
this.source.setFilter(new CompositeEntryListFilter<File>(this.filter, this.locker));
|
||||
this.source.setLocker(locker);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<T> implements EntryListFilter<T> {
|
||||
|
||||
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<T> implements InitializingBean, EntryListFilter<T> {
|
||||
public abstract boolean accept(T t);
|
||||
|
||||
public List<T> filterEntries(T[] entries) {
|
||||
List<T> accepted = new ArrayList<T>();
|
||||
@@ -37,4 +47,8 @@ public abstract class AbstractEntryListFilter<T> implements EntryListFilter<T> {
|
||||
|
||||
return accepted;
|
||||
}
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
// its all you!
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 <T>
|
||||
*/
|
||||
public class AcceptAllEntryListFilter<T> extends AbstractEntryListFilter<T> {
|
||||
@Override
|
||||
public boolean accept(T t) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -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}.
|
||||
* <p/>
|
||||
* This implementation is thread safe.
|
||||
*
|
||||
* @author Iwein Fuld
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public class AcceptOnceEntryFileListFilter<T> extends AbstractEntryListFilter<T> {
|
||||
private final Queue<T> 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<T> extends AbstractEntryListFilter<T>
|
||||
this.seen = new LinkedBlockingQueue<T>();
|
||||
}
|
||||
|
||||
protected boolean accept(T pathname) {
|
||||
public boolean accept(T pathname) {
|
||||
synchronized (this.monitor) {
|
||||
if (seen.contains(pathname)) {
|
||||
return false;
|
||||
|
||||
@@ -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<T> implements EntryListFilter<T> {
|
||||
private final Set<EntryListFilter> fileFilters;
|
||||
private final Set<EntryListFilter<T>> fileFilters;
|
||||
|
||||
public CompositeEntryListFilter(EntryListFilter... fileFilters) {
|
||||
this.fileFilters = new LinkedHashSet<EntryListFilter>(Arrays.asList(fileFilters));
|
||||
public CompositeEntryListFilter(EntryListFilter<T>... fileFilters) {
|
||||
this.fileFilters = new LinkedHashSet<EntryListFilter<T>>(Arrays.asList(fileFilters));
|
||||
}
|
||||
|
||||
public CompositeEntryListFilter(Collection<EntryListFilter> fileFilters) {
|
||||
this.fileFilters = new LinkedHashSet<EntryListFilter>(fileFilters);
|
||||
public CompositeEntryListFilter(Collection<? extends EntryListFilter<T>> fileFilters) {
|
||||
this.fileFilters = new LinkedHashSet<EntryListFilter<T>>(fileFilters);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<T> filterEntries(T[] entries) {
|
||||
Assert.notNull(entries, "'files' should not be null");
|
||||
List<T> leftOver = Arrays.asList(entries);
|
||||
for (EntryListFilter fileFilter : this.fileFilters) {
|
||||
T[] ts =(T[]) leftOver.toArray();
|
||||
|
||||
List<T> leftOver = Arrays.asList(entries);
|
||||
|
||||
for (EntryListFilter<T> fileFilter : this.fileFilters) {
|
||||
T[] ts = (T[]) leftOver.toArray();
|
||||
leftOver = fileFilter.filterEntries(ts);
|
||||
}
|
||||
|
||||
return leftOver;
|
||||
}
|
||||
|
||||
@@ -47,7 +52,7 @@ public class CompositeEntryListFilter<T> implements EntryListFilter<T> {
|
||||
* @return this CompositeFileFilter instance with the added filters
|
||||
* @see #addFilters(Collection)
|
||||
*/
|
||||
public CompositeEntryListFilter addFilter(EntryListFilter... filters) {
|
||||
public CompositeEntryListFilter addFilter(EntryListFilter<T>... filters) {
|
||||
return addFilters(Arrays.asList(filters));
|
||||
}
|
||||
|
||||
@@ -59,7 +64,16 @@ public class CompositeEntryListFilter<T> implements EntryListFilter<T> {
|
||||
* @param filtersToAdd a list of filters to add
|
||||
* @return this CompositeEntryListFilter instance with the added filters
|
||||
*/
|
||||
public CompositeEntryListFilter addFilters(Collection<EntryListFilter> filtersToAdd) {
|
||||
public CompositeEntryListFilter addFilters(Collection<EntryListFilter<T>> filtersToAdd) {
|
||||
for (EntryListFilter<T> elf : filtersToAdd)
|
||||
if (elf instanceof InitializingBean) {
|
||||
try {
|
||||
((InitializingBean) elf).afterPropertiesSet();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
this.fileFilters.addAll(filtersToAdd);
|
||||
|
||||
return this;
|
||||
|
||||
@@ -18,6 +18,19 @@ package org.springframework.integration.file.entries;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public interface EntryListFilter <T> {
|
||||
List<T> filterEntries(T [] entries );
|
||||
/**
|
||||
* Strategy interface for filtering a group of entries / files.
|
||||
* <p/>
|
||||
* {@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}.
|
||||
* <p/>
|
||||
* This implementation is thread safe.
|
||||
*
|
||||
* @author Iwein Fuld
|
||||
* @author Josh Long
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public interface EntryListFilter<T> {
|
||||
List<T> filterEntries(T[] entries);
|
||||
}
|
||||
|
||||
@@ -15,6 +15,21 @@
|
||||
*/
|
||||
package org.springframework.integration.file.entries;
|
||||
|
||||
/**
|
||||
* Responsible for coercing a String identification out of the {@link T} entry.
|
||||
* @param <T> the type of entry (there's an implementation for FTP, SFTP, and plain-old java.io.Files)
|
||||
*
|
||||
* @author Josh Long
|
||||
*/
|
||||
public interface EntryNamer<T> {
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
@@ -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<File> {
|
||||
public String nameOf(File entry) {
|
||||
return (entry != null) ? entry.getName() : null;
|
||||
}
|
||||
}
|
||||
@@ -24,16 +24,29 @@ import java.util.regex.Pattern;
|
||||
|
||||
|
||||
/**
|
||||
* experimental
|
||||
* <emphasis>experimental</emphasis>
|
||||
* <p/>
|
||||
* 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 <T> the type of entry
|
||||
*/
|
||||
public abstract class PatternMatchingEntryListFilter<T> extends AbstractEntryListFilter<T> implements InitializingBean {
|
||||
public class PatternMatchingEntryListFilter<T> extends AbstractEntryListFilter<T> implements InitializingBean {
|
||||
private Pattern pattern;
|
||||
private String patternExpression;
|
||||
private EntryNamer<T> entryNamer;
|
||||
|
||||
public PatternMatchingEntryListFilter(EntryNamer<T> en, String p) {
|
||||
this.entryNamer = en;
|
||||
this.patternExpression = p;
|
||||
}
|
||||
|
||||
public PatternMatchingEntryListFilter(EntryNamer<T> 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<T> 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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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 <b>one</b> argument instea of an array
|
||||
*
|
||||
* @author Josh Long
|
||||
*/
|
||||
public class SingleEntryAdaptingEntryListFilter<T> extends AbstractEntryListFilter<T> {
|
||||
|
||||
/**
|
||||
* the {@link org.springframework.integration.file.entries.EntryListFilter} that you'd like to delegate to
|
||||
*/
|
||||
private volatile EntryListFilter<T> entryFilter;
|
||||
|
||||
public SingleEntryAdaptingEntryListFilter(EntryListFilter<T> 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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
@@ -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}.
|
||||
* <p/>
|
||||
* This implementation is thread safe.
|
||||
*
|
||||
* @author Iwein Fuld
|
||||
* @since 1.0.0
|
||||
*/
|
||||
*/ @Deprecated
|
||||
public class AcceptOnceFileListFilter extends AbstractFileListFilter {
|
||||
|
||||
private final Queue<File> seen;
|
||||
@@ -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<FileListFilter> fileFilters;
|
||||
@@ -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 {
|
||||
|
||||
/**
|
||||
@@ -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;
|
||||
@@ -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<File> implements FileLocker {
|
||||
|
||||
protected final boolean accept(File file) {
|
||||
return isLockable(file);
|
||||
@Override
|
||||
public boolean accept(File file) {
|
||||
return this.isLockable(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
* <p/>
|
||||
* In the meantime, this provides us with a base class for building event driven file adapters quickly. The two cases I see are:
|
||||
* <p/>
|
||||
* <ol>
|
||||
* <li></li>
|
||||
* <li></li>
|
||||
* </ol>
|
||||
*
|
||||
* @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<File> 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<File> 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<File> filter) {
|
||||
this.filter = new SingleEntryAdaptingEntryListFilter<File>(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<File>(this.maxQueueSize);
|
||||
|
||||
if (this.executor == null) {
|
||||
this.executor = new SimpleAsyncTaskExecutor();
|
||||
}
|
||||
|
||||
if (this.filter == null) {
|
||||
this.filter = new SingleEntryAdaptingEntryListFilter<File>(new AcceptAllEntryListFilter<File>());
|
||||
}
|
||||
|
||||
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 <File> acceptOnceEntryFileListFilter=new AcceptOnceEntryFileListFilter<File>() ;
|
||||
acceptOnceEntryFileListFilter.afterPropertiesSet();
|
||||
PatternMatchingEntryListFilter <File> patternMatchingEntryListFilter=
|
||||
new PatternMatchingEntryListFilter<File>(new FileEntryNamer(), ".*?jpg");
|
||||
patternMatchingEntryListFilter.afterPropertiesSet();
|
||||
|
||||
Collection<? extends EntryListFilter<File>> l=Arrays.asList( acceptOnceEntryFileListFilter, patternMatchingEntryListFilter);
|
||||
CompositeEntryListFilter compositeEntryListFilter = new CompositeEntryListFilter<File>(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) {
|
||||
//
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
*/
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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<File> fileMsg = MessageBuilder.withPayload(f).build();
|
||||
this.messagingTemplate.send(fileMsg);
|
||||
}
|
||||
}
|
||||
@@ -53,7 +53,7 @@
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="org.springframework.integration.file.FileListFilter"/>
|
||||
<tool:expected-type type="org.springframework.integration.file.filters.FileListFilter"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:expected-type type="org.springframework.integration.file.FileListFilter"/>
|
||||
<tool:expected-type type="org.springframework.integration.file.entries.EntryListFilter"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
|
||||
@@ -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<File> returnedFiles = Arrays.asList(new File[] { fileMock });
|
||||
when(fileFilterMock1.filterFiles(isA(File[].class))).thenReturn(returnedFiles);
|
||||
when(fileFilterMock2.filterFiles(isA(File[].class))).thenReturn(returnedFiles);
|
||||
|
||||
@@ -1,28 +1,49 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:p="http://www.springframework.org/schema/p"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd">
|
||||
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">
|
||||
|
||||
<!-- under test -->
|
||||
<bean id="pollableFileSource" class="org.springframework.integration.file.FileReadingMessageSource"
|
||||
p:directory="file:${java.io.tmpdir}/FileReadingMessageSourceIntegrationTests"
|
||||
p:filter-ref="compositeFilter"/>
|
||||
<!-- under test -->
|
||||
<bean id="pollableFileSource" class="org.springframework.integration.file.FileReadingMessageSource"
|
||||
p:directory="file:${java.io.tmpdir}/FileReadingMessageSourceIntegrationTests"
|
||||
p:filter-ref="compositeFilter"/>
|
||||
|
||||
<!-- customized filter -->
|
||||
<bean id="compositeFilter" class="org.springframework.integration.file.CompositeFileListFilter">
|
||||
<constructor-arg>
|
||||
<list>
|
||||
<bean class="org.springframework.integration.file.AcceptOnceFileListFilter" />
|
||||
<bean class="org.springframework.integration.file.TestFileListFilter" />
|
||||
<bean class="org.springframework.integration.file.PatternMatchingFileListFilter">
|
||||
<constructor-arg value="^test.*$"/>
|
||||
</bean>
|
||||
</list>
|
||||
</constructor-arg>
|
||||
</bean>
|
||||
<bean class="org.springframework.integration.file.entries.FileEntryNamer" id="entryNamer"/>
|
||||
|
||||
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" />
|
||||
<!-- customized filter -->
|
||||
<!--
|
||||
<bean id="compositeFilter" class="org.springframework.integration.file.entries.CompositeEntryListFilter">
|
||||
<constructor-arg>
|
||||
<list>
|
||||
<bean class="org.springframework.integration.file.entries.AcceptOnceEntryFileListFilter"/>
|
||||
<bean class="org.springframework.integration.file.TestFileListFilter"/>
|
||||
<bean class="org.springframework.integration.file.entries.PatternMatchingEntryListFilter">
|
||||
<constructor-arg ref="entryNamer"/>
|
||||
<constructor-arg value="^test.*$"/>
|
||||
</bean>
|
||||
</list>
|
||||
</constructor-arg>
|
||||
</bean>
|
||||
-->
|
||||
|
||||
</beans>
|
||||
|
||||
<bean class="org.springframework.integration.file.config.FileListFilterFactoryBean" id="compositeFilter">
|
||||
<property name="filterReferences">
|
||||
|
||||
<util:list>
|
||||
|
||||
<bean class="org.springframework.integration.file.config.FileListFilterFactoryBean" p:preventDuplicates="true"/>
|
||||
<bean class="org.springframework.integration.file.config.FileListFilterFactoryBean" p:preventDuplicates="false"/>
|
||||
<bean class="org.springframework.integration.file.config.FileListFilterFactoryBean" p:filenamePattern="^test.*$"/>
|
||||
|
||||
</util:list>
|
||||
|
||||
</property>
|
||||
|
||||
</bean>
|
||||
|
||||
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"/>
|
||||
|
||||
</beans>
|
||||
|
||||
@@ -80,7 +80,8 @@ public class FileReadingMessageSourceIntegrationTests {
|
||||
@Test
|
||||
public void getFiles() throws Exception {
|
||||
Message<File> 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<File> 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();
|
||||
|
||||
@@ -1,46 +1,48 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns:file="http://www.springframework.org/schema/integration/file"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:si="http://www.springframework.org/schema/integration"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:p="http://www.springframework.org/schema/p" xmlns:si="http://www.springframework.org/schema/integration" 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/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd
|
||||
http://www.springframework.org/schema/integration/file
|
||||
http://www.springframework.org/schema/integration/file/spring-integration-file.xsd">
|
||||
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">
|
||||
|
||||
<!-- under test -->
|
||||
<file:inbound-channel-adapter
|
||||
directory="#{inputDirectory.path}"
|
||||
channel="fileMessages" filter="compositeFilter"/>
|
||||
<!-- under test -->
|
||||
<file:inbound-channel-adapter
|
||||
directory="#{inputDirectory.path}"
|
||||
channel="fileMessages" filter="compositeFilter"/>
|
||||
|
||||
<bean id="temp" class="org.junit.rules.TemporaryFolder"
|
||||
init-method="create" destroy-method="delete"/>
|
||||
<bean id="temp" class="org.junit.rules.TemporaryFolder"
|
||||
init-method="create" destroy-method="delete"/>
|
||||
|
||||
<bean id="inputDirectory" class="java.io.File">
|
||||
<constructor-arg value="#{temp.newFolder('FileToChannelIntegrationTests').path}"/>
|
||||
</bean>
|
||||
<bean id="inputDirectory" class="java.io.File">
|
||||
<constructor-arg value="#{temp.newFolder('FileToChannelIntegrationTests').path}"/>
|
||||
</bean>
|
||||
|
||||
<si:channel id="fileMessages">
|
||||
<si:queue capacity="10" />
|
||||
</si:channel>
|
||||
<si:channel id="fileMessages">
|
||||
<si:queue capacity="10"/>
|
||||
</si:channel>
|
||||
|
||||
<!-- customized filter -->
|
||||
<bean id="compositeFilter"
|
||||
class="org.springframework.integration.file.CompositeFileListFilter">
|
||||
<constructor-arg>
|
||||
<list>
|
||||
<bean class="org.springframework.integration.file.AcceptOnceFileListFilter"/>
|
||||
<bean class="org.springframework.integration.file.TestFileListFilter"/>
|
||||
<bean class="org.springframework.integration.file.PatternMatchingFileListFilter">
|
||||
<constructor-arg value="^test.*$"/>
|
||||
</bean>
|
||||
</list>
|
||||
</constructor-arg>
|
||||
</bean>
|
||||
|
||||
<si:poller default="true" fixed-rate="10"/>
|
||||
<bean class="org.springframework.integration.file.config.FileListFilterFactoryBean" id="compositeFilter">
|
||||
<property name="filterReferences">
|
||||
|
||||
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"/>
|
||||
<util:list>
|
||||
|
||||
</beans>
|
||||
<bean class="org.springframework.integration.file.config.FileListFilterFactoryBean" p:preventDuplicates="true"/>
|
||||
<bean class="org.springframework.integration.file.config.FileListFilterFactoryBean" p:preventDuplicates="false"/>
|
||||
<bean class="org.springframework.integration.file.config.FileListFilterFactoryBean" p:filenamePattern="^test.*$"/>
|
||||
|
||||
</util:list>
|
||||
|
||||
</property>
|
||||
|
||||
</bean>
|
||||
|
||||
<si:poller default="true" fixed-rate="10"/>
|
||||
|
||||
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"/>
|
||||
|
||||
</beans>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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<File> filterFiles(File[] files) {
|
||||
return Arrays.asList(files);
|
||||
}
|
||||
|
||||
public class TestFileListFilter implements EntryListFilter<File> {
|
||||
public List<File> filterEntries(File[] entries) {
|
||||
return Arrays.asList(entries);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,15 +20,19 @@
|
||||
</integration:poller>
|
||||
</inbound-channel-adapter>
|
||||
|
||||
<beans:bean id="filter" class="org.springframework.integration.file.CompositeFileListFilter">
|
||||
<beans:bean id="filter" class="org.springframework.integration.file.config.FileListFilterFactoryBean">
|
||||
|
||||
</beans:bean>
|
||||
<!--
|
||||
<beans:bean id="filter" class="org.springframework.integration.file.filters.CompositeFileListFilter">
|
||||
<beans:constructor-arg>
|
||||
<beans:list></beans:list>
|
||||
</beans:constructor-arg>
|
||||
</beans:bean>
|
||||
</beans:bean>-->
|
||||
|
||||
<beans:bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"/>
|
||||
|
||||
<beans:bean id="testComparator"
|
||||
class="org.springframework.integration.file.config.FileInboundChannelAdapterParserTests$TestComparator"/>
|
||||
|
||||
</beans:beans>
|
||||
</beans:beans>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user