ElementFilter now CollectionFilter

Refactored filter to handle a Collection of Resources

Made 'pattern' a constructor-arg since it's mandatory
This commit is contained in:
Mark Fisher
2011-11-22 12:57:48 -05:00
parent 193f3d2439
commit 32d64b19f4
5 changed files with 72 additions and 58 deletions

View File

@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.config.xml;
import org.springframework.beans.BeanMetadataElement;
@@ -33,7 +34,7 @@ public class ResourceInboundChannelAdapterParser extends AbstractPollingInboundC
@Override
protected BeanMetadataElement parseSource(Element element, ParserContext parserContext) {
BeanDefinitionBuilder sourceBuilder = BeanDefinitionBuilder.genericBeanDefinition(ResourceMessageSource.class);
IntegrationNamespaceUtils.setValueIfAttributeDefined(sourceBuilder, element, "pattern");
sourceBuilder.addConstructorArgValue(element.getAttribute("pattern"));
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(sourceBuilder, element, "pattern-resolver");
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(sourceBuilder, element, "filter");
return sourceBuilder.getBeanDefinition();

View File

@@ -16,8 +16,8 @@
package org.springframework.integration.resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Arrays;
import java.util.Collection;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
@@ -27,8 +27,9 @@ import org.springframework.core.io.Resource;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.integration.MessagingException;
import org.springframework.integration.endpoint.AbstractMessageSource;
import org.springframework.integration.util.ElementFilter;
import org.springframework.integration.util.CollectionFilter;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
/**
@@ -36,28 +37,31 @@ import org.springframework.util.ObjectUtils;
* attempt to resolve {@link Resource}s based on the pattern specified.
*
* @author Oleg Zhurakousky
* @author Mark Fisher
* @since 2.1
*/
public class ResourceMessageSource extends AbstractMessageSource<Resource[]> implements ApplicationContextAware, InitializingBean {
private volatile String pattern;
private final String pattern;
private volatile ApplicationContext applicationContext;
private volatile ResourcePatternResolver patternResolver;
private volatile ElementFilter<Resource> filter;
private volatile CollectionFilter<Resource> filter;
public ResourceMessageSource(String pattern) {
Assert.hasText(pattern, "pattern must not be empty");
this.pattern = pattern;
}
public void setPatternResolver(ResourcePatternResolver patternResolver) {
this.patternResolver = patternResolver;
}
public void setPattern(String pattern) {
this.pattern = pattern;
}
public void setFilter(ElementFilter<Resource> filter) {
public void setFilter(CollectionFilter<Resource> filter) {
this.filter = filter;
}
@@ -71,8 +75,7 @@ public class ResourceMessageSource extends AbstractMessageSource<Resource[]> imp
this.patternResolver = this.applicationContext;
}
}
Assert.notNull(this.patternResolver, "no 'patternResolver' is specified");
Assert.hasText(this.pattern, "'pattern' must be specified");
Assert.notNull(this.patternResolver, "no 'patternResolver' available");
}
@Override
@@ -80,14 +83,8 @@ public class ResourceMessageSource extends AbstractMessageSource<Resource[]> imp
try {
Resource[] resources = this.patternResolver.getResources(this.pattern);
if (this.filter != null && !ObjectUtils.isEmpty(resources)) {
List<Resource> filteredResources = new ArrayList<Resource>();
for (Resource resource : resources) {
Resource filteredResource = this.filter.filter(resource);
if (filteredResource != null) {
filteredResources.add(filteredResource);
}
}
if (filteredResources.size() == 0) {
Collection<Resource> filteredResources = this.filter.filter(Arrays.asList(resources));
if (CollectionUtils.isEmpty(filteredResources)) {
resources = null;
}
else {

View File

@@ -13,40 +13,59 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.util;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.Assert;
/**
* An implementation of {@link ElementFilter} which will queue all items that's been seen until
* An implementation of {@link CollectionFilter} which will queue all items that have been seen until
* the queue reaches its capacity after which one item from the queue will be purged to make room for a
* new item to be added. Note that however unlikely the removed item will now appear as unprocessed
* so it is highly recommended to move/delete resources which corresponds to the underlying items once processing
* is done to eliminate duplicate processing.
*
* @author Oleg Zhurakousky
* @author Mark Fisher
* @since 2.1
*/
public class AcceptOnceUntilPurgedElementFilter<T> implements ElementFilter<T> {
public class AcceptOnceUntilPurgedElementFilter<T> implements CollectionFilter<T> {
private final Log logger = LogFactory.getLog(this.getClass());
private final Queue<T> seenItems;
private final Object seenQueueMonitor = new Object();
public AcceptOnceUntilPurgedElementFilter(){
public AcceptOnceUntilPurgedElementFilter() {
this(Integer.MAX_VALUE);
}
public AcceptOnceUntilPurgedElementFilter(int maxCapacity){
seenItems = new LinkedBlockingQueue<T>(maxCapacity);
public AcceptOnceUntilPurgedElementFilter(int maxCapacity) {
this.seenItems = new LinkedBlockingQueue<T>(maxCapacity);
}
public Collection<T> filter(Collection<T> unfilteredElements) {
Assert.notNull(unfilteredElements, "'unfilteredElements' must not be null");
List<T> filteredElements = new ArrayList<T>();
if (unfilteredElements.size() > 0) {
for (T element : unfilteredElements) {
if (this.accept(element)) {
filteredElements.add(element);
}
}
}
return filteredElements;
}
private boolean accept(T item) {
@@ -67,15 +86,4 @@ public class AcceptOnceUntilPurgedElementFilter<T> implements ElementFilter<T> {
}
}
public T filter(T unfilteredElement) {
Assert.notNull(unfilteredElement, "'unfilteredElement' must not be null");
if (this.accept(unfilteredElement)){
return unfilteredElement;
}
else {
return null;
}
}
}

View File

@@ -13,16 +13,20 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.util;
import java.util.Collection;
/**
* Base strategy for filtering out an element
* Base strategy for filtering out a subset of a Collection of elements.
*
* @author Oleg Zhurakousky
* @author Mark Fisher
* @since 2.1
*/
public interface ElementFilter<T> {
public interface CollectionFilter<T> {
Collection<T> filter(Collection<T> unfilteredElements);
T filter(T unfilteredElement);
}

View File

@@ -13,9 +13,18 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.resource;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.io.File;
import java.util.Collection;
import java.util.Collections;
import org.junit.Test;
@@ -27,13 +36,8 @@ import org.springframework.integration.Message;
import org.springframework.integration.channel.QueueChannel;
import org.springframework.integration.endpoint.SourcePollingChannelAdapter;
import org.springframework.integration.test.util.TestUtils;
import org.springframework.integration.util.ElementFilter;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import org.springframework.integration.util.CollectionFilter;
import org.springframework.util.CollectionUtils;
/**
* @author Oleg Zhurakousky
@@ -114,19 +118,19 @@ public class ResourcePatternResolverParserTests {
assertNull(message);
}
public static class OneItemAndNeverAgainResourceListFilter implements ElementFilter<Resource> {
public static class OneItemAndNeverAgainResourceListFilter implements CollectionFilter<Resource> {
private volatile boolean once = false;
public Resource filter(Resource unfilteredElement) {
if (!once){
public Collection<Resource> filter(Collection<Resource> unfilteredResources) {
if (!once && !CollectionUtils.isEmpty(unfilteredResources)) {
once = true;
return unfilteredElement;
return Collections.singletonList(unfilteredResources.iterator().next());
}
return null;
}
}
}