RESOLVED - issue BATCH-88: StatisticsProvider is a leaky abstraction
http://jira.springframework.org/browse/BATCH-88
This commit is contained in:
@@ -11,14 +11,13 @@ import org.springframework.batch.item.ItemReader;
|
||||
import org.springframework.batch.restart.GenericRestartData;
|
||||
import org.springframework.batch.restart.RestartData;
|
||||
import org.springframework.batch.restart.Restartable;
|
||||
import org.springframework.batch.statistics.StatisticsProvider;
|
||||
|
||||
/**
|
||||
* Runs a collection of ItemProcessors in fixed-order sequence.
|
||||
*
|
||||
* @author Robert Kasanicky
|
||||
*/
|
||||
public class CompositeItemProcessor implements ItemProcessor, Restartable, StatisticsProvider {
|
||||
public class CompositeItemProcessor implements ItemProcessor, Restartable {
|
||||
|
||||
private static final String SEPARATOR = "#";
|
||||
|
||||
@@ -72,23 +71,6 @@ public class CompositeItemProcessor implements ItemProcessor, Restartable, Stati
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Properties containing statistics of all injected ItemProcessors,
|
||||
* property keys are prefixed with the list index of the ItemProcessor.
|
||||
*/
|
||||
public Properties getStatistics() {
|
||||
return createCompoundProperties(new PropertiesExtractor() {
|
||||
public Properties extractProperties(Object o) {
|
||||
if (o instanceof StatisticsProvider) {
|
||||
return ((StatisticsProvider) o).getStatistics();
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setItemProcessors(List itemProcessors) {
|
||||
this.itemProcessors = itemProcessors;
|
||||
}
|
||||
|
||||
@@ -8,24 +8,23 @@ import org.springframework.batch.item.ItemWriter;
|
||||
import org.springframework.batch.restart.GenericRestartData;
|
||||
import org.springframework.batch.restart.RestartData;
|
||||
import org.springframework.batch.restart.Restartable;
|
||||
import org.springframework.batch.statistics.StatisticsProvider;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Simple wrapper around {@link ItemWriter} providing {@link Restartable} and
|
||||
* {@link StatisticsProvider} where the {@link ItemWriter} does.
|
||||
* Simple wrapper around {@link ItemWriter} providing {@link Restartable} where
|
||||
* the {@link ItemWriter} does. To make sure
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Robert Kasanicky
|
||||
*/
|
||||
public class ItemWriterItemProcessor implements ItemProcessor, Restartable, Skippable,
|
||||
StatisticsProvider, InitializingBean {
|
||||
public class ItemWriterItemProcessor implements ItemProcessor, Restartable, Skippable, InitializingBean {
|
||||
|
||||
private ItemWriter writer;
|
||||
|
||||
/**
|
||||
* Calls {@link #doProcess(Object)} and then writes the result to the {@link ItemWriter}.
|
||||
* Calls {@link #doProcess(Object)} and then writes the result to the
|
||||
* {@link ItemWriter}.
|
||||
*
|
||||
* @see org.springframework.batch.item.ItemProcessor#process(java.lang.Object)
|
||||
*/
|
||||
@@ -35,8 +34,8 @@ public class ItemWriterItemProcessor implements ItemProcessor, Restartable, Skip
|
||||
}
|
||||
|
||||
/**
|
||||
* By default returns the argument. This method is an extension point
|
||||
* meant to be overridden by subclasses that implement processing logic.
|
||||
* By default returns the argument. This method is an extension point meant
|
||||
* to be overridden by subclasses that implement processing logic.
|
||||
*/
|
||||
protected Object doProcess(Object item) throws Exception {
|
||||
return item;
|
||||
@@ -53,13 +52,13 @@ public class ItemWriterItemProcessor implements ItemProcessor, Restartable, Skip
|
||||
* @see Restartable#getRestartData()
|
||||
*/
|
||||
public RestartData getRestartData() {
|
||||
|
||||
|
||||
Assert.state(writer != null, "Source must not be null.");
|
||||
|
||||
|
||||
if (writer instanceof Restartable) {
|
||||
return ((Restartable) writer).getRestartData();
|
||||
}
|
||||
else{
|
||||
else {
|
||||
return new GenericRestartData(new Properties());
|
||||
}
|
||||
}
|
||||
@@ -68,35 +67,21 @@ public class ItemWriterItemProcessor implements ItemProcessor, Restartable, Skip
|
||||
* @see Restartable#restoreFrom(RestartData)
|
||||
*/
|
||||
public void restoreFrom(RestartData data) {
|
||||
|
||||
|
||||
Assert.state(writer != null, "Source must not be null.");
|
||||
|
||||
|
||||
if (writer instanceof Restartable) {
|
||||
((Restartable) writer).restoreFrom(data);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return delegates to the parent template of it is a
|
||||
* {@link StatisticsProvider}, otherwise returns an empty
|
||||
* {@link Properties} instance.
|
||||
* @see StatisticsProvider#getStatistics()
|
||||
*/
|
||||
public Properties getStatistics() {
|
||||
if (!(writer instanceof StatisticsProvider)) {
|
||||
return new Properties();
|
||||
}
|
||||
return ((StatisticsProvider) writer).getStatistics();
|
||||
}
|
||||
|
||||
public void skip() {
|
||||
if (writer instanceof Skippable) {
|
||||
((Skippable)writer).skip();
|
||||
((Skippable) writer).skip();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
Assert.notNull(writer);
|
||||
}
|
||||
|
||||
@@ -16,13 +16,10 @@
|
||||
|
||||
package org.springframework.batch.item.reader;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import org.springframework.batch.io.Skippable;
|
||||
import org.springframework.batch.item.ItemReader;
|
||||
import org.springframework.batch.restart.RestartData;
|
||||
import org.springframework.batch.restart.Restartable;
|
||||
import org.springframework.batch.statistics.StatisticsProvider;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -33,7 +30,7 @@ import org.springframework.util.Assert;
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class DelegatingItemReader extends AbstractItemReader implements Restartable, StatisticsProvider, Skippable, InitializingBean{
|
||||
public class DelegatingItemReader extends AbstractItemReader implements Restartable, Skippable, InitializingBean{
|
||||
|
||||
private ItemReader inputSource;
|
||||
|
||||
@@ -73,19 +70,6 @@ public class DelegatingItemReader extends AbstractItemReader implements Restarta
|
||||
((Restartable) inputSource).restoreFrom(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return delegates to the parent template of it is a
|
||||
* {@link StatisticsProvider}, otherwise returns an empty
|
||||
* {@link Properties} instance.
|
||||
* @see StatisticsProvider#getStatistics()
|
||||
*/
|
||||
public Properties getStatistics() {
|
||||
if (!(inputSource instanceof StatisticsProvider)) {
|
||||
return new Properties();
|
||||
}
|
||||
return ((StatisticsProvider) inputSource).getStatistics();
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for input source.
|
||||
* @param source
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright 2006-2007 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.batch.statistics;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Simple {@link StatisticsService} that makes no attempt to aggregate or
|
||||
* resolve conflicts between key names. All the contributions registered are
|
||||
* simply polled and added "as is" to the aggregate properties.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class SimpleStatisticsService implements StatisticsService {
|
||||
|
||||
private Map registry = new HashMap();
|
||||
|
||||
/**
|
||||
* Simple aggregate statistics provider for the contributions registered
|
||||
* under the given key.
|
||||
*
|
||||
* @see org.springframework.batch.statistics.StatisticsService#getStatistics(java.lang.Object)
|
||||
*/
|
||||
public Properties getStatistics(Object key) {
|
||||
Set set = new LinkedHashSet();
|
||||
synchronized (registry) {
|
||||
Collection collection = (Collection) registry.get(key);
|
||||
if (collection != null) {
|
||||
set = new LinkedHashSet(collection);
|
||||
}
|
||||
}
|
||||
return aggregate(set);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param list a list of {@link StatisticsProvider}s
|
||||
* @return aggregated statistics
|
||||
*/
|
||||
private Properties aggregate(Collection list) {
|
||||
Properties result = new Properties();
|
||||
for (Iterator iterator = list.iterator(); iterator.hasNext();) {
|
||||
StatisticsProvider provider = (StatisticsProvider) iterator.next();
|
||||
Properties properties = provider.getStatistics();
|
||||
if (properties != null) {
|
||||
result.putAll(properties);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a {@link StatisticsProvider} as one of the interesting providers
|
||||
* under the provided key.
|
||||
*
|
||||
* @see org.springframework.batch.statistics.StatisticsService#register(java.lang.Object,
|
||||
* org.springframework.batch.statistics.StatisticsProvider)
|
||||
*/
|
||||
public void register(Object key, StatisticsProvider provider) {
|
||||
synchronized (registry) {
|
||||
Set set = (Set) registry.get(key);
|
||||
if (set == null) {
|
||||
set = new LinkedHashSet();
|
||||
registry.put(key, set);
|
||||
}
|
||||
set.add(provider);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -20,7 +20,7 @@ import java.util.Properties;
|
||||
|
||||
/**
|
||||
* Provides statistics for a given module run. Any class that implements
|
||||
* this interface is garunteeing that it will provide Statistics.
|
||||
* this interface is guaranteeing that it will provide Statistics.
|
||||
*
|
||||
* @author Lucas Ward
|
||||
*
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2006-2007 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.batch.statistics;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* Generalised statistics aggregation strategy. Clients register
|
||||
* {@link StatisticsProvider} instances under a well-known key, and then when
|
||||
* they ask for statistics by that key, they receive an aggregate of all the
|
||||
* values given by registered providers.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public interface StatisticsService {
|
||||
|
||||
/**
|
||||
* Register the {@link StatisticsProvider} instance as one of possibly
|
||||
* several that are associated with the given key.
|
||||
*
|
||||
* @param key the key under which to add the provider
|
||||
* @param provider a {@link StatisticsProvider}
|
||||
*/
|
||||
void register(Object key, StatisticsProvider provider);
|
||||
|
||||
/**
|
||||
* Extract and aggregate the statistics from all providers under this key.
|
||||
*
|
||||
* @param key the key under which {@link StatisticsProvider} instances might
|
||||
* have been registered.
|
||||
* @return {@link Properties} summarising the statistics of all providers
|
||||
* registered under this key, or empty otherwise.
|
||||
*/
|
||||
Properties getStatistics(Object key);
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user