package eu.dnetlib.enabling.resultset;

import java.util.List;

import javax.xml.bind.JAXBException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.google.common.collect.Lists;

import eu.dnetlib.miscutils.collections.MappedCollection;
import eu.dnetlib.miscutils.functional.UnaryFunction;
import eu.dnetlib.miscutils.jaxb.JaxbFactory;

/**
 * Given a jaxb factory for a given type, wraps TypedResultsetListeners to ResultSetListeners, serializing objects
 * according to the jaxb factory.
 * 
 * @author marko
 * 
 * @param <T>
 */
public class JaxbResultsetListenerWrapper<T> {
	private static final Log log = LogFactory.getLog(JaxbResultsetListenerWrapper.class); // NOPMD by marko on 11/24/08 5:02 PM

	private JaxbFactory<T> factory;

	/**
	 * Returns a listener which serializes each item according to the jaxb factory.
	 * 
	 * @param listener
	 *            listener which returns T
	 * @return listener which returns strings
	 */
	public ResultSetListener wrap(final TypedResultSetListener<T> listener) {
		return new ResultSetListener() {

			@Override
			public List<String> getResult(final int fromPosition, final int toPosition) {
				return Lists.newArrayList(new MappedCollection<String, T>(listener.getResult(fromPosition, toPosition), new UnaryFunction<String, T>() {
					@Override
					public String evaluate(final T value) {
						try {
							return factory.serialize(value);
						} catch (final JAXBException e) {
							log.warn("cannot serialize", e);
							throw new RuntimeException(e);
						}
					}
				}));
			}

			@Override
			public int getSize() {
				return listener.getSize();
			}
		};
	}

	public JaxbFactory<T> getFactory() {
		return factory;
	}

	public void setFactory(final JaxbFactory<T> factory) {
		this.factory = factory;
	}
}
