added dnet-core-services, which embeds old cnr-notifications-common, cnr-blackboard-common, cnr-resultset-service
This commit is contained in:
parent
ec964c0c47
commit
c121531bdc
|
@ -16,10 +16,14 @@ import org.dom4j.Document;
|
|||
import org.dom4j.DocumentException;
|
||||
import org.dom4j.io.SAXReader;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
|
||||
@Ignore
|
||||
// TODO investigate why it takes so long to run
|
||||
// Time elapsed: 303.806 sec - in eu.dnetlib.miscutils.iterators.xml.IterableXmlParserTest
|
||||
public class IterableXmlParserTest {
|
||||
|
||||
private Resource xmlZip = new ClassPathResource("eu/dnetlib/miscutils/iterators/xml/opendoar.zip");
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>eu.dnetlib</groupId>
|
||||
<artifactId>dnet-core</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>dnet-core-services</artifactId>
|
||||
<groupId>eu.dnetlib</groupId>
|
||||
<packaging>jar</packaging>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>eu.dnetlib</groupId>
|
||||
<artifactId>dnet-core-components</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,61 @@
|
|||
package eu.dnetlib.enabling.hcm;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.factory.annotation.Required;
|
||||
|
||||
import eu.dnetlib.enabling.hcm.rmi.HostingContextManagerService;
|
||||
import eu.dnetlib.enabling.tools.AbstractBaseService;
|
||||
import eu.dnetlib.enabling.tools.blackboard.NotificationHandler;
|
||||
|
||||
/**
|
||||
* CNR HostingContextManagerService implementation. Will conflict with NKUA! yes this is ok.
|
||||
*
|
||||
* @author marko
|
||||
*
|
||||
*/
|
||||
public class HostingContextManagerServiceImpl extends AbstractBaseService implements HostingContextManagerService {
|
||||
|
||||
/**
|
||||
* logger.
|
||||
*/
|
||||
private static final Log log = LogFactory.getLog(HostingContextManagerServiceImpl.class); // NOPMD by marko on 11/24/08 5:02 PM
|
||||
|
||||
/**
|
||||
* notification handler.
|
||||
*/
|
||||
private NotificationHandler notificationHandler; // NOPMD
|
||||
|
||||
@Override
|
||||
public void notify(String subscrId, String topic, String isId, String message) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("---- service got notification ----");
|
||||
log.debug("subscrId: " + subscrId);
|
||||
log.debug("topic " + topic);
|
||||
log.debug("isId " + isId);
|
||||
log.debug("msg: " + message);
|
||||
log.debug("____ now processing the notification ____");
|
||||
}
|
||||
getNotificationHandler().notified(subscrId, topic, isId, message);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see eu.dnetlib.enabling.tools.AbstractBaseService#start()
|
||||
*/
|
||||
@Override
|
||||
public void start() {
|
||||
log.info("staring hosting context manager");
|
||||
}
|
||||
|
||||
public NotificationHandler getNotificationHandler() {
|
||||
return notificationHandler;
|
||||
}
|
||||
|
||||
@Required
|
||||
public void setNotificationHandler(NotificationHandler notificationHandler) {
|
||||
this.notificationHandler = notificationHandler;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package eu.dnetlib.enabling.hcm.sn;
|
||||
|
||||
import eu.dnetlib.enabling.is.sn.rmi.ISSNException;
|
||||
|
||||
/**
|
||||
* This component takes care of subscribing the MSRO service to interesting events.
|
||||
*
|
||||
* @author marko
|
||||
*
|
||||
*/
|
||||
public interface HCMSubscriber {
|
||||
/**
|
||||
* performs the subscription.
|
||||
* @throws ISSNException could happen
|
||||
*/
|
||||
void subscribeAll() throws ISSNException;
|
||||
}
|
|
@ -0,0 +1,117 @@
|
|||
package eu.dnetlib.enabling.hcm.sn;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.Resource;
|
||||
import javax.xml.ws.Endpoint;
|
||||
import javax.xml.ws.wsaddressing.W3CEndpointReference;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.factory.annotation.Required;
|
||||
|
||||
import eu.dnetlib.enabling.actions.SubscriptionAction;
|
||||
import eu.dnetlib.enabling.is.sn.rmi.ISSNException;
|
||||
import eu.dnetlib.enabling.is.sn.rmi.ISSNService;
|
||||
import eu.dnetlib.enabling.locators.UniqueServiceLocator;
|
||||
import eu.dnetlib.soap.EndpointReferenceBuilder;
|
||||
|
||||
/**
|
||||
* This component takes care of subscribing the SubscriptionAction(s) to interesting events.
|
||||
*
|
||||
* @author claudio
|
||||
*
|
||||
*/
|
||||
public class HCMSubscriberImpl implements HCMSubscriber {
|
||||
|
||||
/**
|
||||
* logger.
|
||||
*/
|
||||
private static final Log log = LogFactory.getLog(HCMSubscriberImpl.class);
|
||||
|
||||
/**
|
||||
* notification endpoint (normally the msro service).
|
||||
*/
|
||||
private Endpoint endpoint;
|
||||
|
||||
/**
|
||||
* service locator.
|
||||
*/
|
||||
private UniqueServiceLocator serviceLocator;
|
||||
|
||||
/**
|
||||
* injected EPR builder.
|
||||
*/
|
||||
@Resource(name = "jaxwsEndpointReferenceBuilder")
|
||||
private EndpointReferenceBuilder<Endpoint> eprBuilder;
|
||||
|
||||
/**
|
||||
* subscription actions.
|
||||
*/
|
||||
private List<SubscriptionAction> actions;
|
||||
|
||||
@PostConstruct
|
||||
public void printList() {
|
||||
log.info(getActions());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @throws ISSNException
|
||||
* could happen
|
||||
* @see eu.dnetlib.enabling.hcm.sn.HCMSubscriber#subscribeAll()
|
||||
*/
|
||||
@Override
|
||||
public void subscribeAll() throws ISSNException {
|
||||
|
||||
final W3CEndpointReference endpointReference = eprBuilder
|
||||
.getEndpointReference(getEndpoint());
|
||||
|
||||
if (getActions() != null) {
|
||||
for (final SubscriptionAction action : getActions()) {
|
||||
log.info("dynamically subscribing to "
|
||||
+ action.getTopicExpression());
|
||||
serviceLocator.getService(ISSNService.class, true).subscribe(endpointReference,
|
||||
action.getTopicExpression(), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setEndpoint(final Endpoint endpoint) {
|
||||
this.endpoint = endpoint;
|
||||
}
|
||||
|
||||
public Endpoint getEndpoint() {
|
||||
return endpoint;
|
||||
}
|
||||
|
||||
public void setEprBuilder(
|
||||
final EndpointReferenceBuilder<Endpoint> eprBuilder) {
|
||||
this.eprBuilder = eprBuilder;
|
||||
}
|
||||
|
||||
public EndpointReferenceBuilder<Endpoint> getEprBuilder() {
|
||||
return eprBuilder;
|
||||
}
|
||||
|
||||
public List<SubscriptionAction> getActions() {
|
||||
return actions;
|
||||
}
|
||||
|
||||
@Required
|
||||
public void setActions(final List<SubscriptionAction> actions) {
|
||||
this.actions = actions;
|
||||
}
|
||||
|
||||
public UniqueServiceLocator getServiceLocator() {
|
||||
return serviceLocator;
|
||||
}
|
||||
|
||||
@Required
|
||||
public void setServiceLocator(final UniqueServiceLocator serviceLocator) {
|
||||
this.serviceLocator = serviceLocator;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
package eu.dnetlib.enabling.hcm.sn;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import eu.dnetlib.enabling.actions.SubscriptionAction;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
/**
|
||||
* This class acts as a simple registry of msro subscription actions.
|
||||
*
|
||||
* <p>
|
||||
* Subscription actions are autodetected using spring autowiring from the current application context and are available for the manager for
|
||||
* handling subscriptions and delivering notification to particular code interested in those notifications.
|
||||
* </p>
|
||||
*
|
||||
* @author marko
|
||||
*
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
public class HCMSubscriptionListFactory implements FactoryBean<List<SubscriptionAction>> {
|
||||
|
||||
/**
|
||||
* actions. Spring injects all the declared SubscriptionActions here.
|
||||
*/
|
||||
@Autowired(required = false)
|
||||
private List<SubscriptionAction> actions = Lists.newArrayList();
|
||||
|
||||
public List<SubscriptionAction> getActions() {
|
||||
return actions;
|
||||
}
|
||||
|
||||
public void setActions(final List<SubscriptionAction> actions) {
|
||||
this.actions = actions;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see org.springframework.beans.factory.FactoryBean#getObject()
|
||||
*/
|
||||
@Override
|
||||
public List<SubscriptionAction> getObject() {
|
||||
return getActions();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<List> getObjectType() {
|
||||
return List.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleton() {
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package eu.dnetlib.enabling.hnm;
|
||||
|
||||
import eu.dnetlib.enabling.hnm.rmi.HostingNodeManagerService;
|
||||
import eu.dnetlib.enabling.tools.AbstractBaseService;
|
||||
|
||||
/**
|
||||
* HNMService implementation.
|
||||
*
|
||||
* @author michele
|
||||
*
|
||||
*/
|
||||
public class HostingNodeManagerServiceImpl extends AbstractBaseService implements HostingNodeManagerService {
|
||||
|
||||
@Override
|
||||
public String echo(String s) {
|
||||
return s;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,155 @@
|
|||
package eu.dnetlib.enabling.resultset;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
import eu.dnetlib.enabling.resultset.observer.DelegationObserver;
|
||||
import eu.dnetlib.enabling.resultset.observer.Observable;
|
||||
|
||||
|
||||
/**
|
||||
* Common stuff for resultset implementations bound to a ResultSetRegistry.
|
||||
*
|
||||
* @author marko
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractObservableResultset implements ResultSet, Observable {
|
||||
/**
|
||||
* true if the resultset is destroyed.
|
||||
*/
|
||||
private boolean destroyed = false;
|
||||
|
||||
/**
|
||||
* true if the resultset is open.
|
||||
*/
|
||||
private boolean open;
|
||||
|
||||
/**
|
||||
* delegate the real job to a java.util.Observable object.
|
||||
*/
|
||||
private transient final java.util.Observable observable = new DelegationObservable();
|
||||
|
||||
/**
|
||||
* weak map for removing single observers later on.
|
||||
*/
|
||||
private transient Map<ResultSetRegistry, DelegationObserver> observers = new WeakHashMap<ResultSetRegistry, DelegationObserver>();
|
||||
|
||||
/**
|
||||
* java.util.Observable requires a "change" in the object to be made for the notifyObservers methods to trigger
|
||||
* actually the notification. We don't think this should be part of the base Observable/Observer pattern and thus
|
||||
* hide this fact. If an user of AbstractObservable wants this behavior it should implement her own change tracking
|
||||
* and avoid calling notifyObservers altogether. The rationale behind this choice is that not all dirty states can
|
||||
* be expressed using a stateful boolean instance variable like that implemented by java.util.Observable; some users
|
||||
* may prefer/need a lazy dirty flag instead.
|
||||
*
|
||||
* @author marko
|
||||
*
|
||||
*/
|
||||
static class DelegationObservable extends java.util.Observable {
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see java.util.Observable#notifyObservers()
|
||||
*/
|
||||
@Override
|
||||
public void notifyObservers() {
|
||||
setChanged();
|
||||
super.notifyObservers();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see java.util.Observable#notifyObservers(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public void notifyObservers(final Object arg) {
|
||||
setChanged();
|
||||
super.notifyObservers(arg);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see eu.dnetlib.enabling.resultset.ResultSet#destroy()
|
||||
*/
|
||||
@Override
|
||||
public void destroy() {
|
||||
if (!isDestroyed()) {
|
||||
setDestroyed(true);
|
||||
notifyObservers();
|
||||
deleteObservers();
|
||||
}
|
||||
}
|
||||
|
||||
public void setDestroyed(final boolean destroyed) {
|
||||
this.destroyed = destroyed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDestroyed() {
|
||||
return destroyed;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see eu.dnetlib.enabling.resultset.ResultSet#isOpen()
|
||||
*/
|
||||
@Override
|
||||
public boolean isOpen() {
|
||||
return open;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see eu.dnetlib.enabling.resultset.ResultSet#close()
|
||||
*/
|
||||
@Override
|
||||
public void close() {
|
||||
open = false;
|
||||
}
|
||||
|
||||
public void setOpen(final boolean open) {
|
||||
this.open = open;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addObserver(final ResultSetRegistry observer) {
|
||||
final DelegationObserver delegate = new DelegationObserver(this, observer);
|
||||
observers.put(observer, delegate);
|
||||
observable.addObserver(delegate);
|
||||
}
|
||||
|
||||
protected void notifyObservers() {
|
||||
observable.notifyObservers();
|
||||
}
|
||||
|
||||
protected void notifyObservers(final Object arg) {
|
||||
observable.notifyObservers(arg);
|
||||
}
|
||||
|
||||
public int countObservers() {
|
||||
return observable.countObservers();
|
||||
}
|
||||
|
||||
public void deleteObserver(final java.util.Observer observer) {
|
||||
observable.deleteObserver(observer);
|
||||
}
|
||||
|
||||
public void deleteObserver(ResultSetRegistry observer) {
|
||||
DelegationObserver delegate = observers.get(observer);
|
||||
if(delegate != null) {
|
||||
observable.deleteObserver(delegate);
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteObservers() {
|
||||
observable.deleteObservers();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package eu.dnetlib.enabling.resultset;
|
||||
|
||||
import javax.xml.ws.wsaddressing.W3CEndpointReference;
|
||||
|
||||
/**
|
||||
* Resultset factories bound to a resultset service, from which it takes the resultset registry and the epr builder.
|
||||
*
|
||||
* @author marko
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractResultSetFactory implements ResultSetFactory {
|
||||
|
||||
/**
|
||||
* resultset service.
|
||||
*/
|
||||
private ResultSetServiceImpl resultSetService;
|
||||
|
||||
/**
|
||||
* Register a resultset instance to the underlying resultset registry and returns
|
||||
* and EPR to accessible through the resultset service.
|
||||
*
|
||||
* @param resultSet resultset instance
|
||||
* @return epr to the newly created resultset
|
||||
*/
|
||||
public W3CEndpointReference registerResultSet(final ResultSet resultSet) {
|
||||
resultSetService.getResultsetRegistry().addResultSet(resultSet);
|
||||
return resultSetService.getEprBuilder().getEndpointReference(resultSetService.getEndpoint(), resultSet.getIdentifier());
|
||||
}
|
||||
|
||||
public ResultSetServiceImpl getResultSetService() {
|
||||
return resultSetService;
|
||||
}
|
||||
|
||||
public void setResultSetService(final ResultSetServiceImpl resultSetService) {
|
||||
this.resultSetService = resultSetService;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
package eu.dnetlib.enabling.resultset;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.xml.ws.wsaddressing.W3CEndpointReference;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Required;
|
||||
|
||||
import eu.dnetlib.enabling.tools.ServiceResolver;
|
||||
|
||||
public class CachingResultSetFactory {
|
||||
/**
|
||||
* underlying resultset factory, which exposes local resultsets to the world.
|
||||
*/
|
||||
private ResultSetFactory resultSetFactory;
|
||||
|
||||
@Resource
|
||||
private ServiceResolver serviceResolver;
|
||||
|
||||
/**
|
||||
* @param items
|
||||
* @param size
|
||||
* the size of the iterable
|
||||
* @return
|
||||
*/
|
||||
public W3CEndpointReference createCachingResultSet(W3CEndpointReference epr) {
|
||||
return resultSetFactory.createResultSet(new CachingResultSetListener(epr, serviceResolver));
|
||||
}
|
||||
|
||||
public ResultSetFactory getResultSetFactory() {
|
||||
return resultSetFactory;
|
||||
}
|
||||
|
||||
@Required
|
||||
public void setResultSetFactory(ResultSetFactory resultSetFactory) {
|
||||
this.resultSetFactory = resultSetFactory;
|
||||
}
|
||||
|
||||
public ServiceResolver getServiceResolver() {
|
||||
return serviceResolver;
|
||||
}
|
||||
|
||||
public void setServiceResolver(ServiceResolver serviceResolver) {
|
||||
this.serviceResolver = serviceResolver;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
package eu.dnetlib.enabling.resultset;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.xml.ws.wsaddressing.W3CEndpointReference;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import eu.dnetlib.enabling.resultset.rmi.ResultSetException;
|
||||
import eu.dnetlib.enabling.resultset.rmi.ResultSetService;
|
||||
import eu.dnetlib.enabling.tools.ServiceResolver;
|
||||
|
||||
public class CachingResultSetListener implements ResultSetListener {
|
||||
private static final Log log = LogFactory.getLog(CachingResultSetListener.class); // NOPMD by marko on 11/24/08 5:02 PM
|
||||
|
||||
|
||||
private ResultSetService service;
|
||||
private String rsId;
|
||||
|
||||
private ArrayList<String> storage = new ArrayList<String>();
|
||||
|
||||
public CachingResultSetListener(W3CEndpointReference epr, ServiceResolver serviceResolver) {
|
||||
this.service = serviceResolver.getService(ResultSetService.class, epr);
|
||||
this.rsId = serviceResolver.getResourceIdentifier(epr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getResult(int fromPosition, int toPosition) {
|
||||
if (storage.get(fromPosition) != null)
|
||||
return cached(fromPosition, toPosition);
|
||||
try {
|
||||
List<String> data = service.getResult(rsId, fromPosition, toPosition, "waiting");
|
||||
cache(data, fromPosition, toPosition);
|
||||
return data;
|
||||
} catch (ResultSetException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void cache(List<String> data, int fromPosition, int toPosition) {
|
||||
for(String value : data)
|
||||
storage.set(fromPosition++, value);
|
||||
}
|
||||
|
||||
private List<String> cached(int fromPosition, int toPosition) {
|
||||
log.info("found cached page " + fromPosition + ", " + toPosition);
|
||||
return storage.subList(fromPosition-1, toPosition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSize() {
|
||||
try {
|
||||
return service.getNumberOfElements(rsId);
|
||||
} catch (ResultSetException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
package eu.dnetlib.enabling.resultset;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.xml.ws.wsaddressing.W3CEndpointReference;
|
||||
|
||||
import eu.dnetlib.enabling.tools.ServiceResolver;
|
||||
import eu.dnetlib.miscutils.functional.IdentityFunction;
|
||||
import eu.dnetlib.miscutils.functional.UnaryFunction;
|
||||
|
||||
/**
|
||||
* A resultset record counter.
|
||||
*
|
||||
* @author claudio
|
||||
*
|
||||
*/
|
||||
public class CountingResultSet extends MappedResultSet {
|
||||
|
||||
/**
|
||||
* counter.
|
||||
*/
|
||||
private int count;
|
||||
|
||||
|
||||
/**
|
||||
* @param epr
|
||||
* @param serviceResolver
|
||||
*/
|
||||
public CountingResultSet(final W3CEndpointReference epr, final ServiceResolver serviceResolver) {
|
||||
this(epr, new IdentityFunction<String>(), serviceResolver);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param epr
|
||||
* @param mapper
|
||||
* @param serviceResolver
|
||||
*/
|
||||
public CountingResultSet(final W3CEndpointReference epr, final UnaryFunction<String, String> mapper, final ServiceResolver serviceResolver) {
|
||||
super(epr, mapper, serviceResolver);
|
||||
count = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* method sets the counter to the higher allowed value of toPosition.
|
||||
*/
|
||||
@Override
|
||||
public List<String> getResult(int fromPosition, int toPosition) {
|
||||
|
||||
if (toPosition > count)
|
||||
count = toPosition;
|
||||
if (toPosition > super.getSize())
|
||||
count = super.getSize();
|
||||
|
||||
return super.getResult(fromPosition, toPosition);
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
return count;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package eu.dnetlib.enabling.resultset;
|
||||
|
||||
import javax.xml.ws.wsaddressing.W3CEndpointReference;
|
||||
|
||||
/**
|
||||
* Create a new resultset which takes each record of the input resultset and counts them.
|
||||
*
|
||||
* @author claudio
|
||||
*
|
||||
*/
|
||||
public class CountingResultSetFactory extends MappedResultSetFactory {
|
||||
|
||||
/**
|
||||
* Create a new resultset which takes each record of the input resultset and counts them.
|
||||
*
|
||||
* @param source
|
||||
* source resultset epr
|
||||
* @param mapper
|
||||
* mapper function
|
||||
* @return mapped resultset epr
|
||||
*/
|
||||
public W3CEndpointReference createCountingResultSet(final W3CEndpointReference source) {
|
||||
return getResultSetFactory().createResultSet(new CountingResultSet(source, getServiceResolver()));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package eu.dnetlib.enabling.resultset;
|
||||
|
||||
import javax.xml.ws.wsaddressing.W3CEndpointReference;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Required;
|
||||
|
||||
public class EPRPoolingLocalOpenResultSetFactoryImpl extends LocalOpenResultSetFactoryImpl {
|
||||
private ResultSetEPRPool pool;
|
||||
|
||||
@Override
|
||||
public W3CEndpointReference registerResultSet(ResultSet resultSet) {
|
||||
return pool.registerResultSet(resultSet);
|
||||
}
|
||||
|
||||
public ResultSetEPRPool getPool() {
|
||||
return pool;
|
||||
}
|
||||
|
||||
@Required
|
||||
public void setPool(ResultSetEPRPool pool) {
|
||||
this.pool = pool;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package eu.dnetlib.enabling.resultset;
|
||||
|
||||
import javax.xml.ws.wsaddressing.W3CEndpointReference;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Required;
|
||||
|
||||
public class EPRPoolingLocalResultSetFactoryImpl extends LocalResultSetFactoryImpl {
|
||||
|
||||
private ResultSetEPRPool pool;
|
||||
|
||||
@Override
|
||||
public W3CEndpointReference registerResultSet(ResultSet resultSet) {
|
||||
return pool.registerResultSet(resultSet);
|
||||
}
|
||||
|
||||
public ResultSetEPRPool getPool() {
|
||||
return pool;
|
||||
}
|
||||
|
||||
@Required
|
||||
public void setPool(ResultSetEPRPool pool) {
|
||||
this.pool = pool;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,105 @@
|
|||
package eu.dnetlib.enabling.resultset;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
|
||||
/**
|
||||
* a LinkedList populated by a given iterable, which provides a fetch window of elements
|
||||
*
|
||||
* @author claudio
|
||||
*
|
||||
* @param <T>
|
||||
* The FetchList type
|
||||
*/
|
||||
public class FetchList<T> extends LinkedList<T> {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 7135272008563693321L;
|
||||
|
||||
/**
|
||||
* represents the number of elements ready to be pulled out of the list
|
||||
*/
|
||||
private int fetchSize;
|
||||
|
||||
/**
|
||||
* represents the number of elements already consumed by a poll call
|
||||
*/
|
||||
private int consumedElements;
|
||||
|
||||
/**
|
||||
* the given itarable used to populate the list
|
||||
*/
|
||||
private Iterator<T> iter;
|
||||
|
||||
/**
|
||||
* @param iter
|
||||
* @param fetchSize
|
||||
*/
|
||||
public FetchList(final Iterator<T> iter, final int fetchSize) {
|
||||
super();
|
||||
this.consumedElements = 0;
|
||||
this.fetchSize = fetchSize;
|
||||
this.iter = iter;
|
||||
}
|
||||
|
||||
/**
|
||||
* used to fill the list
|
||||
*/
|
||||
public synchronized void fill() {
|
||||
for (int i = 0; i < fetchSize; i++) {
|
||||
if (!iter.hasNext()) {
|
||||
break;
|
||||
}
|
||||
this.add(iter.next());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* return the first element and makes the list to be filled in case its size is zero
|
||||
*/
|
||||
@Override
|
||||
public T poll() {
|
||||
if (this.isEmpty()) {
|
||||
fill();
|
||||
}
|
||||
|
||||
if (this.size() > 0) {
|
||||
consumedElements++;
|
||||
return super.poll();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the number of elements already consumed by a "poll"
|
||||
*/
|
||||
public int getConsumedElements() {
|
||||
return consumedElements;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the actual number of elements of the list
|
||||
*/
|
||||
public int getTotalElements() {
|
||||
return consumedElements + this.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* to provide an actual size, fills the list if there are elements to fill it
|
||||
*/
|
||||
@Override
|
||||
public int size() {
|
||||
if (this.isEmpty() && iter.hasNext()) {
|
||||
fill();
|
||||
}
|
||||
return super.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return super.size() == 0;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,116 @@
|
|||
package eu.dnetlib.enabling.resultset;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* an open ResultSet that can be iterated to get it's data results.
|
||||
*
|
||||
* @author claudio
|
||||
*
|
||||
*/
|
||||
public class IterableResultSet implements ResultSetListener, ResultSetAware {
|
||||
|
||||
/**
|
||||
* logger.
|
||||
*/
|
||||
private static final Log log = LogFactory.getLog(IterableResultSet.class);
|
||||
|
||||
/**
|
||||
* the container for the data results.
|
||||
*/
|
||||
private ResultSet resultSet;
|
||||
|
||||
/**
|
||||
* the list that provides data for this resultSet.
|
||||
*/
|
||||
private FetchList<String> fetchList;
|
||||
|
||||
private int optionalNumberOfElements;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param iter
|
||||
* @param fetchSize
|
||||
*/
|
||||
protected IterableResultSet(Iterable<String> iter, int fetchSize) {
|
||||
fetchList = new FetchList<String>(iter.iterator(), fetchSize);
|
||||
if (iter instanceof SizedIterable<?>) {
|
||||
optionalNumberOfElements = ((SizedIterable<?>) iter).getNumberOfElements();
|
||||
} else {
|
||||
optionalNumberOfElements = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param fromPosition
|
||||
* @param toPosition
|
||||
* @return <T> List
|
||||
*/
|
||||
@Override
|
||||
public List<String> getResult(int fromPosition, int toPosition) {
|
||||
|
||||
log.debug(" - getting result from " + fromPosition + " to " + toPosition + ", consumedElements: " + fetchList.getConsumedElements());
|
||||
|
||||
if (fromPosition != fetchList.getConsumedElements() + 1)
|
||||
throw new RuntimeException("Unexpected value for 'fromPosition' parameter");
|
||||
if (toPosition < fromPosition)
|
||||
throw new RuntimeException("'fromPosition' must be lower or equal than 'toPosition'");
|
||||
|
||||
List<String> result = new ArrayList<String>();
|
||||
|
||||
for (int i = fromPosition; i <= toPosition; i++) {
|
||||
if (fetchList.size() > 0)
|
||||
result.add(fetchList.poll());
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
ensureClosed();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private void ensureClosed() {
|
||||
if (fetchList.size() == 0 && resultSet.isOpen()) {
|
||||
log.info(">>>>>>>>>>> closing resultset <<<<<<<<<<<<<");
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
public String getRSStatus() {
|
||||
if (resultSet.isOpen())
|
||||
return "open";
|
||||
return "closed";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSize() {
|
||||
ensureClosed();
|
||||
|
||||
if (optionalNumberOfElements == -1)
|
||||
return fetchList.getTotalElements();
|
||||
else
|
||||
return optionalNumberOfElements;
|
||||
}
|
||||
|
||||
/**
|
||||
* closes the resultset.
|
||||
*/
|
||||
protected void close() {
|
||||
resultSet.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setResultSet(ResultSet resultSet) {
|
||||
this.resultSet = resultSet;
|
||||
}
|
||||
|
||||
public ResultSet getResultSet() {
|
||||
return resultSet;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
package eu.dnetlib.enabling.resultset;
|
||||
|
||||
import javax.xml.ws.wsaddressing.W3CEndpointReference;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Required;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author claudio
|
||||
*
|
||||
*/
|
||||
public class IterableResultSetFactory {
|
||||
|
||||
/**
|
||||
* {@link ResultSetFactory}
|
||||
*/
|
||||
private LocalOpenResultSetFactoryImpl resultSetFactory;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private int fetchSize;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param source
|
||||
* @return
|
||||
*/
|
||||
public W3CEndpointReference createIterableResultSet(final Iterable<String> source) {
|
||||
return resultSetFactory.createResultSet(new IterableResultSet(source, fetchSize));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public LocalOpenResultSetFactoryImpl getResultSetFactory() {
|
||||
return resultSetFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param resultSetFactory
|
||||
*/
|
||||
@Required
|
||||
public void setResultSetFactory(final LocalOpenResultSetFactoryImpl resultSetFactory) {
|
||||
this.resultSetFactory = resultSetFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param fetchSize
|
||||
*/
|
||||
@Required
|
||||
public void setFetchSize(int fetchSize) {
|
||||
this.fetchSize = fetchSize;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int getFetchSize() {
|
||||
return fetchSize;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
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;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package eu.dnetlib.enabling.resultset;
|
||||
|
||||
/**
|
||||
* Creates an "open" (unbounded, unfreezed) local resultset.
|
||||
*
|
||||
* @author marko
|
||||
*
|
||||
*/
|
||||
public class LocalOpenResultSetFactoryImpl extends LocalResultSetFactoryImpl {
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @see eu.dnetlib.enabling.resultset.LocalResultSetFactoryImpl#createInstance(eu.dnetlib.enabling.resultset.ResultSetListener)
|
||||
*/
|
||||
@Override
|
||||
protected LocalResultSetImpl createInstance(final ResultSetListener provider) {
|
||||
final LocalResultSetImpl instance = super.createInstance(provider);
|
||||
instance.setOpen(true);
|
||||
return instance;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package eu.dnetlib.enabling.resultset;
|
||||
|
||||
import javax.xml.ws.wsaddressing.W3CEndpointReference;
|
||||
|
||||
/**
|
||||
* This factory creates resultset bound to a given resultset registry shared with a resultset service which exposed them
|
||||
* to the outside world.
|
||||
*
|
||||
* It's tightly coupled with a local instance of the ResultSetService.
|
||||
*
|
||||
* @see eu.dnetlib.enabling.resultset.ResultSetServiceImpl
|
||||
*
|
||||
* @author marko
|
||||
*
|
||||
*/
|
||||
public class LocalResultSetFactoryImpl extends AbstractResultSetFactory {
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see eu.dnetlib.enabling.resultset.ResultSetFactory#createResultSet(eu.dnetlib.enabling.resultset.ResultSetListener)
|
||||
*/
|
||||
@Override
|
||||
public W3CEndpointReference createResultSet(final ResultSetListener provider) {
|
||||
return registerResultSet(createInstance(provider));
|
||||
}
|
||||
|
||||
/**
|
||||
* create a new local resultset instance. Subclasses may override this to supply additional configuration.
|
||||
*
|
||||
* @param provider provider
|
||||
* @return a new resultset instance.
|
||||
*/
|
||||
protected LocalResultSetImpl createInstance(final ResultSetListener provider) {
|
||||
return new LocalResultSetImpl(provider);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
package eu.dnetlib.enabling.resultset;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
/**
|
||||
* Resultset backing implementation.
|
||||
*
|
||||
* @author marko
|
||||
*
|
||||
*/
|
||||
public class LocalResultSetImpl extends AbstractObservableResultset implements ResultSet {
|
||||
|
||||
/**
|
||||
* rsId.
|
||||
*/
|
||||
private String identifier;
|
||||
|
||||
/**
|
||||
* this listener will provide the data to this local resultset by listening to events.
|
||||
*/
|
||||
private ResultSetListener listener;
|
||||
|
||||
/**
|
||||
* Construct a new local ResultSet which pulls data from the listener. If the listener implements ResultSetAware, it
|
||||
* will be injected with this instance.
|
||||
*
|
||||
* @param listener
|
||||
* a resultset listener
|
||||
*/
|
||||
public LocalResultSetImpl(final ResultSetListener listener) {
|
||||
super();
|
||||
this.listener = listener;
|
||||
|
||||
if (listener instanceof ResultSetAware)
|
||||
((ResultSetAware) listener).setResultSet(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see eu.dnetlib.enabling.resultset.ResultSet#getNumberOfResults()
|
||||
*/
|
||||
@Override
|
||||
public int getNumberOfResults() {
|
||||
return listener.getSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see eu.dnetlib.enabling.resultset.ResultSet#getResults(int, int)
|
||||
*/
|
||||
@Override
|
||||
public List<String> getResults(final int fromPosition, final int toPosition) {
|
||||
int toPos = toPosition;
|
||||
int fromPos = fromPosition;
|
||||
if (!isOpen()) {
|
||||
final int size = getNumberOfResults();
|
||||
|
||||
if (size == 0)
|
||||
return Lists.newArrayList();
|
||||
|
||||
if (fromPos > size)
|
||||
return Lists.newArrayList();
|
||||
|
||||
if (toPos > size)
|
||||
toPos = size;
|
||||
}
|
||||
|
||||
if (fromPos < 1)
|
||||
fromPos = 1;
|
||||
if (toPos < fromPos)
|
||||
toPos = fromPos;
|
||||
|
||||
return listener.getResult(fromPos, toPos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdentifier() {
|
||||
return identifier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIdentifier(final String identifier) {
|
||||
this.identifier = identifier;
|
||||
}
|
||||
|
||||
public ResultSetListener getListener() {
|
||||
return listener;
|
||||
}
|
||||
|
||||
public void setListener(final ResultSetListener listener) {
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,151 @@
|
|||
package eu.dnetlib.enabling.resultset;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.xml.ws.wsaddressing.W3CEndpointReference;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Required;
|
||||
|
||||
import eu.dnetlib.enabling.resultset.rmi.ResultSetException;
|
||||
import eu.dnetlib.enabling.resultset.rmi.ResultSetService;
|
||||
import eu.dnetlib.enabling.tools.ServiceResolver;
|
||||
import eu.dnetlib.miscutils.collections.MappedCollection;
|
||||
import eu.dnetlib.miscutils.functional.UnaryFunction;
|
||||
|
||||
/**
|
||||
* A resultset filter. Applies a transformation for every resultset record.
|
||||
*
|
||||
* @author marko
|
||||
*
|
||||
*/
|
||||
public class MappedResultSet implements ResultSetListener, ResultSetAware {
|
||||
|
||||
/**
|
||||
* input resultset.
|
||||
*/
|
||||
private ResultSetService resultSetService;
|
||||
|
||||
/**
|
||||
* input resultset id.
|
||||
*/
|
||||
private String rsId;
|
||||
|
||||
/**
|
||||
* mapper function.
|
||||
*/
|
||||
private UnaryFunction<String, String> mapper;
|
||||
|
||||
/**
|
||||
* service resolver.
|
||||
*/
|
||||
private ServiceResolver serviceResolver;
|
||||
|
||||
private ResultSet resultSet;
|
||||
|
||||
/**
|
||||
* Create a new mapped resultset.
|
||||
*
|
||||
* @param epr
|
||||
* input resultset epr
|
||||
* @param mapper
|
||||
* mapper function
|
||||
* @param serviceResolver
|
||||
* service resolver
|
||||
*/
|
||||
public MappedResultSet(final W3CEndpointReference epr, final UnaryFunction<String, String> mapper, final ServiceResolver serviceResolver) {
|
||||
super();
|
||||
|
||||
this.resultSetService = serviceResolver.getService(ResultSetService.class, epr);
|
||||
this.rsId = serviceResolver.getResourceIdentifier(epr);
|
||||
|
||||
this.mapper = mapper;
|
||||
|
||||
this.serviceResolver = serviceResolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see eu.dnetlib.enabling.resultset.ResultSetListener#getResult(int, int)
|
||||
*/
|
||||
@Override
|
||||
public List<String> getResult(final int fromPosition, final int toPosition) {
|
||||
return MappedCollection.listMap(getResultFromSource(fromPosition, toPosition), mapper);
|
||||
|
||||
}
|
||||
|
||||
protected List<String> getResultFromSource(final int fromPosition, final int toPosition) {
|
||||
try {
|
||||
List<String> res = resultSetService.getResult(rsId, fromPosition, toPosition, "waiting");
|
||||
checkStatus();
|
||||
return res;
|
||||
} catch (final ResultSetException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkStatus() throws ResultSetException {
|
||||
if (getResultSet().isOpen() && resultSetService.getRSStatus(rsId).equals("closed")) {
|
||||
getResultSet().close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see eu.dnetlib.enabling.resultset.ResultSetListener#getSize()
|
||||
*/
|
||||
@Override
|
||||
public int getSize() {
|
||||
try {
|
||||
int numberOfElements = resultSetService.getNumberOfElements(rsId);
|
||||
checkStatus();
|
||||
return numberOfElements;
|
||||
} catch (final ResultSetException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public ResultSetService getResultSetService() {
|
||||
return resultSetService;
|
||||
}
|
||||
|
||||
public void setResultSetService(final ResultSetService resultSetService) {
|
||||
this.resultSetService = resultSetService;
|
||||
}
|
||||
|
||||
public UnaryFunction<String, String> getMapper() {
|
||||
return mapper;
|
||||
}
|
||||
|
||||
public void setMapper(final UnaryFunction<String, String> mapper) {
|
||||
this.mapper = mapper;
|
||||
}
|
||||
|
||||
public ServiceResolver getServiceResolver() {
|
||||
return serviceResolver;
|
||||
}
|
||||
|
||||
@Required
|
||||
public void setServiceResolver(final ServiceResolver serviceResolver) {
|
||||
this.serviceResolver = serviceResolver;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setResultSet(ResultSet resultSet) {
|
||||
this.resultSet = resultSet;
|
||||
}
|
||||
|
||||
public ResultSet getResultSet() {
|
||||
return resultSet;
|
||||
}
|
||||
|
||||
public String getRsId() {
|
||||
return rsId;
|
||||
}
|
||||
|
||||
public void setRsId(String rsId) {
|
||||
this.rsId = rsId;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
package eu.dnetlib.enabling.resultset;
|
||||
|
||||
import javax.xml.ws.wsaddressing.W3CEndpointReference;
|
||||
|
||||
import eu.dnetlib.enabling.tools.ServiceResolver;
|
||||
import eu.dnetlib.miscutils.functional.UnaryFunction;
|
||||
|
||||
/**
|
||||
* Create a new resultset which takes each record of the input resultset and applies the mapping function to it.
|
||||
*
|
||||
* @author marko
|
||||
*
|
||||
*/
|
||||
public class MappedResultSetFactory {
|
||||
|
||||
/**
|
||||
* underlying resultset factory, which exposes local resultsets to the world.
|
||||
*/
|
||||
private ResultSetFactory resultSetFactory;
|
||||
|
||||
/**
|
||||
* service resolver, transforms eprs to services.
|
||||
*/
|
||||
private ServiceResolver serviceResolver;
|
||||
|
||||
/**
|
||||
* Create a new resultset which takes each record of the input resultset and applies the mapping function to it.
|
||||
*
|
||||
* @param source source resultset epr
|
||||
* @param mapper mapper function
|
||||
* @return mapped resultset epr
|
||||
*/
|
||||
public W3CEndpointReference createMappedResultSet(final W3CEndpointReference source, final UnaryFunction<String, String> mapper) {
|
||||
return resultSetFactory.createResultSet(new MappedResultSet(source, mapper, serviceResolver));
|
||||
}
|
||||
|
||||
public ResultSetFactory getResultSetFactory() {
|
||||
return resultSetFactory;
|
||||
}
|
||||
|
||||
public void setResultSetFactory(final ResultSetFactory resultSetFactory) {
|
||||
this.resultSetFactory = resultSetFactory;
|
||||
}
|
||||
|
||||
public ServiceResolver getServiceResolver() {
|
||||
return serviceResolver;
|
||||
}
|
||||
|
||||
public void setServiceResolver(final ServiceResolver serviceResolver) {
|
||||
this.serviceResolver = serviceResolver;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
package eu.dnetlib.enabling.resultset;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import javax.xml.ws.wsaddressing.W3CEndpointReference;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import eu.dnetlib.enabling.tools.ServiceResolver;
|
||||
import eu.dnetlib.miscutils.collections.MappedCollection;
|
||||
import eu.dnetlib.miscutils.functional.UnaryFunction;
|
||||
|
||||
public class ParallelMappedResultSet extends MappedResultSet {
|
||||
|
||||
private ExecutorService executor;
|
||||
|
||||
public ParallelMappedResultSet(final W3CEndpointReference source, final UnaryFunction<String, String> mapper, final ServiceResolver serviceResolver,
|
||||
final ExecutorService executor) {
|
||||
super(source, mapper, serviceResolver);
|
||||
this.executor = executor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getResult(int fromPosition, int toPosition) {
|
||||
|
||||
// log.info("Parallel page " + (toPosition - fromPosition + 1));
|
||||
|
||||
List<Future<String>> results = Lists.newArrayList();
|
||||
|
||||
for (final String input : getResultFromSource(fromPosition, toPosition)) {
|
||||
results.add(executor.submit(new Callable<String>() {
|
||||
@Override
|
||||
public String call() throws Exception {
|
||||
return getMapper().evaluate(input);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
return MappedCollection.listMap(results, new UnaryFunction<String, Future<String>>() {
|
||||
@Override
|
||||
public String evaluate(Future<String> arg) {
|
||||
try {
|
||||
return arg.get();
|
||||
} catch (InterruptedException e) {
|
||||
throw new IllegalStateException(e);
|
||||
} catch (ExecutionException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
package eu.dnetlib.enabling.resultset;
|
||||
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.xml.ws.wsaddressing.W3CEndpointReference;
|
||||
|
||||
import eu.dnetlib.miscutils.functional.UnaryFunction;
|
||||
|
||||
public class ParallelMappedResultSetFactory extends MappedResultSetFactory {
|
||||
|
||||
private ExecutorService executor;
|
||||
|
||||
private static final int QUEUE_SIZE = 40;
|
||||
|
||||
private int queueSize = QUEUE_SIZE;
|
||||
|
||||
private int cpus = 0;
|
||||
|
||||
public ParallelMappedResultSetFactory() {
|
||||
super();
|
||||
|
||||
if (cpus == 0)
|
||||
cpus = getNumberOfCPUs();
|
||||
executor = new ThreadPoolExecutor(cpus, cpus, 5, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(queueSize),
|
||||
new ThreadPoolExecutor.CallerRunsPolicy());
|
||||
}
|
||||
|
||||
@Override
|
||||
public W3CEndpointReference createMappedResultSet(final W3CEndpointReference source, final UnaryFunction<String, String> mapper) {
|
||||
return getResultSetFactory().createResultSet(new ParallelMappedResultSet(source, mapper, getServiceResolver(), executor));
|
||||
}
|
||||
|
||||
private int getNumberOfCPUs() {
|
||||
return Runtime.getRuntime().availableProcessors();
|
||||
}
|
||||
|
||||
public int getCpus() {
|
||||
return cpus;
|
||||
}
|
||||
|
||||
public void setCpus(int cpus) {
|
||||
if(cpus > 0)
|
||||
this.cpus = cpus;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
package eu.dnetlib.enabling.resultset;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import eu.dnetlib.enabling.resultset.observer.Observable;
|
||||
|
||||
/**
|
||||
* A ResultSet represents a set of data results.
|
||||
*
|
||||
* @author marko
|
||||
*
|
||||
*/
|
||||
public interface ResultSet extends Observable {
|
||||
/**
|
||||
* get the resource identifier.
|
||||
*
|
||||
* @return rsId
|
||||
*/
|
||||
String getIdentifier();
|
||||
|
||||
/**
|
||||
* sets the resource identifier. The ResultSetRegistry will assign a new rsId.
|
||||
*
|
||||
* @param rsId allocated resultset identifier
|
||||
*/
|
||||
void setIdentifier(String rsId);
|
||||
|
||||
/**
|
||||
* get a 'page' of results.
|
||||
*
|
||||
* @param fromPosition
|
||||
* from 1
|
||||
* @param toPosition
|
||||
* last included
|
||||
* @return a page of data
|
||||
*/
|
||||
List<String> getResults(int fromPosition, int toPosition);
|
||||
|
||||
/**
|
||||
* get the number of result elements present in the resultset.
|
||||
*
|
||||
* @return number of results
|
||||
*/
|
||||
int getNumberOfResults();
|
||||
|
||||
/**
|
||||
* Tells if the resultset is open or closed.
|
||||
*
|
||||
* @return true if open
|
||||
*/
|
||||
boolean isOpen();
|
||||
|
||||
/**
|
||||
* close a resultset.
|
||||
*/
|
||||
void close();
|
||||
|
||||
/**
|
||||
* Tells if the resultset is destroyed.
|
||||
*
|
||||
* @return true if the resultset is destroyed.
|
||||
*/
|
||||
boolean isDestroyed();
|
||||
|
||||
/**
|
||||
* Destroy the resultset and free associated resources, remove it from the ResultSetRegistry.
|
||||
* After calling this method, the resultset is no more accessible from other services.
|
||||
*/
|
||||
void destroy();
|
||||
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package eu.dnetlib.enabling.resultset;
|
||||
|
||||
/**
|
||||
* ResultSet listeners can add this interface in order to receive the ResultSet they are bound to.
|
||||
*
|
||||
* @author marko
|
||||
*
|
||||
*/
|
||||
public interface ResultSetAware {
|
||||
/**
|
||||
* sets the resultset instance.
|
||||
*
|
||||
* @param resultSet the resultset instance
|
||||
*/
|
||||
void setResultSet(ResultSet resultSet);
|
||||
}
|
|
@ -0,0 +1,137 @@
|
|||
package eu.dnetlib.enabling.resultset;
|
||||
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.xml.ws.wsaddressing.W3CEndpointReference;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.factory.annotation.Required;
|
||||
|
||||
import eu.dnetlib.enabling.tools.UniqueIdentifierGenerator;
|
||||
import eu.dnetlib.enabling.tools.UniqueIdentifierGeneratorImpl;
|
||||
|
||||
public class ResultSetEPRPool {
|
||||
private static final Log log = LogFactory.getLog(ResultSetEPRPool.class); // NOPMD by marko on 11/24/08 5:02 PM
|
||||
|
||||
static class PreparedResultSet {
|
||||
private String rsId;
|
||||
private W3CEndpointReference epr;
|
||||
|
||||
public PreparedResultSet(final String rsId, final W3CEndpointReference epr) {
|
||||
super();
|
||||
this.rsId = rsId;
|
||||
this.epr = epr;
|
||||
}
|
||||
|
||||
public String getRsId() {
|
||||
return rsId;
|
||||
}
|
||||
|
||||
public void setRsId(final String rsId) {
|
||||
this.rsId = rsId;
|
||||
}
|
||||
|
||||
public W3CEndpointReference getEpr() {
|
||||
return epr;
|
||||
}
|
||||
|
||||
public void setEpr(final W3CEndpointReference epr) {
|
||||
this.epr = epr;
|
||||
}
|
||||
}
|
||||
|
||||
class PoolFiller implements Runnable {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
while (true)
|
||||
try {
|
||||
final PreparedResultSet resultSet = prepareResultSet();
|
||||
pool.put(resultSet);
|
||||
} catch (final InterruptedException e) {
|
||||
// eat this exception
|
||||
log.debug("cannot add resultset to pool", e);
|
||||
}
|
||||
}
|
||||
|
||||
private PreparedResultSet prepareResultSet() {
|
||||
final String rsId = idGenerator.generateIdentifier();
|
||||
return new PreparedResultSet(rsId, createEPR(rsId));
|
||||
}
|
||||
|
||||
private W3CEndpointReference createEPR(final String rsId) {
|
||||
return getResultSetService().getEprBuilder().getEndpointReference(getResultSetService().getEndpoint(), rsId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* resultset service.
|
||||
*/
|
||||
private ResultSetServiceImpl resultSetService;
|
||||
|
||||
private int capacity = 1000;
|
||||
private int fillerThreads = 10;
|
||||
private final BlockingQueue<PreparedResultSet> pool = new LinkedBlockingQueue<PreparedResultSet>(capacity);
|
||||
|
||||
/**
|
||||
* identifier generator.
|
||||
*/
|
||||
private UniqueIdentifierGenerator idGenerator = new UniqueIdentifierGeneratorImpl("rs-");
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
log.info("-------<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>> Starting fill threads");
|
||||
for (int i = 0; i < fillerThreads; i++)
|
||||
startFillter();
|
||||
}
|
||||
|
||||
protected void startFillter() {
|
||||
final Thread filler = new Thread(new PoolFiller());
|
||||
filler.setDaemon(true);
|
||||
filler.start();
|
||||
}
|
||||
|
||||
public W3CEndpointReference registerResultSet(final ResultSet resultSet) {
|
||||
final PreparedResultSet prepared = nextPreparedResultSet();
|
||||
if (prepared == null) {
|
||||
log.info("EPR cache is empty, creating EPR in caller thread");
|
||||
return getResultSetService().getEprBuilder().getEndpointReference(getResultSetService().getEndpoint(), idGenerator.generateIdentifier());
|
||||
}
|
||||
|
||||
getResultSetService().getResultsetRegistry().addResultSet(resultSet, prepared.getRsId());
|
||||
return prepared.getEpr();
|
||||
}
|
||||
|
||||
private PreparedResultSet nextPreparedResultSet() {
|
||||
log.info(">>>> fetching a prepared resultset from the pool");
|
||||
return pool.poll();
|
||||
}
|
||||
|
||||
public int getCapacity() {
|
||||
return capacity;
|
||||
}
|
||||
|
||||
public void setCapacity(int capacity) {
|
||||
this.capacity = capacity;
|
||||
}
|
||||
|
||||
public UniqueIdentifierGenerator getIdGenerator() {
|
||||
return idGenerator;
|
||||
}
|
||||
|
||||
public void setIdGenerator(UniqueIdentifierGenerator idGenerator) {
|
||||
this.idGenerator = idGenerator;
|
||||
}
|
||||
|
||||
public ResultSetServiceImpl getResultSetService() {
|
||||
return resultSetService;
|
||||
}
|
||||
|
||||
@Required
|
||||
public void setResultSetService(ResultSetServiceImpl resultSetService) {
|
||||
this.resultSetService = resultSetService;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package eu.dnetlib.enabling.resultset;
|
||||
|
||||
import javax.xml.ws.wsaddressing.W3CEndpointReference;
|
||||
|
||||
/**
|
||||
* Creates a resultset service from a producer.
|
||||
*
|
||||
* @author marko
|
||||
*
|
||||
*/
|
||||
public interface ResultSetFactory {
|
||||
/**
|
||||
* TODO other parameters like expiration time etc.
|
||||
*
|
||||
* @param provider a resultset listener which provides the data
|
||||
* @return an EPR to the resultset.
|
||||
*/
|
||||
W3CEndpointReference createResultSet(ResultSetListener provider);
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package eu.dnetlib.enabling.resultset;
|
||||
|
||||
|
||||
/**
|
||||
* A ResultSetListener is a pull interface to a ResultSet.
|
||||
*
|
||||
* The Resultset will call method of ResultSetListener implementors whenever it needs to pull some data and provide it
|
||||
* to clients. The ResultSet service acts as a decouple point between the producer and the consumer.
|
||||
*
|
||||
* @author marko
|
||||
*
|
||||
*/
|
||||
public interface ResultSetListener extends TypedResultSetListener<String> {
|
||||
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package eu.dnetlib.enabling.resultset;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* access resultset properties.
|
||||
*
|
||||
* @author marko
|
||||
*
|
||||
*/
|
||||
public interface ResultSetPropertyDao {
|
||||
/**
|
||||
* return a map of custom resultset properties.
|
||||
*
|
||||
* @param resultSet resultset
|
||||
* @return property map
|
||||
*/
|
||||
Map<String, String> getProperties(ResultSet resultSet);
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package eu.dnetlib.enabling.resultset;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* fake resultset property dao.
|
||||
*
|
||||
* @author marko
|
||||
*
|
||||
*/
|
||||
public class ResultSetPropertyDaoImpl implements ResultSetPropertyDao {
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @see eu.dnetlib.enabling.resultset.ResultSetPropertyDao#getProperties(eu.dnetlib.enabling.resultset.ResultSet)
|
||||
*/
|
||||
@Override
|
||||
public Map<String, String> getProperties(final ResultSet resultSet) {
|
||||
return new HashMap<String, String>();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
package eu.dnetlib.enabling.resultset;
|
||||
|
||||
import eu.dnetlib.enabling.resultset.observer.ResultSetObserver;
|
||||
|
||||
/**
|
||||
* Instances of ResultSetRegistry manage a set of resultset objects and manage their garbage collection.
|
||||
*
|
||||
* @author marko
|
||||
*
|
||||
*/
|
||||
public interface ResultSetRegistry extends ResultSetObserver {
|
||||
/**
|
||||
* add a resultset object to the registry.
|
||||
*
|
||||
* The given resultset object from now on is managed by the resultset registry.
|
||||
*
|
||||
* @param resultSet
|
||||
* a resultset object
|
||||
*/
|
||||
void addResultSet(ResultSet resultSet);
|
||||
|
||||
/**
|
||||
* add a resultset object to the registry.
|
||||
*
|
||||
* The given resultset object from now on is managed by the resultset registry.
|
||||
*
|
||||
* @param resultSet
|
||||
* a resultset object
|
||||
* @param identifier the identifier you want for the resultset
|
||||
*/
|
||||
void addResultSet(ResultSet resultSet, String identifier);
|
||||
|
||||
/**
|
||||
* add a resultset object to the registry.
|
||||
*
|
||||
* The given resultset object from now on is managed by the resultset registry.
|
||||
*
|
||||
* @param resultSet
|
||||
* a resultset object
|
||||
* @param maxIdleTime
|
||||
* max idle time
|
||||
*/
|
||||
void addResultSet(ResultSet resultSet, int maxIdleTime);
|
||||
|
||||
/**
|
||||
* add a resultset object to the registry.
|
||||
*
|
||||
* The given resultset object from now on is managed by the resultset registry.
|
||||
*
|
||||
* @param resultSet
|
||||
* a resultset object
|
||||
* @param identifier the identifier you want for the resultset
|
||||
* @param maxIdleTime max idle time
|
||||
*/
|
||||
void addResultSet(ResultSet resultSet, String identifier, int maxIdleTime);
|
||||
|
||||
/**
|
||||
* obtain the resultset with the given id.
|
||||
*
|
||||
* @param rsId
|
||||
* resultset id
|
||||
* @return the resultset object matching the rsId or null
|
||||
*/
|
||||
ResultSet getResultSetById(String rsId);
|
||||
|
||||
/**
|
||||
* obtain the resultset's maxIdleTime parameter for a resultset with the given id.
|
||||
*
|
||||
* @param rsId
|
||||
* resultset id
|
||||
* @return max idle time in seconds, as specified when the resultset has been registered
|
||||
*/
|
||||
int getMaxIdleTimeById(String rsId);
|
||||
|
||||
}
|
|
@ -0,0 +1,123 @@
|
|||
package eu.dnetlib.enabling.resultset;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Required;
|
||||
|
||||
import eu.dnetlib.enabling.tools.UniqueIdentifierGenerator;
|
||||
import eu.dnetlib.enabling.tools.UniqueIdentifierGeneratorImpl;
|
||||
import eu.dnetlib.miscutils.cache.Cache;
|
||||
|
||||
/**
|
||||
* Implement a in memory resultset registry.
|
||||
*
|
||||
* @author marko
|
||||
*
|
||||
*/
|
||||
public class ResultSetRegistryImpl implements ResultSetRegistry {
|
||||
|
||||
/**
|
||||
* rsId -> ResultSet mappings are stored here.
|
||||
*/
|
||||
private Cache<String, ResultSet> cache;
|
||||
|
||||
/**
|
||||
* rsID -> initial maxIdleTime time are store here.
|
||||
*/
|
||||
private Cache<String, Integer> maxIdleTimeCache;
|
||||
|
||||
/**
|
||||
* identifier generator.
|
||||
*/
|
||||
private UniqueIdentifierGenerator idGenerator = new UniqueIdentifierGeneratorImpl("rs-");
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @see eu.dnetlib.enabling.resultset.ResultSetRegistry#addResultSet(eu.dnetlib.enabling.resultset.ResultSet)
|
||||
*/
|
||||
@Override
|
||||
public void addResultSet(final ResultSet resultSet) {
|
||||
addResultSet(resultSet, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @see eu.dnetlib.enabling.resultset.ResultSetRegistry#addResultSet(eu.dnetlib.enabling.resultset.ResultSet, java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public void addResultSet(final ResultSet resultSet, final String identifier) {
|
||||
addResultSet(resultSet, identifier, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @see eu.dnetlib.enabling.resultset.ResultSetRegistry#addResultSet(eu.dnetlib.enabling.resultset.ResultSet, int)
|
||||
*/
|
||||
@Override
|
||||
public void addResultSet(final ResultSet resultSet, final int maxIdleTime) {
|
||||
addResultSet(resultSet, idGenerator.generateIdentifier(), maxIdleTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @see eu.dnetlib.enabling.resultset.ResultSetRegistry#addResultSet(eu.dnetlib.enabling.resultset.ResultSet, java.lang.String, int)
|
||||
*/
|
||||
@Override
|
||||
public void addResultSet(final ResultSet resultSet, final String identifier, final int maxIdleTime) {
|
||||
resultSet.setIdentifier(identifier);
|
||||
resultSet.addObserver(this);
|
||||
cache.put(resultSet.getIdentifier(), resultSet);
|
||||
maxIdleTimeCache.put(resultSet.getIdentifier(), maxIdleTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see eu.dnetlib.enabling.resultset.ResultSetRegistry#getResultSetById(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public ResultSet getResultSetById(final String rsId) {
|
||||
return cache.get(rsId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxIdleTimeById(final String rsId) {
|
||||
return maxIdleTimeCache.get(rsId);
|
||||
}
|
||||
|
||||
|
||||
public Cache<String, ResultSet> getCache() {
|
||||
return cache;
|
||||
}
|
||||
|
||||
@Required
|
||||
public void setCache(final Cache<String, ResultSet> cache) {
|
||||
this.cache = cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @see eu.dnetlib.miscutils.observer.Observer#update(eu.dnetlib.enabling.resultset.observer.Observable, java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public void update(final ResultSet observed, final Object arg) {
|
||||
if (!observed.isOpen())
|
||||
cache.remove(observed.getIdentifier());
|
||||
}
|
||||
|
||||
public UniqueIdentifierGenerator getIdGenerator() {
|
||||
return idGenerator;
|
||||
}
|
||||
|
||||
public void setIdGenerator(final UniqueIdentifierGenerator idGenerator) {
|
||||
this.idGenerator = idGenerator;
|
||||
}
|
||||
|
||||
public Cache<String, Integer> getMaxIdleTimeCache() {
|
||||
return maxIdleTimeCache;
|
||||
}
|
||||
|
||||
@Required
|
||||
public void setMaxIdleTimeCache(Cache<String, Integer> maxIdleTimeCache) {
|
||||
this.maxIdleTimeCache = maxIdleTimeCache;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,259 @@
|
|||
package eu.dnetlib.enabling.resultset;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.jws.WebService;
|
||||
import javax.xml.ws.Endpoint;
|
||||
import javax.xml.ws.wsaddressing.W3CEndpointReference;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.factory.annotation.Required;
|
||||
|
||||
import eu.dnetlib.common.rmi.UnimplementedException;
|
||||
import eu.dnetlib.enabling.resultset.push.PushResultSet;
|
||||
import eu.dnetlib.enabling.resultset.push.PushResultSetFactory;
|
||||
import eu.dnetlib.enabling.resultset.rmi.ResultSetException;
|
||||
import eu.dnetlib.enabling.resultset.rmi.ResultSetService;
|
||||
import eu.dnetlib.enabling.tools.AbstractBaseService;
|
||||
import eu.dnetlib.soap.EndpointReferenceBuilder;
|
||||
|
||||
/**
|
||||
* This component dispatches the service method calls to stateful datastructure instances and to the singleton core.
|
||||
*
|
||||
* @author marko
|
||||
*
|
||||
*/
|
||||
@WebService(targetNamespace = "http://services.dnetlib.eu/")
|
||||
public class ResultSetServiceImpl extends AbstractBaseService implements ResultSetService {
|
||||
|
||||
/**
|
||||
* logger.
|
||||
*/
|
||||
private static final Log log = LogFactory.getLog(ResultSetServiceImpl.class); // NOPMD by marko on 11/24/08 5:02 PM
|
||||
|
||||
/**
|
||||
* Maps resultset identifiers to resultsets and manages expiration etc.
|
||||
*/
|
||||
private ResultSetRegistry resultsetRegistry;
|
||||
|
||||
/**
|
||||
* push resultset factory.
|
||||
*/
|
||||
private PushResultSetFactory pushFactory;
|
||||
|
||||
/**
|
||||
* Service endpoint.
|
||||
*/
|
||||
private Endpoint endpoint;
|
||||
|
||||
/**
|
||||
* injected epr builder.
|
||||
*/
|
||||
private EndpointReferenceBuilder<Endpoint> eprBuilder;
|
||||
|
||||
/**
|
||||
* custom resultset properties.
|
||||
*/
|
||||
private ResultSetPropertyDao customPropertyDao;
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see eu.dnetlib.enabling.resultset.rmi.ResultSetService#closeRS(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public void closeRS(final String rsId) {
|
||||
try {
|
||||
final ResultSet resultSet = getResultSetById(rsId);
|
||||
resultSet.close();
|
||||
} catch (ResultSetException e) {
|
||||
log.warn("should throw checked exception but wasn't declared in cnr-rmi-api", e);
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see eu.dnetlib.enabling.resultset.rmi.ResultSetService#createPullRS(java.lang.String, java.lang.String, int, int, java.lang.String,
|
||||
* java.lang.Integer, java.lang.Integer)
|
||||
*/
|
||||
@Override
|
||||
public W3CEndpointReference createPullRS(final String providerAddress,
|
||||
final String bdId,
|
||||
final int initialPageSize,
|
||||
final int expiryTime,
|
||||
final String styleSheet,
|
||||
final Integer keepAliveTime,
|
||||
final Integer total) {
|
||||
throw new UnimplementedException();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see eu.dnetlib.enabling.resultset.rmi.ResultSetService#createPullRSEPR(javax.xml.ws.wsaddressing.W3CEndpointReference,
|
||||
* java.lang.String, int, int, java.lang.String, java.lang.Integer, java.lang.Integer)
|
||||
*/
|
||||
@Override
|
||||
public W3CEndpointReference createPullRSEPR(final W3CEndpointReference dataProviderEPR,
|
||||
final String bdId,
|
||||
final int initialPageSize,
|
||||
final int expiryTime,
|
||||
final String styleSheet,
|
||||
final Integer keepAliveTime,
|
||||
final Integer total) {
|
||||
throw new UnimplementedException();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see eu.dnetlib.enabling.resultset.rmi.ResultSetService#getNumberOfElements(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public int getNumberOfElements(final String rsId) throws ResultSetException {
|
||||
final ResultSet resultSet = getResultSetById(rsId); // NOPMD
|
||||
return resultSet.getNumberOfResults();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see eu.dnetlib.enabling.resultset.rmi.ResultSetService#getResult(java.lang.String, int, int, java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public List<String> getResult(final String rsId, final int fromPosition, final int toPosition, final String requestMode) throws ResultSetException {
|
||||
final ResultSet resultSet = getResultSetById(rsId); // NOPMD
|
||||
return resultSet.getResults(fromPosition, toPosition);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see eu.dnetlib.enabling.resultset.rmi.ResultSetService#createPushRS(int, int)
|
||||
*/
|
||||
@Override
|
||||
public W3CEndpointReference createPushRS(final int expiryTime, final int keepAliveTime) throws ResultSetException {
|
||||
return pushFactory.createPushResultSet(expiryTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see eu.dnetlib.enabling.resultset.rmi.ResultSetService#getProperty(java.lang.String, java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public String getProperty(final String rsId, final String name) throws ResultSetException {
|
||||
final ResultSet resultSet = getResultSetById(rsId); // NOPMD
|
||||
|
||||
if ("rsId".equals(name)) return resultSet.getIdentifier();
|
||||
else if ("total".equals(name)) return Integer.toString(resultSet.getNumberOfResults());
|
||||
else if ("maxExpiryTime".equals(name)) return Integer.toString(resultsetRegistry.getMaxIdleTimeById(rsId));
|
||||
else if ("expiryTime".equals(name)) return Integer.toString(resultsetRegistry.getMaxIdleTimeById(rsId));
|
||||
else if ("keepAliveTime".equals(name)) return Integer.toString(resultsetRegistry.getMaxIdleTimeById(rsId));
|
||||
else if ("classSimpleName".equals(name)) return resultSet.getClass().getSimpleName();
|
||||
// ...
|
||||
|
||||
return customPropertyDao.getProperties(resultSet).get(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see eu.dnetlib.enabling.resultset.rmi.ResultSetService#getRSStatus(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public String getRSStatus(final String rsId) throws ResultSetException {
|
||||
final ResultSet resultSet = getResultSetById(rsId); // NOPMD
|
||||
if (resultSet.isOpen()) return "open";
|
||||
return "closed";
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see eu.dnetlib.enabling.resultset.rmi.ResultSetService#populateRS(java.lang.String, java.util.List)
|
||||
*/
|
||||
@Override
|
||||
public String populateRS(final String rsId, final List<String> elements) throws ResultSetException {
|
||||
final ResultSet resultSet = getResultSetById(rsId); // NOPMD
|
||||
if (resultSet instanceof PushResultSet) {
|
||||
((PushResultSet) resultSet).addElements(elements);
|
||||
} else throw new ResultSetException("ResultSet '" + rsId + "' is not a push resultset");
|
||||
|
||||
return "1";
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see eu.dnetlib.common.rmi.BaseService#start()
|
||||
*/
|
||||
@Override
|
||||
public void start() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* obtain the resultset object for a given id.
|
||||
*
|
||||
* @param rsId
|
||||
* resultset id
|
||||
* @return resultset object, never null
|
||||
* @throws ResultSetException
|
||||
* thrown when the id doesn't exist;
|
||||
*/
|
||||
private ResultSet getResultSetById(final String rsId) throws ResultSetException {
|
||||
final ResultSet resultSet = resultsetRegistry.getResultSetById(rsId); // NOPMD
|
||||
if (resultSet == null) throw new ResultSetException("resultset with id '" + rsId + "' doesn't exist");
|
||||
return resultSet;
|
||||
}
|
||||
|
||||
public ResultSetRegistry getResultsetRegistry() {
|
||||
return resultsetRegistry;
|
||||
}
|
||||
|
||||
@Required
|
||||
public void setResultsetRegistry(final ResultSetRegistry resultsetRegistry) {
|
||||
this.resultsetRegistry = resultsetRegistry;
|
||||
}
|
||||
|
||||
public EndpointReferenceBuilder<Endpoint> getEprBuilder() {
|
||||
return eprBuilder;
|
||||
}
|
||||
|
||||
@Required
|
||||
public void setEprBuilder(final EndpointReferenceBuilder<Endpoint> eprBuilder) {
|
||||
this.eprBuilder = eprBuilder;
|
||||
}
|
||||
|
||||
public Endpoint getEndpoint() {
|
||||
return endpoint;
|
||||
}
|
||||
|
||||
@Required
|
||||
public void setEndpoint(final Endpoint endpoint) {
|
||||
this.endpoint = endpoint;
|
||||
}
|
||||
|
||||
public PushResultSetFactory getPushFactory() {
|
||||
return pushFactory;
|
||||
}
|
||||
|
||||
@Required
|
||||
public void setPushFactory(final PushResultSetFactory pushFactory) {
|
||||
this.pushFactory = pushFactory;
|
||||
}
|
||||
|
||||
public ResultSetPropertyDao getCustomPropertyDao() {
|
||||
return customPropertyDao;
|
||||
}
|
||||
|
||||
public void setCustomPropertyDao(final ResultSetPropertyDao customPropertyDao) {
|
||||
this.customPropertyDao = customPropertyDao;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
package eu.dnetlib.enabling.resultset;
|
||||
|
||||
public interface SizedIterable<T> extends Iterable<T> {
|
||||
|
||||
public int getNumberOfElements();
|
||||
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package eu.dnetlib.enabling.resultset;
|
||||
|
||||
import javax.xml.ws.wsaddressing.W3CEndpointReference;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Required;
|
||||
|
||||
public class StreamingResultSetFactory {
|
||||
/**
|
||||
* underlying resultset factory, which exposes local resultsets to the world.
|
||||
*/
|
||||
private ResultSetFactory resultSetFactory;
|
||||
|
||||
/**
|
||||
* @param items
|
||||
* @param size the size of the iterable
|
||||
* @return
|
||||
*/
|
||||
public W3CEndpointReference createStreamingResultSet(final Iterable<String> items, int size) {
|
||||
return resultSetFactory.createResultSet(new StreamingResultSetListener(items.iterator(), size));
|
||||
}
|
||||
|
||||
|
||||
public ResultSetFactory getResultSetFactory() {
|
||||
return resultSetFactory;
|
||||
}
|
||||
|
||||
@Required
|
||||
public void setResultSetFactory(ResultSetFactory resultSetFactory) {
|
||||
this.resultSetFactory = resultSetFactory;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,132 @@
|
|||
package eu.dnetlib.enabling.resultset;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Exposes an iterable through our resultset protocol.
|
||||
*
|
||||
* <p>
|
||||
* The resultset protocol is constructed as if it were random access. Some kind of sources, like an iterable, is not
|
||||
* random access. The consumer of such a resultset knows that, and won't try to access the resultset randomly. However,
|
||||
* it could ask for some data which is already sent, because of retries caused by network issues.
|
||||
* </p>
|
||||
*
|
||||
* @author marko
|
||||
*
|
||||
*/
|
||||
public class StreamingResultSetListener implements ResultSetListener, ResultSetAware {
|
||||
private static final Log log = LogFactory.getLog(StreamingResultSetListener.class); // NOPMD by marko on 11/24/08 5:02 PM
|
||||
|
||||
private ResultSet resultSet;
|
||||
|
||||
private Iterable<String> iterable;
|
||||
private Iterator<String> items;
|
||||
private int size;
|
||||
|
||||
private int lastFrom = 0;
|
||||
private int lastTo = 0;
|
||||
private List<String> lastChunk;
|
||||
|
||||
public StreamingResultSetListener(Iterable<String> items, int size) {
|
||||
this(items.iterator(), size);
|
||||
this.iterable = items;
|
||||
}
|
||||
|
||||
public StreamingResultSetListener(Iterator<String> items, int size) {
|
||||
super();
|
||||
this.items = items;
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
protected void reset() {
|
||||
lastFrom = 0;
|
||||
items = iterable.iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getResult(int from, int to) {
|
||||
|
||||
log.debug("STREAM: getResult(" + from + ", " + to + ")");
|
||||
|
||||
// handle retry because of network error.
|
||||
if (from == lastFrom && to == lastTo)
|
||||
return lastChunk;
|
||||
|
||||
if (from != lastTo + 1) {
|
||||
if (from == 1 && iterable != null)
|
||||
reset();
|
||||
else
|
||||
throw new IllegalArgumentException("this resultset is not random access, you can only retry last chunk only, asked from " + from + " to "
|
||||
+ to + " but lastTo = " + lastTo + ". Size = " + size);
|
||||
}
|
||||
|
||||
List<String> chunk = new ArrayList<String>();
|
||||
for (int i = from; i <= to; i++)
|
||||
chunk.add(items.next());
|
||||
|
||||
if (resultSet != null && !items.hasNext())
|
||||
resultSet.close();
|
||||
|
||||
lastFrom = from;
|
||||
lastTo = to;
|
||||
lastChunk = chunk;
|
||||
|
||||
return chunk;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public void setSize(int size) {
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
public Iterator<String> getItems() {
|
||||
return items;
|
||||
}
|
||||
|
||||
public void setItems(Iterator<String> items) {
|
||||
this.items = items;
|
||||
}
|
||||
|
||||
public int getLastFrom() {
|
||||
return lastFrom;
|
||||
}
|
||||
|
||||
public void setLastFrom(int lastFrom) {
|
||||
this.lastFrom = lastFrom;
|
||||
}
|
||||
|
||||
public int getLastTo() {
|
||||
return lastTo;
|
||||
}
|
||||
|
||||
public void setLastTo(int lastTo) {
|
||||
this.lastTo = lastTo;
|
||||
}
|
||||
|
||||
public List<String> getLastChunk() {
|
||||
return lastChunk;
|
||||
}
|
||||
|
||||
public void setLastChunk(List<String> lastChunk) {
|
||||
this.lastChunk = lastChunk;
|
||||
}
|
||||
|
||||
public ResultSet getResultSet() {
|
||||
return resultSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setResultSet(ResultSet resultSet) {
|
||||
this.resultSet = resultSet;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package eu.dnetlib.enabling.resultset;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A TypedResultSetListener is a pull interface to a ResultSet.
|
||||
*
|
||||
* The Resultset will call method of ResultSetListener implementors whenever it needs to pull some data and provide it
|
||||
* to clients. The ResultSet service acts as a decouple point between the producer and the consumer.
|
||||
*
|
||||
* @author marko
|
||||
*
|
||||
*/
|
||||
public interface TypedResultSetListener<T> {
|
||||
|
||||
/**
|
||||
* get a single page of results.
|
||||
*
|
||||
* @param fromPosition
|
||||
* from 1
|
||||
* @param toPosition
|
||||
* last included
|
||||
* @return page of results
|
||||
*/
|
||||
List<T> getResult(int fromPosition, int toPosition);
|
||||
|
||||
/**
|
||||
* get number of elements.
|
||||
*
|
||||
* @return number of elements
|
||||
*/
|
||||
int getSize();
|
||||
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
package eu.dnetlib.enabling.resultset;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.xml.transform.Source;
|
||||
import javax.xml.transform.TransformerConfigurationException;
|
||||
import javax.xml.transform.TransformerFactoryConfigurationError;
|
||||
import javax.xml.ws.wsaddressing.W3CEndpointReference;
|
||||
|
||||
import org.springframework.core.io.Resource;
|
||||
|
||||
import eu.dnetlib.miscutils.functional.xml.ApplyXslt;
|
||||
|
||||
/**
|
||||
* Create a mapped resultset using a given XSLT.
|
||||
*
|
||||
* @author marko
|
||||
*
|
||||
*/
|
||||
public class XSLTMappedResultSetFactory extends MappedResultSetFactory {
|
||||
|
||||
public W3CEndpointReference createMappedResultSet(final W3CEndpointReference source, final String xslt) {
|
||||
return createMappedResultSet(source, new ApplyXslt(xslt));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a mapped resultset using a given XSLT.
|
||||
*
|
||||
* @param source
|
||||
* source
|
||||
* @param xslt
|
||||
* XSLT source
|
||||
* @return epr of mapped resultset
|
||||
* @throws TransformerConfigurationException
|
||||
* could happen
|
||||
*/
|
||||
public W3CEndpointReference createMappedResultSet(final W3CEndpointReference source, final String xslt, final String name)
|
||||
throws TransformerConfigurationException {
|
||||
return createMappedResultSet(source, new ApplyXslt(xslt, name));
|
||||
}
|
||||
|
||||
public W3CEndpointReference createMappedResultSet(final W3CEndpointReference source, final Resource xslt) {
|
||||
return createMappedResultSet(source, new ApplyXslt(xslt));
|
||||
}
|
||||
|
||||
public W3CEndpointReference createMappedResultSet(final W3CEndpointReference source, final Source xslt) {
|
||||
return createMappedResultSet(source, new ApplyXslt(xslt));
|
||||
}
|
||||
|
||||
public W3CEndpointReference createMappedResultSet(final W3CEndpointReference source, final Resource xslt, final Map<String, String> parameters) {
|
||||
return createMappedResultSet(source, new ApplyXslt(xslt, parameters));
|
||||
}
|
||||
|
||||
public W3CEndpointReference createMappedResultSet(final W3CEndpointReference source, final String xslt, final Map<String, String> parameters) {
|
||||
return createMappedResultSet(source, new ApplyXslt(xslt, "rs-" + UUID.randomUUID(), parameters));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a mapped resultset using a given XSLT.
|
||||
*
|
||||
* @param source
|
||||
* source
|
||||
* @param xslt
|
||||
* XSLT
|
||||
* @return epr of mapped resultset
|
||||
* @throws TransformerFactoryConfigurationError
|
||||
* @throws TransformerConfigurationException
|
||||
* could happen
|
||||
*/
|
||||
public W3CEndpointReference createMappedResultSet(final W3CEndpointReference source, final Source xslt, final String name) {
|
||||
return createMappedResultSet(source, new ApplyXslt(xslt, name));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package eu.dnetlib.enabling.resultset.observer;
|
||||
|
||||
import eu.dnetlib.enabling.resultset.ResultSet;
|
||||
import eu.dnetlib.enabling.resultset.ResultSetRegistry;
|
||||
|
||||
/**
|
||||
* This class delegates an observation event from the java.util.Observable producer to the real consumer which is not a
|
||||
* java.util.Observer (as expected by java.util.Observable) but instead a miscutils Observer.
|
||||
*
|
||||
* @author marko, claudio, alessia, michele
|
||||
*
|
||||
*/
|
||||
public class DelegationObserver implements java.util.Observer {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private transient final ResultSet observable;
|
||||
private transient final ResultSetRegistry observer;
|
||||
|
||||
public DelegationObserver(final ResultSet observable, final ResultSetRegistry observer) {
|
||||
this.observable = observable;
|
||||
this.observer = observer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(final java.util.Observable ignored, final Object arg) {
|
||||
observer.update(observable, arg);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package eu.dnetlib.enabling.resultset.observer;
|
||||
|
||||
import eu.dnetlib.enabling.resultset.ResultSetRegistry;
|
||||
|
||||
/**
|
||||
* Declares the JDK-like standard observable pattern as a java interface.
|
||||
*
|
||||
* @author marko, claudio, alessia, michele
|
||||
*/
|
||||
public interface Observable {
|
||||
/**
|
||||
* add a given observer to this object.
|
||||
*
|
||||
* @param observer
|
||||
* observer
|
||||
*/
|
||||
void addObserver(ResultSetRegistry observer);
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package eu.dnetlib.enabling.resultset.observer;
|
||||
|
||||
import eu.dnetlib.enabling.resultset.ResultSet;
|
||||
|
||||
|
||||
/**
|
||||
* Implement the same interface as JDK java.util.Observer as java interface (not as a class) and introduce static type
|
||||
* safeness through generics.
|
||||
*
|
||||
* @author marko, claudio, alessia, michele
|
||||
*
|
||||
*/
|
||||
public interface ResultSetObserver {
|
||||
/**
|
||||
* gets notified when an observed object is updated.
|
||||
*
|
||||
* @param observed
|
||||
* observed object which modification triggered this call.
|
||||
* @param arg
|
||||
* arg
|
||||
*/
|
||||
void update(ResultSet observed, Object arg);
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
package eu.dnetlib.enabling.resultset.push;
|
||||
|
||||
import javax.xml.ws.wsaddressing.W3CEndpointReference;
|
||||
|
||||
import eu.dnetlib.enabling.resultset.ResultSetServiceImpl;
|
||||
|
||||
/**
|
||||
* push resultset factory.
|
||||
*
|
||||
* @author marko
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractPushResultSetFactoryImpl implements PushResultSetFactory {
|
||||
/**
|
||||
* resultset service.
|
||||
*/
|
||||
private ResultSetServiceImpl resultSetService;
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @see eu.dnetlib.enabling.resultset.push.PushResultSetFactory#createPushResultSet(int)
|
||||
*/
|
||||
@Override
|
||||
public W3CEndpointReference createPushResultSet(final int maxIdleTime) {
|
||||
final PushResultSet resultSet = newInstance();
|
||||
resultSetService.getResultsetRegistry().addResultSet(resultSet, maxIdleTime);
|
||||
return resultSetService.getEprBuilder().getEndpointReference(resultSetService.getEndpoint(), resultSet.getIdentifier());
|
||||
}
|
||||
|
||||
/**
|
||||
* subclasses should override it and create a new push resultset instance.
|
||||
* @return push resultset instance
|
||||
*/
|
||||
protected abstract PushResultSet newInstance();
|
||||
|
||||
public ResultSetServiceImpl getResultSetService() {
|
||||
return resultSetService;
|
||||
}
|
||||
|
||||
public void setResultSetService(final ResultSetServiceImpl resultSetService) {
|
||||
this.resultSetService = resultSetService;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,179 @@
|
|||
package eu.dnetlib.enabling.resultset.push;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.factory.annotation.Required;
|
||||
|
||||
import eu.dnetlib.enabling.resultset.push.ResultSetDescriptor.Range;
|
||||
import eu.dnetlib.miscutils.cache.Cache;
|
||||
import eu.dnetlib.miscutils.factory.Factory;
|
||||
|
||||
/**
|
||||
* implement a resultset dao.
|
||||
*
|
||||
* @author marko
|
||||
*
|
||||
*/
|
||||
public class CacheTransientResultSetDaoImpl implements TransientPushResultSetDao {
|
||||
|
||||
/**
|
||||
* logger.
|
||||
*/
|
||||
private static final Log log = LogFactory.getLog(CacheTransientResultSetDaoImpl.class); // NOPMD by marko on 11/24/08 5:02 PM
|
||||
|
||||
/**
|
||||
* range cache. Keys are "rsid-rangenumber".
|
||||
*/
|
||||
private Cache<String, List<String>> cache;
|
||||
|
||||
/**
|
||||
* resultsets
|
||||
*/
|
||||
private Cache<String, ResultSetDescriptor> resultSetCache;
|
||||
|
||||
/**
|
||||
* resultset descriptor factory.
|
||||
*/
|
||||
@Resource
|
||||
private Factory<ResultSetDescriptor> resultSetDescriptorFactory;
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see eu.dnetlib.enabling.resultset.push.TransientPushResultSetDao#getSize(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public int getSize(final String key) {
|
||||
final ResultSetDescriptor desc = resultSetCache.get(key);
|
||||
if (desc == null)
|
||||
return 0;
|
||||
return (desc.getRanges() - 1) * desc.getRangeLength() + cache.get(key + "-" + desc.getLastRange()).size();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see eu.dnetlib.enabling.resultset.push.TransientPushResultSetDao#addElements(java.lang.String, java.util.List)
|
||||
*/
|
||||
@Override
|
||||
public void addElements(final String key, final List<String> elements) {
|
||||
// TODO: huuuuu, chaos, fix this please!
|
||||
synchronized (cache) {
|
||||
|
||||
ResultSetDescriptor desc = resultSetCache.get(key);
|
||||
|
||||
log.debug("got desc: " + desc);
|
||||
if (desc == null) {
|
||||
desc = resultSetDescriptorFactory.newInstance();
|
||||
resultSetCache.put(key, desc);
|
||||
}
|
||||
log.debug("desc now is desc: " + desc);
|
||||
|
||||
if (elements.size() > desc.getRangeLength())
|
||||
throw new IllegalArgumentException("The current implementation of the push resultset doesn't accept pages longer than "
|
||||
+ desc.getRangeLength() + ", got: " + elements.size());
|
||||
|
||||
|
||||
int lastRangeIndex = desc.getLastRange();
|
||||
|
||||
if (lastRangeIndex < 0)
|
||||
lastRangeIndex = 0;
|
||||
|
||||
log.debug("last range: " + lastRangeIndex);
|
||||
|
||||
List<String> lastRange = cache.get(key + "-" + lastRangeIndex);
|
||||
log.debug("stored last range: " + lastRange);
|
||||
|
||||
if (lastRange == null) {
|
||||
lastRange = new ArrayList<String>();
|
||||
desc.setRanges(desc.getRanges() + 1);
|
||||
}
|
||||
|
||||
log.debug("last range is: " + lastRange);
|
||||
|
||||
final int free = desc.getRangeLength() - lastRange.size();
|
||||
log.debug("free: " + free);
|
||||
log.debug("desc range length: " + desc.getRangeLength());
|
||||
log.debug("last range size: " + lastRange.size());
|
||||
|
||||
int toElements = free;
|
||||
if (toElements > elements.size()) {
|
||||
toElements = elements.size();
|
||||
} else {
|
||||
|
||||
final List<String> nextRange = new ArrayList<String>(elements.subList(free, elements.size()));
|
||||
log.debug("next range: " + nextRange);
|
||||
|
||||
cache.put(key + "-" + (lastRangeIndex + 1), nextRange);
|
||||
log.debug("next range stored at: " + key + "-" + (lastRangeIndex + 1));
|
||||
desc.setRanges(desc.getRanges() + 1);
|
||||
}
|
||||
lastRange.addAll(elements.subList(0, toElements));
|
||||
|
||||
log.debug("LAST RANGE SIZE: " + lastRange.size() + " range index " + lastRangeIndex);
|
||||
|
||||
log.debug("after add: " + lastRange);
|
||||
|
||||
cache.put(key + "-" + lastRangeIndex, lastRange);
|
||||
log.debug("range stored at: " + key + "-" + lastRangeIndex);
|
||||
|
||||
resultSetCache.put(key, desc);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see eu.dnetlib.enabling.resultset.push.TransientPushResultSetDao#getElements(java.lang.String, int, int)
|
||||
*/
|
||||
@Override
|
||||
public List<String> getElements(final String key, final int fromPosition, final int toPosition) {
|
||||
ResultSetDescriptor desc = resultSetCache.get(key);
|
||||
log.debug("got desc: " + desc);
|
||||
|
||||
if (desc == null)
|
||||
desc = resultSetDescriptorFactory.newInstance();
|
||||
|
||||
final List<String> res = new ArrayList<String>();
|
||||
|
||||
log.debug("ranges containing " + fromPosition + " to " + toPosition);
|
||||
for (final Range range : desc.getRangesContaining(fromPosition, toPosition)) {
|
||||
log.debug("reading range " + key + "-" + range.getRange() + " begin: " + range.getBegin() + " end: " + range.getEnd());
|
||||
res.addAll(cache.get(key + "-" + range.getRange()).subList(range.getBegin(), range.getEnd()));
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
public Cache<String, List<String>> getCache() {
|
||||
return cache;
|
||||
}
|
||||
|
||||
@Required
|
||||
public void setCache(final Cache<String, List<String>> cache) {
|
||||
this.cache = cache;
|
||||
}
|
||||
|
||||
public Cache<String, ResultSetDescriptor> getResultSetCache() {
|
||||
return resultSetCache;
|
||||
}
|
||||
|
||||
@Required
|
||||
public void setResultSetCache(final Cache<String, ResultSetDescriptor> resultSetCache) {
|
||||
this.resultSetCache = resultSetCache;
|
||||
}
|
||||
|
||||
public Factory<ResultSetDescriptor> getResultSetDescriptorFactory() {
|
||||
return resultSetDescriptorFactory;
|
||||
}
|
||||
|
||||
public void setResultSetDescriptorFactory(final Factory<ResultSetDescriptor> resultSetDescriptorFactory) {
|
||||
this.resultSetDescriptorFactory = resultSetDescriptorFactory;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package eu.dnetlib.enabling.resultset.push;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import eu.dnetlib.enabling.resultset.ResultSet;
|
||||
|
||||
/**
|
||||
* resultset which receive data through the "push" interface, i.e. data is directly appended to it.
|
||||
*
|
||||
* @author marko
|
||||
*
|
||||
*/
|
||||
public interface PushResultSet extends ResultSet {
|
||||
|
||||
/**
|
||||
* add a list of elements at the end of the resultset.
|
||||
*
|
||||
* @param elements list of elements
|
||||
*/
|
||||
void addElements(List<String> elements);
|
||||
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package eu.dnetlib.enabling.resultset.push;
|
||||
|
||||
import javax.xml.ws.wsaddressing.W3CEndpointReference;
|
||||
|
||||
/**
|
||||
* creates a new push resultset.
|
||||
*
|
||||
* @author marko
|
||||
*
|
||||
*/
|
||||
public interface PushResultSetFactory {
|
||||
|
||||
/**
|
||||
* create a new push resultset.
|
||||
*
|
||||
* @param maxIdleTime max time the resultset can be idle
|
||||
* @return push resultset epr
|
||||
*/
|
||||
W3CEndpointReference createPushResultSet(int maxIdleTime);
|
||||
|
||||
}
|
|
@ -0,0 +1,156 @@
|
|||
package eu.dnetlib.enabling.resultset.push;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Describes a push resultset.
|
||||
*
|
||||
* <p>
|
||||
* A push resultset stores it's data in several ranges
|
||||
* </p>
|
||||
*
|
||||
* @author marko
|
||||
*
|
||||
*/
|
||||
public class ResultSetDescriptor implements Serializable {
|
||||
|
||||
/**
|
||||
* logger.
|
||||
*/
|
||||
private static final Log log = LogFactory.getLog(Range.class); // NOPMD by marko on 11/24/08 5:02 PM
|
||||
|
||||
/**
|
||||
* This class describes a range.
|
||||
*
|
||||
* @author marko
|
||||
*
|
||||
*/
|
||||
public class Range {
|
||||
private int range;
|
||||
private int begin;
|
||||
private int end;
|
||||
|
||||
public Range(final int range, final int begin, final int end) {
|
||||
super();
|
||||
this.range = range;
|
||||
this.begin = begin;
|
||||
this.end = end;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Range(" + range + ", " + begin + ", " + end + ")";
|
||||
}
|
||||
|
||||
public int getRange() {
|
||||
return range;
|
||||
}
|
||||
|
||||
public void setRange(final int range) {
|
||||
this.range = range;
|
||||
}
|
||||
|
||||
public int getBegin() {
|
||||
return begin;
|
||||
}
|
||||
|
||||
public void setBegin(final int begin) {
|
||||
this.begin = begin;
|
||||
}
|
||||
|
||||
public int getEnd() {
|
||||
return end;
|
||||
}
|
||||
|
||||
public void setEnd(final int end) {
|
||||
this.end = end;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 7699992350256317181L;
|
||||
|
||||
private int rangeLength = 100;
|
||||
|
||||
private int ranges = 0;
|
||||
|
||||
public int getLastRange() {
|
||||
return ranges - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param fromPosition
|
||||
* 1 based count
|
||||
* @param toPosition
|
||||
* 1 based count
|
||||
* @return
|
||||
*/
|
||||
public Iterable<Range> getRangesContaining(final int fromPosition, final int toPosition) {
|
||||
|
||||
final int fromRange = (fromPosition - 1) / rangeLength;
|
||||
int ttoRange = (int) Math.ceil((toPosition * 1.0) / rangeLength);
|
||||
|
||||
if (ttoRange > ranges)
|
||||
ttoRange = ranges;
|
||||
|
||||
final int toRange = ttoRange;
|
||||
|
||||
log.debug("FROM range: " + fromRange);
|
||||
log.debug("TTO range: " + ttoRange);
|
||||
log.debug("TO range: " + toRange);
|
||||
|
||||
return new Iterable<Range>() {
|
||||
|
||||
@Override
|
||||
public Iterator<Range> iterator() {
|
||||
return new Iterator<Range>() {
|
||||
|
||||
int current = fromRange;
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return current < toRange;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Range next() {
|
||||
int begin = 0;
|
||||
int end = rangeLength;
|
||||
if (current == fromRange)
|
||||
begin = (fromPosition - 1) % rangeLength;
|
||||
if ((current + 1) == toRange)
|
||||
end = (toPosition - 1) % rangeLength + 1;
|
||||
return new Range(current++, begin, end);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new IllegalStateException("text");
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public int getRangeLength() {
|
||||
return rangeLength;
|
||||
}
|
||||
|
||||
public void setRangeLength(final int rangeLength) {
|
||||
this.rangeLength = rangeLength;
|
||||
}
|
||||
|
||||
public int getRanges() {
|
||||
return ranges;
|
||||
}
|
||||
|
||||
public void setRanges(final int ranges) {
|
||||
this.ranges = ranges;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
package eu.dnetlib.enabling.resultset.push;
|
||||
|
||||
import eu.dnetlib.miscutils.factory.Factory;
|
||||
|
||||
public interface ResultSetDescriptorFactory extends Factory<ResultSetDescriptor> {
|
||||
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
package eu.dnetlib.enabling.resultset.push;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* offer access to the underlying in-memory or pseudo-memory (serialization backed caches) storage for the transient
|
||||
* push-resultsets.
|
||||
*
|
||||
* This type of push resultsets doesn't even try to make efficient access to records, they just keep them as big lists
|
||||
* on the underlying storage. Actual implementations may decide to keep them on the heap or to use some caching
|
||||
* technology like ehcache.
|
||||
*
|
||||
* @author marko
|
||||
*
|
||||
*/
|
||||
public interface TransientPushResultSetDao {
|
||||
/**
|
||||
* add elements to a given key.
|
||||
*
|
||||
* @param key
|
||||
* usually a rsid.
|
||||
* @param elements
|
||||
* list of elements
|
||||
*/
|
||||
void addElements(String key, List<String> elements);
|
||||
|
||||
/**
|
||||
* obtain content for a given key (resultset) in a given range (1 based).
|
||||
*
|
||||
* @param key
|
||||
* usually a rsid
|
||||
* @param fromPosition from position (1 based, inclusive)
|
||||
* @param toPosition to position (1 based, inclusive)
|
||||
* @return all the elements for a given key
|
||||
*/
|
||||
List<String> getElements(String key, int fromPosition, int toPosition);
|
||||
|
||||
/**
|
||||
* get the resultset size (number of elements).
|
||||
*
|
||||
* @param key usually a rsid
|
||||
* @return resultset size
|
||||
*/
|
||||
int getSize(String key);
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package eu.dnetlib.enabling.resultset.push;
|
||||
|
||||
|
||||
/**
|
||||
* creates a transient push resultset.
|
||||
*
|
||||
* @author marko
|
||||
*
|
||||
*/
|
||||
public class TransientPushResultSetFactory extends AbstractPushResultSetFactoryImpl {
|
||||
|
||||
/**
|
||||
* dao.
|
||||
*/
|
||||
private TransientPushResultSetDao dao;
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @see eu.dnetlib.enabling.resultset.push.AbstractPushResultSetFactoryImpl#newInstance()
|
||||
*/
|
||||
@Override
|
||||
protected PushResultSet newInstance() {
|
||||
return new TransientPushResultSetImpl(dao);
|
||||
}
|
||||
|
||||
public TransientPushResultSetDao getDao() {
|
||||
return dao;
|
||||
}
|
||||
|
||||
public void setDao(final TransientPushResultSetDao dao) {
|
||||
this.dao = dao;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
package eu.dnetlib.enabling.resultset.push;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import eu.dnetlib.enabling.resultset.AbstractObservableResultset;
|
||||
|
||||
/**
|
||||
* a push resultset which holds it's data in a transient cache.
|
||||
*
|
||||
* @author marko
|
||||
*
|
||||
*/
|
||||
public class TransientPushResultSetImpl extends AbstractObservableResultset implements PushResultSet {
|
||||
|
||||
/**
|
||||
* logger.
|
||||
*/
|
||||
private static final Log log = LogFactory.getLog(TransientPushResultSetImpl.class); // NOPMD by marko on 11/24/08 5:02 PM
|
||||
|
||||
/**
|
||||
* dao.
|
||||
*/
|
||||
private final transient TransientPushResultSetDao dao;
|
||||
|
||||
/**
|
||||
* rsId.
|
||||
*/
|
||||
private String identifier;
|
||||
|
||||
/**
|
||||
* constructed by the transient push resultset factory.
|
||||
*
|
||||
* @param dao dao
|
||||
*/
|
||||
public TransientPushResultSetImpl(final TransientPushResultSetDao dao) {
|
||||
super();
|
||||
this.dao = dao;
|
||||
setOpen(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see eu.dnetlib.enabling.resultset.push.PushResultSet#addElements(java.util.List)
|
||||
*/
|
||||
@Override
|
||||
public void addElements(final List<String> elements) {
|
||||
log.debug("adding to push RS: " + elements);
|
||||
|
||||
if (isOpen())
|
||||
dao.addElements(getIdentifier(), elements);
|
||||
else
|
||||
throw new IllegalStateException("cannot write to a closed push resultset");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumberOfResults() {
|
||||
return dao.getSize(getIdentifier());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see eu.dnetlib.enabling.resultset.ResultSet#getResults(int, int)
|
||||
*/
|
||||
@Override
|
||||
public List<String> getResults(final int fromPosition, final int toPosition) {
|
||||
|
||||
final int size = getNumberOfResults();
|
||||
int toPos = toPosition;
|
||||
int fromPos = fromPosition;
|
||||
if (fromPos > size)
|
||||
fromPos = size;
|
||||
if (toPos > size)
|
||||
toPos = size;
|
||||
|
||||
log.debug("calling get elements: " + getIdentifier() + " from " + fromPos + " to " + toPos);
|
||||
return dao.getElements(getIdentifier(), fromPos, toPos);
|
||||
}
|
||||
|
||||
public TransientPushResultSetDao getDao() {
|
||||
return dao;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdentifier() {
|
||||
return identifier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setIdentifier(final String identifier) {
|
||||
this.identifier = identifier;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
|
||||
xmlns:util="http://www.springframework.org/schema/util" xmlns:template="http://dnetlib.eu/springbeans/template"
|
||||
xmlns:t="http://dnetlib.eu/springbeans/t"
|
||||
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://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
|
||||
http://dnetlib.eu/springbeans/template http://dnetlib.eu/springbeans/template.xsd
|
||||
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
|
||||
|
||||
<!-- beans -->
|
||||
|
||||
<bean id="hcmService"
|
||||
class="eu.dnetlib.enabling.hcm.HostingContextManagerServiceImpl"
|
||||
init-method="start" destroy-method="stop"
|
||||
p:notificationHandler-ref="hcmNotificationHandler"/>
|
||||
|
||||
<bean id="hcmNotificationHandler" class="eu.dnetlib.enabling.tools.blackboard.NotificationHandlerChainImpl"
|
||||
p:handlers-ref="dynamicSubscriptionActions">
|
||||
<property name="handlerExecutor">
|
||||
<bean class="org.springframework.core.task.SyncTaskExecutor" />
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="dynamicSubscriptionActions"
|
||||
class="eu.dnetlib.enabling.hcm.sn.HCMSubscriptionListFactory" />
|
||||
|
||||
<bean id="hcmSubscriber" class="eu.dnetlib.enabling.hcm.sn.HCMSubscriberImpl"
|
||||
p:endpoint-ref="hcmServiceEndpoint" p:serviceLocator-ref="uniqueServiceLocator"
|
||||
p:actions-ref="dynamicSubscriptionActions" />
|
||||
|
||||
<bean t:id="hcmJobSchedulerAccessor"
|
||||
class="org.springframework.scheduling.quartz.SchedulerAccessorBean"
|
||||
p:scheduler-ref="jobScheduler">
|
||||
<property name="triggers">
|
||||
<list>
|
||||
<bean id="hcmSubscriptionTrigger"
|
||||
class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean"
|
||||
p:startDelay="6000" p:repeatCount="0">
|
||||
<property name="jobDetail">
|
||||
<bean id="hcmSubscriptionJobDetails"
|
||||
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"
|
||||
p:targetObject-ref="hcmSubscriber" p:targetMethod="subscribeAll" />
|
||||
</property>
|
||||
</bean>
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<!-- endpoints -->
|
||||
<jaxws:endpoint id="hcmServiceEndpoint" implementor="#hcmService"
|
||||
implementorClass="eu.dnetlib.enabling.hcm.rmi.HostingContextManagerService"
|
||||
address="/hcm" />
|
||||
|
||||
<template:instance name="serviceRegistrationManager"
|
||||
t:serviceRegistrationManagerClass="eu.dnetlib.enabling.tools.registration.ValidatingServiceRegistrationManagerImpl"
|
||||
t:name="hcmServiceRegistrationManager" t:service="hcmService"
|
||||
t:endpoint="hcmServiceEndpoint" t:jobScheduler="jobScheduler" />
|
||||
</beans>
|
|
@ -0,0 +1,45 @@
|
|||
<?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:jaxws="http://cxf.apache.org/jaxws"
|
||||
xmlns:sec="http://cxf.apache.org/configuration/security" xmlns:wsa="http://cxf.apache.org/ws/addressing"
|
||||
xmlns:p="http://www.springframework.org/schema/p" xmlns:http="http://cxf.apache.org/transports/http/configuration"
|
||||
xmlns:t="http://dnetlib.eu/springbeans/t" xmlns:template="http://dnetlib.eu/springbeans/template"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://cxf.apache.org/ws/addressing http://cxf.apache.org/schemas/ws-addr-conf.xsd
|
||||
http://cxf.apache.org/configuration/security http://cxf.apache.org/schemas/configuration/security.xsd
|
||||
http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd
|
||||
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
|
||||
http://dnetlib.eu/springbeans/template http://dnetlib.eu/springbeans/template.xsd">
|
||||
|
||||
<!-- beans -->
|
||||
<bean id="hnmService" class="eu.dnetlib.enabling.hnm.HostingNodeManagerServiceImpl"
|
||||
init-method="start" destroy-method="stop"/>
|
||||
|
||||
<!-- endpoints -->
|
||||
<jaxws:endpoint id="hnmServiceEndpoint"
|
||||
implementor="#hnmService" implementorClass="eu.dnetlib.enabling.hnm.rmi.HostingNodeManagerService"
|
||||
address="/hnm" />
|
||||
|
||||
<template:instance name="serviceRegistrationManager"
|
||||
t:serviceRegistrationManagerClass="eu.dnetlib.enabling.tools.registration.ValidatingServiceRegistrationManagerImpl"
|
||||
t:name="hnmServiceRegistrationManager" t:service="hnmService"
|
||||
t:endpoint="hnmServiceEndpoint" t:jobScheduler="jobScheduler"
|
||||
t:serviceRegistrator="hnmServiceRegistrator" />
|
||||
|
||||
|
||||
<bean id="hnmServiceRegistrator"
|
||||
class="eu.dnetlib.enabling.tools.registration.BlackboardServiceRegistrator"
|
||||
p:serviceLocator-ref="uniqueServiceLocator"
|
||||
p:serviceNameResolver-ref="defaultServiceNameResolver"
|
||||
p:eprBuilder-ref="jaxwsEndpointReferenceBuilder">
|
||||
<property name="serviceProperties">
|
||||
<map>
|
||||
<entry key="name" value="unknown" />
|
||||
<entry key="latitude" value="0" />
|
||||
<entry key="longitude" value="0" />
|
||||
<entry key="timezone" value="0" />
|
||||
</map>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
</beans>
|
|
@ -0,0 +1,10 @@
|
|||
services.is.resultset.resultSetRegistryCache.timeToIdle = 240
|
||||
services.is.resultset.resultSetRegistryMaxIdleTimeCache.timeToIdle = 240
|
||||
|
||||
# jaxwsEndpointReferenceBuilder | staticResultSetServiceEprBuilder
|
||||
services.resultset.eprbuilder.bean = jaxwsEndpointReferenceBuilder
|
||||
services.resultset.endpoint.static.address = ${transport.soap.baseAddress}/resultSet
|
||||
|
||||
services.is.resultset.push.timeToIdle=36000
|
||||
services.is.resultset.push.maxElementsInMemory=500
|
||||
services.is.resultset.push.maxElementsOnDisk=5000000
|
|
@ -0,0 +1,138 @@
|
|||
<?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:jaxws="http://cxf.apache.org/jaxws"
|
||||
xmlns:sec="http://cxf.apache.org/configuration/security" xmlns:wsa="http://cxf.apache.org/ws/addressing"
|
||||
xmlns:p="http://www.springframework.org/schema/p" xmlns:http="http://cxf.apache.org/transports/http/configuration"
|
||||
xmlns:t="http://dnetlib.eu/springbeans/t" xmlns:template="http://dnetlib.eu/springbeans/template"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://cxf.apache.org/ws/addressing http://cxf.apache.org/schemas/ws-addr-conf.xsd
|
||||
http://cxf.apache.org/configuration/security http://cxf.apache.org/schemas/configuration/security.xsd
|
||||
http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd
|
||||
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
|
||||
http://dnetlib.eu/springbeans/template http://dnetlib.eu/springbeans/template.xsd">
|
||||
|
||||
<!-- beans -->
|
||||
<bean id="resultSetCacheManager"
|
||||
class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" />
|
||||
<!-- p:configLocation="classpath:eu/dnetlib/enabling/resultset/ehcache.xml" -->
|
||||
|
||||
<bean id="resultSetRegistryCache" class="eu.dnetlib.miscutils.cache.EhCache">
|
||||
<property name="cache">
|
||||
<bean id="resultSetRegistryCacheCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean"
|
||||
p:cacheManager-ref="resultSetCacheManager" p:cacheName="resultSetFactoryCache"
|
||||
p:eternal="false" p:timeToLive="${services.is.resultset.resultSetRegistryCache.timeToIdle}"
|
||||
p:timeToIdle="${services.is.resultset.resultSetRegistryCache.timeToIdle}" />
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="resultSetRegistryMaxIdleTimeCache" class="eu.dnetlib.miscutils.cache.EhCache">
|
||||
<property name="cache">
|
||||
<bean id="resultSetRegistryMaxIdleTimeCacheCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean"
|
||||
p:cacheManager-ref="resultSetCacheManager" p:cacheName="resultSetFactoryMaxIdleTimeCache"
|
||||
p:eternal="false" p:timeToLive="${services.is.resultset.resultSetRegistryMaxIdleTimeCache.timeToIdle}"
|
||||
p:timeToIdle="${services.is.resultset.resultSetRegistryMaxIdleTimeCache.timeToIdle}" />
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<!-- backing store for the pushResultSetDao -->
|
||||
<bean id="pushResultSetStoreCache" class="eu.dnetlib.miscutils.cache.EhCache">
|
||||
<property name="cache">
|
||||
<bean id="pushResultSetStoreCacheCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean"
|
||||
p:eternal="false" p:timeToLive="${services.is.resultset.push.timeToIdle}" p:timeToIdle="${services.is.resultset.push.timeToIdle}"
|
||||
p:overflowToDisk="true"
|
||||
p:maxElementsInMemory="${services.is.resultset.push.maxElementsInMemory}"
|
||||
p:maxElementsOnDisk="${services.is.resultset.push.maxElementsOnDisk}"
|
||||
p:cacheManager-ref="resultSetCacheManager" p:cacheName="pushResultSetStoreCache" />
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<!-- resultset descriptor store for the pushResultSetDao -->
|
||||
<bean id="pushResultSetDescriptorCache" class="eu.dnetlib.miscutils.cache.EhCache">
|
||||
<property name="cache">
|
||||
<bean id="pushResultSetDescriptorCacheCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean"
|
||||
p:eternal="false" p:timeToLive="1800" p:timeToIdle="1800"
|
||||
p:cacheManager-ref="resultSetCacheManager" p:cacheName="pushResultSetDescriptorCache" />
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="resultSetDescriptorFactory" class="eu.dnetlib.springutils.beans.factory.PrototypeFactory">
|
||||
<lookup-method name="newInstance" bean="resultSetDescriptorPrototype" />
|
||||
</bean>
|
||||
|
||||
<bean id="resultSetDescriptorPrototype" class="eu.dnetlib.enabling.resultset.push.ResultSetDescriptor"
|
||||
p:rangeLength="100" scope="prototype" />
|
||||
|
||||
<bean id="resultSetRegistry" class="eu.dnetlib.enabling.resultset.ResultSetRegistryImpl"
|
||||
p:cache-ref="resultSetRegistryCache" p:maxIdleTimeCache-ref="resultSetRegistryMaxIdleTimeCache" />
|
||||
|
||||
<!--
|
||||
<bean id="resultSetEPRPool" class="eu.dnetlib.enabling.resultset.ResultSetEPRPool"
|
||||
p:resultSetService-ref="resultSetService" />
|
||||
-->
|
||||
|
||||
<!-- <bean id="resultSetFactory" class="eu.dnetlib.enabling.resultset.LocalResultSetFactoryImpl" -->
|
||||
<!-- <bean id="resultSetFactory" class="eu.dnetlib.enabling.resultset.EPRPoolingLocalResultSetFactoryImpl" p:pool-ref="resultSetEPRPool"
|
||||
p:resultSetService-ref="resultSetService" /> -->
|
||||
|
||||
<bean id="resultSetFactory" class="eu.dnetlib.enabling.resultset.LocalResultSetFactoryImpl"
|
||||
p:resultSetService-ref="resultSetService" />
|
||||
|
||||
<bean id="openResultSetFactory"
|
||||
class="eu.dnetlib.enabling.resultset.LocalOpenResultSetFactoryImpl"
|
||||
p:resultSetService-ref="resultSetService" />
|
||||
|
||||
<!--
|
||||
<bean id="openResultSetFactory"
|
||||
class="eu.dnetlib.enabling.resultset.EPRPoolingLocalOpenResultSetFactoryImpl" p:pool-ref="resultSetEPRPool"
|
||||
p:resultSetService-ref="resultSetService" />
|
||||
-->
|
||||
<bean id="mappedResultSetFactory" class="eu.dnetlib.enabling.resultset.MappedResultSetFactory"
|
||||
p:serviceResolver-ref="serviceResolver" p:resultSetFactory-ref="resultSetFactory" />
|
||||
|
||||
<bean id="parallelMappedResultSetFactory" class="eu.dnetlib.enabling.resultset.ParallelMappedResultSetFactory"
|
||||
p:serviceResolver-ref="serviceResolver" p:resultSetFactory-ref="resultSetFactory" />
|
||||
|
||||
<bean id="xsltResultSetFactory"
|
||||
class="eu.dnetlib.enabling.resultset.XSLTMappedResultSetFactory"
|
||||
p:serviceResolver-ref="serviceResolver" p:resultSetFactory-ref="resultSetFactory" />
|
||||
|
||||
<bean id="countingResultSetFactory" class="eu.dnetlib.enabling.resultset.CountingResultSetFactory"
|
||||
p:serviceResolver-ref="serviceResolver" p:resultSetFactory-ref="resultSetFactory" />
|
||||
|
||||
<bean id="streamingResultSetFactory" class="eu.dnetlib.enabling.resultset.StreamingResultSetFactory"
|
||||
p:resultSetFactory-ref="resultSetFactory" />
|
||||
|
||||
<bean id="cachingResultSetFactory" class="eu.dnetlib.enabling.resultset.CachingResultSetFactory"
|
||||
p:resultSetFactory-ref="resultSetFactory" />
|
||||
|
||||
<bean id="pushResultSetFactory"
|
||||
class="eu.dnetlib.enabling.resultset.push.TransientPushResultSetFactory"
|
||||
p:dao-ref="pushResultSetDao" p:resultSetService-ref="resultSetService" />
|
||||
|
||||
<bean id="iterableResultSetFactory" class="eu.dnetlib.enabling.resultset.IterableResultSetFactory"
|
||||
p:fetchSize="10" p:resultSetFactory-ref="openResultSetFactory"
|
||||
lazy-init="true" />
|
||||
|
||||
|
||||
<bean id="pushResultSetDao"
|
||||
class="eu.dnetlib.enabling.resultset.push.CacheTransientResultSetDaoImpl"
|
||||
p:cache-ref="pushResultSetStoreCache" p:resultSetCache-ref="pushResultSetDescriptorCache" />
|
||||
|
||||
<bean id="customResultSetPropertyDao" class="eu.dnetlib.enabling.resultset.ResultSetPropertyDaoImpl" />
|
||||
|
||||
<bean id="resultSetService" class="eu.dnetlib.enabling.resultset.ResultSetServiceImpl"
|
||||
init-method="start" p:resultsetRegistry-ref="resultSetRegistry"
|
||||
p:pushFactory-ref="pushResultSetFactory" p:endpoint-ref="resultSetServiceEndpoint"
|
||||
p:eprBuilder-ref="jaxwsEndpointReferenceBuilder" p:customPropertyDao-ref="customResultSetPropertyDao" />
|
||||
|
||||
<!-- endpoints -->
|
||||
<jaxws:endpoint id="resultSetServiceEndpoint"
|
||||
implementor="#resultSetService" implementorClass="eu.dnetlib.enabling.resultset.rmi.ResultSetService"
|
||||
address="/resultSet" />
|
||||
|
||||
<template:instance name="serviceRegistrationManager"
|
||||
t:serviceRegistrationManagerClass="eu.dnetlib.enabling.tools.registration.ValidatingServiceRegistrationManagerImpl"
|
||||
t:name="resultSetServiceRegistrationManager" t:service="resultSetService"
|
||||
t:endpoint="resultSetServiceEndpoint" t:jobScheduler="jobScheduler" />
|
||||
|
||||
</beans>
|
|
@ -0,0 +1,75 @@
|
|||
package eu.dnetlib.enabling.resultset;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class FetchListTest {
|
||||
|
||||
/**
|
||||
* object to test
|
||||
*/
|
||||
private FetchList<String> fetchList;
|
||||
|
||||
private List<String> list;
|
||||
private Iterator<String> iter;
|
||||
|
||||
private int FETCH_SIZE = 10;
|
||||
|
||||
private int TOTAL_ELEMENTS = 100;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
list = new ArrayList<String>();
|
||||
for (int i = 0; i < TOTAL_ELEMENTS; i++) {
|
||||
list.add("XXX" + i);
|
||||
}
|
||||
this.iter = list.iterator();
|
||||
fetchList = new FetchList<String>(iter, FETCH_SIZE);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFetchList() {
|
||||
assertNotNull(fetchList);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPoll_consumedElements() {
|
||||
assertEquals(0, fetchList.getConsumedElements());
|
||||
fetchList.poll();
|
||||
assertEquals(1, fetchList.getConsumedElements());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFill_totalElements() {
|
||||
assertEquals(FETCH_SIZE, fetchList.getTotalElements());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPoll() {
|
||||
for (int i = 0; i < TOTAL_ELEMENTS; i++) {
|
||||
assertEquals(i, fetchList.getConsumedElements());
|
||||
assertEquals(list.get(i), fetchList.poll());
|
||||
}
|
||||
assertEquals(TOTAL_ELEMENTS, fetchList.getConsumedElements());
|
||||
assertEquals(TOTAL_ELEMENTS, fetchList.getTotalElements());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPoll_null() {
|
||||
for (int i = 0; i < TOTAL_ELEMENTS; i++) {
|
||||
fetchList.poll();
|
||||
}
|
||||
assertNull(fetchList.poll());
|
||||
assertNull(fetchList.poll());
|
||||
assertNull(fetchList.poll());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,150 @@
|
|||
package eu.dnetlib.enabling.resultset;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNotSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
/**
|
||||
* tests the IterableResult class
|
||||
*
|
||||
* @author claudio
|
||||
*
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class IterableResultSetTest {
|
||||
|
||||
/**
|
||||
* number of total elements
|
||||
*/
|
||||
private static int NUM_ELEM = 100;
|
||||
|
||||
/**
|
||||
* number of elements available to fetch
|
||||
*/
|
||||
private static int FETCH_SIZE = 10;
|
||||
|
||||
@Mock
|
||||
private ResultSet mockResultSet;
|
||||
|
||||
/**
|
||||
* a list used to compare elements.
|
||||
*/
|
||||
private List<String> list;
|
||||
|
||||
/**
|
||||
* Iterator associated with the test list.
|
||||
*/
|
||||
private Iterator<String> iter;
|
||||
|
||||
/**
|
||||
* Object to test.
|
||||
*/
|
||||
private IterableResultSet iterResultSet;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
list = new ArrayList<String>();
|
||||
for (int i=0; i< NUM_ELEM; i++)
|
||||
list.add("XXXXX " + i);
|
||||
|
||||
iter = list.iterator();
|
||||
when(mockResultSet.isOpen()).thenReturn(iter.hasNext());
|
||||
|
||||
iterResultSet = new IterableResultSet(list, FETCH_SIZE);
|
||||
iterResultSet.setResultSet(mockResultSet);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIterableResultSet() {
|
||||
assertNotNull(iterResultSet);
|
||||
assertTrue(iterResultSet.getSize() > 0);
|
||||
}
|
||||
|
||||
@Test(expected=RuntimeException.class)
|
||||
public void testGetResult_fail_1() {
|
||||
iterResultSet.getResult(0, 5);
|
||||
}
|
||||
|
||||
@Test(expected=RuntimeException.class)
|
||||
public void testGetResult_fail_2() {
|
||||
iterResultSet.getResult(1, 5);
|
||||
iterResultSet.getResult(1, 5);
|
||||
}
|
||||
|
||||
@Test(expected=RuntimeException.class)
|
||||
public void testGetResult_fail_3() {
|
||||
iterResultSet.getResult(1, 5);
|
||||
iterResultSet.getResult(6, 5);
|
||||
}
|
||||
|
||||
@Test(expected=RuntimeException.class)
|
||||
public void testGetResult_fail_4() {
|
||||
iterResultSet.getResult(1, 5);
|
||||
iterResultSet.getResult(7, 10);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetResult_success_1() {
|
||||
List<String> result = iterResultSet.getResult(1, NUM_ELEM);
|
||||
for (int i=0; i<NUM_ELEM; i++) {
|
||||
assertEquals(list.get(i), result.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetResult_success_2() {
|
||||
List<String> result = iterResultSet.getResult(1, NUM_ELEM);
|
||||
|
||||
for (int i=0; i<NUM_ELEM; i++) {
|
||||
assertEquals(list.get(i), result.get(i));
|
||||
iter.next();
|
||||
}
|
||||
verify(mockResultSet).close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetResult_success_3() {
|
||||
for (int i = 1; i < NUM_ELEM; i+= FETCH_SIZE)
|
||||
iterResultSet.getResult(i, i + FETCH_SIZE-1);
|
||||
verify(mockResultSet, times(1)).close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetResult_success_4() {
|
||||
iterResultSet.getResult(1, NUM_ELEM + 1);
|
||||
verify(mockResultSet, times(1)).close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetResultSet_success_1() {
|
||||
assertNotNull(iterResultSet.getResultSet());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSize_fail_1() {
|
||||
iterResultSet.getResult(1, 8);
|
||||
assertNotSame(7, iterResultSet.getSize());
|
||||
assertNotSame(9, iterResultSet.getSize());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSize_success_1() {
|
||||
iterResultSet.getResult(1, 8);
|
||||
assertEquals(FETCH_SIZE, iterResultSet.getSize());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,174 @@
|
|||
package eu.dnetlib.enabling.resultset;
|
||||
|
||||
import static org.junit.Assert.*; // NOPMD
|
||||
import static org.mockito.Mockito.*; // NOPMD by marko on 11/26/08 9:13 PM
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
/**
|
||||
* test the resultset concrete implementation.
|
||||
*
|
||||
* @author marko
|
||||
*
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class LocalResultSetImplTest {
|
||||
|
||||
/**
|
||||
* This class could be an anonymous class, but is here to be shared among tests.
|
||||
*
|
||||
* @author marko
|
||||
*
|
||||
*/
|
||||
private static final class TestResultSetListener implements ResultSetListener {
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see eu.dnetlib.enabling.resultset.ResultSetListener#getResult(int, int)
|
||||
*/
|
||||
@Override
|
||||
public List<String> getResult(final int fromPosition, final int toPosition) {
|
||||
final List<String> res = new ArrayList<String>();
|
||||
for (int i = fromPosition; i <= toPosition; i++)
|
||||
res.add(((Integer) (i - 1)).toString());
|
||||
return res;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSize() {
|
||||
return RESULT_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Mockito lacks of multiple interfaces mocking.
|
||||
*
|
||||
* @author marko
|
||||
*
|
||||
*/
|
||||
private abstract static class AbstractResultSetAware implements ResultSetListener, ResultSetAware {
|
||||
}
|
||||
|
||||
/**
|
||||
* resultset registry mock.
|
||||
*/
|
||||
@Mock
|
||||
private transient ResultSetRegistry registry;
|
||||
|
||||
/**
|
||||
* object under test.
|
||||
*/
|
||||
private transient LocalResultSetImpl resultSet;
|
||||
|
||||
/**
|
||||
* number of returned test results.
|
||||
*/
|
||||
private static final int RESULT_SIZE = 3;
|
||||
|
||||
/**
|
||||
* provides data to the resultset under test.
|
||||
*/
|
||||
private transient TestResultSetListener resultSetListener;
|
||||
|
||||
/**
|
||||
* prepare.
|
||||
*
|
||||
*/
|
||||
@Before
|
||||
public void setUp() {
|
||||
resultSetListener = new TestResultSetListener();
|
||||
resultSet = new LocalResultSetImpl(resultSetListener);
|
||||
}
|
||||
|
||||
/**
|
||||
* test the get number of results method.
|
||||
*/
|
||||
@Test
|
||||
public void testGetNumberOfResults() {
|
||||
assertEquals("check number of results", RESULT_SIZE, resultSet.getNumberOfResults());
|
||||
}
|
||||
|
||||
/**
|
||||
* test the get result method.
|
||||
*/
|
||||
@Test
|
||||
public void testGetResults() {
|
||||
final List<String> res = resultSet.getResults(1, RESULT_SIZE); // NOPMD by marko on 11/27/08 3:00 AM
|
||||
assertEquals("whole length", RESULT_SIZE, res.size());
|
||||
for (int i = 0; i < RESULT_SIZE; i++)
|
||||
assertEquals("check element", ((Integer) i).toString(), res.get(i));
|
||||
|
||||
final List<String> res2 = resultSet.getResults(1, RESULT_SIZE - 1); // NOPMD by marko on 11/27/08 3:00 AM
|
||||
assertEquals("shorter", RESULT_SIZE - 1, res2.size());
|
||||
|
||||
final List<String> res3 = resultSet.getResults(1, RESULT_SIZE + 1); // NOPMD by marko on 11/27/08 3:00 AM
|
||||
assertEquals("to out of bounds", RESULT_SIZE, res3.size());
|
||||
|
||||
final List<String> res4 = resultSet.getResults(RESULT_SIZE + 1, RESULT_SIZE); // NOPMD by marko on 11/27/08 3:00 AM
|
||||
assertEquals("from out of bounds", 0, res4.size());
|
||||
|
||||
final List<String> res5 = resultSet.getResults(0, RESULT_SIZE); // NOPMD by marko on 11/27/08 3:00 AM
|
||||
assertEquals("from lesser than 1", RESULT_SIZE, res5.size());
|
||||
|
||||
final List<String> res6 = resultSet.getResults(RESULT_SIZE, 1); // NOPMD by marko on 11/27/08 3:00 AM
|
||||
assertEquals("inverted from and to", 1, res6.size());
|
||||
|
||||
resultSet.setOpen(true);
|
||||
final List<String> res7 = resultSet.getResults(1, RESULT_SIZE + 1); // NOPMD by marko on 11/27/08 3:00 AM
|
||||
assertEquals("to out of bounds - pass through", RESULT_SIZE + 1, res7.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* test observer/observable pattern.
|
||||
*/
|
||||
@Test
|
||||
public void testDestroy() {
|
||||
resultSet.addObserver(registry);
|
||||
assertEquals("observer should be added", 1, resultSet.countObservers());
|
||||
|
||||
resultSet.destroy();
|
||||
assertTrue("should be destroyed", resultSet.isDestroyed());
|
||||
|
||||
assertEquals("observers should be cleared", 0, resultSet.countObservers());
|
||||
verify(registry, times(1)).update(resultSet, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* test getter ... let's make code coverage happy.
|
||||
*/
|
||||
@Test
|
||||
public void testGetListener() {
|
||||
assertEquals("test getter?", resultSetListener, resultSet.getListener());
|
||||
}
|
||||
|
||||
/**
|
||||
* test setter ... let's make code coverage happy.
|
||||
*/
|
||||
@Test
|
||||
public void testSetListener() {
|
||||
assertEquals("test getter?", resultSetListener, resultSet.getListener());
|
||||
resultSet.setListener(null);
|
||||
assertNull("test setter?", resultSet.getListener());
|
||||
}
|
||||
|
||||
/**
|
||||
* test.
|
||||
*/
|
||||
@Test
|
||||
public void testResultSetAware() {
|
||||
final AbstractResultSetAware abr = mock(AbstractResultSetAware.class);
|
||||
resultSet = new LocalResultSetImpl(abr);
|
||||
assertNotNull("dummy", resultSet);
|
||||
|
||||
verify(abr).setResultSet((ResultSet) anyObject());
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,140 @@
|
|||
package eu.dnetlib.enabling.resultset; // NOPMD
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Matchers.anyInt;
|
||||
import static org.mockito.Matchers.anyObject;
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.xml.ws.wsaddressing.W3CEndpointReference;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import eu.dnetlib.enabling.resultset.rmi.ResultSetException;
|
||||
import eu.dnetlib.enabling.resultset.rmi.ResultSetService;
|
||||
import eu.dnetlib.enabling.tools.ServiceResolver;
|
||||
import eu.dnetlib.miscutils.factory.Factory;
|
||||
import eu.dnetlib.miscutils.functional.ThreadSafeUnaryFunction;
|
||||
import eu.dnetlib.miscutils.functional.UnaryFunction;
|
||||
|
||||
/**
|
||||
* test xslt resultset.
|
||||
*
|
||||
* @author marko
|
||||
*
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class MappedResultSetTest {
|
||||
|
||||
/**
|
||||
* instance under test.
|
||||
*/
|
||||
private transient MappedResultSet mappedResultSet;
|
||||
|
||||
/**
|
||||
* service resolver.
|
||||
*/
|
||||
@Mock
|
||||
private transient ServiceResolver serviceResolver;
|
||||
|
||||
/**
|
||||
* resultset service mock.
|
||||
*/
|
||||
@Mock
|
||||
private transient ResultSetService resultSetService;
|
||||
|
||||
/**
|
||||
* resultset mock.
|
||||
*/
|
||||
@Mock
|
||||
private transient ResultSet resultSet;
|
||||
|
||||
private Answer<Object> resultSetAnswer = new Answer<Object>() {
|
||||
|
||||
private List<String> list = Lists.newArrayList("1","2","3","4","5","6","7","8","9","10");
|
||||
|
||||
@Override
|
||||
public Object answer(InvocationOnMock invocation) throws Throwable {
|
||||
String method = invocation.getMethod().getName();
|
||||
if (method.equals("getResult") || method.equals("getResults")) {
|
||||
int from = (Integer) invocation.getArguments()[1];
|
||||
int to = (Integer) invocation.getArguments()[2];
|
||||
|
||||
return list.subList(from-1, to);
|
||||
}
|
||||
if (method.equals("getNumberOfElements") || method.equals("getNumberOfResults")) {
|
||||
return list.size();
|
||||
}
|
||||
if (method.equals("getRSStatus")) {
|
||||
return "closed";
|
||||
}
|
||||
if (method.equals("isOpen")) {
|
||||
return false;
|
||||
}
|
||||
System.out.println(invocation.toString());
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Common setup.
|
||||
* @throws ResultSetException
|
||||
*
|
||||
*/
|
||||
@Before
|
||||
public void setUp() throws ResultSetException {
|
||||
|
||||
when(serviceResolver.getService(eq(ResultSetService.class), any(W3CEndpointReference.class))).thenReturn(resultSetService);
|
||||
when(serviceResolver.getResourceIdentifier(any(W3CEndpointReference.class))).thenReturn("123");
|
||||
|
||||
when(resultSetService.getNumberOfElements(anyString())).thenAnswer(resultSetAnswer);
|
||||
when(resultSetService.getResult(anyString(), anyInt(), anyInt(), anyString())).thenAnswer(resultSetAnswer );
|
||||
when(resultSetService.getRSStatus(anyString())).thenAnswer(resultSetAnswer);
|
||||
|
||||
when(resultSet.getNumberOfResults()).thenAnswer(resultSetAnswer);
|
||||
when(resultSet.getResults(anyInt(), anyInt())).thenAnswer(resultSetAnswer );
|
||||
when(resultSet.isOpen()).thenAnswer(resultSetAnswer);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testThreadSafeMappedResultSet_1() {
|
||||
|
||||
final Factory<UnaryFunction<String, String>> functionFactory = new Factory<UnaryFunction<String,String>>() {
|
||||
@Override
|
||||
public UnaryFunction<String, String> newInstance() {
|
||||
return new UnaryFunction<String, String>() {
|
||||
@Override
|
||||
public String evaluate(String arg) {
|
||||
return "mapped-" + arg;
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
mappedResultSet = new MappedResultSet(null, new ThreadSafeUnaryFunction<String, String>(functionFactory), serviceResolver);
|
||||
mappedResultSet.setResultSet(resultSet);
|
||||
|
||||
for (String s : mappedResultSet.getResult(1, 10)) {
|
||||
assertNotNull("null result", s);
|
||||
assertFalse("empty result", s.isEmpty());
|
||||
assertNotNull("null element", s);
|
||||
assertTrue("transformed correctly", s.startsWith("mapped-"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,184 @@
|
|||
package eu.dnetlib.enabling.resultset;
|
||||
|
||||
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 static org.mockito.Matchers.matches;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import net.sf.ehcache.Cache;
|
||||
import net.sf.ehcache.CacheManager;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import eu.dnetlib.miscutils.cache.EhCache;
|
||||
|
||||
/**
|
||||
* Test ResultSetRegistryImpl.
|
||||
*
|
||||
* @author marko
|
||||
*
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class ResultSetRegistryImplTest {
|
||||
|
||||
/**
|
||||
* max in memory elements.
|
||||
*/
|
||||
private static final int MAX_IN_MEM = 100;
|
||||
|
||||
/**
|
||||
* default time.
|
||||
*/
|
||||
private static final int DEFAULT_TTI = 1000;
|
||||
|
||||
/**
|
||||
* default time to live.
|
||||
*/
|
||||
private static final int DEFAULT_TTL = 1000;
|
||||
|
||||
/**
|
||||
* class under test.
|
||||
*/
|
||||
private transient ResultSetRegistryImpl registry;
|
||||
|
||||
/**
|
||||
* mock of a resultset object.
|
||||
*/
|
||||
@Mock
|
||||
private transient ResultSet resultSet;
|
||||
|
||||
/**
|
||||
* ehcache manager.
|
||||
*/
|
||||
private final transient CacheManager cacheManager = CacheManager.create();
|
||||
|
||||
/**
|
||||
* Set up basic mocks.
|
||||
*/
|
||||
@Before
|
||||
public void setUp() {
|
||||
final Cache ehCache = new net.sf.ehcache.Cache("testCache", MAX_IN_MEM, false, false, DEFAULT_TTL, DEFAULT_TTI);
|
||||
cacheManager.addCache(ehCache);
|
||||
|
||||
final Cache mtEhCache = new net.sf.ehcache.Cache("testMTCache", MAX_IN_MEM, false, false, DEFAULT_TTL, DEFAULT_TTI);
|
||||
cacheManager.addCache(mtEhCache);
|
||||
|
||||
final EhCache<String, ResultSet> cache = new EhCache<String, ResultSet>(ehCache);
|
||||
cache.setCache(ehCache);
|
||||
|
||||
final EhCache<String, Integer> mtCache = new EhCache<String, Integer>(mtEhCache);
|
||||
mtCache.setCache(mtEhCache);
|
||||
|
||||
registry = new ResultSetRegistryImpl();
|
||||
registry.setCache(cache);
|
||||
registry.setMaxIdleTimeCache(mtCache);
|
||||
|
||||
when(resultSet.getIdentifier()).thenReturn("123456");
|
||||
when(resultSet.isOpen()).thenReturn(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* remove ehcache from ehcachemanager.
|
||||
*/
|
||||
@After
|
||||
public void tearDown() {
|
||||
cacheManager.removeAllCaches();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that registered resultsets are really registered.
|
||||
*/
|
||||
@Test
|
||||
public void testAddResultSet() {
|
||||
|
||||
final String rsId = resultSet.getIdentifier();
|
||||
assertNotNull("the resultset should not be null", rsId);
|
||||
|
||||
registry.addResultSet(resultSet);
|
||||
verify(resultSet).setIdentifier(matches("rs-" + registry.getIdGenerator().getRegEx()));
|
||||
|
||||
final ResultSet res = registry.getResultSetById(rsId); // NOPMD
|
||||
assertNotNull("the resultset is not found", res);
|
||||
assertEquals("the resultsets don't have the same id", rsId, res.getIdentifier());
|
||||
assertEquals("the resultsets are not the same instance", resultSet, res);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that registered resultsets are really registered.
|
||||
*/
|
||||
@Test
|
||||
public void testAddResultSetWithId() {
|
||||
resultSet = mock(ResultSet.class);
|
||||
when(resultSet.getIdentifier()).thenReturn("123");
|
||||
|
||||
final String rsId = resultSet.getIdentifier();
|
||||
|
||||
registry.addResultSet(resultSet, rsId);
|
||||
verify(resultSet).setIdentifier(rsId);
|
||||
|
||||
final ResultSet res = registry.getResultSetById(rsId); // NOPMD
|
||||
assertNotNull("the resultset is not found", res);
|
||||
assertEquals("the resultsets don't have the same id", rsId, res.getIdentifier());
|
||||
assertEquals("the resultsets are not the same instance", resultSet, res);
|
||||
}
|
||||
|
||||
/**
|
||||
* try to obtain a inexistent resultset.
|
||||
*/
|
||||
@Test
|
||||
public void testInexistentResultSet() {
|
||||
final String rsId = resultSet.getIdentifier();
|
||||
assertNull("inexisten resultset returns null", registry.getResultSetById(rsId));
|
||||
}
|
||||
|
||||
/**
|
||||
* test closing of resultset and its pruning from the registry.
|
||||
*/
|
||||
@Test
|
||||
public void testResultSetClose() {
|
||||
final String rsId = resultSet.getIdentifier();
|
||||
|
||||
assertTrue("check if resultset is open", resultSet.isOpen());
|
||||
|
||||
registry.addResultSet(resultSet);
|
||||
verify(resultSet).addObserver(registry);
|
||||
|
||||
// simulate a resultset close on the mock
|
||||
when(resultSet.isOpen()).thenReturn(false);
|
||||
registry.update(resultSet, null);
|
||||
|
||||
assertFalse("check if resultset is closed", resultSet.isOpen());
|
||||
assertNull("check if the object is pruned from the registry", registry.getResultSetById(rsId));
|
||||
}
|
||||
|
||||
/**
|
||||
* same as testResultSetClose() but with a real observer/observable mechanism, i.e. without resultset mock class.
|
||||
*
|
||||
*/
|
||||
@Test
|
||||
public void testWithRealObservable() {
|
||||
final LocalResultSetImpl rset = new LocalResultSetImpl(null);
|
||||
rset.setIdentifier("123456");
|
||||
resultSet = rset;
|
||||
|
||||
final String rsId = resultSet.getIdentifier();
|
||||
|
||||
assertFalse("check if resultset is not destroyed", resultSet.isDestroyed());
|
||||
|
||||
registry.addResultSet(resultSet);
|
||||
resultSet.destroy();
|
||||
|
||||
assertTrue("check if resultset is destroyed", resultSet.isDestroyed());
|
||||
assertNull("check if the object is pruned from the registry", registry.getResultSetById(rsId));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
package eu.dnetlib.enabling.resultset;
|
||||
|
||||
import static org.junit.Assert.*; // NOPMD
|
||||
import static org.mockito.Mockito.*; // NOPMD
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import eu.dnetlib.enabling.resultset.rmi.ResultSetException;
|
||||
|
||||
/**
|
||||
* resultset service rmi implementation test.
|
||||
*
|
||||
* @author marko
|
||||
*
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class ResultSetServiceImplTest {
|
||||
|
||||
/**
|
||||
* mock resultset id.
|
||||
*/
|
||||
private static final String RS_ID = "123";
|
||||
|
||||
/**
|
||||
* instance under test.
|
||||
*/
|
||||
private transient ResultSetServiceImpl service;
|
||||
|
||||
/**
|
||||
* custom property dao mock.
|
||||
*/
|
||||
@Mock
|
||||
private transient ResultSetPropertyDao customPropertyDao;
|
||||
|
||||
/**
|
||||
* resultset registry mock.
|
||||
*/
|
||||
@Mock
|
||||
private transient ResultSetRegistry resultsetRegistry;
|
||||
|
||||
/**
|
||||
* resultset instance mock.
|
||||
*/
|
||||
@Mock
|
||||
private transient ResultSet resultSet;
|
||||
|
||||
/**
|
||||
* setup.
|
||||
*/
|
||||
@Before
|
||||
public void setUp() {
|
||||
service = new ResultSetServiceImpl();
|
||||
service.setCustomPropertyDao(customPropertyDao);
|
||||
service.setResultsetRegistry(resultsetRegistry);
|
||||
|
||||
when(resultsetRegistry.getResultSetById(RS_ID)).thenReturn(resultSet);
|
||||
when(resultSet.getIdentifier()).thenReturn(RS_ID);
|
||||
}
|
||||
|
||||
/**
|
||||
* test get property.
|
||||
* @throws ResultSetException shouldn't happen
|
||||
*/
|
||||
@Test
|
||||
public void testGetProperty() throws ResultSetException {
|
||||
final Map<String, String> properties = new HashMap<String, String>();
|
||||
properties.put("prefetch", "true");
|
||||
|
||||
when(customPropertyDao.getProperties(resultSet)).thenReturn(properties);
|
||||
when(resultSet.getNumberOfResults()).thenReturn(1);
|
||||
|
||||
assertEquals("test builtin", "1", service.getProperty(RS_ID, "total"));
|
||||
assertEquals("test builtin", RS_ID, service.getProperty(RS_ID, "rsId"));
|
||||
|
||||
assertEquals("test custom", "true", service.getProperty(RS_ID, "prefetch"));
|
||||
assertNull("test custom", service.getProperty(RS_ID, "unexistent"));
|
||||
}
|
||||
|
||||
/**
|
||||
* get resultset status.
|
||||
*
|
||||
* @throws ResultSetException shouldn't happen
|
||||
*/
|
||||
@Test
|
||||
public void testGetRSStatus() throws ResultSetException {
|
||||
when(resultSet.isOpen()).thenReturn(true);
|
||||
|
||||
assertEquals("check open", service.getRSStatus(RS_ID), "open");
|
||||
|
||||
when(resultSet.isOpen()).thenReturn(false);
|
||||
assertEquals("check closed", service.getRSStatus(RS_ID), "closed");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
package eu.dnetlib.enabling.resultset;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
public class StreamingResultSetListenerTest {
|
||||
|
||||
private StreamingResultSetListener listener;
|
||||
private List<String> data;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
data = Lists.newArrayList("uno", "due", "tre", "quattro");
|
||||
listener = new StreamingResultSetListener(data.iterator(), data.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetResult() {
|
||||
assertEquals(data.size(), listener.getSize());
|
||||
|
||||
final List<String> res = listener.getResult(1, 2);
|
||||
assertEquals(2, res.size());
|
||||
assertEquals("uno", res.get(0));
|
||||
assertEquals("due", res.get(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetResult2() {
|
||||
listener.getResult(1, 2);
|
||||
final List<String> res = listener.getResult(3, 4);
|
||||
assertEquals(2, res.size());
|
||||
assertEquals("tre", res.get(0));
|
||||
assertEquals("quattro", res.get(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetResult_retry() {
|
||||
listener.getResult(1, 2);
|
||||
final List<String> res = listener.getResult(1, 2);
|
||||
assertEquals(2, res.size());
|
||||
assertEquals("uno", res.get(0));
|
||||
assertEquals("due", res.get(1));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testGetResult_random() {
|
||||
listener.getResult(1, 2);
|
||||
listener.getResult(2, 3);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testGetResult_skip() {
|
||||
listener.getResult(1, 2);
|
||||
listener.getResult(4, 4);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,139 @@
|
|||
package eu.dnetlib.enabling.resultset; // NOPMD
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.mockito.Matchers.anyObject;
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Matchers.argThat;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
import java.util.List;
|
||||
|
||||
import javax.xml.transform.TransformerConfigurationException;
|
||||
import javax.xml.ws.wsaddressing.W3CEndpointReference;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentMatcher;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import eu.dnetlib.enabling.resultset.rmi.ResultSetException;
|
||||
import eu.dnetlib.enabling.resultset.rmi.ResultSetService;
|
||||
import eu.dnetlib.enabling.tools.ServiceResolver;
|
||||
|
||||
/**
|
||||
* test xslt resultset.
|
||||
*
|
||||
* @author marko
|
||||
*
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class XSLTMappedResultSetFactoryTest {
|
||||
|
||||
/**
|
||||
* instance under test.
|
||||
*/
|
||||
private transient XSLTMappedResultSetFactory factory;
|
||||
|
||||
/**
|
||||
* resultset factory mock.
|
||||
*/
|
||||
@Mock
|
||||
private transient ResultSetFactory resultSetFactory;
|
||||
|
||||
/**
|
||||
* service resolver.
|
||||
*/
|
||||
@Mock
|
||||
private transient ServiceResolver serviceResolver;
|
||||
|
||||
/**
|
||||
* resultset service mock.
|
||||
*/
|
||||
@Mock
|
||||
private transient ResultSetService resultSetService;
|
||||
|
||||
/**
|
||||
* underlying resultSet mock
|
||||
*/
|
||||
@Mock
|
||||
private transient ResultSet resultSet;
|
||||
|
||||
/**
|
||||
* Common setup.
|
||||
*
|
||||
*/
|
||||
@Before
|
||||
public void setUp() {
|
||||
factory = new XSLTMappedResultSetFactory();
|
||||
factory.setResultSetFactory(resultSetFactory);
|
||||
factory.setServiceResolver(serviceResolver);
|
||||
}
|
||||
|
||||
/**
|
||||
* test invalid xslt.
|
||||
*
|
||||
* @throws TransformerConfigurationException
|
||||
* could happen
|
||||
*/
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void testInvalidXslt() throws TransformerConfigurationException {
|
||||
factory.createMappedResultSet(null, "<bla/>");
|
||||
}
|
||||
|
||||
/**
|
||||
* test xslt.
|
||||
*
|
||||
* @throws TransformerConfigurationException
|
||||
* could happen
|
||||
* @throws IOException
|
||||
* could happen
|
||||
* @throws ResultSetException mock
|
||||
*/
|
||||
@Test
|
||||
public void testXslt() throws TransformerConfigurationException, IOException, ResultSetException {
|
||||
when(serviceResolver.getService(eq(ResultSetService.class), (W3CEndpointReference) anyObject())).thenReturn(resultSetService);
|
||||
when(serviceResolver.getResourceIdentifier((W3CEndpointReference) anyObject())).thenReturn("123");
|
||||
|
||||
//when(resultSetService.getNumberOfElements(anyString())).thenReturn(1);
|
||||
when(resultSetService.getResult("123", 1, 1, "waiting")).thenReturn(Lists.newArrayList("<first>something</first>"));
|
||||
when(resultSetService.getRSStatus("123")).thenReturn("closed");
|
||||
|
||||
when(resultSet.isOpen()).thenReturn(true);
|
||||
|
||||
final StringWriter xsltSource = new StringWriter();
|
||||
IOUtils.copy(getClass().getResourceAsStream("test.xsl"), xsltSource);
|
||||
factory.createMappedResultSet(null, xsltSource.toString());
|
||||
|
||||
verify(resultSetFactory, times(1)).createResultSet(argThat(new ArgumentMatcher<ResultSetListener>() {
|
||||
|
||||
@Override
|
||||
public boolean matches(final ResultSetListener argument) {
|
||||
final MappedResultSet listener = (MappedResultSet) argument;
|
||||
listener.setResultSet(resultSet);
|
||||
final List<String> res = listener.getResult(1, 1);
|
||||
|
||||
assertNotNull("null result", res);
|
||||
assertFalse("empty result", res.isEmpty());
|
||||
|
||||
assertNotNull("null element", res.get(0));
|
||||
|
||||
assertTrue("transformed correctly", res.get(0).contains("<second>something</second>"));
|
||||
|
||||
return true;
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,223 @@
|
|||
package eu.dnetlib.enabling.resultset.push;
|
||||
|
||||
import static org.junit.Assert.*; // NOPMD
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import eu.dnetlib.miscutils.cache.Cache;
|
||||
|
||||
/**
|
||||
* subclass this unit test class and provide a concrete transient push resultset dao implementation.
|
||||
*
|
||||
* @author marko
|
||||
*
|
||||
*/
|
||||
@Ignore
|
||||
public abstract class AbstractTransientPushResultSetDaoTest {
|
||||
/**
|
||||
* logger.
|
||||
*/
|
||||
private static final Log log = LogFactory.getLog(AbstractTransientPushResultSetDaoTest.class); // NOPMD by marko on 11/24/08 5:02 PM
|
||||
|
||||
/**
|
||||
* test first element.
|
||||
*/
|
||||
private static final String TWO = "two";
|
||||
|
||||
/**
|
||||
* test second element.
|
||||
*/
|
||||
private static final String ONE = "one";
|
||||
|
||||
/**
|
||||
* some key.
|
||||
*/
|
||||
private static final String RS_ID = "123";
|
||||
|
||||
/**
|
||||
* instance under test.
|
||||
*/
|
||||
private TransientPushResultSetDao dao;
|
||||
|
||||
/**
|
||||
* prepare the instance under test.
|
||||
*
|
||||
*/
|
||||
@Before
|
||||
public void setUp() {
|
||||
setDao(newInstance());
|
||||
}
|
||||
|
||||
/**
|
||||
* specific unit tests will override this method and provide a concrete instance to test.
|
||||
*
|
||||
* @return new transient push resultset dao instance
|
||||
*/
|
||||
protected abstract TransientPushResultSetDao newInstance();
|
||||
|
||||
/**
|
||||
* test add elements.
|
||||
*/
|
||||
@Test
|
||||
public void testAddElements() {
|
||||
final List<String> freshGet = getDao().getElements(RS_ID, 1, 0);
|
||||
assertNotNull("fresh get", freshGet);
|
||||
assertEquals("fresh get", 0, freshGet.size());
|
||||
|
||||
final List<String> list = new ArrayList<String>();
|
||||
list.add(ONE);
|
||||
|
||||
getDao().addElements(RS_ID, list);
|
||||
|
||||
final List<String> firstGet = getDao().getElements(RS_ID, 1, 1);
|
||||
assertEquals("first get", 1, firstGet.size());
|
||||
assertEquals("first get", ONE, firstGet.get(0));
|
||||
|
||||
final List<String> listAppend = new ArrayList<String>();
|
||||
listAppend.add(TWO);
|
||||
|
||||
getDao().addElements(RS_ID, listAppend);
|
||||
|
||||
final List<String> secondGet = getDao().getElements(RS_ID, 1, 2);
|
||||
assertEquals("second get", 2, secondGet.size());
|
||||
assertEquals("second get", ONE, secondGet.get(0));
|
||||
assertEquals("second get", TWO, secondGet.get(1));
|
||||
|
||||
final List<String> listBig = new ArrayList<String>();
|
||||
for (int i = 0; i < 90; i++)
|
||||
listBig.add(Integer.toString(i));
|
||||
|
||||
getDao().addElements(RS_ID, listBig);
|
||||
|
||||
final List<String> thirdGet = getDao().getElements(RS_ID, 3, 90);
|
||||
assertEquals("third get", 88, thirdGet.size());
|
||||
assertEquals("third get", "0", thirdGet.get(0));
|
||||
assertEquals("third get", "1", thirdGet.get(1));
|
||||
}
|
||||
|
||||
/**
|
||||
* check get elements.
|
||||
*/
|
||||
@Test
|
||||
public void testGetElements() {
|
||||
final List<String> list = new ArrayList<String>();
|
||||
list.add(ONE);
|
||||
|
||||
getDao().addElements(RS_ID, list);
|
||||
|
||||
final List<String> res = getDao().getElements(RS_ID, 1, 1);
|
||||
assertEquals("check size", 1, res.size());
|
||||
assertEquals("check element", ONE, res.get(0));
|
||||
}
|
||||
|
||||
/**
|
||||
* introduced for reproducing of #904. Thanks to Jochen for this one.
|
||||
*/
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testAddElementsDifferentSize() {
|
||||
List<Integer> sizes = Lists.newArrayList(100, 200, 300, 99);
|
||||
int run = 0;
|
||||
int total = 0;
|
||||
|
||||
List<String> records = new LinkedList<String>();
|
||||
for (int size : sizes) {
|
||||
for (int i = 0; i < size; i++)
|
||||
records.add("bla-" + run + "-" + i);
|
||||
|
||||
dao.addElements(RS_ID, records);
|
||||
records.clear();
|
||||
|
||||
total += size;
|
||||
run++;
|
||||
}
|
||||
|
||||
assertEquals("check size", total, dao.getSize(RS_ID));
|
||||
}
|
||||
|
||||
/**
|
||||
* introduced for reproducing of #904. with correct size (limited by 100)
|
||||
*/
|
||||
@Test
|
||||
public void testAddElementsDifferentSizeCorrectSize() {
|
||||
List<Integer> sizes = Lists.newArrayList(51, 51, 51, 51);
|
||||
|
||||
int total = 0;
|
||||
int run = 0;
|
||||
String lastName = null;
|
||||
|
||||
List<String> records = new LinkedList<String>();
|
||||
for (int size : sizes) {
|
||||
for (int i = 0; i < size; i++) {
|
||||
lastName = "bla-" + run + "-" + i;
|
||||
records.add(lastName);
|
||||
}
|
||||
|
||||
dao.addElements(RS_ID, records);
|
||||
records.clear();
|
||||
|
||||
total += size;
|
||||
run++;
|
||||
}
|
||||
|
||||
inspect();
|
||||
|
||||
assertEquals("check size", total, dao.getSize(RS_ID));
|
||||
assertEquals("check last", lastName, dao.getElements(RS_ID, total, total).get(0));
|
||||
|
||||
assertEquals("check first page", "bla-0-11", dao.getElements(RS_ID, 12, 12).get(0));
|
||||
assertEquals("check last page", "bla-1-11", dao.getElements(RS_ID, 51 + 12, 51 + 12).get(0));
|
||||
|
||||
assertEquals("check range", 10, dao.getElements(RS_ID, 1, 10).size());
|
||||
assertEquals("check range", 10, dao.getElements(RS_ID, 51 + 1, 51 + 10).size());
|
||||
assertEquals("check range", 51, dao.getElements(RS_ID, 1, 51).size());
|
||||
assertEquals("check range", 52, dao.getElements(RS_ID, 1, 52).size());
|
||||
assertEquals("check range", 51, dao.getElements(RS_ID, 2, 52).size());
|
||||
|
||||
assertEquals("check range", 100, dao.getElements(RS_ID, 1, 100).size());
|
||||
assertEquals("check range", 99, dao.getElements(RS_ID, 2, 100).size());
|
||||
assertEquals("check range", 100, dao.getElements(RS_ID, 2, 101).size());
|
||||
|
||||
assertEquals("check range", 200, dao.getElements(RS_ID, 2, 201).size());
|
||||
}
|
||||
|
||||
private void inspect() {
|
||||
CacheTransientResultSetDaoImpl dao = (CacheTransientResultSetDaoImpl) this.dao;
|
||||
ResultSetDescriptor desc = dao.getResultSetCache().get(RS_ID);
|
||||
Cache<String, List<String>> cache = dao.getCache();
|
||||
|
||||
log.debug("----------------");
|
||||
log.debug("ranges: " + desc.getRanges());
|
||||
log.debug("last range index: " + desc.getLastRange());
|
||||
for (int i = 0; i < desc.getRanges(); i++) {
|
||||
final List<String> range = cache.get(RS_ID + "-" + i);
|
||||
log.debug("range: " + i + " has " + range.size() + " elements");
|
||||
log.debug(" " + range);
|
||||
}
|
||||
|
||||
log.debug("----------------");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSizeOfEmpty() {
|
||||
assertEquals("empty size", 0, dao.getSize(RS_ID));
|
||||
}
|
||||
|
||||
public TransientPushResultSetDao getDao() {
|
||||
return dao;
|
||||
}
|
||||
|
||||
public void setDao(final TransientPushResultSetDao dao) {
|
||||
this.dao = dao;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
package eu.dnetlib.enabling.resultset.push;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import net.sf.ehcache.CacheManager;
|
||||
|
||||
import org.junit.After;
|
||||
|
||||
import eu.dnetlib.miscutils.cache.Cache;
|
||||
import eu.dnetlib.miscutils.cache.EhCache;
|
||||
import eu.dnetlib.miscutils.factory.Factory;
|
||||
|
||||
/**
|
||||
* concrete push resultset dao test.
|
||||
*
|
||||
* @author marko
|
||||
*
|
||||
*/
|
||||
public class CacheTransientPushResultSetDaoTest extends AbstractTransientPushResultSetDaoTest { // NOPMD
|
||||
|
||||
/**
|
||||
* max in memory elements.
|
||||
*/
|
||||
private static final int MAX_IN_MEM = 100;
|
||||
|
||||
/**
|
||||
* default time.
|
||||
*/
|
||||
private static final int DEFAULT_TTI = 1000;
|
||||
|
||||
/**
|
||||
* default time to live.
|
||||
*/
|
||||
private static final int DEFAULT_TTL = 1000;
|
||||
|
||||
/**
|
||||
* cache manager.
|
||||
*/
|
||||
private final transient CacheManager cacheManager = CacheManager.create();
|
||||
|
||||
/**
|
||||
* clean cache after test.
|
||||
*/
|
||||
@After
|
||||
public void cleanCache() {
|
||||
cacheManager.removeAllCaches();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @see eu.dnetlib.enabling.resultset.push.AbstractTransientPushResultSetDaoTest#newInstance()
|
||||
*/
|
||||
@Override
|
||||
protected TransientPushResultSetDao newInstance() {
|
||||
final net.sf.ehcache.Cache ehcache = new net.sf.ehcache.Cache("testCache", MAX_IN_MEM, false, false, DEFAULT_TTL, DEFAULT_TTI);
|
||||
cacheManager.addCache(ehcache);
|
||||
|
||||
final net.sf.ehcache.Cache rsehcache = new net.sf.ehcache.Cache("rsetCache", MAX_IN_MEM, false, false, DEFAULT_TTL, DEFAULT_TTI);
|
||||
cacheManager.addCache(rsehcache);
|
||||
|
||||
final CacheTransientResultSetDaoImpl resultSet = new CacheTransientResultSetDaoImpl();
|
||||
final Cache<String, List<String>> cache = new EhCache<String, List<String>>(ehcache);
|
||||
final Cache<String, ResultSetDescriptor> rscache = new EhCache<String, ResultSetDescriptor>(rsehcache);
|
||||
resultSet.setCache(cache);
|
||||
resultSet.setResultSetCache(rscache);
|
||||
|
||||
resultSet.setResultSetDescriptorFactory(new Factory<ResultSetDescriptor>() {
|
||||
|
||||
@Override
|
||||
public ResultSetDescriptor newInstance() {
|
||||
return new ResultSetDescriptor();
|
||||
}
|
||||
});
|
||||
return resultSet;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package eu.dnetlib.enabling.resultset.push;
|
||||
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import eu.dnetlib.miscutils.factory.Factory;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration
|
||||
public class ResultSetDescriptorFactoryTest {
|
||||
|
||||
@Resource
|
||||
Factory<ResultSetDescriptor> factory;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFactory() {
|
||||
ResultSetDescriptor desc1 = factory.newInstance();
|
||||
ResultSetDescriptor desc2 = factory.newInstance();
|
||||
|
||||
assertTrue("check different instances", desc1 != desc2);
|
||||
assertEquals("check that it's a spring prototype", 200, desc1.getRangeLength());
|
||||
assertEquals("check that it's a spring prototype", 200, desc2.getRangeLength());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
package eu.dnetlib.enabling.resultset.push;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import eu.dnetlib.enabling.resultset.push.ResultSetDescriptor.Range;
|
||||
|
||||
public class ResultSetDescriptorTest {
|
||||
|
||||
private static final Log log = LogFactory.getLog(ResultSetDescriptorTest.class); // NOPMD by marko on 11/24/08 5:02 PM
|
||||
|
||||
private transient ResultSetDescriptor descriptor;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
descriptor = new ResultSetDescriptor();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetRangesContaining() {
|
||||
log.debug("--- 1, 1");
|
||||
for(Range i : descriptor.getRangesContaining(1, 1))
|
||||
log.debug("i " + i);
|
||||
|
||||
log.debug("--- 2, 1000");
|
||||
for(Range i : descriptor.getRangesContaining(2, 1000))
|
||||
log.debug("i " + i);
|
||||
|
||||
log.debug("--- 5, 2000");
|
||||
for(Range i : descriptor.getRangesContaining(5, 2000))
|
||||
log.debug("i " + i);
|
||||
|
||||
log.debug("--- 5, 2001");
|
||||
for(Range i : descriptor.getRangesContaining(5, 2001))
|
||||
log.debug("i " + i);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNext() {
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,166 @@
|
|||
package eu.dnetlib.enabling.resultset.push;
|
||||
|
||||
import static org.junit.Assert.*; // NOPMD
|
||||
import static org.mockito.Mockito.*; // NOPMD
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import eu.dnetlib.enabling.resultset.ResultSetRegistry;
|
||||
|
||||
/**
|
||||
* test the transient push resultset.
|
||||
*
|
||||
* @author marko
|
||||
*
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class TransientPushResultSetImplTest {
|
||||
|
||||
/**
|
||||
* first test value.
|
||||
*/
|
||||
private static final String ONE = "one";
|
||||
|
||||
/**
|
||||
* second test value.
|
||||
*/
|
||||
private static final String TWO = "two";
|
||||
|
||||
/**
|
||||
* test rs id.
|
||||
*/
|
||||
private static final String RS_ID = "123";
|
||||
|
||||
/**
|
||||
* instance to be tested.
|
||||
*/
|
||||
private transient TransientPushResultSetImpl resultSet;
|
||||
|
||||
/**
|
||||
* dao mock.
|
||||
*/
|
||||
@Mock
|
||||
private transient TransientPushResultSetDao dao;
|
||||
|
||||
/**
|
||||
* resultset registry mock.
|
||||
*/
|
||||
@Mock
|
||||
private transient ResultSetRegistry registry;
|
||||
|
||||
/**
|
||||
* setup class to be tested.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@Before
|
||||
public void setUp() {
|
||||
resultSet = new TransientPushResultSetImpl(dao);
|
||||
resultSet.setIdentifier(RS_ID);
|
||||
resultSet.getDao(); // getter code coverage hack
|
||||
}
|
||||
|
||||
/**
|
||||
* test adding elements.
|
||||
*/
|
||||
@Test
|
||||
public void testAddElements() {
|
||||
final List<String> list = new ArrayList<String>();
|
||||
list.add(ONE);
|
||||
|
||||
resultSet.addElements(list);
|
||||
|
||||
verify(dao).addElements(RS_ID, list);
|
||||
assertNotNull("dummy", resultSet);
|
||||
}
|
||||
|
||||
/**
|
||||
* test get number of results.
|
||||
*/
|
||||
@Test
|
||||
public void testGetNumberOfResults() {
|
||||
when(dao.getSize(RS_ID)).thenReturn(1);
|
||||
|
||||
assertEquals("check size", 1, resultSet.getNumberOfResults());
|
||||
}
|
||||
|
||||
/**
|
||||
* get result.
|
||||
*/
|
||||
@Test
|
||||
public void testGetResults() {
|
||||
final List<String> list = new ArrayList<String>();
|
||||
list.add(TWO);
|
||||
|
||||
when(dao.getSize(RS_ID)).thenReturn(2);
|
||||
when(dao.getElements(RS_ID, 2, 2)).thenReturn(list);
|
||||
|
||||
assertEquals("check list", TWO, resultSet.getResults(2, 2).get(0));
|
||||
assertEquals("check size", 1, resultSet.getResults(2, 2).size());
|
||||
}
|
||||
|
||||
/**
|
||||
* test when indices are out of range, trailing stuff should be skipped.
|
||||
*/
|
||||
@Test
|
||||
public void testGetResultOutOfRange() {
|
||||
final List<String> list = new ArrayList<String>();
|
||||
list.add(TWO);
|
||||
|
||||
when(dao.getSize(RS_ID)).thenReturn(2);
|
||||
when(dao.getElements(RS_ID, 2, 2)).thenReturn(list);
|
||||
|
||||
assertEquals("check list", TWO, resultSet.getResults(2, 2 + 1).get(0));
|
||||
assertEquals("check size", 1, resultSet.getResults(2, 2 + 1).size());
|
||||
}
|
||||
|
||||
/**
|
||||
* open.
|
||||
*/
|
||||
@Test
|
||||
public void testIsOpen() {
|
||||
assertTrue("check is open by default", resultSet.isOpen());
|
||||
}
|
||||
|
||||
/**
|
||||
* test close.
|
||||
*/
|
||||
@Test
|
||||
public void testClose() {
|
||||
resultSet.addObserver(registry);
|
||||
assertEquals("observer should be added", 1, resultSet.countObservers());
|
||||
|
||||
resultSet.destroy();
|
||||
assertTrue("should be destroyed", resultSet.isDestroyed());
|
||||
|
||||
assertEquals("observers should be cleared", 0, resultSet.countObservers());
|
||||
verify(registry, times(1)).update(resultSet, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFromAfterSize() {
|
||||
final List<String> list = new ArrayList<String>();
|
||||
list.add(TWO);
|
||||
|
||||
when(dao.getSize(RS_ID)).thenReturn(2);
|
||||
when(dao.getElements(RS_ID, 2, 2)).thenReturn(list);
|
||||
|
||||
resultSet.getResults(3, 2);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void testWriteClosed() {
|
||||
resultSet.close();
|
||||
resultSet.addElements(Lists.newArrayList("test"));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
<?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:context="http://www.springframework.org/schema/context"
|
||||
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
|
||||
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
|
||||
|
||||
<bean id="resultSetDescriptorPrototype" class="eu.dnetlib.enabling.resultset.push.ResultSetDescriptor"
|
||||
p:rangeLength="200" scope="prototype" />
|
||||
|
||||
<bean id="resultSetDescriptorFactory" class="eu.dnetlib.springutils.beans.factory.PrototypeFactory">
|
||||
<lookup-method name="newInstance" bean="resultSetDescriptorPrototype" />
|
||||
</bean>
|
||||
</beans>
|
|
@ -0,0 +1,6 @@
|
|||
<xsl:stylesheet version="1.0"
|
||||
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
|
||||
<xsl:template match="first">
|
||||
<second><xsl:value-of select="."/></second>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
25
pom.xml
25
pom.xml
|
@ -10,6 +10,7 @@
|
|||
|
||||
<modules>
|
||||
<module>dnet-core-components</module>
|
||||
<module>dnet-core-services</module>
|
||||
</modules>
|
||||
|
||||
|
||||
|
@ -141,13 +142,6 @@
|
|||
<artifactId>gson</artifactId>
|
||||
<version>${google.gson.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.9</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
|
@ -230,6 +224,12 @@
|
|||
<version>1.7</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.9</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
|
@ -336,7 +336,16 @@
|
|||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
|
Loading…
Reference in New Issue