Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/pom.xml
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/pom.xml	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/pom.xml	(revision 48492)
@@ -0,0 +1,203 @@
+<?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/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+
+	<groupId>eu.dnetlib</groupId>
+	<artifactId>dnet-openaire-exporter</artifactId>
+	<version>1.0.0</version>
+	<scm>
+		<developerConnection>scm:svn:https://svn.driver.research-infrastructures.eu/driver/dnet45/modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0</developerConnection>
+      <url>https://github.com/spring-projects/spring-boot/spring-boot-starter-parent/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0</url>
+  </scm>
+	<ciManagement>
+		<system>jenkins</system>
+		<url>https://jenkins-dnet.d4science.org/view/DNet45/job/DSL45_dnet-openaire-exporter/</url>
+	</ciManagement>
+	<distributionManagement>
+		<repository>
+			<id>dnet45-releases</id>
+			<name>D-Net 45 Releases</name>
+			<url>http://maven.research-infrastructures.eu/nexus/content/repositories/dnet45-releases</url>
+			<layout>default</layout>
+		</repository>
+	</distributionManagement>
+
+	<!-- Inherit defaults from Spring Boot -->
+	<parent>
+		<groupId>org.springframework.boot</groupId>
+		<artifactId>spring-boot-starter-parent</artifactId>
+		<version>1.5.2.RELEASE</version>
+	</parent>
+
+	<repositories>
+		<repository>
+			<id>dnet-deps</id>
+			<name>dnet-dependencies</name>
+			<url>http://maven.research-infrastructures.eu/nexus/content/repositories/dnet-deps</url>
+			<layout>default</layout>
+		</repository>
+		<repository>
+			<id>dnet45-releases</id>
+			<name>D-Net 45 Releases</name>
+			<url>http://maven.research-infrastructures.eu/nexus/content/repositories/dnet45-releases</url>
+			<layout>default</layout>
+			<snapshots>
+				<enabled>true</enabled>
+			</snapshots>
+		</repository>
+	</repositories>
+	<profiles>
+		<profile>
+			<id>java8-doclint-disabled</id>
+			<activation>
+				<jdk>[1.8,)</jdk>
+			</activation>
+			<properties>
+				<javadoc.opts>-Xdoclint:none</javadoc.opts>
+			</properties>
+		</profile>
+	</profiles>
+
+	<!-- Add typical dependencies for a web application -->
+	<dependencies>
+
+		<dependency>
+			<groupId>eu.dnetlib</groupId>
+			<artifactId>cnr-rmi-api</artifactId>
+			<version>[2.0.0,3.0.0)</version>
+		</dependency>
+		<dependency>
+			<groupId>eu.dnetlib</groupId>
+			<artifactId>cnr-service-common</artifactId>
+			<version>[2.0.0,3.0.0)</version>
+		</dependency>
+		<dependency>
+			<groupId>eu.dnetlib</groupId>
+			<artifactId>dnet-openaireplus-mapping-utils</artifactId>
+			<version>[6.0.0,7.0.0)</version>
+			<exclusions>
+				<exclusion>
+					<groupId>com.sun.jersey</groupId>
+					<artifactId>jersey-server</artifactId>
+				</exclusion>
+				<exclusion>
+					<groupId>eu.dnetlib</groupId>
+					<artifactId>dnet-hadoop-commons</artifactId>
+				</exclusion>
+			</exclusions>
+		</dependency>
+
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-web</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-jdbc</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-data-jpa</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.postgresql</groupId>
+			<artifactId>postgresql</artifactId>
+			<version>42.0.0</version>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.commons</groupId>
+			<artifactId>commons-dbcp2</artifactId>
+			<version>2.1</version>
+		</dependency>
+		<!-- TODO: migrate to stringtemplate4 -->
+		<!--<dependency>-->
+		<!--<groupId>org.antlr</groupId>-->
+		<!--<artifactId>stringtemplate</artifactId>-->
+		<!--<version>4.0.2</version>-->
+		<!--</dependency>-->
+		<dependency>
+			<groupId>org.antlr</groupId>
+			<artifactId>stringtemplate</artifactId>
+			<version>3.2.1</version>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.commons</groupId>
+			<artifactId>commons-lang3</artifactId>
+			<version>3.5</version>
+		</dependency>
+		<dependency>
+			<groupId>commons-io</groupId>
+			<artifactId>commons-io</artifactId>
+			<version>2.5</version>
+		</dependency>
+
+		<dependency>
+			<groupId>com.google.guava</groupId>
+			<artifactId>guava</artifactId>
+			<version>21.0</version>
+		</dependency>
+		<dependency>
+			<groupId>net.sf.supercsv</groupId>
+			<artifactId>super-csv</artifactId>
+			<version>2.4.0</version>
+		</dependency>
+		<dependency>
+			<groupId>com.google.code.gson</groupId>
+			<artifactId>gson</artifactId>
+			<version>2.8.0</version>
+		</dependency>
+
+
+		<dependency>
+			<groupId>com.fasterxml.jackson.datatype</groupId>
+			<artifactId>jackson-datatype-joda</artifactId>
+			<version>2.6.6</version>
+		</dependency>
+		<dependency>
+			<groupId>joda-time</groupId>
+			<artifactId>joda-time</artifactId>
+			<version>2.8.2</version>
+		</dependency>
+
+		<dependency>
+			<groupId>org.mongodb</groupId>
+			<artifactId>mongo-java-driver</artifactId>
+			<version>${mongodb.driver.version}</version>
+		</dependency>
+
+		<dependency>
+			<groupId>io.springfox</groupId>
+			<artifactId>springfox-swagger2</artifactId>
+			<version>${springfox-version}</version>
+		</dependency>
+		<dependency>
+			<groupId>io.springfox</groupId>
+			<artifactId>springfox-swagger-ui</artifactId>
+			<version>${springfox-version}</version>
+		</dependency>
+
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-test</artifactId>
+			<scope>test</scope>
+		</dependency>
+
+	</dependencies>
+
+	<build>
+		<plugins>
+			<plugin>
+				<groupId>org.springframework.boot</groupId>
+				<artifactId>spring-boot-maven-plugin</artifactId>
+			</plugin>
+		</plugins>
+	</build>
+
+	<properties>
+		<java.version>1.8</java.version>
+		<mongodb.driver.version>3.4.2</mongodb.driver.version>
+		<springfox-version>2.7.0</springfox-version>
+		<maven.javadoc.failOnError>false</maven.javadoc.failOnError>
+	</properties>
+</project>
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/Header.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/Header.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/Header.java	(revision 48492)
@@ -0,0 +1,59 @@
+package eu.dnetlib.openaire.exporter.model.datasource;
+
+import com.fasterxml.jackson.annotation.JsonAutoDetect;
+import io.swagger.annotations.ApiModel;
+
+/**
+ * Created by claudio on 24/11/2016.
+ */
+@ApiModel
+@JsonAutoDetect
+public class Header {
+
+	private long queryTime;
+
+	private String datasourceId;
+
+	private int statusCode;
+
+	private String error = "";
+
+	public Header() {
+	}
+
+	public Header setQueryTime(final long queryTime) {
+		this.queryTime = queryTime;
+		return this;
+	}
+
+	public Header setDatasourceId(final String datasourceId) {
+		this.datasourceId = datasourceId;
+		return this;
+	}
+
+	public Header setError(final String error) {
+		this.error = error;
+		return this;
+	}
+
+	public long getQueryTime() {
+		return queryTime;
+	}
+
+	public String getDatasourceId() {
+		return datasourceId;
+	}
+
+	public String getError() {
+		return error;
+	}
+
+	public int getStatusCode() {
+		return statusCode;
+	}
+
+	public Header setStatusCode(final int statusCode) {
+		this.statusCode = statusCode;
+		return this;
+	}
+}
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/deploy.info
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/deploy.info	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/deploy.info	(revision 48492)
@@ -0,0 +1,3 @@
+{"type_source": "SVN", "goal": "package -U source:jar", 
+"url": "http://svn-public.driver.research-infrastructures.eu/driver/dnet45/modules/dnet-openaire-exporter/trunk/", "deploy_repository": "dnet45-snapshots", "version": "4", "mail": "sandro.labruzzo@isti.cnr.it,michele.artini@isti.cnr.it, claudio.atzori@isti.cnr.it, alessia.bardi@isti.cnr.it",
+"deploy_repository_url": "http://maven.research-infrastructures.eu/nexus/content/repositories/dnet45-snapshots", "name": "dnet-openaire-exporter"}
\ No newline at end of file
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/AggregationStage.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/AggregationStage.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/AggregationStage.java	(revision 48492)
@@ -0,0 +1,25 @@
+package eu.dnetlib.openaire.exporter.model.datasource;
+
+/**
+ * Created by claudio on 12/09/16.
+ */
+public enum AggregationStage {
+	COLLECT, TRANSFORM;
+
+	public static AggregationStage parse(final String s) {
+		switch (s) {
+		case "collect":
+		case "collection":
+		case "COLLECT":
+		case "COLLECTION":
+			return AggregationStage.COLLECT;
+		case "transform":
+		case "transformation":
+		case "TRANSFORM":
+		case "TRANSFORMATION":
+			return AggregationStage.TRANSFORM;
+
+		}
+		throw new IllegalArgumentException("invalid AggregationStage: " + s);
+	}
+}
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/db/Api.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/db/Api.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/db/Api.java	(revision 48492)
@@ -0,0 +1,287 @@
+package eu.dnetlib.openaire.exporter.model.datasource.db;
+
+import java.sql.Date;
+import java.util.Objects;
+import java.util.Set;
+
+import javax.persistence.*;
+
+import com.google.common.collect.ComparisonChain;
+import com.google.gson.Gson;
+import io.swagger.annotations.ApiModel;
+
+/**
+ * Api
+ */
+@Entity
+@Table(name = "dsm_api")
+@ApiModel(value = "Datasource Api model", description = "describes the datasource api")
+public class Api implements Comparable<Api> {
+
+	@Id
+	private String id = null;
+
+	private String protocol = null;
+
+	private String datasource = null;
+	private String contentdescription = null;
+	private Boolean active = false;
+	private Boolean removable = false;
+	private String typology = null;
+
+	private String compatibility;
+
+	@Column(name = "metadata_identifier_path")
+	private String metadataIdentifierPath;
+
+	@Column(name = "last_collection_total")
+	private Integer lastCollectionTotal;
+	@Column(name = "last_collection_date")
+	private Date lastCollectionDate;
+	@Column(name = "last_collection_mdid")
+	private String lastCollectionMdid;
+
+	@Column(name = "last_aggregation_total")
+	private Integer lastAggregationTotal;
+	@Column(name = "last_aggregation_date")
+	private Date lastAggregationDate;
+	@Column(name = "last_aggregation_mdid")
+	private String lastAggregationMdid;
+
+	@Column(name = "last_download_total")
+	private Integer lastDownloadTotal;
+	@Column(name = "last_download_date")
+	private Date lastDownloadDate;
+	@Column(name = "last_download_objid")
+	private String lastDownloadMdid;
+
+	@Column(name = "last_validation_job")
+	private String lastValidationJob;
+
+	private String baseurl = null;
+
+	@OneToMany(mappedBy = "id.api", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
+	private Set<Apiparam> apiparam;
+
+	public Api() {}
+
+	public String getId() {
+		return id;
+	}
+
+	public String getProtocol() {
+		return protocol;
+	}
+
+	public String getDatasource() {
+		return datasource;
+	}
+
+	public String getContentdescription() {
+		return contentdescription;
+	}
+
+	public Boolean getActive() {
+		return active;
+	}
+
+	public Boolean getRemovable() {
+		return removable;
+	}
+
+	public String getTypology() {
+		return typology;
+	}
+
+	public String getCompatibility() {
+		return compatibility;
+	}
+
+	public String getMetadataIdentifierPath() {
+		return metadataIdentifierPath;
+	}
+
+	public Integer getLastCollectionTotal() {
+		return lastCollectionTotal;
+	}
+
+	public Date getLastCollectionDate() {
+		return lastCollectionDate;
+	}
+
+	public String getLastCollectionMdid() {
+		return lastCollectionMdid;
+	}
+
+	public Integer getLastAggregationTotal() {
+		return lastAggregationTotal;
+	}
+
+	public Date getLastAggregationDate() {
+		return lastAggregationDate;
+	}
+
+	public String getLastAggregationMdid() {
+		return lastAggregationMdid;
+	}
+
+	public Integer getLastDownloadTotal() {
+		return lastDownloadTotal;
+	}
+
+	public Date getLastDownloadDate() {
+		return lastDownloadDate;
+	}
+
+	public String getLastDownloadMdid() {
+		return lastDownloadMdid;
+	}
+
+	public String getLastValidationJob() {
+		return lastValidationJob;
+	}
+
+	public String getBaseurl() {
+		return baseurl;
+	}
+
+	public Set<Apiparam> getApiparam() {
+		return apiparam;
+	}
+
+	public Api setId(final String id) {
+		this.id = id;
+		return this;
+	}
+
+	public Api setProtocol(final String protocol) {
+		this.protocol = protocol;
+		return this;
+	}
+
+	public Api setDatasource(final String datasource) {
+		this.datasource = datasource;
+		return this;
+	}
+
+	public Api setContentdescription(final String contentdescription) {
+		this.contentdescription = contentdescription;
+		return this;
+	}
+
+	public Api setActive(final Boolean active) {
+		this.active = active;
+		return this;
+	}
+
+	public Api setRemovable(final Boolean removable) {
+		this.removable = removable;
+		return this;
+	}
+
+	public Api setTypology(final String typology) {
+		this.typology = typology;
+		return this;
+	}
+
+	public Api setCompatibility(final String compatibility) {
+		this.compatibility = compatibility;
+		return this;
+	}
+
+	public Api setMetadataIdentifierPath(final String metadataIdentifierPath) {
+		this.metadataIdentifierPath = metadataIdentifierPath;
+		return this;
+	}
+
+	public Api setLastCollectionTotal(final Integer lastCollectionTotal) {
+		this.lastCollectionTotal = lastCollectionTotal;
+		return this;
+	}
+
+	public Api setLastCollectionDate(final Date lastCollectionDate) {
+		this.lastCollectionDate = lastCollectionDate;
+		return this;
+	}
+
+	public Api setLastCollectionMdid(final String lastCollectionMdid) {
+		this.lastCollectionMdid = lastCollectionMdid;
+		return this;
+	}
+
+	public Api setLastAggregationTotal(final Integer lastAggregationTotal) {
+		this.lastAggregationTotal = lastAggregationTotal;
+		return this;
+	}
+
+	public Api setLastAggregationDate(final Date lastAggregationDate) {
+		this.lastAggregationDate = lastAggregationDate;
+		return this;
+	}
+
+	public Api setLastAggregationMdid(final String lastAggregationMdid) {
+		this.lastAggregationMdid = lastAggregationMdid;
+		return this;
+	}
+
+	public Api setLastDownloadTotal(final Integer lastDownloadTotal) {
+		this.lastDownloadTotal = lastDownloadTotal;
+		return this;
+	}
+
+	public Api setLastDownloadDate(final Date lastDownloadDate) {
+		this.lastDownloadDate = lastDownloadDate;
+		return this;
+	}
+
+	public Api setLastDownloadMdid(final String lastDownloadMdid) {
+		this.lastDownloadMdid = lastDownloadMdid;
+		return this;
+	}
+
+	public Api setLastValidationJob(final String lastValidationJob) {
+		this.lastValidationJob = lastValidationJob;
+		return this;
+	}
+
+	public Api setBaseurl(final String baseurl) {
+		this.baseurl = baseurl;
+		return this;
+	}
+
+	public Api setApiparam(final Set<Apiparam> apiparam) {
+		this.apiparam = apiparam;
+		return this;
+	}
+
+	@Override
+	public boolean equals(Object o) {
+		if (this == o) {
+			return true;
+		}
+		if (o == null || getClass() != o.getClass()) {
+			return false;
+		}
+		Api api = (Api) o;
+		return Objects.equals(this.id, api.id);
+	}
+
+	@Override
+	public int hashCode() {
+		return Objects.hash(id);
+	}
+
+	@Override
+	public String toString() {
+		return new Gson().toJson(this);
+	}
+
+	@Override
+	public int compareTo(final Api a) {
+		return ComparisonChain.start()
+				.compare(getId(), a.getId())
+				.result();
+	}
+
+}
+

Property changes on: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/db/Api.java
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/test/java/eu/dnetlib/openaire/exporter/project/ProjectsControllerTest.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/test/java/eu/dnetlib/openaire/exporter/project/ProjectsControllerTest.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/test/java/eu/dnetlib/openaire/exporter/project/ProjectsControllerTest.java	(revision 48492)
@@ -0,0 +1,134 @@
+package eu.dnetlib.openaire.exporter.project;
+
+import java.io.IOException;
+
+import org.antlr.stringtemplate.StringTemplate;
+import org.apache.commons.io.IOUtils;
+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 org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.core.io.Resource;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import static org.junit.Assert.assertEquals;
+
+@Ignore
+@SpringBootTest
+@RunWith(SpringJUnit4ClassRunner.class)
+public class ProjectsControllerTest {
+
+	private static final Log log = LogFactory.getLog(ProjectsControllerTest.class);
+	private String queryTemplate = "/eu/dnetlib/openaire/exporter/sql/projects_fundings.sql.st";
+
+	private Resource expectedQueryTemplate = new ClassPathResource("/eu/dnetlib/openaire/exporter/sql/expected_projects_fundings.sql.st");
+
+	private ProjectsController controller;
+	private ProjectQueryParams params;
+
+	@Before
+	public void setup() {
+		controller = new ProjectsController();
+		Resource template = new ClassPathResource(queryTemplate);
+
+		//TODO reimplement bean injection for testing
+		//controller.setProjectsFundingQueryTemplate(template);
+		params = new ProjectQueryParams();
+	}
+
+	@Test
+	public void testObtainFP7Query() throws IllegalArgumentException, IOException {
+		params.setFundingProgramme("FP7");
+		params.setFundingPath(null);
+		String res = controller.obtainQuery(params);
+		final StringTemplate st = new StringTemplate(IOUtils.toString(expectedQueryTemplate.getInputStream(),  ProjectsController.UTF8));
+		st.setAttribute("fundingprefix", "ec__________::EC::FP7");
+		log.debug(res);
+		log.debug(st);
+		assertEquals(st.toString(), res);
+	}
+
+	@Test
+	public void testObtainFP7QuerySP1() throws IllegalArgumentException, IOException {
+		params.setFundingProgramme("FP7");
+		params.setFundingPath("SP1");
+		String res = controller.obtainQuery(params);
+		final StringTemplate st = new StringTemplate(IOUtils.toString(expectedQueryTemplate.getInputStream(),  ProjectsController.UTF8));
+		st.setAttribute("fundingprefix", "ec__________::EC::FP7::SP1");
+		log.debug(res);
+		assertEquals(st.toString(), res);
+	}
+
+	@Test
+	public void testObtainFP7QueryHealth() throws IllegalArgumentException, IOException {
+		params.setFundingProgramme("FP7");
+		params.setFundingPath("SP1::HEALTH");
+		String res = controller.obtainQuery(params);
+		final StringTemplate st = new StringTemplate(IOUtils.toString(expectedQueryTemplate.getInputStream(),  ProjectsController.UTF8));
+		st.setAttribute("fundingprefix", "ec__________::EC::FP7::SP1::HEALTH");
+		log.debug(res);
+		assertEquals(st.toString(), res);
+	}
+
+	@Test
+	public void testObtainFP7QueryHealth2() throws IllegalArgumentException, IOException {
+		params.setFundingProgramme("FP7");
+		params.setFundingPath("%::HEALTH");
+		String res = controller.obtainQuery(params);
+		final StringTemplate st = new StringTemplate(IOUtils.toString(expectedQueryTemplate.getInputStream(),  ProjectsController.UTF8));
+		st.setAttribute("fundingprefix", "ec__________::EC::FP7::%::HEALTH");
+		log.debug(res);
+		assertEquals(st.toString(), res);
+	}
+
+	@Test
+	public void testObtainWellcomeTrustQuery() throws IllegalArgumentException, IOException {
+		params.setFundingProgramme("WT");
+		params.setFundingPath(null);
+		String res = controller.obtainQuery(params);
+		final StringTemplate st = new StringTemplate(IOUtils.toString(expectedQueryTemplate.getInputStream(),  ProjectsController.UTF8));
+		st.setAttribute("fundingprefix", "wt__________::WT");
+		log.debug(res);
+		assertEquals(st.toString(), res);
+	}
+
+	@Test
+	public void testObtainFCTQuery() throws IllegalArgumentException, IOException {
+		params.setFundingProgramme("FCT");
+		params.setFundingPath(null);
+		String res = controller.obtainQuery(params);
+		final StringTemplate st = new StringTemplate(IOUtils.toString(expectedQueryTemplate.getInputStream(),  ProjectsController.UTF8));
+		st.setAttribute("fundingprefix", "fct_________::FCT");
+		log.debug(res);
+		assertEquals(st.toString(), res);
+	}
+
+	@Test
+	public void testQueryWithDateParams() throws IllegalArgumentException, IOException {
+		params.setFundingProgramme("WT");
+		params.setFundingPath(null);
+		params.setStartFrom("2015-05-04");
+		String res = controller.obtainQuery(params);
+		log.debug(res);
+		final StringTemplate st = new StringTemplate(IOUtils.toString(expectedQueryTemplate.getInputStream(),  ProjectsController.UTF8));
+		st.setAttribute("fundingprefix", "wt__________::WT");
+		String q = st.toString() + " AND startdate >= '2015-05-04'";
+		assertEquals(q, res);
+	}
+
+	@Test
+	public void testObtainSNSFQuery() throws IllegalArgumentException, IOException {
+		params.setFundingProgramme("SNSF");
+		params.setFundingPath(null);
+		String res = controller.obtainQuery(params);
+		final StringTemplate st = new StringTemplate(IOUtils.toString(expectedQueryTemplate.getInputStream(),  ProjectsController.UTF8));
+		st.setAttribute("fundingprefix", "snsf________::SNSF");
+		log.debug(res);
+		assertEquals(st.toString(), res);
+	}
+
+}
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/db/ProtocolTerm.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/db/ProtocolTerm.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/db/ProtocolTerm.java	(revision 48492)
@@ -0,0 +1,47 @@
+package eu.dnetlib.openaire.exporter.model.datasource.db;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+import com.fasterxml.jackson.annotation.JsonAutoDetect;
+import eu.dnetlib.openaire.exporter.model.datasource.BrowseTerm;
+import io.swagger.annotations.ApiModel;
+
+/**
+ * Created by claudio on 20/04/2017.
+ */
+@Entity
+@Table(name = "browse_protocols")
+@ApiModel
+@JsonAutoDetect
+public class ProtocolTerm implements Comparable<ProtocolTerm>, BrowseTerm {
+
+	@Id
+	private String term;
+	private long total;
+
+	@Override
+	public String getTerm() {
+		return term;
+	}
+
+	public void setTerm(final String term) {
+		this.term = term;
+	}
+
+	@Override
+	public long getTotal() {
+		return total;
+	}
+
+	public void setTotal(final long total) {
+		this.total = total;
+	}
+
+	@Override
+	public int compareTo(final ProtocolTerm o) {
+		return getTerm().compareTo(o.getTerm());
+	}
+
+}
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/test/java/eu/dnetlib/openaire/exporter/project/ProjectQueryParamsTest.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/test/java/eu/dnetlib/openaire/exporter/project/ProjectQueryParamsTest.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/test/java/eu/dnetlib/openaire/exporter/project/ProjectQueryParamsTest.java	(revision 48492)
@@ -0,0 +1,42 @@
+package eu.dnetlib.openaire.exporter.project;
+
+import eu.dnetlib.openaire.exporter.project.ProjectQueryParams;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class ProjectQueryParamsTest {
+
+	private ProjectQueryParams queryParams;
+
+	@Before
+	public void setUp() throws Exception {
+		queryParams = new ProjectQueryParams();
+
+	}
+
+	@Test
+	public void testVerifyParamWhiteSpace() {
+		queryParams.verifyParam("Discovery Projects");
+	}
+
+	@Test
+	public void testVerifyParamPercentage() {
+		queryParams.verifyParam("Discovery%20Projects");
+	}
+
+	@Test
+	public void testVerifyDateParam(){
+		String correctDate = "2012-03-04";
+		assertEquals(correctDate, queryParams.verifyDateParam(correctDate));
+
+	}
+
+	@Test(expected=IllegalArgumentException.class)
+	public void testVerifyDateParamException(){
+		String wrongDate = "12-12-12";
+		queryParams.verifyDateParam(wrongDate);
+
+	}
+}
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/db/Datasource.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/db/Datasource.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/db/Datasource.java	(revision 48492)
@@ -0,0 +1,487 @@
+package eu.dnetlib.openaire.exporter.model.datasource.db;
+
+import java.sql.Date;
+import java.util.Set;
+
+import javax.persistence.*;
+
+import io.swagger.annotations.ApiModel;
+
+/**
+ * Datasource
+ */
+@Entity
+@Table(name = "dsm_datasources")
+@ApiModel(value = "Datasource model", description = "provides datasource details")
+public class Datasource {
+
+	@Id
+	private String id = null;
+	private String officialname = null;
+	private String englishname = null;
+	private String websiteurl = null;
+	private String logourl = null;
+	private String contactemail = null;
+	private Double latitude;
+	private Double longitude;
+	private String timezone = null;
+
+	@Column(name = "namespaceprefix", columnDefinition = "bpchar(12)")
+	private String namespaceprefix;
+
+	private String languages;
+
+	private String od_contenttypes;
+	private String collectedfrom = null;
+	private Date dateofvalidation = null;
+	private String typology = null;
+	private String provenanceaction;
+	private Date dateofcollection;
+	private String platform;
+
+	@Column(name = "activationid")
+	private String activationId;
+	private String description = null;
+
+	private Date releasestartdate;
+	private Date releaseenddate;
+	private String missionstatementurl;
+	private Boolean dataprovider;
+	private Boolean serviceprovider;
+
+	private String databaseaccesstype;
+	private String datauploadtype;
+	private String databaseaccessrestriction;
+	private String datauploadrestriction;
+
+	private Boolean versioning;
+	private String citationguidelineurl;
+	private String qualitymanagementkind;
+	private String pidsystems;
+
+	private String certificates;
+	private String aggregator;
+
+	private String issn = null;
+	private String eissn = null;
+	private String lissn = null;
+
+	private String registeredby = null;
+
+	private String subjects;
+
+	private Boolean managed;
+
+	/*
+	@JsonIgnore
+	@OneToMany(mappedBy = "datasource", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
+	private Set<Api> api = null;
+	*/
+
+	@ManyToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE }, fetch = FetchType.EAGER)
+	@JoinTable(
+			name = "dsm_datasource_organization",
+			joinColumns = @JoinColumn(name="datasource"),
+			inverseJoinColumns = @JoinColumn(name="organization"))
+	private Set<Organization> organizations;
+
+	@ManyToMany(
+			cascade = { CascadeType.PERSIST, CascadeType.MERGE },
+	        fetch = FetchType.EAGER )
+	@JoinTable(
+			name = "dsm_datasourcepids",
+			joinColumns = @JoinColumn(name = "datasource"),
+			inverseJoinColumns = @JoinColumn(name="pid"))
+	private Set<Identity> identities;
+
+	public Datasource() {}
+
+	public String getId() {
+		return id;
+	}
+
+	public String getOfficialname() {
+		return officialname;
+	}
+
+	public String getEnglishname() {
+		return englishname;
+	}
+
+	public String getWebsiteurl() {
+		return websiteurl;
+	}
+
+	public String getLogourl() {
+		return logourl;
+	}
+
+	public String getContactemail() {
+		return contactemail;
+	}
+
+	public Double getLatitude() {
+		return latitude;
+	}
+
+	public Double getLongitude() {
+		return longitude;
+	}
+
+	public String getTimezone() {
+		return timezone;
+	}
+
+	public String getNamespaceprefix() {
+		return namespaceprefix;
+	}
+
+	public String getLanguages() {
+		return languages;
+	}
+
+	public String getOd_contenttypes() {
+		return od_contenttypes;
+	}
+
+	public String getCollectedfrom() {
+		return collectedfrom;
+	}
+
+	public Date getDateofvalidation() {
+		return dateofvalidation;
+	}
+
+	public String getTypology() {
+		return typology;
+	}
+
+	public String getProvenanceaction() {
+		return provenanceaction;
+	}
+
+	public Date getDateofcollection() {
+		return dateofcollection;
+	}
+
+	public String getPlatform() {
+		return platform;
+	}
+
+	public String getActivationId() {
+		return activationId;
+	}
+
+	public String getDescription() {
+		return description;
+	}
+
+	public Date getReleasestartdate() {
+		return releasestartdate;
+	}
+
+	public Date getReleaseenddate() {
+		return releaseenddate;
+	}
+
+	public String getMissionstatementurl() {
+		return missionstatementurl;
+	}
+
+	public Boolean isDataprovider() {
+		return dataprovider;
+	}
+
+	public Boolean isServiceprovider() {
+		return serviceprovider;
+	}
+
+	public String getDatabaseaccesstype() {
+		return databaseaccesstype;
+	}
+
+	public String getDatauploadtype() {
+		return datauploadtype;
+	}
+
+	public String getDatabaseaccessrestriction() {
+		return databaseaccessrestriction;
+	}
+
+	public String getDatauploadrestriction() {
+		return datauploadrestriction;
+	}
+
+	public Boolean isVersioning() {
+		return versioning;
+	}
+
+	public String getCitationguidelineurl() {
+		return citationguidelineurl;
+	}
+
+	public String getQualitymanagementkind() {
+		return qualitymanagementkind;
+	}
+
+	public String getPidsystems() {
+		return pidsystems;
+	}
+
+	public String getCertificates() {
+		return certificates;
+	}
+
+	public String getAggregator() {
+		return aggregator;
+	}
+
+	public String getIssn() {
+		return issn;
+	}
+
+	public String getEissn() {
+		return eissn;
+	}
+
+	public String getLissn() {
+		return lissn;
+	}
+
+	public String getRegisteredby() {
+		return registeredby;
+	}
+
+	public String getSubjects() {
+		return subjects;
+	}
+
+	public Boolean isManaged() {
+		return managed;
+	}
+
+	public Set<Organization> getOrganizations() {
+		return organizations;
+	}
+
+	public Set<Identity> getIdentities() {
+		return identities;
+	}
+
+	public Datasource setId(final String id) {
+		this.id = id;
+		return this;
+	}
+
+	public Datasource setOfficialname(final String officialname) {
+		this.officialname = officialname;
+		return this;
+	}
+
+	public Datasource setEnglishname(final String englishname) {
+		this.englishname = englishname;
+		return this;
+	}
+
+	public Datasource setWebsiteurl(final String websiteurl) {
+		this.websiteurl = websiteurl;
+		return this;
+	}
+
+	public Datasource setLogourl(final String logourl) {
+		this.logourl = logourl;
+		return this;
+	}
+
+	public Datasource setContactemail(final String contactemail) {
+		this.contactemail = contactemail;
+		return this;
+	}
+
+	public Datasource setLatitude(final Double latitude) {
+		this.latitude = latitude;
+		return this;
+	}
+
+	public Datasource setLongitude(final Double longitude) {
+		this.longitude = longitude;
+		return this;
+	}
+
+	public Datasource setTimezone(final String timezone) {
+		this.timezone = timezone;
+		return this;
+	}
+
+	public Datasource setNamespaceprefix(final String namespaceprefix) {
+		this.namespaceprefix = namespaceprefix;
+		return this;
+	}
+
+	public Datasource setLanguages(final String languages) {
+		this.languages = languages;
+		return this;
+	}
+
+	public Datasource setOd_contenttypes(final String od_contenttypes) {
+		this.od_contenttypes = od_contenttypes;
+		return this;
+	}
+
+	public Datasource setCollectedfrom(final String collectedfrom) {
+		this.collectedfrom = collectedfrom;
+		return this;
+	}
+
+	public Datasource setDateofvalidation(final Date dateofvalidation) {
+		this.dateofvalidation = dateofvalidation;
+		return this;
+	}
+
+	public Datasource setTypology(final String typology) {
+		this.typology = typology;
+		return this;
+	}
+
+	public Datasource setProvenanceaction(final String provenanceaction) {
+		this.provenanceaction = provenanceaction;
+		return this;
+	}
+
+	public Datasource setDateofcollection(final Date dateofcollection) {
+		this.dateofcollection = dateofcollection;
+		return this;
+	}
+
+	public Datasource setPlatform(final String platform) {
+		this.platform = platform;
+		return this;
+	}
+
+	public Datasource setActivationId(final String activationId) {
+		this.activationId = activationId;
+		return this;
+	}
+
+	public Datasource setDescription(final String description) {
+		this.description = description;
+		return this;
+	}
+
+	public Datasource setReleasestartdate(final Date releasestartdate) {
+		this.releasestartdate = releasestartdate;
+		return this;
+	}
+
+	public Datasource setReleaseenddate(final Date releaseenddate) {
+		this.releaseenddate = releaseenddate;
+		return this;
+	}
+
+	public Datasource setMissionstatementurl(final String missionstatementurl) {
+		this.missionstatementurl = missionstatementurl;
+		return this;
+	}
+
+	public Datasource setDataprovider(final Boolean dataprovider) {
+		this.dataprovider = dataprovider;
+		return this;
+	}
+
+	public Datasource setServiceprovider(final Boolean serviceprovider) {
+		this.serviceprovider = serviceprovider;
+		return this;
+	}
+
+	public Datasource setDatabaseaccesstype(final String databaseaccesstype) {
+		this.databaseaccesstype = databaseaccesstype;
+		return this;
+	}
+
+	public Datasource setDatauploadtype(final String datauploadtype) {
+		this.datauploadtype = datauploadtype;
+		return this;
+	}
+
+	public Datasource setDatabaseaccessrestriction(final String databaseaccessrestriction) {
+		this.databaseaccessrestriction = databaseaccessrestriction;
+		return this;
+	}
+
+	public Datasource setDatauploadrestriction(final String datauploadrestriction) {
+		this.datauploadrestriction = datauploadrestriction;
+		return this;
+	}
+
+	public Datasource setVersioning(final Boolean versioning) {
+		this.versioning = versioning;
+		return this;
+	}
+
+	public Datasource setCitationguidelineurl(final String citationguidelineurl) {
+		this.citationguidelineurl = citationguidelineurl;
+		return this;
+	}
+
+	public Datasource setQualitymanagementkind(final String qualitymanagementkind) {
+		this.qualitymanagementkind = qualitymanagementkind;
+		return this;
+	}
+
+	public Datasource setPidsystems(final String pidsystems) {
+		this.pidsystems = pidsystems;
+		return this;
+	}
+
+	public Datasource setCertificates(final String certificates) {
+		this.certificates = certificates;
+		return this;
+	}
+
+	public Datasource setAggregator(final String aggregator) {
+		this.aggregator = aggregator;
+		return this;
+	}
+
+	public Datasource setIssn(final String issn) {
+		this.issn = issn;
+		return this;
+	}
+
+	public Datasource setEissn(final String eissn) {
+		this.eissn = eissn;
+		return this;
+	}
+
+	public Datasource setLissn(final String lissn) {
+		this.lissn = lissn;
+		return this;
+	}
+
+	public Datasource setRegisteredby(final String registeredby) {
+		this.registeredby = registeredby;
+		return this;
+	}
+
+	public Datasource setSubjects(final String subjects) {
+		this.subjects = subjects;
+		return this;
+	}
+
+	public Datasource setManaged(final Boolean managed) {
+		this.managed = managed;
+		return this;
+	}
+
+	public Datasource setOrganizations(final Set<Organization> organizations) {
+		this.organizations = organizations;
+		return this;
+	}
+
+	public Datasource setIdentities(final Set<Identity> identities) {
+		this.identities = identities;
+		return this;
+	}
+
+}
+

Property changes on: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/db/Datasource.java
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/test/java/eu/dnetlib/openaire/exporter/model/project/ProjectDetailsTest.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/test/java/eu/dnetlib/openaire/exporter/model/project/ProjectDetailsTest.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/test/java/eu/dnetlib/openaire/exporter/model/project/ProjectDetailsTest.java	(revision 48492)
@@ -0,0 +1,25 @@
+package eu.dnetlib.openaire.exporter.model.project;
+
+import java.io.IOException;
+
+import org.junit.Test;
+
+/**
+ * Created by claudio on 05/07/2017.
+ */
+public class ProjectDetailsTest {
+
+	@Test
+	public void testCSV() throws IOException {
+
+		final ProjectDetails p = ProjectDetails.fromCSV(
+				"arc_________::ANZCCART,,ANZCCART,{},\"[\"\"\\u003cfundingtree\\u003e\\n      \\u003cfunder\\u003e\\n         \\u003cid\\u003earc_________::ARC\\u003c/id\\u003e\\n         \\u003cshortname\\u003eARC\\u003c/shortname\\u003e\\n         \\u003cname\\u003eAustralian Research Council (ARC)\\u003c/name\\u003e\\n         \\u003cjurisdiction\\u003eAU\\u003c/jurisdiction\\u003e\\n      \\u003c/funder\\u003e\\n      \\u003cfunding_level_0\\u003e\\n         \\u003cid\\u003earc_________::ARC::Special Research initiative (Australian and New Zealand Council for the Care of Animals in Research and Teaching)\\u003c/id\\u003e\\n         \\u003cname\\u003eSpecial Research initiative (Australian and New Zealand Council for the Care of Animals in Research and Teaching)\\u003c/name\\u003e\\n         \\u003cdescription\\u003eSpecial Research initiative (Australian and New Zealand Council for the Care of Animals in Research and Teaching)\\u003c/description\\u003e\\n         \\u003cparent/\\u003e\\n         \\u003cclass\\u003earc:fundingStream\\u003c/class\\u003e\\n      \\u003c/funding_level_0\\u003e\\n   \\u003c/fundingtree\\u003e\"\"]\"");
+
+		System.out.println(p.asJson());
+
+		System.out.println(p.asCSV());
+
+
+	}
+
+}
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/db/SearchInterfacesEntry.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/db/SearchInterfacesEntry.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/db/SearchInterfacesEntry.java	(revision 48492)
@@ -0,0 +1,172 @@
+package eu.dnetlib.openaire.exporter.model.datasource.db;
+
+import java.sql.Date;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+import com.fasterxml.jackson.annotation.JsonAutoDetect;
+import io.swagger.annotations.ApiModel;
+
+/**
+ * Created by claudio on 13/04/2017.
+ */
+@Entity
+@Table(name = "search_api")
+@ApiModel
+@JsonAutoDetect
+public class SearchInterfacesEntry implements Comparable<SearchInterfacesEntry> {
+
+	@Id
+	private String id;
+
+	@Column(name = "compatibility")
+	private String compliance;
+
+	@Column(name = "protocol")
+	private String protocol;
+
+	@Column(name = "active")
+	private boolean active;
+
+	@Column(name = "repoid")
+	private String repoid = "unknown";
+
+	@Column(name = "officialname")
+	private String repoName = "unknown";
+
+	@Column(name = "englishname")
+	private String alternativeName = "unknown";
+
+	@Column(name = "country")
+	private String repoCountry = "-";
+
+	@Column(name = "organization")
+	private String repoOrganization = "-";
+
+	@Column(name = "namespaceprefix", columnDefinition = "bpchar(12)")
+	private String repoPrefix = "";
+
+	@Column(name = "last_aggregation_date")
+	private Date aggrDate;
+
+	@Column(name = "last_aggregation_total")
+	private Integer aggrTotal = 0;
+
+	public SearchInterfacesEntry() {}
+
+	@Override
+	public int compareTo(final SearchInterfacesEntry e) {
+		return compliance.compareTo(e.getCompliance());
+	}
+
+	public String getId() {
+		return id;
+	}
+
+	public String getCompliance() {
+		return compliance;
+	}
+
+	public String getProtocol() {
+		return protocol;
+	}
+
+	public boolean isActive() {
+		return active;
+	}
+
+	public String getRepoid() {
+		return repoid;
+	}
+
+	public String getRepoName() {
+		return repoName;
+	}
+
+	public String getAlternativeName() {
+		return alternativeName;
+	}
+
+	public String getRepoCountry() {
+		return repoCountry;
+	}
+
+	public String getRepoOrganization() {
+		return repoOrganization;
+	}
+
+	public String getRepoPrefix() {
+		return repoPrefix;
+	}
+
+	public Date getAggrDate() {
+		return aggrDate;
+	}
+
+	public Integer getAggrTotal() {
+		return aggrTotal;
+	}
+
+	public SearchInterfacesEntry setId(final String id) {
+		this.id = id;
+		return this;
+	}
+
+	public SearchInterfacesEntry setCompliance(final String compliance) {
+		this.compliance = compliance;
+		return this;
+	}
+
+	public SearchInterfacesEntry setProtocol(final String protocol) {
+		this.protocol = protocol;
+		return this;
+	}
+
+	public SearchInterfacesEntry setActive(final boolean active) {
+		this.active = active;
+		return this;
+	}
+
+	public SearchInterfacesEntry setRepoid(final String repoid) {
+		this.repoid = repoid;
+		return this;
+	}
+
+	public SearchInterfacesEntry setRepoName(final String repoName) {
+		this.repoName = repoName;
+		return this;
+	}
+
+	public SearchInterfacesEntry setAlternativeName(final String alternativeName) {
+		this.alternativeName = alternativeName;
+		return this;
+	}
+
+	public SearchInterfacesEntry setRepoCountry(final String repoCountry) {
+		this.repoCountry = repoCountry;
+		return this;
+	}
+
+	public SearchInterfacesEntry setRepoOrganization(final String repoOrganization) {
+		this.repoOrganization = repoOrganization;
+		return this;
+	}
+
+	public SearchInterfacesEntry setRepoPrefix(final String repoPrefix) {
+		this.repoPrefix = repoPrefix;
+		return this;
+	}
+
+	public SearchInterfacesEntry setAggrDate(final Date aggrDate) {
+		this.aggrDate = aggrDate;
+		return this;
+	}
+
+	public SearchInterfacesEntry setAggrTotal(final Integer aggrTotal) {
+		this.aggrTotal = aggrTotal;
+		return this;
+	}
+
+}
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/CollectionInfo.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/CollectionInfo.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/CollectionInfo.java	(revision 48492)
@@ -0,0 +1,23 @@
+package eu.dnetlib.openaire.exporter.model.datasource;
+
+import com.fasterxml.jackson.annotation.JsonAutoDetect;
+import io.swagger.annotations.ApiModel;
+
+/**
+ * Created by claudio on 29/11/2016.
+ */
+@ApiModel
+@JsonAutoDetect
+public class CollectionInfo extends AggregationInfo {
+
+	private CollectionMode collectionMode;
+
+	public CollectionMode getCollectionMode() {
+		return collectionMode;
+	}
+
+	public void setCollectionMode(final CollectionMode collectionMode) {
+		this.collectionMode = collectionMode;
+	}
+
+}
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/test/resources/logback-test.xml
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/test/resources/logback-test.xml	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/test/resources/logback-test.xml	(revision 48492)
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration>
+	<include resource="org/springframework/boot/logging/logback/base.xml"/>
+	<logger name="org.springframework" level="OFF">
+		<appender-ref ref="CONSOLE" />
+	</logger>
+	<logger name="root" level="OFF">
+		<appender-ref ref="CONSOLE" />
+	</logger>
+	<logger name="eu.dnetlib" level="INFO">
+		<appender-ref ref="CONSOLE" />
+	</logger>
+	<logger name="eu.dnetlib.openaire.exporter" level="INFO">
+		<appender-ref ref="CONSOLE" />
+	</logger>
+</configuration>
\ No newline at end of file
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/DatasourceResponse.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/DatasourceResponse.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/DatasourceResponse.java	(revision 48492)
@@ -0,0 +1,91 @@
+package eu.dnetlib.openaire.exporter.model.datasource;
+
+import java.util.List;
+
+import com.fasterxml.jackson.annotation.JsonAutoDetect;
+import eu.dnetlib.openaire.exporter.model.datasource.db.Datasource;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * Created by claudio on 12/09/16.
+ */
+@JsonAutoDetect
+@ApiModel(value = "Datasource response model", description = "provides information about the datasource and its aggregation status")
+public class DatasourceResponse {
+
+	@ApiModelProperty(position = 1)
+	private long indexRecords;
+
+	@ApiModelProperty(position = 2)
+	private String lastIndexingDate;
+
+	@ApiModelProperty(position = 3)
+	private Datasource datasource;
+
+	@ApiModelProperty(position = 4)
+	private List<AggregationInfo> aggregationHistory;
+
+	@ApiModelProperty(position = 5)
+	private AggregationInfo lastCollection;
+
+	@ApiModelProperty(position = 6)
+	private AggregationInfo lastTransformation;
+
+	public DatasourceResponse() {
+		super();
+	}
+
+	public DatasourceResponse setIndexRecords(final long indexRecords) {
+		this.indexRecords = indexRecords;
+		return this;
+	}
+
+	public DatasourceResponse setLastIndexingDate(final String lastIndexingDate) {
+		this.lastIndexingDate = lastIndexingDate;
+		return this;
+	}
+
+	public DatasourceResponse setAggregationHistory(final List<AggregationInfo> aggregationHistory) {
+		this.aggregationHistory = aggregationHistory;
+		return this;
+	}
+
+	public DatasourceResponse setLastCollection(final AggregationInfo lastCollection) {
+		this.lastCollection = lastCollection;
+		return this;
+	}
+
+	public DatasourceResponse setLastTransformation(final AggregationInfo lastTransformation) {
+		this.lastTransformation = lastTransformation;
+		return this;
+	}
+
+	public long getIndexRecords() {
+		return indexRecords;
+	}
+
+	public String getLastIndexingDate() {
+		return lastIndexingDate;
+	}
+
+	public List<AggregationInfo> getAggregationHistory() {
+		return aggregationHistory;
+	}
+
+	public AggregationInfo getLastCollection() {
+		return lastCollection;
+	}
+
+	public AggregationInfo getLastTransformation() {
+		return lastTransformation;
+	}
+
+	public Datasource getDatasource() {
+		return datasource;
+	}
+
+	public void setDatasource(final Datasource datasource) {
+		this.datasource = datasource;
+	}
+}
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/test/resources/eu/dnetlib/openaire/exporter/sql/expected_projects_fundings.sql.st
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/test/resources/eu/dnetlib/openaire/exporter/sql/expected_projects_fundings.sql.st	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/test/resources/eu/dnetlib/openaire/exporter/sql/expected_projects_fundings.sql.st	(revision 48492)
@@ -0,0 +1,11 @@
+SELECT
+	funder,
+	jurisdiction,
+	fundingpathid,
+	acronym,
+	title,
+	code,
+	startdate,
+	enddate
+FROM projects_api
+WHERE fundingpathid like '$fundingprefix$%'
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/project/JdbcApiDao.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/project/JdbcApiDao.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/project/JdbcApiDao.java	(revision 48492)
@@ -0,0 +1,214 @@
+package eu.dnetlib.openaire.exporter.project;
+
+import java.io.BufferedOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.charset.Charset;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.time.Duration;
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.zip.GZIPOutputStream;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+import com.google.common.base.Joiner;
+import com.google.common.base.Splitter;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import eu.dnetlib.OpenaireExporterConfig;
+import eu.dnetlib.openaire.exporter.datasource.ApiException;
+import eu.dnetlib.openaire.exporter.model.project.Project;
+import eu.dnetlib.openaire.exporter.model.project.ProjectTsv;
+import eu.dnetlib.openaire.exporter.project.repository.ProjectDetailsRepository;
+import eu.dnetlib.openaire.exporter.project.repository.ProjectTsvRepository;
+import org.antlr.stringtemplate.StringTemplate;
+import org.apache.commons.dbcp2.BasicDataSource;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+/**
+ * Created by claudio on 20/09/16.
+ */
+@Component
+public class JdbcApiDao {
+
+	public static final Charset UTF8 = Charset.forName("UTF-8");
+
+	private static final Log log = LogFactory.getLog(JdbcApiDao.class);
+
+	@Autowired
+	private OpenaireExporterConfig config;
+
+	@Autowired
+	private BasicDataSource projectApiDataSource;
+
+	@Autowired
+	private ProjectDetailsRepository projectDetailsRepository;
+
+	@Autowired
+	private ProjectTsvRepository projectTsvRepository;
+
+
+	public Map<String, String> readFundingpathIds() {
+
+		log.debug("loading funding ids");
+		final String sql = "SELECT id FROM fundingpaths";
+		final Set<String> ids = Sets.newHashSet();
+		try (final Connection con = getConn(); final PreparedStatement stm = getStm(sql, con); final ResultSet rs = stm.executeQuery()) {
+			while (rs.next()) {
+				ids.add(rs.getString("id"));
+			}
+		} catch (SQLException e) {
+			throw new RuntimeException(e);
+		}
+		log.debug(String.format("loaded %s funding ids", ids.size()));
+
+		final Map<String, String> res = Maps.newHashMap();
+		final Splitter sp = Splitter.on("::").trimResults();
+		ids.stream()
+				.filter(s -> sp.splitToList(s).size() < 3)
+				.forEach(s -> res.put(StringUtils.substringAfterLast(s, "::").toUpperCase(), s));
+
+		res.put("FP7", "ec__________::EC::FP7");
+		res.put("H2020", "ec__________::EC::H2020");
+		log.debug(String.format("processed %s funding ids", res.size()));
+		res.forEach((k,v) -> log.debug(String.format("%s : '%s'", k, v)));
+		return res;
+	}
+
+	public void processProjectDetails(final OutputStream outputStream, String format, Boolean compress) throws IOException {
+		final OutputStream out = getOutputStream(outputStream, compress);
+		try {
+			final AtomicInteger i = new AtomicInteger(0);
+			projectDetailsRepository.findAll().forEach(p -> {
+					try {
+						switch (format) {
+						case "csv":
+							out.write(p.asCSV().getBytes(UTF8));
+							break;
+						case "json":
+							out.write(p.asJson().getBytes(UTF8));
+							break;
+						}
+						i.incrementAndGet();
+						if (i.intValue() % config.getProject().getGzipFlushSize() == 0) {
+							log.debug("flushing output stream");
+							out.flush();
+						}
+					} catch (IOException e) {
+						throw new RuntimeException(e);
+					}
+				}
+			);
+		} finally {
+			if (out instanceof GZIPOutputStream) {
+				((GZIPOutputStream) out).finish();
+			}
+			out.close();
+		}
+	}
+
+	private OutputStream getOutputStream(final OutputStream outputStream, final Boolean compress) throws IOException {
+		if (compress != null && compress) {
+			return new GZIPOutputStream(outputStream);
+		}
+		return outputStream;
+	}
+
+	public void processTsvRequest(final OutputStream outputStream, final Boolean article293, final String fundingPrefix, final String filename) throws ApiException {
+		try(final ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(outputStream))) {
+			out.putNextEntry(new ZipEntry(filename));
+			writeTsvLine(out, Splitter.on(",").trimResults().splitToList(config.getProject().getTsvFields()));
+			queryForTsv(fundingPrefix, article293).forEach(p -> {
+				try {
+					writeTsvLine(out, p.asList());
+				} catch (IOException e) {
+					throw new RuntimeException(e);
+				}
+			});
+		} catch (Throwable e) {
+			throw new RuntimeException("Error processing the request", e);
+		}
+	}
+
+	private void writeTsvLine(final ZipOutputStream out, final List<String> s) throws IOException {
+		out.write(Joiner.on('\t').useForNull("").join(s).getBytes(UTF8));
+		out.write('\n');
+	}
+
+	private Iterable<ProjectTsv> queryForTsv(final String fundingPrefix, final Boolean article293) {
+		log.debug(String.format("fundingPrefix:'%s' and article293:'%s'", fundingPrefix, article293));
+		if (article293 != null) {
+			return projectTsvRepository.findByFundingpathidStartingWithAndOaMandateForDatasetsOrderByAcronym(fundingPrefix, article293);
+		} else {
+			return projectTsvRepository.findByFundingpathidStartingWithOrderByAcronym(fundingPrefix);
+		}
+	}
+
+	public void streamProjects(final String sql, final OutputStream out,
+			final String head, final StringTemplate projectTemplate, final String tail,
+			final ValueCleaner cleaner) throws IOException, SQLException {
+
+		if (log.isDebugEnabled()) {
+			log.debug("Thread " + Thread.currentThread().getId() + " begin");
+		}
+		final LocalDateTime start = LocalDateTime.now();
+
+		if (StringUtils.isNotBlank(head)) {
+			out.write(head.getBytes(UTF8));
+		}
+
+		try (final Connection con = getConn(); final PreparedStatement stm = getStm(sql, con); final ResultSet rs = stm.executeQuery()) {
+			while (rs.next()) {
+				final Project p = new Project()
+						.setFunder(cleaner.clean(rs.getString("funder")))
+						.setJurisdiction(cleaner.clean(rs.getString("jurisdiction")))
+						.setFundingpathid(cleaner.clean(rs.getString("fundingpathid")))
+						.setAcronym(cleaner.clean(rs.getString("acronym")))
+						.setTitle(cleaner.clean(rs.getString("title")))
+						.setCode(cleaner.clean(rs.getString("code")))
+						.setStartdate(cleaner.clean(rs.getString("startdate")))
+						.setEnddate(cleaner.clean(rs.getString("enddate")));
+
+				projectTemplate.reset();
+				projectTemplate.setAttribute("p", p);
+				out.write(projectTemplate.toString().getBytes(UTF8));
+			}
+			if (StringUtils.isNotBlank(tail)) {
+				out.write(tail.getBytes(UTF8));
+			}
+			final LocalDateTime end = LocalDateTime.now();
+			if (log.isDebugEnabled()) {
+				log.debug("Thread " + Thread.currentThread().getId() + " ends, took: " + Duration.between(start, end).toMillis() + " ms");
+			}
+		} finally {
+			out.close();
+			if (log.isDebugEnabled()) {
+				log.debug("Thread " + Thread.currentThread().getId() + " closed output stream");
+			}
+		}
+	}
+
+	private Connection getConn() throws SQLException {
+		final Connection conn = projectApiDataSource.getConnection();
+		conn.setAutoCommit(false);
+		return conn;
+	}
+
+	private PreparedStatement getStm(final String sql, final Connection con) throws SQLException {
+		final PreparedStatement stm = con.prepareStatement(sql);
+		stm.setFetchSize(config.getJdbc().getMaxRows());
+		return stm;
+	}
+
+}
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/test/resources/eu/dnetlib/openaire/exporter/FP7-project.xml
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/test/resources/eu/dnetlib/openaire/exporter/FP7-project.xml	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/test/resources/eu/dnetlib/openaire/exporter/FP7-project.xml	(revision 48492)
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ROW>
+	<FIELD name="funder">EC</FIELD>
+	<FIELD name="jurisdiction">EU</FIELD>
+	<FIELD name="end_date">2012-07-31</FIELD>
+	<FIELD name="grant_agreement_number">255646</FIELD>
+	<FIELD name="title">Semiconductor lasers for generation of non-diffracting (Bessel) beams.</FIELD>
+	<FIELD name="fundingpathid">ec__________::EC::FP7::SP3::PEOPLE</FIELD>
+	<FIELD name="acronym">SENDBEAMS</FIELD>
+	<FIELD name="start_date">2010-08-01</FIELD>
+	<FIELD name="description">description of the funding path</FIELD>
+</ROW> 
+
+	
\ No newline at end of file
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/project/repository/ProjectTsvRepository.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/project/repository/ProjectTsvRepository.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/project/repository/ProjectTsvRepository.java	(revision 48492)
@@ -0,0 +1,17 @@
+package eu.dnetlib.openaire.exporter.project.repository;
+
+import eu.dnetlib.openaire.exporter.model.project.ProjectTsv;
+import org.springframework.data.repository.PagingAndSortingRepository;
+import org.springframework.stereotype.Repository;
+
+/**
+ * Created by claudio on 04/07/2017.
+ */
+@Repository
+public interface ProjectTsvRepository extends PagingAndSortingRepository<ProjectTsv, String> {
+
+	Iterable<ProjectTsv> findByFundingpathidStartingWithOrderByAcronym(String fundingpathid);
+
+	Iterable<ProjectTsv> findByFundingpathidStartingWithAndOaMandateForDatasetsOrderByAcronym(String fundingpathid, boolean article293);
+
+}
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/project/ValueCleaner.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/project/ValueCleaner.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/project/ValueCleaner.java	(revision 48492)
@@ -0,0 +1,10 @@
+package eu.dnetlib.openaire.exporter.project;
+
+/**
+ * Created by claudio on 23/09/2016.
+ */
+public interface ValueCleaner {
+
+	public String clean(String s);
+
+}
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/test/resources/eu/dnetlib/openaire/exporter/FCT-project.xml
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/test/resources/eu/dnetlib/openaire/exporter/FCT-project.xml	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/test/resources/eu/dnetlib/openaire/exporter/FCT-project.xml	(revision 48492)
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ROW>
+	<FIELD name="funder">FCT</FIELD>
+	<FIELD name="jurisdiction">PT</FIELD>
+	<FIELD name="end_date">2003-10-31</FIELD>
+	<FIELD name="grant_agreement_number">32639</FIELD>
+	<FIELD name="title">Social Classes and «lifestyles» in the city of Oporto</FIELD>
+	<FIELD name="fundingpathid">fct_________::FCT::Orçamento de Funcionamento/POSC</FIELD>
+	<FIELD name="acronym">PTDC/FIL-FIL/109889/2009</FIELD>
+	<FIELD name="start_date">2000-11-01</FIELD>
+	<FIELD name="description">description of the funding path</FIELD>
+</ROW> 
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/clients/utils/DatasourceFunctions.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/clients/utils/DatasourceFunctions.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/clients/utils/DatasourceFunctions.java	(revision 48492)
@@ -0,0 +1,16 @@
+package eu.dnetlib.openaire.exporter.datasource.clients.utils;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+public class DatasourceFunctions {
+
+	private static final Log log = LogFactory.getLog(DatasourceFunctions.class); // NOPMD by marko on 11/24/08 5:02 PM
+
+	private static final String DATE_FIELDS_SUFFIX = "_date";
+
+	private static final String MDID_SUFFIX = "_mdId";
+
+	public static final String DATE_FORMAT = "yyyy-MM-dd";
+
+}
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/test/resources/eu/dnetlib/openaire/exporter/SFI-project.xml
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/test/resources/eu/dnetlib/openaire/exporter/SFI-project.xml	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/test/resources/eu/dnetlib/openaire/exporter/SFI-project.xml	(revision 48492)
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ROW>
+	<FIELD name="funder">SFI</FIELD>
+	<FIELD name="end_date">2016-08-31</FIELD>
+	<FIELD name="grant_agreement_number">14/ADV/RC3022</FIELD>
+	<FIELD name="title">Dr. Vesna Jaksic</FIELD>
+	<FIELD name="acronym" isNull="true"/>
+	<FIELD name="fundingpathid">sfi_________::SFI::Advance Award Programme</FIELD>
+	<FIELD name="jurisdiction" isNull="true"/>
+	<FIELD name="start_date">2014-09-01</FIELD>
+</ROW>
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/clients/DatasourceIndexClient.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/clients/DatasourceIndexClient.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/clients/DatasourceIndexClient.java	(revision 48492)
@@ -0,0 +1,92 @@
+package eu.dnetlib.openaire.exporter.datasource.clients;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import com.google.common.collect.Iterables;
+import eu.dnetlib.data.index.CloudIndexClient;
+import eu.dnetlib.data.index.CloudIndexClientException;
+import eu.dnetlib.data.index.CloudIndexClientFactory;
+import eu.dnetlib.miscutils.functional.hash.Hashing;
+import eu.dnetlib.openaire.exporter.datasource.ApiException;
+import eu.dnetlib.openaire.exporter.datasource.clients.utils.DatasourceFunctions;
+import eu.dnetlib.openaire.exporter.datasource.clients.utils.IndexDsInfo;
+import eu.dnetlib.openaire.exporter.datasource.clients.utils.IndexRecordsInfo;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang.time.DateFormatUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.solr.client.solrj.response.QueryResponse;
+import org.apache.solr.common.SolrDocument;
+import org.springframework.http.HttpStatus;
+import org.springframework.stereotype.Component;
+
+/**
+ * Created by claudio on 20/10/2016.
+ */
+@Component
+public class DatasourceIndexClient {
+
+	private static final Log log = LogFactory.getLog(DatasourceIndexClient.class);
+
+	public static final String SEPARATOR = "::";
+	public static final String DSVERSION = "__dsversion";
+
+	private static Map<String, CloudIndexClient> indexClientMap = new ConcurrentHashMap<>();
+
+	public IndexRecordsInfo getIndexInfo(final String dsId, final IndexDsInfo info) throws ApiException {
+		try {
+			final String collectedFrom = StringUtils.substringBefore(dsId, SEPARATOR) + SEPARATOR + Hashing.md5(StringUtils.substringAfter(dsId, SEPARATOR));
+			final CloudIndexClient indexClient = getIndexClient(info);
+			final String query = String.format("oaftype:result AND deletedbyinference:false AND collectedfromdatasourceid:\"%s\"", collectedFrom);
+			log.debug(String.format("query on %s: %s", info.getFormat(), query));
+
+			final QueryResponse rsp = indexClient.query(query, 1);
+
+			long count = rsp.getResults().getNumFound();
+			final SolrDocument doc = Iterables.getFirst(rsp.getResults(), new SolrDocument());
+			if (log.isDebugEnabled()) {
+				log.debug(String.format("got document %s", doc.toString()));
+			}
+			if (doc.isEmpty()) {
+				throw new ApiException(HttpStatus.INTERNAL_SERVER_ERROR.value(), String.format("cannot find document matching query: %s", query));
+			}
+			final String date = getDate(doc);
+
+			return new IndexRecordsInfo(count, date);
+		} catch (final Throwable e) {
+			throw new ApiException(HttpStatus.INTERNAL_SERVER_ERROR.value(), "Error querying publications from: " + dsId, e);
+		}
+	}
+
+	private String getDate(final SolrDocument doc) throws ApiException {
+		final List<Date> dsversion = (List<Date>) doc.get(DSVERSION);
+		if (dsversion == null || dsversion.isEmpty()) {
+			throw new ApiException(HttpStatus.INTERNAL_SERVER_ERROR.value(), String.format("cannot find %s in matched solr document", DSVERSION));
+		}
+		final Date date = Iterables.getLast(dsversion);
+
+		return DateFormatUtils.format(date, DatasourceFunctions.DATE_FORMAT);
+	}
+
+	public String getLastIndexingDate(final IndexDsInfo info) throws ApiException {
+		try {
+			final QueryResponse rsp = getIndexClient(info).query("oaftype:datasource", 1);
+			final SolrDocument doc = Iterables.getFirst(rsp.getResults(), null);
+			final String dsversion = doc.get("__dsversion").toString();
+			return StringUtils.substringBefore(dsversion, "T");
+		} catch (CloudIndexClientException e) {
+			throw new ApiException(HttpStatus.INTERNAL_SERVER_ERROR.value(), "Error querying index DS profile: " + info, e);
+		}
+	}
+
+	private synchronized CloudIndexClient getIndexClient(final IndexDsInfo info) throws CloudIndexClientException {
+		if (!indexClientMap.containsKey(info.getColl())) {
+			indexClientMap.put(info.getColl(), CloudIndexClientFactory.newIndexClient(info.getIndexBaseUrl(), info.getColl(), false));
+		}
+		return indexClientMap.get(info.getColl());
+	}
+
+}
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/repository/ActivationTermRepository.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/repository/ActivationTermRepository.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/repository/ActivationTermRepository.java	(revision 48492)
@@ -0,0 +1,13 @@
+package eu.dnetlib.openaire.exporter.datasource.repository;
+
+import eu.dnetlib.openaire.exporter.model.datasource.db.ActivationTerm;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+/**
+ * Created by claudio on 19/04/2017.
+ */
+@Repository
+public interface ActivationTermRepository extends JpaRepository<ActivationTerm, String> {
+
+}
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/test/resources/eu/dnetlib/openaire/exporter/MSES-project.xml
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/test/resources/eu/dnetlib/openaire/exporter/MSES-project.xml	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/test/resources/eu/dnetlib/openaire/exporter/MSES-project.xml	(revision 48492)
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ROW>
+	<FIELD name="funder">MSES</FIELD>
+	<FIELD name="end_date">2009-12-31</FIELD>
+	<FIELD name="grant_agreement_number">001-0000000-3177</FIELD>
+	<FIELD name="title">Residence time of bacteria Escherichia coli in seawater and marine organisms</FIELD>
+	<FIELD name="acronym" isNull="true"/>
+	<FIELD name="fundingpathid">irb_hr______::MSES::fundingStream</FIELD>
+	<FIELD name="jurisdiction">HR</FIELD>
+	<FIELD name="start_date">2007-01-01</FIELD>
+</ROW>
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/test/resources/eu/dnetlib/openaire/exporter/WT-project.xml
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/test/resources/eu/dnetlib/openaire/exporter/WT-project.xml	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/test/resources/eu/dnetlib/openaire/exporter/WT-project.xml	(revision 48492)
@@ -0,0 +1,11 @@
+<ROW>
+	<FIELD name="funder">WT</FIELD>
+	<FIELD name="end_date">2013-07-29</FIELD>
+	<FIELD name="grant_agreement_number">098241</FIELD>
+	<FIELD name="title">EYEDIO DIGI - DEVELOPMENT OF AN INNOVATIVE, AFFORDABLE, EASY TO USE, HANDHELD RETINAL IMAGING PRODUCT FOR THE DIAGNOSIS OF DIABETIC RETINOPATHY.</FIELD>
+	<FIELD name="acronym"></FIELD>
+	<FIELD name="fundingpathid">wt__________::WT::Immunology and Infectious Disease</FIELD>
+	<FIELD name="start_date">2012-01-30</FIELD>
+	<FIELD name="jurisdiction"/>
+	<FIELD name="description">description of the funding path</FIELD>
+</ROW> 
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/project/ProjectsController.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/project/ProjectsController.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/project/ProjectsController.java	(revision 48492)
@@ -0,0 +1,212 @@
+package eu.dnetlib.openaire.exporter.project;
+
+import java.io.BufferedOutputStream;
+import java.io.IOException;
+import java.sql.SQLException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Map;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.google.common.xml.XmlEscapers;
+import eu.dnetlib.OpenaireExporterConfig;
+import eu.dnetlib.OpenaireExporterConfig.Project;
+import eu.dnetlib.common.rmi.DNetRestDocumentation;
+import org.antlr.stringtemplate.StringTemplate;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.io.Resource;
+import org.springframework.http.HttpStatus;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.*;
+
+@Controller
+@DNetRestDocumentation
+public class ProjectsController {
+
+	private static final Log log = LogFactory.getLog(ProjectsController.class); // NOPMD by marko on 11/24/08 5:02 PM
+
+	public final static String UTF8 = "UTF-8";
+
+	@Autowired
+	private OpenaireExporterConfig config;
+
+	@Autowired
+	private JdbcApiDao dao;
+
+	@Autowired
+	private ProjectQueryParamsFactory projectQueryParamsFactory;
+
+	@RequestMapping(value = "/openaire/export/**/project/dspace.do", method = RequestMethod.GET)
+	void processDspace(final HttpServletRequest request, final ServletResponse response,
+			@RequestParam(value = "startFrom", required = false) final String startFrom,
+			@RequestParam(value = "startUntil", required = false) final String startUntil,
+			@RequestParam(value = "endFrom", required = false) final String endFrom,
+			@RequestParam(value = "endUntil", required = false) final String endUntil) throws Exception {
+
+		final Project conf = config.getProject();
+
+		final ProjectQueryParams params = projectQueryParamsFactory.generateParams(request, startFrom, startUntil, endFrom, endUntil);
+		final StringTemplate headSt = new StringTemplate(IOUtils.toString(conf.getDspaceHeadTemplate().getInputStream(), UTF8));
+
+		headSt.setAttribute("fundingProgramme", params.getFundingProgramme());
+
+		final StringTemplate tailSt = new StringTemplate(IOUtils.toString(conf.getDspaceTailTemplate().getInputStream(), UTF8));
+
+		response.setContentType("text/xml");
+		doProcess(response, params, headSt.toString(), conf.getDspaceTemplate(), tailSt.toString(), s -> XmlEscapers.xmlContentEscaper().escape(oneLiner(s)));
+	}
+
+	@RequestMapping(value = "/openaire/export/**/project/eprints.do", method = RequestMethod.GET)
+	void processEprints(final HttpServletRequest request, final ServletResponse response,
+			@RequestParam(value = "startFrom", required = false) final String startFrom,
+			@RequestParam(value = "startUntil", required = false) final String startUntil,
+			@RequestParam(value = "endFrom", required = false) final String endFrom,
+			@RequestParam(value = "endUntil", required = false) final String endUntil) throws Exception {
+
+		final ProjectQueryParams params = projectQueryParamsFactory.generateParams(request, startFrom, startUntil, endFrom, endUntil);
+		response.setContentType("text/html");
+		doProcess(response, params, null, config.getProject().getEprintsTemplate(), null, s -> oneLiner(s));
+	}
+
+	private String oneLiner(final String s) {
+		return StringUtils.isNotBlank(s) ? s.replaceAll("\\n", " ").trim() : "";
+	}
+
+	private void doProcess(
+			final ServletResponse response,
+			final ProjectQueryParams params,
+			final String head, final Resource projectTemplate, final String tail,
+			final ValueCleaner cleaner) throws IOException, SQLException {
+
+		final StringTemplate st = new StringTemplate(IOUtils.toString(projectTemplate.getInputStream(), UTF8));
+		dao.streamProjects(obtainQuery(params), new BufferedOutputStream(response.getOutputStream()), head, st, tail, cleaner);
+	}
+
+	@RequestMapping(value = "/openaire/export/project2tsv.do", method = RequestMethod.GET)
+	void processTsv(final HttpServletRequest request, final HttpServletResponse response,
+			@RequestParam(value = "funding", required = true) final String funding,
+			@RequestParam(value = "article293", required = false) final Boolean article293) throws Exception {
+
+		final String fundingPrefix = getFundingPrefix(funding, null);
+
+		final String date = new SimpleDateFormat("yyyyMMdd").format(new Date());
+		final String filename = "projects_" + funding + "_" + date + ".tsv";
+		response.setContentType("text/tab-separated-values");
+		response.setHeader("Content-Disposition", "attachment; filename=\"" + filename + ".zip\"");
+
+		dao.processTsvRequest(response.getOutputStream(), article293, fundingPrefix, filename);
+	}
+
+	@RequestMapping(value = "/openaire/export/streamProjectDetails.do", method = RequestMethod.GET)
+	void streamProjectDetails(final HttpServletResponse response,
+			@RequestParam(value = "format", required = true) final String format,
+			@RequestParam(value = "compress", required = false) final Boolean compress) throws IOException, SQLException {
+
+		if (compress != null && compress) {
+			response.setHeader("Content-Encoding", "gzip");
+		}
+		switch (format) {
+			case "csv":
+				response.setContentType("text/csv");
+				break;
+			case "json":
+				response.setContentType("text/plain");
+				break;
+			default: throw new IllegalArgumentException("unsupported format: " + format);
+		}
+
+		dao.processProjectDetails(response.getOutputStream(), format, compress);
+	}
+
+	@ExceptionHandler({Exception.class, Throwable.class})
+	@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
+	public @ResponseBody ErrorMessage handleSqlException(final Exception e) {
+		log.debug(e.getMessage(), e);
+		if (StringUtils.containsIgnoreCase(ExceptionUtils.getRootCauseMessage(e), "Broken pipe")) {
+			return null;        //socket is closed, cannot return any response
+		} else {
+			return new ErrorMessage(e);
+		}
+	}
+
+	public class ErrorMessage {
+
+		private final String message;
+		private final String stacktrace;
+
+		public ErrorMessage(final Exception e) {
+			this(e.getMessage(), ExceptionUtils.getStackTrace(e));
+		}
+
+		public ErrorMessage(final String message, final String stacktrace) {
+			this.message = message;
+			this.stacktrace = stacktrace;
+		}
+
+		public String getMessage() {
+			return this.message;
+		}
+
+		public String getStacktrace() {
+			return this.stacktrace;
+		}
+	}
+
+	/**
+	 * Creates the query on the fundingProgramme specified in the given parameters.
+	 *
+	 * @param params
+	 *            request parameters
+	 * @return the query string
+	 * @throws IllegalArgumentException
+	 *             if the funding program is not recognized
+	 * @throws IOException
+	 *             if there are problem loading the query temlate
+	 * @throws IllegalArgumentException
+	 *             if the funding program is not recognized
+	 */
+	protected String obtainQuery(final ProjectQueryParams params) throws IllegalArgumentException, IOException {
+		String funding = params.getFundingProgramme();
+		String suffix = params.getFundingPath();
+
+		final StringTemplate st = new StringTemplate(IOUtils.toString(config.getProject().getProjectsFundingQueryTemplate().getInputStream(), UTF8));
+		st.setAttribute("fundingprefix", getFundingPrefix(funding, suffix));
+		String theQuery = setDateParameters(st.toString(), params);
+		log.debug("Generated query: " + theQuery);
+		return theQuery;
+	}
+
+	private String getFundingPrefix(final String funding, final String suffix) {
+		final Map<String, String> fundingIds = dao.readFundingpathIds();
+		if (!fundingIds.containsKey(funding.toUpperCase())) {
+			throw new IllegalArgumentException("invalid funding " + funding);
+		}
+		String fundingPrefix = fundingIds.get(funding.toUpperCase());
+		return StringUtils.isBlank(suffix) ? fundingPrefix : fundingPrefix + "::" + suffix.toUpperCase();
+	}
+
+	private String setDateParameters(final String query, final ProjectQueryParams params) {
+		String queryWithDates = query;
+		if (params.getStartFrom() != null) {
+			queryWithDates += " AND startdate >= '" + params.getStartFrom() + "'";
+		}
+		if (params.getStartUntil() != null) {
+			queryWithDates += " AND startdate <= '" + params.getStartUntil() + "'";
+		}
+		if (params.getEndFrom() != null) {
+			queryWithDates += " AND enddate >= '" + params.getEndFrom() + "'";
+		}
+		if (params.getEndUntil() != null) {
+			queryWithDates += " AND enddate <= '" + params.getEndUntil() + "'";
+		}
+		return queryWithDates;
+	}
+
+}
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/project/ProjectDetails.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/project/ProjectDetails.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/project/ProjectDetails.java	(revision 48492)
@@ -0,0 +1,180 @@
+package eu.dnetlib.openaire.exporter.model.project;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.util.Arrays;
+import java.util.List;
+import javax.persistence.*;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.google.gson.Gson;
+import io.swagger.annotations.ApiModel;
+import org.hibernate.annotations.Type;
+import org.supercsv.cellprocessor.Optional;
+import org.supercsv.cellprocessor.ift.CellProcessor;
+import org.supercsv.cellprocessor.ift.StringCellProcessor;
+import org.supercsv.io.CsvBeanReader;
+import org.supercsv.io.CsvBeanWriter;
+import org.supercsv.io.ICsvBeanReader;
+import org.supercsv.io.ICsvBeanWriter;
+import org.supercsv.prefs.CsvPreference;
+import org.supercsv.util.CsvContext;
+
+/**
+ * Created by claudio on 04/07/2017.
+ */
+@Entity
+@Table(name = "project_details")
+@ApiModel(value = "Project details model", description = "provides project details")
+public class ProjectDetails {
+
+	@Transient
+	@JsonIgnore
+	private transient static final String[] FIELDS = Arrays.stream(ProjectDetails.class.getDeclaredFields())
+			.map(f -> f.getName())
+			.filter(s -> !s.equals("FIELDS"))
+			.filter(s -> !s.startsWith("optional"))
+			.toArray(String[]::new);
+
+	@Id
+	@Column(name = "projectid")
+	private String projectId;
+	private String acronym;
+	private String code;
+
+	@Transient
+	@JsonIgnore
+	private transient String optional1;
+
+	@Transient
+	@JsonIgnore
+	private transient String optional2;
+
+	private String jsonextrainfo;
+
+	@Type(type = "eu.dnetlib.openaire.exporter.model.GenericArrayUserType")
+	@Column(name = "fundingpath", columnDefinition = "text[]")
+	private String[] fundingPath;
+
+	public ProjectDetails() {
+	}
+
+	public String getProjectId() {
+		return projectId;
+	}
+
+	public void setProjectId(final String projectId) {
+		this.projectId = projectId;
+	}
+
+	public String getAcronym() {
+		return acronym;
+	}
+
+	public void setAcronym(final String acronym) {
+		this.acronym = acronym;
+	}
+
+	public String getCode() {
+		return code;
+	}
+
+	public void setCode(final String code) {
+		this.code = code;
+	}
+
+	public String getOptional1() {
+		return optional1;
+	}
+
+	public void setOptional1(final String optional1) {
+		this.optional1 = optional1;
+	}
+
+	public String getOptional2() {
+		return optional2;
+	}
+
+	public void setOptional2(final String optional2) {
+		this.optional2 = optional2;
+	}
+
+	public String getJsonextrainfo() {
+		return jsonextrainfo;
+	}
+
+	public void setJsonextrainfo(final String jsonextrainfo) {
+		this.jsonextrainfo = jsonextrainfo;
+	}
+
+	public String[] getFundingPath() {
+		return fundingPath;
+	}
+
+	public void setFundingPath(final String[] fundingPath) {
+		this.fundingPath = fundingPath;
+	}
+
+	public void setFundingPath(final List<String> fundingPath) {
+		if(fundingPath != null && !fundingPath.isEmpty()) {
+			this.fundingPath = fundingPath.toArray(new String[fundingPath.size()]);
+		}
+	}
+
+	public static ProjectDetails fromJson(final String json) {
+		return new Gson().fromJson(json, ProjectDetails.class);
+	}
+
+	public static ProjectDetails fromCSV(final String csv) throws IOException {
+		ICsvBeanReader beanReader = null;
+		try {
+			beanReader = new CsvBeanReader(new StringReader(csv), CsvPreference.STANDARD_PREFERENCE);
+			return beanReader.read(ProjectDetails.class, FIELDS, getProcessors(new StringCellProcessor() {
+				@Override
+				public Object execute(final Object value, final CsvContext context) {
+					return new Gson().fromJson(value.toString(), List.class);
+				}
+			}));
+		} finally {
+			if (beanReader != null) {
+				beanReader.close();
+			}
+		}
+	}
+
+	/**
+	 * Sets up the processors used for the examples. There are 10 CSV columns, so 10 processors are defined. Empty
+	 * columns are read as null (hence the NotNull() for mandatory columns).
+	 *
+	 * @return the cell processors
+	 */
+	private static CellProcessor[] getProcessors(final CellProcessor fundingPathProcessor) {
+		return new CellProcessor[] {
+				new Optional(), // projectId
+				new Optional(), // acronym
+				new Optional(), // code
+				new Optional(), // jsonextrainfo
+				fundingPathProcessor
+		};
+	}
+
+	public String asJson() {
+		return new Gson().toJson(this) + '\n';
+	}
+
+	public String asCSV() throws IOException {
+		final StringWriter sb = new StringWriter();
+		try (ICsvBeanWriter beanWriter = new CsvBeanWriter(sb, CsvPreference.STANDARD_PREFERENCE)) {
+			beanWriter.write(this, FIELDS, getProcessors(new StringCellProcessor() {
+				@Override
+				public Object execute(final Object value, final CsvContext context) {
+					return new Gson().toJson(value);
+				}
+			}));
+			beanWriter.flush();
+		}
+
+		return sb.toString();
+	}
+}
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/project/repository/ProjectDetailsRepository.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/project/repository/ProjectDetailsRepository.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/project/repository/ProjectDetailsRepository.java	(revision 48492)
@@ -0,0 +1,13 @@
+package eu.dnetlib.openaire.exporter.project.repository;
+
+import eu.dnetlib.openaire.exporter.model.project.ProjectDetails;
+import org.springframework.data.repository.PagingAndSortingRepository;
+import org.springframework.stereotype.Repository;
+
+/**
+ * Created by claudio on 04/07/2017.
+ */
+@Repository
+public interface ProjectDetailsRepository extends PagingAndSortingRepository<ProjectDetails, String> {
+
+}
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/project/ProjectApi.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/project/ProjectApi.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/project/ProjectApi.java	(revision 48492)
@@ -0,0 +1,152 @@
+package eu.dnetlib.openaire.exporter.model.project;
+
+import java.sql.Date;
+import java.util.ArrayList;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.google.common.base.Splitter;
+import com.google.common.collect.Lists;
+import io.swagger.annotations.ApiModel;
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ * Created by claudio on 20/09/16.
+ */
+@Entity
+@Table(name = "projects_api")
+@ApiModel(value = "Project api model", description = "Project api model used by DSpace and Eprints exporter")
+public class ProjectApi {
+
+	public static final String INFO_EU_REPO_GRANT_AGREEMENT = "info:eu-repo/grantAgreement/";
+
+	@Id
+	@JsonIgnore
+	private String id;
+
+	private String code;
+	private String acronym;
+	private String title;
+	private String funder;
+	private String jurisdiction;
+	private Date startdate;
+	private Date enddate;
+	private String fundingpathid;
+
+	public ProjectApi() { }
+
+	public String getIdnamespace() {
+		String res = INFO_EU_REPO_GRANT_AGREEMENT + getFunder()+"/";
+		final String fundingProgram = asFundingProgram(getFundingpathid());
+		if (StringUtils.isNotBlank(fundingProgram)) {
+			res += fundingProgram;
+		}
+		res += "/" + escapeCode(getCode());
+		if (StringUtils.isNotBlank(getJurisdiction())) {
+			res += "/" + getJurisdiction();
+		}
+		return res;
+	}
+
+	public String getListLabel() {
+		return String.format("for:value:component:_%s_project_id", asFunder(getFunder()));
+	}
+
+	private String asFunder(final String legalshortname) {
+		switch (legalshortname.toLowerCase()) {
+		case "ec":
+			return asFundingProgram(getFundingpathid()).toLowerCase();
+		default:
+			return legalshortname.toLowerCase();
+		}
+	}
+
+	private String escapeCode(final String code) {
+		return replaceSlash(code);
+	}
+
+	private String asFundingProgram(final String fundingpathid) {
+		final ArrayList<String> strings = Lists.newArrayList(Splitter.on("::").split(fundingpathid));
+		if(strings.size() <= 1) throw new IllegalStateException("Unexpected funding id: "+fundingpathid);
+		if(strings.size() == 2) return "";
+		else return replaceSlash(strings.get(2));
+	}
+
+	private String replaceSlash(final String s) {
+		return s.replaceAll("/", "%2F");
+	}
+
+	public String getId() {
+		return id;
+	}
+
+	public void setId(final String id) {
+		this.id = id;
+	}
+
+	public String getCode() {
+		return code;
+	}
+
+	public void setCode(final String code) {
+		this.code = code;
+	}
+
+	public String getAcronym() {
+		return acronym;
+	}
+
+	public void setAcronym(final String acronym) {
+		this.acronym = acronym;
+	}
+
+	public String getTitle() {
+		return title;
+	}
+
+	public void setTitle(final String title) {
+		this.title = title;
+	}
+
+	public String getFunder() {
+		return funder;
+	}
+
+	public void setFunder(final String funder) {
+		this.funder = funder;
+	}
+
+	public String getJurisdiction() {
+		return jurisdiction;
+	}
+
+	public void setJurisdiction(final String jurisdiction) {
+		this.jurisdiction = jurisdiction;
+	}
+
+	public Date getStartdate() {
+		return startdate;
+	}
+
+	public void setStartdate(final Date startdate) {
+		this.startdate = startdate;
+	}
+
+	public Date getEnddate() {
+		return enddate;
+	}
+
+	public void setEnddate(final Date enddate) {
+		this.enddate = enddate;
+	}
+
+	public String getFundingpathid() {
+		return fundingpathid;
+	}
+
+	public void setFundingpathid(final String fundingpathid) {
+		this.fundingpathid = fundingpathid;
+	}
+}
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/clients/ISLookupClient.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/clients/ISLookupClient.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/clients/ISLookupClient.java	(revision 48492)
@@ -0,0 +1,47 @@
+package eu.dnetlib.openaire.exporter.datasource.clients;
+
+import java.nio.charset.Charset;
+
+import eu.dnetlib.OpenaireExporterConfig;
+import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService;
+import eu.dnetlib.openaire.exporter.datasource.ApiException;
+import eu.dnetlib.openaire.exporter.datasource.clients.utils.IndexDsInfo;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.Cacheable;
+import org.springframework.http.HttpStatus;
+import org.springframework.stereotype.Component;
+
+/**
+ * Created by claudio on 20/10/2016.
+ */
+@Component
+public class ISLookupClient {
+
+	private static final Log log = LogFactory.getLog(ISLookupClient.class);
+
+	@Autowired
+	private OpenaireExporterConfig config;
+
+	@Autowired
+	private ISLookUpService isLookUpService;
+
+	@Cacheable("datasources-is-cache")
+	public IndexDsInfo calculateCurrentIndexDsInfo() throws ApiException {
+		log.warn("calculateCurrentIndexDsInfo(): not using cache");
+		try {
+			final String queryUrl = IOUtils.toString(config.getFindSolrIndexUrl().getInputStream(), Charset.defaultCharset());
+			final String queryDs = IOUtils.toString(config.getFindIndexDsInfo().getInputStream(), Charset.defaultCharset());
+
+			final String indexBaseUrl = isLookUpService.getResourceProfileByQuery(queryUrl);
+			final String[] arr = isLookUpService.getResourceProfileByQuery(queryDs).split("@@@");
+
+			return new IndexDsInfo(indexBaseUrl, arr[0].trim(), arr[1].trim(), arr[2].trim());
+		} catch (Exception e) {
+			throw new ApiException(HttpStatus.INTERNAL_SERVER_ERROR.value(), "Error querying information system");
+		}
+	}
+
+}
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/project/ProjectTsv.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/project/ProjectTsv.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/project/ProjectTsv.java	(revision 48492)
@@ -0,0 +1,220 @@
+package eu.dnetlib.openaire.exporter.model.project;
+
+import java.sql.Date;
+import java.util.List;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.google.common.collect.Lists;
+import io.swagger.annotations.ApiModel;
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ * Created by claudio on 05/07/2017.
+ */
+@Entity
+@Table(name = "projects_tsv")
+@ApiModel(value = "Project TSV model", description = "project TSV model description")
+public class ProjectTsv {
+
+	@Id
+	@JsonIgnore
+	private String id;
+	private String code;
+	private String acronym;
+	private String title;
+	@Column(name = "call_identifier")
+	private String callIdentifier;
+	private Date startdate;
+	private Date enddate;
+	@Column(name = "ec_sc39")
+	private Boolean ecSc39;
+	@Column(name = "oa_mandate_for_publications")
+	private Boolean oaMandateForPublications;
+	@Column(name = "oa_mandate_for_datasets")
+	private Boolean oaMandateForDatasets;
+	@JsonIgnore
+	private String fundingpathid;
+	private String description;
+	@Column(name = "legalname")
+	private String orgLegalname;
+	@Column(name = "country")
+	private String orgCountry;
+	@Column(name = "role")
+	private String orgRole;
+	private String firstname;
+	private String secondnames;
+	private String email;
+
+	public ProjectTsv() {}
+
+	public List<String> asList() {
+		return Lists.newArrayList(
+				clean(getCode()),
+				clean(getAcronym()),
+				clean(getTitle()),
+				clean(getCallIdentifier()),
+				clean(getStartdate() != null ? getStartdate().toString() : ""),
+				clean(getEnddate() != null ? getEnddate().toString() : ""),
+				clean(String.valueOf(isOaMandateForPublications())),
+				clean(String.valueOf(isOaMandateForDatasets())),
+				clean(getDescription()),
+				clean(getOrgLegalname()),
+				clean(getOrgCountry()),
+				clean(getOrgRole()),
+				clean(getFirstname()),
+				clean(getSecondnames()),
+				clean(getEmail()));
+	}
+
+	private String clean(final String s) {
+		return StringUtils.isNotBlank(s) ? "\"" + s.replaceAll("\\n|\\t|\\s+", " ").replace("\"","\"\"").trim() + "\"" : "";
+	}
+
+	public String getId() {
+		return id;
+	}
+
+	public void setId(final String id) {
+		this.id = id;
+	}
+
+	public String getCode() {
+		return code;
+	}
+
+	public void setCode(final String code) {
+		this.code = code;
+	}
+
+	public String getAcronym() {
+		return acronym;
+	}
+
+	public void setAcronym(final String acronym) {
+		this.acronym = acronym;
+	}
+
+	public String getTitle() {
+		return title;
+	}
+
+	public void setTitle(final String title) {
+		this.title = title;
+	}
+
+	public String getCallIdentifier() {
+		return callIdentifier;
+	}
+
+	public void setCallIdentifier(final String callIdentifier) {
+		this.callIdentifier = callIdentifier;
+	}
+
+	public Date getStartdate() {
+		return startdate;
+	}
+
+	public void setStartdate(final Date startdate) {
+		this.startdate = startdate;
+	}
+
+	public Date getEnddate() {
+		return enddate;
+	}
+
+	public void setEnddate(final Date enddate) {
+		this.enddate = enddate;
+	}
+
+	public Boolean isEcSc39() {
+		return ecSc39;
+	}
+
+	public void setEcSc39(final Boolean ecSc39) {
+		this.ecSc39 = ecSc39;
+	}
+
+	public Boolean isOaMandateForPublications() {
+		return oaMandateForPublications;
+	}
+
+	public void setOaMandateForPublications(final Boolean oaMandateForPublications) {
+		this.oaMandateForPublications = oaMandateForPublications;
+	}
+
+	public Boolean isOaMandateForDatasets() {
+		return oaMandateForDatasets;
+	}
+
+	public void setOaMandateForDatasets(final Boolean oaMandateForDatasets) {
+		this.oaMandateForDatasets = oaMandateForDatasets;
+	}
+
+	public String getFundingpathid() {
+		return fundingpathid;
+	}
+
+	public void setFundingpathid(final String fundingpathid) {
+		this.fundingpathid = fundingpathid;
+	}
+
+	public String getDescription() {
+		return description;
+	}
+
+	public void setDescription(final String description) {
+		this.description = description;
+	}
+
+	public String getOrgLegalname() {
+		return orgLegalname;
+	}
+
+	public void setOrgLegalname(final String orgLegalname) {
+		this.orgLegalname = orgLegalname;
+	}
+
+	public String getOrgCountry() {
+		return orgCountry;
+	}
+
+	public void setOrgCountry(final String orgCountry) {
+		this.orgCountry = orgCountry;
+	}
+
+	public String getOrgRole() {
+		return orgRole;
+	}
+
+	public void setOrgRole(final String orgRole) {
+		this.orgRole = orgRole;
+	}
+
+	public String getFirstname() {
+		return firstname;
+	}
+
+	public void setFirstname(final String firstname) {
+		this.firstname = firstname;
+	}
+
+	public String getSecondnames() {
+		return secondnames;
+	}
+
+	public void setSecondnames(final String secondnames) {
+		this.secondnames = secondnames;
+	}
+
+	public String getEmail() {
+		return email;
+	}
+
+	public void setEmail(final String email) {
+		this.email = email;
+	}
+}
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/clients/utils/IndexRecordsInfo.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/clients/utils/IndexRecordsInfo.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/clients/utils/IndexRecordsInfo.java	(revision 48492)
@@ -0,0 +1,32 @@
+package eu.dnetlib.openaire.exporter.datasource.clients.utils;
+
+/**
+ * Created by claudio on 21/10/2016.
+ */
+public class IndexRecordsInfo {
+
+	private long count;
+
+	private String date;
+
+	public IndexRecordsInfo(final long count, final String date) {
+		this.count = count;
+		this.date = date;
+	}
+
+	public long getCount() {
+		return count;
+	}
+
+	public void setCount(final long count) {
+		this.count = count;
+	}
+
+	public String getDate() {
+		return date;
+	}
+
+	public void setDate(final String date) {
+		this.date = date;
+	}
+}
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/clients/ClientResponse.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/clients/ClientResponse.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/clients/ClientResponse.java	(revision 48492)
@@ -0,0 +1,33 @@
+package eu.dnetlib.openaire.exporter.datasource.clients;
+
+import java.util.Queue;
+
+import eu.dnetlib.openaire.exporter.model.datasource.DatasourceResponse;
+
+/**
+ * Created by claudio on 30/11/2016.
+ */
+public class ClientResponse {
+
+	private DatasourceResponse datasourceResponse;
+
+	private Queue<Throwable> errors;
+
+	public DatasourceResponse getDatasourceResponse() {
+		return datasourceResponse;
+	}
+
+	public Queue<Throwable> getErrors() {
+		return errors;
+	}
+
+	public ClientResponse datasourceInfo(DatasourceResponse datasourceResponse) {
+		this.datasourceResponse = datasourceResponse;
+		return this;
+	}
+
+	public ClientResponse errors(Queue<Throwable> errors) {
+		this.errors = errors;
+		return this;
+	}
+}
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/project/Project.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/project/Project.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/project/Project.java	(revision 48492)
@@ -0,0 +1,264 @@
+package eu.dnetlib.openaire.exporter.model.project;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.google.common.base.Splitter;
+import com.google.common.collect.Lists;
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ * Created by claudio on 20/09/16.
+ */
+public class Project {
+
+	public static final String INFO_EU_REPO_GRANT_AGREEMENT = "info:eu-repo/grantAgreement/";
+	private String code;
+	private String acronym;
+	private String title;
+	private String callIdentifier;
+	private String startdate;
+	private String enddate;
+	private boolean oaMandateForPublications;
+	private boolean oaMandateForDatasets;
+	private String fundingpathid;
+	private String description;
+	private String funder;
+	private String jurisdiction;
+	private String orgLegalname;
+	private String orgCountry;
+	private String orgRole;
+	private String firstname;
+	private String secondnames;
+	private String email;
+
+	public Project() {
+	}
+
+	public String getIdnamespace() {
+		String res = INFO_EU_REPO_GRANT_AGREEMENT + getFunder()+"/";
+		final String fundingProgram = asFundingProgram(getFundingpathid());
+		if (StringUtils.isNotBlank(fundingProgram)) {
+			res += fundingProgram;
+		}
+		res += "/" + escapeCode(getCode());
+		if (StringUtils.isNotBlank(getJurisdiction())) {
+			res += "/" + getJurisdiction();
+		}
+		return res;
+	}
+
+	public String getListLabel() {
+		return String.format("for:value:component:_%s_project_id", asFunder(getFunder()));
+	}
+
+	private String asFunder(final String legalshortname) {
+		switch (legalshortname.toLowerCase()) {
+		case "ec":
+			return asFundingProgram(getFundingpathid()).toLowerCase();
+		default:
+			return legalshortname.toLowerCase();
+		}
+	}
+
+	public List<String> asList() {
+		return Lists.newArrayList(
+				clean(getCode()),
+				clean(getAcronym()),
+				clean(getTitle()),
+				clean(getCallIdentifier()),
+				clean(getStartdate()),
+				clean(getEnddate()),
+				String.valueOf(isOaMandateForPublications()),
+				String.valueOf(isOaMandateForDatasets()),
+				clean(getDescription()),
+				clean(getOrgLegalname()),
+				clean(getOrgCountry()),
+				clean(getOrgRole()),
+				clean(getFirstname()),
+				clean(getSecondnames()),
+				clean(getEmail()));
+	}
+
+	private String clean(final String s) {
+		return StringUtils.isNotBlank(s) ? "\"" + s.replaceAll("\\n|\\t|\\s+", " ").replace("\"","\"\"").trim() + "\"" : "";
+	}
+
+	private String escapeCode(final String code) {
+		return replaceSlash(code);
+	}
+
+	private String asFundingProgram(final String fundingpathid) {
+		final ArrayList<String> strings = Lists.newArrayList(Splitter.on("::").split(fundingpathid));
+		if(strings.size() <= 1) throw new IllegalStateException("Unexpected funding id: "+fundingpathid);
+		if(strings.size() == 2) return "";
+		else return replaceSlash(strings.get(2));
+	}
+
+	private String replaceSlash(final String s) {
+		return s.replaceAll("/", "%2F");
+	}
+
+	public String getCode() {
+		return code;
+	}
+
+	public Project setCode(final String code) {
+		this.code = code;
+		return this;
+	}
+
+	public String getAcronym() {
+		return acronym;
+	}
+
+	public Project setAcronym(final String acronym) {
+		this.acronym = acronym;
+		return this;
+	}
+
+	public String getTitle() {
+		return title;
+	}
+
+	public Project setTitle(final String title) {
+		this.title = title;
+		return this;
+	}
+
+	public String getCallIdentifier() {
+		return callIdentifier;
+	}
+
+	public Project setCallIdentifier(final String call_identifier) {
+		this.callIdentifier = call_identifier;
+		return this;
+	}
+
+	public String getStartdate() {
+		return startdate;
+	}
+
+	public Project setStartdate(final String startdate) {
+		this.startdate = startdate;
+		return this;
+	}
+
+	public String getEnddate() {
+		return enddate;
+	}
+
+	public Project setEnddate(final String enddate) {
+		this.enddate = enddate;
+		return this;
+	}
+
+	public boolean isOaMandateForPublications() {
+		return oaMandateForPublications;
+	}
+
+	public Project setOaMandateForPublications(final boolean oaMandateForPublications) {
+		this.oaMandateForPublications = oaMandateForPublications;
+		return this;
+	}
+
+	public boolean isOaMandateForDatasets() {
+		return oaMandateForDatasets;
+	}
+
+	public Project setOaMandateForDatasets(final boolean oaMandateForDatasets) {
+		this.oaMandateForDatasets = oaMandateForDatasets;
+		return this;
+	}
+
+
+	public String getFundingpathid() {
+		return fundingpathid;
+	}
+
+	public Project setFundingpathid(final String fundingpathid) {
+		this.fundingpathid = fundingpathid;
+		return this;
+	}
+
+	public String getDescription() {
+		return description;
+	}
+
+	public Project setDescription(final String description) {
+		this.description = description;
+		return this;
+	}
+
+	public String getJurisdiction() {
+		return jurisdiction;
+	}
+
+	public Project setJurisdiction(final String jurisdiction) {
+		this.jurisdiction = jurisdiction;
+		return this;
+	}
+
+	public String getOrgLegalname() {
+		return orgLegalname;
+	}
+
+	public Project setOrgLegalname(final String legalname) {
+		this.orgLegalname = legalname;
+		return this;
+	}
+
+	public String getOrgCountry() {
+		return orgCountry;
+	}
+
+	public Project setOrgCountry(final String country) {
+		this.orgCountry = country;
+		return this;
+	}
+
+	public String getOrgRole() {
+		return orgRole;
+	}
+
+	public Project setOrgRole(final String role) {
+		this.orgRole = role;
+		return this;
+	}
+
+	public String getFirstname() {
+		return firstname;
+	}
+
+	public Project setFirstname(final String firstname) {
+		this.firstname = firstname;
+		return this;
+	}
+
+	public String getSecondnames() {
+		return secondnames;
+	}
+
+	public Project setSecondnames(final String secondnames) {
+		this.secondnames = secondnames;
+		return this;
+	}
+
+	public String getEmail() {
+		return email;
+	}
+
+	public Project setEmail(final String email) {
+		this.email = email;
+		return this;
+	}
+
+	public String getFunder() {
+		return funder;
+	}
+
+	public Project setFunder(final String funder) {
+		this.funder = funder;
+		return this;
+	}
+}
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/ConverterTextArray.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/ConverterTextArray.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/ConverterTextArray.java	(revision 48492)
@@ -0,0 +1,59 @@
+package eu.dnetlib.openaire.exporter.model;
+
+import java.sql.Array;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+import javax.persistence.AttributeConverter;
+import javax.persistence.Converter;
+import javax.sql.DataSource;
+
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+
+/**
+ * Created by claudio on 05/07/2017.
+ */
+@Converter
+public class ConverterTextArray implements AttributeConverter<List<String>, Array>, ApplicationContextAware {
+
+	private ApplicationContext applicationContext;
+
+	@Override
+	public Array convertToDatabaseColumn(List<String> attribute) {
+
+		final Map<String, DataSource> datasources = applicationContext.getBeansOfType(DataSource.class);
+		DataSource source = datasources.values().stream().findFirst().get();
+
+		try {
+			Connection conn = source.getConnection();
+			Array array = conn.createArrayOf("text", attribute.toArray());
+			return  array;
+
+		} catch (SQLException e) {
+			e.printStackTrace();
+		}
+
+		return null;
+
+	}
+
+	@Override
+	public List<String> convertToEntityAttribute(Array dbData) {
+		try {
+			return Arrays.stream((Object[]) dbData.getArray()).map(d -> (String) d).collect(Collectors.toList());
+		} catch (SQLException e) {
+			e.printStackTrace();
+			return null;
+		}
+	}
+
+	@Override
+	public void setApplicationContext(final ApplicationContext applicationContext) throws BeansException {
+		this.applicationContext = applicationContext;
+	}
+}
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/project/ProjectQueryParamsFactory.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/project/ProjectQueryParamsFactory.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/project/ProjectQueryParamsFactory.java	(revision 48492)
@@ -0,0 +1,45 @@
+package eu.dnetlib.openaire.exporter.project;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.springframework.stereotype.Component;
+
+@Component
+public class ProjectQueryParamsFactory {
+
+	private static final String BASE_PATH = "/openaire/export/";
+	private static final String NO_FILTER = "ALL";
+
+	public ProjectQueryParams generateParams(final HttpServletRequest request,
+			final String startFrom,
+			final String startUntil,
+			final String endFrom,
+			final String endUntil) {
+		ProjectQueryParams params = new ProjectQueryParams();
+
+		String[] arr = request.getServletPath().replace(BASE_PATH, "").split("\\/");
+		if (arr.length != 5) throw new IllegalArgumentException("Invalid url");
+
+		params.setFundingProgramme(arr[0]);
+		String stream = NO_FILTER.equals(arr[1]) ? null : arr[1];
+		String substream = NO_FILTER.equals(arr[2]) ? null : arr[2];
+		if (substream == null) {
+			params.setFundingPath(stream);
+		} else {
+			if (stream == null) {
+				stream = "%";
+			}
+			params.setFundingPath(stream + "::" + substream);
+		}
+		// params.setSpecificProgramme(NO_FILTER.equals(arr[1]) ? null : arr[1]);
+		// params.setSubdivision(NO_FILTER.equals(arr[2]) ? null : arr[2]);
+		// NB: arr[3] should be 'projects'
+		// NB: arr[4] should be '[file].do'
+		params.setStartFrom(startFrom);
+		params.setStartUntil(startUntil);
+		params.setEndFrom(endFrom);
+		params.setEndUntil(endUntil);
+
+		return params;
+	}
+}
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/GenericArrayUserType.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/GenericArrayUserType.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/GenericArrayUserType.java	(revision 48492)
@@ -0,0 +1,100 @@
+package eu.dnetlib.openaire.exporter.model;
+
+import java.io.Serializable;
+import java.sql.*;
+
+import org.hibernate.HibernateException;
+import org.hibernate.engine.spi.SessionImplementor;
+import org.hibernate.usertype.UserType;
+
+/**
+ * Created by claudio on 05/07/2017.
+ */
+public class GenericArrayUserType<T extends Serializable> implements UserType {
+
+	protected static final int[] SQL_TYPES = { Types.ARRAY };
+
+	private  Class<T> typeParameterClass;
+
+	@Override
+	public Object assemble(Serializable cached, Object owner) throws HibernateException {
+		return this.deepCopy(cached);
+	}
+
+	@Override
+	public Object deepCopy(Object value) throws HibernateException {
+		return value;
+	}
+
+	@SuppressWarnings("unchecked")
+	@Override
+	public Serializable disassemble(Object value) throws HibernateException {
+		return (T) this.deepCopy(value);
+	}
+
+	@Override
+	public boolean equals(Object x, Object y) throws HibernateException {
+
+		if (x == null) {
+			return y == null;
+		}
+		return x.equals(y);
+	}
+
+	@Override
+	public int hashCode(Object x) throws HibernateException {
+		return x.hashCode();
+	}
+
+	@Override
+	public boolean isMutable() {
+		return true;
+	}
+
+	@Override
+	public Object nullSafeGet(ResultSet resultSet, String[] names, SessionImplementor session, Object owner)
+			throws HibernateException, SQLException {
+		if (resultSet.wasNull()) {
+			return null;
+		}
+		if (resultSet.getArray(names[0]) == null) {
+			return new Integer[0];
+		}
+
+		Array array = resultSet.getArray(names[0]);
+		@SuppressWarnings("unchecked")
+		T javaArray = (T) array.getArray();
+		return javaArray;
+	}
+
+	@Override
+	public void nullSafeSet(PreparedStatement statement, Object value, int index, SessionImplementor session)
+			throws HibernateException, SQLException {
+		Connection connection = statement.getConnection();
+		if (value == null) {
+			statement.setNull(index, SQL_TYPES[0]);
+		} else {
+			@SuppressWarnings("unchecked")
+			T castObject = (T) value;
+			Array array = connection.createArrayOf("integer", (Object[]) castObject);
+			statement.setArray(index, array);
+		}
+	}
+
+	@Override
+	public Object replace(Object original, Object target, Object owner) throws HibernateException {
+		return original;
+	}
+
+	@Override
+	public Class<T> returnedClass() {
+		return typeParameterClass;
+	}
+
+	@Override
+	public int[] sqlTypes() {
+		return new int[] { Types.ARRAY };
+	}
+
+
+}
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/clients/DatasourceDao.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/clients/DatasourceDao.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/clients/DatasourceDao.java	(revision 48492)
@@ -0,0 +1,377 @@
+package eu.dnetlib.openaire.exporter.datasource.clients;
+
+import java.util.List;
+import java.util.Queue;
+import java.util.concurrent.*;
+
+import javax.annotation.PostConstruct;
+
+import com.google.common.collect.Lists;
+import com.google.common.util.concurrent.*;
+import eu.dnetlib.OpenaireExporterConfig;
+import eu.dnetlib.openaire.exporter.datasource.ApiException;
+import eu.dnetlib.openaire.exporter.datasource.clients.utils.IndexDsInfo;
+import eu.dnetlib.openaire.exporter.datasource.clients.utils.IndexRecordsInfo;
+import eu.dnetlib.openaire.exporter.datasource.repository.*;
+import eu.dnetlib.openaire.exporter.model.datasource.AggregationInfo;
+import eu.dnetlib.openaire.exporter.model.datasource.AggregationStage;
+import eu.dnetlib.openaire.exporter.model.datasource.DatasourceResponse;
+import eu.dnetlib.openaire.exporter.model.datasource.db.*;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.http.HttpStatus;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Slice;
+import org.springframework.stereotype.Component;
+import org.springframework.util.concurrent.ListenableFuture;
+import org.springframework.util.concurrent.ListenableFutureCallback;
+
+/**
+ * Created by claudio on 20/10/2016.
+ */
+@Component
+public class DatasourceDao {
+
+	private static final Log log = LogFactory.getLog(DatasourceDao.class);
+
+	@Autowired
+	private OpenaireExporterConfig config;
+
+	@Autowired
+	private MongoLoggerClient mongoLoggerClient;
+
+	@Autowired
+	private DatasourceIndexClient datasourceIndexClient;
+
+	@Autowired
+	private DatasourceRepository dsRepository;
+
+	@Autowired
+	private SearchInterfaceRepository searchInterfaceRepository;
+
+	@Autowired
+	private CountryTermRepository countryTermRepository;
+
+	@Autowired
+	private TypologyTermRepository typologyTermRepository;
+
+	@Autowired
+	private ProtocolTermRepository protocolTermRepository;
+
+	@Autowired
+	private CompatibilityTermRepository compatibilityTermRepository;
+
+	@Autowired
+	private ActivationTermRepository activationTermRepository;
+
+	@Autowired
+	private ApiRepository apiRepository;
+
+	@Autowired
+	private ISLookupClient isLookupClient;
+
+	private ListeningExecutorService service;
+
+	@PostConstruct
+	public void init() {
+		service = MoreExecutors.listeningDecorator(
+				new ScheduledThreadPoolExecutor(config.getRequestWorkers(),
+						new ThreadFactoryBuilder().setNameFormat("datasource-info-retriever-%d").build()));
+	}
+
+	public List<String> listIds(final Pageable pageable) throws ApiException {
+		return dsRepository.findAll(pageable)
+				.map(d -> d.getId())
+				.getContent();
+	}
+
+	public List<DatasourceResponse> searchByName(final String name, final Pageable pageable) {
+
+		final List<DatasourceResponse> datasourceResponse = Lists.newArrayList();
+
+		final CountDownLatch outerLatch = new CountDownLatch(3);
+		final Queue<Throwable> errors = new ConcurrentLinkedQueue<>();
+
+		log.debug(String.format("search ds by name '%s'", name));
+		final ListenableFuture<Slice<Datasource>> c =
+				dsRepository.findByOfficialnameContainingOrEnglishnameContainingAllIgnoreCase(name, name, pageable);
+		c.addCallback(getSearchCallback(outerLatch, errors, datasourceResponse));
+
+		waitLatch(outerLatch, errors, config.getRequestTimeout());
+
+		return datasourceResponse;
+	}
+
+	public List<DatasourceResponse> searchByCountry(final String country, final Pageable pageable) {
+
+		final List<DatasourceResponse> datasourceResponse = Lists.newArrayList();
+
+		final CountDownLatch outerLatch = new CountDownLatch(3);
+		final Queue<Throwable> errors = new ConcurrentLinkedQueue<>();
+
+		log.debug(String.format("search ds by country '%s'", country));
+		//dsRepository.findByOrganizationsCountryIgnoreCase(country, pageable).addCallback(getSearchCallback(outerLatch, errors, datasourceResponse));
+
+		waitLatch(outerLatch, errors, config.getRequestTimeout());
+
+		return datasourceResponse;
+	}
+
+	public List<DatasourceResponse> searchByContactemail(final String email, final Pageable pageable) {
+		final List<DatasourceResponse> datasourceResponse = Lists.newArrayList();
+
+		final CountDownLatch outerLatch = new CountDownLatch(3);
+		final Queue<Throwable> errors = new ConcurrentLinkedQueue<>();
+
+		log.debug(String.format("search ds by email '%s'", email));
+		dsRepository.findByContactemailContainingAllIgnoreCase(email, pageable).addCallback(getSearchCallback(outerLatch, errors, datasourceResponse));
+
+		waitLatch(outerLatch, errors, config.getRequestTimeout());
+
+		return datasourceResponse;
+	}
+
+	private ListenableFutureCallback<Slice<Datasource>> getSearchCallback(final CountDownLatch outerLatch,
+			final Queue<Throwable> errors,
+			final List<DatasourceResponse> datasourceResponse) {
+
+		return new ListenableFutureCallback<Slice<Datasource>>() {
+
+			@Override
+			public void onSuccess(final Slice<Datasource> datasources) {
+				datasources.forEach(d -> {
+					final DatasourceResponse response = new DatasourceResponse();
+					response.setDatasource(d);
+					getAggregationHistory(d.getId(), outerLatch, errors, response);
+					getIndexDsInfo(d.getId(), outerLatch, errors, response);
+					datasourceResponse.add(response);
+				});
+				outerLatch.countDown();
+			}
+
+			@Override
+			public void onFailure(final Throwable e) {
+				errors.offer(e);
+				outerLatch.countDown();
+			}
+		};
+	}
+
+	public ClientResponse getInfo(final String dsId) {
+
+		final CountDownLatch outerLatch = new CountDownLatch(3);
+		final Queue<Throwable> errors = new ConcurrentLinkedQueue<>();
+		final DatasourceResponse datasourceResponse = new DatasourceResponse();
+
+		getAggregationHistory(dsId, outerLatch, errors, datasourceResponse);
+
+		dsRepository.findOneById(dsId).addCallback(new ListenableFutureCallback<Datasource>() {
+			@Override
+			public void onSuccess(final Datasource datasource) {
+				datasourceResponse.setDatasource(datasource);
+				outerLatch.countDown();
+			}
+
+			@Override
+			public void onFailure(final Throwable e) {
+				log.error(ExceptionUtils.getStackTrace(e));
+				errors.offer(e);
+				outerLatch.countDown();
+			}
+		});
+
+		getIndexDsInfo(dsId, outerLatch, errors, datasourceResponse);
+
+		waitLatch(outerLatch, errors, config.getRequestTimeout());
+
+		/*
+		if (!errors.isEmpty()) {
+			datasourceResponse.getResponseHeader().setError(Joiner.on("\n").skipNulls().join(errors.stream().map(e -> e.getMessage()).collect(Collectors.toList())));
+			log.error(Joiner.on("\n").skipNulls().join(errors.stream().map(e -> ExceptionUtils.getFullStackTrace(e)).collect(Collectors.toList())));
+		}
+		*/
+
+		return new ClientResponse().datasourceInfo(datasourceResponse).errors(errors);
+	}
+
+	public void setManaged(final String id, final boolean managed) {
+		log.info(String.format("setting managed = '%s' for ds '%s'", managed, id));
+		dsRepository.setManaged(id, managed);
+	}
+
+	public List<SearchInterfacesEntry> searchInterface(final String field, final String value) {
+		switch (field) {
+		case "__SEARCH__":
+			return searchInterfaceRepository
+					.findByRepoidContainingOrRepoNameContainingOrAlternativeNameContainingOrRepoPrefixContainingOrRepoOrganizationContainingAllIgnoreCase(
+							value, value, value, value, value);
+		case "country":
+			break;
+		case "type":
+			break;
+		case "protocol":
+			break;
+		case "compliance":
+			break;
+		case "active":
+			break;
+		default:
+			throw new IllegalArgumentException("");
+		}
+		return null;
+	}
+
+	public List<CountryTerm> browseCountries() {
+		return countryTermRepository.findAll();
+	}
+
+	public List<TypologyTerm> browseTypologies() {
+		return typologyTermRepository.findAll();
+	}
+
+	public List<ProtocolTerm> browseProtocols() {
+		return protocolTermRepository.findAll();
+	}
+
+	public List<CompatibilityTerm> browseCompatibility() {
+		return compatibilityTermRepository.findAll();
+	}
+
+	public List<ActivationTerm> browseActivation() {
+		return activationTermRepository.findAll();
+	}
+
+	public List<Api> getApi(final String dsId) {
+		return apiRepository.findByDatasource(dsId);
+	}
+
+	public void deleteApi(final String apiId) {
+		apiRepository.delete(apiId);
+		log.info(String.format("deleted api '%s'", apiId));
+	}
+
+	public void addApi(final Api api) {
+
+		if (StringUtils.isBlank(api.getId())) {
+			api.setId(ApiRepository.createId(api));
+			log.info(String.format("missing api id, created '%s'"));
+		}
+
+		apiRepository.save(api);
+	}
+
+	public boolean exist(final Datasource d) throws ApiException {
+		try {
+			return dsRepository.findOneById(d.getId()).get() != null;
+		} catch (Exception e) {
+			log.error(e);
+			throw new ApiException(HttpStatus.SC_INTERNAL_SERVER_ERROR, String.format("error retrieving datasource information '%s'", d.getId()), e);
+		}
+	}
+
+	public Datasource save(final Datasource d) {
+		log.info(String.format("saving datasource '%s'", d.getId()));
+		final Datasource datasource = dsRepository.save(d);
+		log.info(String.format("saved datasource '%s'", datasource.getId()));
+		return datasource;
+	}
+
+	public void updateOfficialName(final String dsId, final String officialname) {
+		dsRepository.setOfficialname(dsId, officialname);
+		log.info(String.format("updated datasource '%s' with officialname '%s'", dsId, officialname));
+	}
+
+	public void updateEnglishName(final String dsId, final String englishname) {
+		dsRepository.setEnglishname(dsId, englishname);
+		log.info(String.format("updated datasource '%s' with englishname '%s'", dsId, englishname));
+	}
+
+	public void updateLatitude(final String dsId, final Double latitude) {
+		dsRepository.setLatitude(dsId, latitude);
+		log.info(String.format("updated datasource '%s' with latitude '%s'", dsId, latitude));
+	}
+
+	public void updateLongitude(final String dsId, final Double longitude) {
+		dsRepository.setLongitude(dsId, longitude);
+		log.info(String.format("updated datasource '%s' with longitude '%s'", dsId, longitude));
+	}
+
+	private void getIndexDsInfo(final String dsId,
+			final CountDownLatch outerLatch,
+			final Queue<Throwable> errors,
+			final DatasourceResponse datasourceResponse) {
+		Futures.addCallback(
+				service.submit(() -> isLookupClient.calculateCurrentIndexDsInfo()),
+				new FutureCallback<IndexDsInfo>() {
+
+					public void onSuccess(final IndexDsInfo info) {
+
+						final CountDownLatch innerLatch = new CountDownLatch(1);
+
+						Futures.addCallback(
+								service.submit(() -> datasourceIndexClient.getIndexInfo(dsId, info)),
+								new FutureCallback<IndexRecordsInfo>() {
+									public void onSuccess(IndexRecordsInfo info) {
+										datasourceResponse.setIndexRecords(info.getCount()).setLastIndexingDate(info.getDate());
+										innerLatch.countDown();
+									}
+									public void onFailure(Throwable e) {
+										errors.offer(e);
+										innerLatch.countDown();
+									}
+						});
+						waitLatch(innerLatch, errors, config.getRequestTimeout());
+
+						outerLatch.countDown();
+					}
+
+					public void onFailure(final Throwable e) {
+						log.error(ExceptionUtils.getStackTrace(e));
+						errors.offer(e);
+						outerLatch.countDown();
+					}
+		});
+	}
+
+	private void getAggregationHistory(final String dsId,
+			final CountDownLatch outerLatch,
+			final Queue<Throwable> errors,
+			final DatasourceResponse datasourceResponse) {
+		Futures.addCallback(
+				service.submit(() -> mongoLoggerClient.getAggregationHistory(dsId)),
+				new FutureCallback<List<AggregationInfo>>() {
+					public void onSuccess(List<AggregationInfo> info) {
+						setAggregationHistory(datasourceResponse, info);
+						outerLatch.countDown();
+					}
+					public void onFailure(Throwable e) {
+						log.error(ExceptionUtils.getStackTrace(e));
+						errors.offer(e);
+						outerLatch.countDown();
+					}
+		});
+	}
+
+	private void setAggregationHistory(DatasourceResponse datasourceResponse, final List<AggregationInfo> info) {
+		datasourceResponse.setAggregationHistory(info);
+		if (!info.isEmpty()) {
+			datasourceResponse
+					.setLastCollection(info.stream().filter(a -> AggregationStage.COLLECT.equals(a.getAggregationStage())).findFirst().get())
+					.setLastTransformation(info.stream().filter(a -> AggregationStage.TRANSFORM.equals(a.getAggregationStage())).findFirst().get());
+		}
+	}
+
+	private void waitLatch(final CountDownLatch latch, final Queue<Throwable> errors, final int waitSeconds) {
+		try {
+			if (!latch.await(waitSeconds, TimeUnit.SECONDS)) {
+				errors.offer(new TimeoutException("Waiting for requests to complete has timed out."));
+			}
+		} catch (final InterruptedException e) {
+			errors.offer(e);
+		}
+	}
+
+}
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/clients/utils/IndexDsInfo.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/clients/utils/IndexDsInfo.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/clients/utils/IndexDsInfo.java	(revision 48492)
@@ -0,0 +1,36 @@
+package eu.dnetlib.openaire.exporter.datasource.clients.utils;
+
+/**
+ * Created by claudio on 20/10/2016.
+ */
+public class IndexDsInfo {
+
+	private final String indexBaseUrl;
+	private final String indexDsId;
+	private final String format;
+	private final String coll;
+
+	public IndexDsInfo(final String indexBaseUrl, final String indexDsId, final String format, final String coll) {
+		this.indexBaseUrl = indexBaseUrl;
+		this.indexDsId = indexDsId;
+		this.format = format;
+		this.coll = coll;
+	}
+
+	public String getIndexBaseUrl() {
+		return indexBaseUrl;
+	}
+
+	public String getIndexDsId() {
+		return indexDsId;
+	}
+
+	public String getFormat() {
+		return format;
+	}
+
+	public String getColl() {
+		return coll;
+	}
+
+}
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/CollectionMode.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/CollectionMode.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/CollectionMode.java	(revision 48492)
@@ -0,0 +1,13 @@
+package eu.dnetlib.openaire.exporter.model.datasource;
+
+import com.fasterxml.jackson.annotation.JsonAutoDetect;
+import io.swagger.annotations.ApiModel;
+
+/**
+ * Created by claudio on 12/09/16.
+ */
+@ApiModel
+@JsonAutoDetect
+public enum CollectionMode {
+	REFRESH, INCREMENTAL
+}
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/repository/CompatibilityTermRepository.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/repository/CompatibilityTermRepository.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/repository/CompatibilityTermRepository.java	(revision 48492)
@@ -0,0 +1,13 @@
+package eu.dnetlib.openaire.exporter.datasource.repository;
+
+import eu.dnetlib.openaire.exporter.model.datasource.db.CompatibilityTerm;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+/**
+ * Created by claudio on 19/04/2017.
+ */
+@Repository
+public interface CompatibilityTermRepository extends JpaRepository<CompatibilityTerm, String> {
+
+}
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/repository/ProtocolTermRepository.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/repository/ProtocolTermRepository.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/repository/ProtocolTermRepository.java	(revision 48492)
@@ -0,0 +1,13 @@
+package eu.dnetlib.openaire.exporter.datasource.repository;
+
+import eu.dnetlib.openaire.exporter.model.datasource.db.ProtocolTerm;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+/**
+ * Created by claudio on 19/04/2017.
+ */
+@Repository
+public interface ProtocolTermRepository extends JpaRepository<ProtocolTerm, String> {
+
+}
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/TransformationInfo.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/TransformationInfo.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/TransformationInfo.java	(revision 48492)
@@ -0,0 +1,13 @@
+package eu.dnetlib.openaire.exporter.model.datasource;
+
+import com.fasterxml.jackson.annotation.JsonAutoDetect;
+import io.swagger.annotations.ApiModel;
+
+/**
+ * Created by claudio on 29/11/2016.
+ */
+@ApiModel
+@JsonAutoDetect
+public class TransformationInfo extends AggregationInfo {
+
+}
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/DatasourcesApi.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/DatasourcesApi.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/DatasourcesApi.java	(revision 48492)
@@ -0,0 +1,114 @@
+package eu.dnetlib.openaire.exporter.datasource;
+
+import java.util.List;
+
+import eu.dnetlib.openaire.exporter.model.datasource.BrowseTerm;
+import eu.dnetlib.openaire.exporter.model.datasource.DatasourceResponse;
+import eu.dnetlib.openaire.exporter.model.datasource.Response;
+import eu.dnetlib.openaire.exporter.model.datasource.db.Api;
+import eu.dnetlib.openaire.exporter.model.datasource.db.Datasource;
+import eu.dnetlib.openaire.exporter.model.datasource.db.SearchInterfacesEntry;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+
+@io.swagger.annotations.Api(value = "datasources", description = "the datasource manager API")
+public interface DatasourcesApi {
+
+    @ApiOperation(value = "list identifiers", notes = "List the Datasource identifiers.", response = List.class)
+    @ApiResponses(value = { 
+        @ApiResponse(code = 200, message = "OK", response = String[].class),
+        @ApiResponse(code = 500, message = "unexpected error", response = Response.class) })
+    List<String> listIds(int page, int size) throws ApiException;
+
+    @ApiOperation(value = "get datasource by id", notes = "Returns Datasource details.", response = DatasourceResponse.class)
+    @ApiResponses(value = { 
+        @ApiResponse(code = 200, message = "OK", response = DatasourceResponse[].class),
+        @ApiResponse(code = 500, message = "unexpected error", response = Response.class) })
+    DatasourceResponse getDs(String id);
+
+    @ApiOperation(value = "search datasources by name", notes = "Returns list of Datasource details.", response = DatasourceResponse[].class)
+    @ApiResponses(value = {
+            @ApiResponse(code = 200, message = "OK", response = DatasourceResponse[].class),
+            @ApiResponse(code = 500, message = "unexpected error", response = Response.class) })
+    List<DatasourceResponse> searchByName(String name, int page, int size);
+
+    @ApiOperation(value = "search datasources by contact email", notes = "Returns list of Datasource details.", response = DatasourceResponse[].class)
+    @ApiResponses(value = {
+            @ApiResponse(code = 200, message = "OK", response = DatasourceResponse[].class),
+            @ApiResponse(code = 500, message = "unexpected error", response = Response.class) })
+    List<DatasourceResponse> searchByContactemail(String contactemail, int page, int size);
+
+    @ApiOperation(value = "search datasources by country", notes = "Returns list of Datasource details.", response = DatasourceResponse[].class)
+    @ApiResponses(value = {
+            @ApiResponse(code = 200, message = "OK", response = DatasourceResponse[].class),
+            @ApiResponse(code = 500, message = "unexpected error", response = Response.class) })
+    List<DatasourceResponse> searchByCountry(String country, int page, int size);
+
+    @ApiOperation(value = "search among datasource APIs", notes = "Returns Datasource Api details.", response = SearchInterfacesEntry[].class)
+    @ApiResponses(value = {
+            @ApiResponse(code = 200, message = "OK", response = SearchInterfacesEntry[].class),
+            @ApiResponse(code = 500, message = "unexpected error", response = Response.class) })
+    List<SearchInterfacesEntry> searchInterface(String field, String value);
+
+    @ApiOperation(value = "terms and count for the given field", notes = "Returns the list of BrowseTerms.", response = BrowseTerm[].class)
+    @ApiResponses(value = {
+            @ApiResponse(code = 200, message = "OK", response = BrowseTerm[].class),
+            @ApiResponse(code = 500, message = "unexpected error", response = Response.class) })
+    List<? extends BrowseTerm> browseField(String field) throws ApiException;
+
+    @ApiOperation(value = "get the list of API for a given datasource", notes = "Returns the list of API for a given datasource.", httpMethod = "GET", response = Api[].class)
+    @ApiResponses(value = {
+            @ApiResponse(code = 200, message = "OK", response = Api[].class),
+            @ApiResponse(code = 500, message = "unexpected error", response = Response.class) })
+    List<Api> getApi(String dsId) throws ApiException;
+
+    @ApiOperation(value = "delete an API", notes = "delete an API", httpMethod = "DELETE")
+    @ApiResponses(value = {
+            @ApiResponse(code = 200, message = "OK"),
+            @ApiResponse(code = 500, message = "unexpected error") })
+    void deleteApi(String apiId) throws ApiException;
+
+    @ApiOperation(value = "adds a new API to one Datasource", notes = "adds an API to one Datasource", httpMethod = "POST")
+    @ApiResponses(value = {
+            @ApiResponse(code = 200, message = "OK"),
+            @ApiResponse(code = 500, message = "unexpected error") })
+    void addApi(Api api) throws ApiException;
+
+    @ApiOperation(value = "set the managed status for a given datasource", notes = "set the managed status for a given datasource", httpMethod = "POST")
+    @ApiResponses(value = {
+            @ApiResponse(code = 200, message = "OK"),
+            @ApiResponse(code = 500, message = "unexpected error") })
+    void setManaged(String id, boolean managed);
+
+    @ApiOperation(value = "adds a new Datasource", notes = "adds a new Datasource", httpMethod = "POST")
+    @ApiResponses(value = {
+            @ApiResponse(code = 200, message = "OK"),
+            @ApiResponse(code = 500, message = "unexpected error") })
+    void saveDatasource(Datasource datasource) throws ApiException;
+
+    @ApiOperation(value = "updates a datasource official name", notes = "updates a datasource official name", httpMethod = "POST")
+    @ApiResponses(value = {
+            @ApiResponse(code = 200, message = "OK"),
+            @ApiResponse(code = 500, message = "unexpected error") })
+    void updateOfficialname(String dsId, String officialname) throws ApiException;
+
+    @ApiOperation(value = "updates a datasource english name", notes = "updates a datasource english name", httpMethod = "POST")
+    @ApiResponses(value = {
+            @ApiResponse(code = 200, message = "OK"),
+            @ApiResponse(code = 500, message = "unexpected error") })
+    void updateEnglishname(String dsId, String english) throws ApiException;
+
+    @ApiOperation(value = "updates a datasource latitude", notes = "updates a datasource latitude", httpMethod = "POST")
+    @ApiResponses(value = {
+            @ApiResponse(code = 200, message = "OK"),
+            @ApiResponse(code = 500, message = "unexpected error") })
+    void updateLatitude(String dsId, Double latitude) throws ApiException;
+
+    @ApiOperation(value = "updates a datasource longitude", notes = "updates a datasource longitude", httpMethod = "POST")
+    @ApiResponses(value = {
+            @ApiResponse(code = 200, message = "OK"),
+            @ApiResponse(code = 500, message = "unexpected error") })
+    void updateLongitude(String dsId, Double longitude) throws ApiException;
+
+}

Property changes on: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/DatasourcesApi.java
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/swagger/configuration/SwaggerDocumentationConfig.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/swagger/configuration/SwaggerDocumentationConfig.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/swagger/configuration/SwaggerDocumentationConfig.java	(revision 48492)
@@ -0,0 +1,52 @@
+package eu.dnetlib.swagger.configuration;
+
+import eu.dnetlib.OpenaireExporterConfig;
+import eu.dnetlib.OpenaireExporterConfig.Swagger;
+import eu.dnetlib.common.rmi.DNetRestDocumentation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import springfox.documentation.builders.ApiInfoBuilder;
+import springfox.documentation.builders.RequestHandlerSelectors;
+import springfox.documentation.service.ApiInfo;
+import springfox.documentation.service.Contact;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spring.web.plugins.Docket;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+
+@Configuration
+@EnableSwagger2
+public class SwaggerDocumentationConfig {
+
+	@Autowired
+	private OpenaireExporterConfig config;
+
+    @Bean
+    public Docket customImplementation() {
+        return new Docket(DocumentationType.SWAGGER_2)
+                .select()
+		            .apis(RequestHandlerSelectors.withClassAnnotation(DNetRestDocumentation.class))
+                    .build()
+                .directModelSubstitute(org.joda.time.LocalDate.class, java.sql.Date.class)
+                .directModelSubstitute(org.joda.time.DateTime.class, java.util.Date.class)
+                .apiInfo(apiInfo());
+    }
+
+	private ApiInfo apiInfo() {
+		final Swagger swag = config.getSwagger();
+		return new ApiInfoBuilder()
+				.title(swag.getApiTitle())
+				.description(swag.getApiDescription())
+				.license(swag.getApiLicense())
+				.licenseUrl(swag.getApiLicenseUrl())
+				.termsOfServiceUrl("")
+				.version("1.0.0")
+				.contact(new Contact(
+						swag.getApiContactName(),
+						swag.getApiContactUrl(),
+						swag.getApiContactEmail()))
+				.build();
+	}
+
+}
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/AggregationInfo.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/AggregationInfo.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/AggregationInfo.java	(revision 48492)
@@ -0,0 +1,47 @@
+package eu.dnetlib.openaire.exporter.model.datasource;
+
+import com.fasterxml.jackson.annotation.JsonAutoDetect;
+import io.swagger.annotations.ApiModel;
+
+/**
+ * Created by claudio on 12/09/16.
+ */
+@JsonAutoDetect
+@ApiModel(value = "AggregationInfo model", description = "describes an aggregation stage: collection or transformation")
+public abstract class AggregationInfo {
+
+	private int numberOfRecords;
+
+	private String date;
+
+	private AggregationStage aggregationStage;
+
+	public AggregationInfo() {
+	}
+
+	public int getNumberOfRecords() {
+		return numberOfRecords;
+	}
+
+	public void setNumberOfRecords(final int numberOfRecords) {
+		this.numberOfRecords = numberOfRecords;
+	}
+
+	public String getDate() {
+		return date;
+	}
+
+	public void setDate(final String date) {
+		this.date = date;
+	}
+
+	public AggregationStage getAggregationStage() {
+		return aggregationStage;
+	}
+
+	public void setAggregationStage(final AggregationStage aggregationStage) {
+		this.aggregationStage = aggregationStage;
+	}
+
+
+}
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/Utils.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/Utils.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/Utils.java	(revision 48492)
@@ -0,0 +1,18 @@
+package eu.dnetlib;
+
+import java.util.Iterator;
+import java.util.Spliterator;
+import java.util.Spliterators;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
+
+/**
+ * Created by claudio on 13/04/2017.
+ */
+public class Utils {
+
+	public static <T> Stream<T> stream(Iterator<T> iterator) {
+		return StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, Spliterator.ORDERED), false);
+	}
+
+}
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/resources/eu/dnetlib/openaire/exporter/st/projects_eprints.st
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/resources/eu/dnetlib/openaire/exporter/st/projects_eprints.st	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/resources/eu/dnetlib/openaire/exporter/st/projects_eprints.st	(revision 48492)
@@ -0,0 +1 @@
+$p.acronym$ - $p.title$&#9;<li style='border-right: solid 50px #30FF30' >$p.code$ - $p.acronym$ - $p.title$<ul><li id="$p.listLabel$">$p.idnamespace$</li></ul></li>
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/resources/application.properties
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/resources/application.properties	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/resources/application.properties	(revision 48492)
@@ -0,0 +1,58 @@
+# COMMON
+#server.contextPath=/api
+services.is.host=localhost
+services.is.port=8280
+services.is.baseurl=http://${services.is.host}:${services.is.port}/is/services
+
+spring.datasource.driverClassName=org.postgresql.Driver
+spring.jpa.database-platform=org.hibernate.dialect.PostgreSQL9Dialect
+spring.jpa.show-sql=true
+spring.jpa.hibernate.ddl-auto=validate
+
+openaire.exporter.isLookupUrl=${services.is.baseurl}/isLookUp
+openaire.exporter.requestWorkers        =   100
+openaire.exporter.requestTimeout        =   10
+
+# JDBC
+openaire.exporter.jdbc.url              =   jdbc:postgresql://localhost:5432/dnet_openaire
+openaire.exporter.jdbc.user             =   dnetapi
+openaire.exporter.jdbc.pwd              =   dnetPwd
+openaire.exporter.jdbc.minIdle          =   1
+openaire.exporter.jdbc.maxIdle          =   20
+openaire.exporter.jdbc.maxRows          =   100
+
+# PROJECTS
+openaire.exporter.project.dspaceHeadTemplate    =   classpath:/eu/dnetlib/openaire/exporter/st/projects_dspace_header.st
+openaire.exporter.project.dspaceTemplate        =   classpath:/eu/dnetlib/openaire/exporter/st/projects_dspace_project.st
+openaire.exporter.project.dspaceTailTemplate    =   classpath:/eu/dnetlib/openaire/exporter/st/projects_dspace_tail.st
+openaire.exporter.project.eprintsTemplate       =   classpath:/eu/dnetlib/openaire/exporter/st/projects_eprints.st
+openaire.exporter.project.tsvFields             =   Grant Agreement Number, Project Acronym, Project Title, Call ID, Start Date, End Date, OA Mandate on Publications, OA Mandate on Datasets, Discipline, Organization, Country, Role, Person Name, Person Second Names, Person Email
+openaire.exporter.project.projectsFundingQueryTemplate=classpath:/eu/dnetlib/openaire/exporter/sql/projects_fundings.sql.st
+openaire.exporter.project.gzipFlushSize         =   1000
+
+# DATSOURCES
+openaire.exporter.datasource.title		    =	Data Sources
+openaire.exporter.datasource.mongoHost      =   localhost
+openaire.exporter.datasource.mongoPort      =   27017
+openaire.exporter.datasource.mongoConnectionsPerHost = 10
+openaire.exporter.datasource.mongoCollectionName = wf_logs
+openaire.exporter.datasource.mongoDbName    =   dnet_logs
+openaire.exporter.datasource.mongoQueryLimit= 100
+openaire.exporter.findSolrIndexUrl          =   /eu/dnetlib/datasource/publisher/findSolrIndexUrl.xquery
+openaire.exporter.findIndexDsInfo           =   /eu/dnetlib/datasource/publisher/findIndexDsInfo.xquery
+
+
+# REST API CONFIGURATION
+openaire.exporter.swagger.apiTitle          =   OpenAIRE aggregator REST API
+openaire.exporter.swagger.apiDescription    =   The OpenAIRE data provision REST API allows developers to access the metadata information space of OpenAIRE programmatically.
+openaire.exporter.swagger.apiLicense        =   LICENSED UNDER GNU AFFERO GENERAL PUBLIC LICENSE.
+openaire.exporter.swagger.apiLicenseUrl     =   https://www.gnu.org/licenses/agpl-3.0.txt
+openaire.exporter.swagger.apiContacName     =   D-Net team
+openaire.exporter.swagger.apiContactUrl     =   http://www.d-net.research-infrastructures.eu
+openaire.exporter.swagger.apiContactEmail   =   dnet-team@isti.cnr.it
+
+# SWAGGER
+springfox.documentation.swagger.v2.path     =   /api-docs
+spring.jackson.date-format                  =   eu.dnetlib.swagger.configuration.RFC3339DateFormat
+spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS=false
+
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/db/CompatibilityTerm.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/db/CompatibilityTerm.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/db/CompatibilityTerm.java	(revision 48492)
@@ -0,0 +1,47 @@
+package eu.dnetlib.openaire.exporter.model.datasource.db;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+import com.fasterxml.jackson.annotation.JsonAutoDetect;
+import eu.dnetlib.openaire.exporter.model.datasource.BrowseTerm;
+import io.swagger.annotations.ApiModel;
+
+/**
+ * Created by claudio on 20/04/2017.
+ */
+@Entity
+@Table(name = "browse_compatibility")
+@ApiModel
+@JsonAutoDetect
+public class CompatibilityTerm implements Comparable<CompatibilityTerm>, BrowseTerm {
+
+	@Id
+	private String term;
+	private long total;
+
+	@Override
+	public String getTerm() {
+		return term;
+	}
+
+	public void setTerm(final String term) {
+		this.term = term;
+	}
+
+	@Override
+	public long getTotal() {
+		return total;
+	}
+
+	public void setTotal(final long total) {
+		this.total = total;
+	}
+
+	@Override
+	public int compareTo(final CompatibilityTerm o) {
+		return getTerm().compareTo(o.getTerm());
+	}
+
+}
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/repository/CountryTermRepository.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/repository/CountryTermRepository.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/repository/CountryTermRepository.java	(revision 48492)
@@ -0,0 +1,13 @@
+package eu.dnetlib.openaire.exporter.datasource.repository;
+
+import eu.dnetlib.openaire.exporter.model.datasource.db.CountryTerm;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+/**
+ * Created by claudio on 19/04/2017.
+ */
+@Repository
+public interface CountryTermRepository extends JpaRepository<CountryTerm, String> {
+
+}
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/repository/ApiRepository.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/repository/ApiRepository.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/repository/ApiRepository.java	(revision 48492)
@@ -0,0 +1,25 @@
+package eu.dnetlib.openaire.exporter.datasource.repository;
+
+import java.util.List;
+
+import eu.dnetlib.openaire.exporter.model.datasource.db.Api;
+import org.apache.commons.lang3.RandomStringUtils;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.stereotype.Repository;
+
+/**
+ * Created by claudio on 15/06/2017.
+ */
+@Repository
+public interface ApiRepository extends JpaRepository<Api, String> {
+
+	String ID_PREFIX = "api_________::";
+
+	static String createId(Api api) {
+		return ID_PREFIX + api.getDatasource() + "::" + RandomStringUtils.randomAlphanumeric(8);
+	}
+
+	@Query("select a from Api a where a.datasource = ?1")
+	List<Api> findByDatasource(String dsId);
+}
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/DatasourcesApiController.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/DatasourcesApiController.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/DatasourcesApiController.java	(revision 48492)
@@ -0,0 +1,155 @@
+package eu.dnetlib.openaire.exporter.datasource;
+
+import java.util.List;
+
+import eu.dnetlib.common.rmi.DNetRestDocumentation;
+
+import eu.dnetlib.openaire.exporter.datasource.clients.ClientResponse;
+import eu.dnetlib.openaire.exporter.datasource.clients.DatasourceDao;
+import eu.dnetlib.openaire.exporter.model.datasource.BrowseTerm;
+import eu.dnetlib.openaire.exporter.model.datasource.DatasourceResponse;
+import eu.dnetlib.openaire.exporter.model.datasource.db.Api;
+import eu.dnetlib.openaire.exporter.model.datasource.db.Datasource;
+import eu.dnetlib.openaire.exporter.model.datasource.db.SearchInterfacesEntry;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.http.HttpStatus;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.web.bind.annotation.*;
+
+@RestController
+@DNetRestDocumentation
+public class DatasourcesApiController implements DatasourcesApi {
+
+	private static final Log log = LogFactory.getLog(DatasourcesApiController.class);
+
+	@Autowired
+	private DatasourceDao dsDao;
+
+	@Override
+	@RequestMapping(value = "/ds/list/{page}/{size}", produces = { "application/json" }, method = RequestMethod.GET)
+    public List<String> listIds(@PathVariable int page, @PathVariable int size) throws ApiException {
+	    return dsDao.listIds(new PageRequest(page, size));
+    }
+
+    @Override
+    @RequestMapping(value = "/ds/get/{id}", produces = { "application/json" }, method = RequestMethod.GET)
+    public DatasourceResponse getDs(@PathVariable final String id) {
+
+	    if (log.isDebugEnabled()) {
+		    log.debug(String.format("getDatasourceInfo(dsId = %s)", id));
+	    }
+
+	    final ClientResponse clientResponse = dsDao.getInfo(id);
+    	return clientResponse.getDatasourceResponse();
+    }
+
+	@Override
+	@RequestMapping(value = "/ds/search/name/{page}/{size}", produces = { "application/json" }, method = RequestMethod.GET)
+	public List<DatasourceResponse> searchByName(
+			@RequestParam final String name, @PathVariable final int page, @PathVariable final int size) {
+		return dsDao.searchByName(name, new PageRequest(page, size));
+	}
+
+	@Override
+	@RequestMapping(value = "/ds/search/email/{page}/{size}", produces = { "application/json" }, method = RequestMethod.GET)
+	public List<DatasourceResponse> searchByContactemail(
+			@RequestParam final String contactemail, @PathVariable final int page, @PathVariable final int size) {
+		return dsDao.searchByContactemail(contactemail, new PageRequest(page, size));
+	}
+
+	@Override
+	@RequestMapping(value = "/ds/search/country/{page}/{size}", produces = { "application/json" }, method = RequestMethod.GET)
+	public List<DatasourceResponse> searchByCountry(
+			@RequestParam final String country, @PathVariable final int page, @PathVariable final int size) {
+		return dsDao.searchByCountry(country, new PageRequest(page, size));
+	}
+
+	@Override
+	@RequestMapping(value = "/api/search/{field}", produces = { "application/json" }, method = RequestMethod.GET)
+	public List<SearchInterfacesEntry> searchInterface(@PathVariable final String field, @RequestParam final String value) {
+		return dsDao.searchInterface(field, value);
+	}
+
+	@Override
+	@RequestMapping(value = "/api/browse/{field}", produces = { "application/json" }, method = RequestMethod.GET)
+	public List<? extends BrowseTerm> browseField(@PathVariable final String field) throws ApiException {
+		switch (field) {
+		case "country":
+			return dsDao.browseCountries();
+		case "typology":
+			return dsDao.browseTypologies();
+		case "protocol":
+			return dsDao.browseProtocols();
+		case "compatibility":
+			return dsDao.browseCompatibility();
+		case "activation":
+			return dsDao.browseActivation();
+		default:
+			throw new ApiException(HttpStatus.SC_BAD_REQUEST, String.format("unsupported browse field '%s'", field));
+		}
+	}
+
+	@Override
+	@RequestMapping(value = "/ds/api/{dsId}", produces = { "application/json" }, method = RequestMethod.GET)
+	public List<Api> getApi(@PathVariable final String dsId) throws ApiException {
+		return dsDao.getApi(dsId);
+	}
+
+	@Override
+	@RequestMapping(value = "/ds/api/{dsId}", method = RequestMethod.DELETE)
+	public void deleteApi(@PathVariable final String apiId) throws ApiException {
+		dsDao.deleteApi(apiId);
+	}
+
+	@Override
+	@RequestMapping(value = "/ds/api/add", method = RequestMethod.POST)
+	public void addApi(@RequestParam final Api api) throws ApiException {
+		if (StringUtils.isBlank(api.getDatasource())) {
+			throw new ApiException(HttpStatus.SC_BAD_REQUEST, "missing datasource id");
+		}
+		dsDao.addApi(api);
+	}
+
+	@Override
+	@RequestMapping(value = "/ds/manage", method = RequestMethod.POST)
+	public void setManaged(@RequestParam final String id, @RequestParam final boolean managed) {
+		dsDao.setManaged(id, managed);
+	}
+
+	@Override
+	@RequestMapping(value = "/ds/add", method = RequestMethod.POST)
+	public void saveDatasource(@RequestBody final Datasource datasource) throws ApiException {
+		if (dsDao.exist(datasource)) { //TODO further check that the DS doesn't have any API
+			throw new ApiException(HttpStatus.SC_CONFLICT, String.format("cannot already defined '%s'", datasource.getId()));
+		}
+		dsDao.save(datasource);
+	}
+
+	@Override
+	@RequestMapping(value = "/ds/update/officialname", method = RequestMethod.POST)
+	public void updateOfficialname(@RequestParam final String dsId, @RequestParam final String officialname) throws ApiException {
+		dsDao.updateOfficialName(dsId, officialname);
+	}
+
+	@Override
+	@RequestMapping(value = "/ds/update/englishname", method = RequestMethod.POST)
+	public void updateEnglishname(@RequestParam final String dsId, @RequestParam final String englishname) throws ApiException {
+		dsDao.updateEnglishName(dsId, englishname);
+	}
+
+	@Override
+	@RequestMapping(value = "/ds/update/latitude", method = RequestMethod.POST)
+	public void updateLatitude(final String dsId, final Double latitude) throws ApiException {
+		dsDao.updateLatitude(dsId, latitude);
+	}
+
+	@Override
+	@RequestMapping(value = "/ds/update/longitude", method = RequestMethod.POST)
+	public void updateLongitude(final String dsId, final Double longitude) throws ApiException {
+		dsDao.updateLongitude(dsId, longitude);
+	}
+
+}

Property changes on: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/DatasourcesApiController.java
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/repository/TypologyTermRepository.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/repository/TypologyTermRepository.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/repository/TypologyTermRepository.java	(revision 48492)
@@ -0,0 +1,13 @@
+package eu.dnetlib.openaire.exporter.datasource.repository;
+
+import eu.dnetlib.openaire.exporter.model.datasource.db.TypologyTerm;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+/**
+ * Created by claudio on 19/04/2017.
+ */
+@Repository
+public interface TypologyTermRepository extends JpaRepository<TypologyTerm, String> {
+
+}
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/OpenaireExporterConfig.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/OpenaireExporterConfig.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/OpenaireExporterConfig.java	(revision 48492)
@@ -0,0 +1,358 @@
+package eu.dnetlib;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.core.io.Resource;
+import org.springframework.stereotype.Component;
+
+/**
+ * Created by Alessia Bardi on 31/03/17.
+ *
+ * @author Alessia Bardi
+ */
+@Component
+@ConfigurationProperties(prefix = "openaire.exporter")
+public class OpenaireExporterConfig {
+
+	// ISLOOKUP
+	private ClassPathResource findSolrIndexUrl;
+	private ClassPathResource findIndexDsInfo;
+	private String isLookupUrl;
+	private int requestWorkers = 100;
+	private int requestTimeout = 10;
+
+	private Datasource datasource;
+	private Project project;
+	private Jdbc jdbc;
+	private Swagger swagger;
+
+	public static class Datasource {
+		// MONGODB
+		private String mongoHost;
+		private int mongoPort;
+		private String mongoCollectionName;
+		private String mongoDbName;
+		private int mongoConnectionsPerHost;
+		private int mongoQueryLimit;
+
+		public String getMongoHost() {
+			return mongoHost;
+		}
+
+		public void setMongoHost(final String mongoHost) {
+			this.mongoHost = mongoHost;
+		}
+
+		public int getMongoPort() {
+			return mongoPort;
+		}
+
+		public void setMongoPort(final int mongoPort) {
+			this.mongoPort = mongoPort;
+		}
+
+		public String getMongoCollectionName() {
+			return mongoCollectionName;
+		}
+
+		public void setMongoCollectionName(final String mongoCollectionName) {
+			this.mongoCollectionName = mongoCollectionName;
+		}
+
+		public String getMongoDbName() {
+			return mongoDbName;
+		}
+
+		public void setMongoDbName(final String mongoDbName) {
+			this.mongoDbName = mongoDbName;
+		}
+
+		public int getMongoConnectionsPerHost() {
+			return mongoConnectionsPerHost;
+		}
+
+		public void setMongoConnectionsPerHost(final int mongoConnectionsPerHost) {
+			this.mongoConnectionsPerHost = mongoConnectionsPerHost;
+		}
+
+		public int getMongoQueryLimit() {
+			return mongoQueryLimit;
+		}
+
+		public void setMongoQueryLimit(final int mongoQueryLimit) {
+			this.mongoQueryLimit = mongoQueryLimit;
+		}
+	}
+
+	public static class Project {
+
+		private int gzipFlushSize;
+		private String tsvFields;
+		private Resource projectsFundingQueryTemplate;
+		private Resource dspaceTemplate;
+		private Resource dspaceHeadTemplate;
+		private Resource dspaceTailTemplate;
+		private Resource eprintsTemplate;
+
+		public int getGzipFlushSize() {
+			return gzipFlushSize;
+		}
+
+		public void setGzipFlushSize(final int gzipFlushSize) {
+			this.gzipFlushSize = gzipFlushSize;
+		}
+
+		public String getTsvFields() {
+			return tsvFields;
+		}
+
+		public void setTsvFields(final String tsvFields) {
+			this.tsvFields = tsvFields;
+		}
+
+		public Resource getProjectsFundingQueryTemplate() {
+			return projectsFundingQueryTemplate;
+		}
+
+		public void setProjectsFundingQueryTemplate(final Resource projectsFundingQueryTemplate) {
+			this.projectsFundingQueryTemplate = projectsFundingQueryTemplate;
+		}
+
+		public Resource getDspaceTemplate() {
+			return dspaceTemplate;
+		}
+
+		public void setDspaceTemplate(final Resource dspaceTemplate) {
+			this.dspaceTemplate = dspaceTemplate;
+		}
+
+		public Resource getDspaceHeadTemplate() {
+			return dspaceHeadTemplate;
+		}
+
+		public void setDspaceHeadTemplate(final Resource dspaceHeadTemplate) {
+			this.dspaceHeadTemplate = dspaceHeadTemplate;
+		}
+
+		public Resource getDspaceTailTemplate() {
+			return dspaceTailTemplate;
+		}
+
+		public void setDspaceTailTemplate(final Resource dspaceTailTemplate) {
+			this.dspaceTailTemplate = dspaceTailTemplate;
+		}
+
+		public Resource getEprintsTemplate() {
+			return eprintsTemplate;
+		}
+
+		public void setEprintsTemplate(final Resource eprintsTemplate) {
+			this.eprintsTemplate = eprintsTemplate;
+		}
+	}
+
+	public static class Jdbc {
+
+		// JDBC
+		@Value("${spring.datasource.driverClassName}")
+		private String driverClassName;
+
+		private String url;
+		private String user;
+		private String pwd;
+		private int minIdle;
+		private int maxidle;
+		private int maxRows;
+
+		public String getDriverClassName() {
+			return driverClassName;
+		}
+
+		public String getUrl() {
+			return url;
+		}
+
+		public void setUrl(final String url) {
+			this.url = url;
+		}
+
+		public String getUser() {
+			return user;
+		}
+
+		public void setUser(final String user) {
+			this.user = user;
+		}
+
+		public String getPwd() {
+			return pwd;
+		}
+
+		public void setPwd(final String pwd) {
+			this.pwd = pwd;
+		}
+
+		public int getMinIdle() {
+			return minIdle;
+		}
+
+		public void setMinIdle(final int minIdle) {
+			this.minIdle = minIdle;
+		}
+
+		public int getMaxidle() {
+			return maxidle;
+		}
+
+		public void setMaxidle(final int maxidle) {
+			this.maxidle = maxidle;
+		}
+
+		public int getMaxRows() {
+			return maxRows;
+		}
+
+		public void setMaxRows(final int maxRows) {
+			this.maxRows = maxRows;
+		}
+	}
+
+	public static class Swagger {
+		private String apiTitle;
+		private String apiDescription;
+		private String apiLicense;
+		private String apiLicenseUrl;
+		private String apiContactName;
+		private String apiContactUrl;
+		private String apiContactEmail;
+
+		public String getApiTitle() {
+			return apiTitle;
+		}
+
+		public void setApiTitle(final String apiTitle) {
+			this.apiTitle = apiTitle;
+		}
+
+		public String getApiDescription() {
+			return apiDescription;
+		}
+
+		public void setApiDescription(final String apiDescription) {
+			this.apiDescription = apiDescription;
+		}
+
+		public String getApiLicense() {
+			return apiLicense;
+		}
+
+		public void setApiLicense(final String apiLicense) {
+			this.apiLicense = apiLicense;
+		}
+
+		public String getApiLicenseUrl() {
+			return apiLicenseUrl;
+		}
+
+		public void setApiLicenseUrl(final String apiLicenseUrl) {
+			this.apiLicenseUrl = apiLicenseUrl;
+		}
+
+		public String getApiContactName() {
+			return apiContactName;
+		}
+
+		public void setApiContactName(final String apiContactName) {
+			this.apiContactName = apiContactName;
+		}
+
+		public String getApiContactUrl() {
+			return apiContactUrl;
+		}
+
+		public void setApiContactUrl(final String apiContactUrl) {
+			this.apiContactUrl = apiContactUrl;
+		}
+
+		public String getApiContactEmail() {
+			return apiContactEmail;
+		}
+
+		public void setApiContactEmail(final String apiContactEmail) {
+			this.apiContactEmail = apiContactEmail;
+		}
+	}
+
+	public ClassPathResource getFindSolrIndexUrl() {
+		return findSolrIndexUrl;
+	}
+
+	public void setFindSolrIndexUrl(final ClassPathResource findSolrIndexUrl) {
+		this.findSolrIndexUrl = findSolrIndexUrl;
+	}
+
+	public ClassPathResource getFindIndexDsInfo() {
+		return findIndexDsInfo;
+	}
+
+	public void setFindIndexDsInfo(final ClassPathResource findIndexDsInfo) {
+		this.findIndexDsInfo = findIndexDsInfo;
+	}
+
+	public String getIsLookupUrl() {
+		return isLookupUrl;
+	}
+
+	public void setIsLookupUrl(final String isLookupUrl) {
+		this.isLookupUrl = isLookupUrl;
+	}
+
+	public int getRequestWorkers() {
+		return requestWorkers;
+	}
+
+	public void setRequestWorkers(final int requestWorkers) {
+		this.requestWorkers = requestWorkers;
+	}
+
+	public int getRequestTimeout() {
+		return requestTimeout;
+	}
+
+	public void setRequestTimeout(final int requestTimeout) {
+		this.requestTimeout = requestTimeout;
+	}
+
+	public Datasource getDatasource() {
+		return datasource;
+	}
+
+	public void setDatasource(final Datasource datasource) {
+		this.datasource = datasource;
+	}
+
+	public Project getProject() {
+		return project;
+	}
+
+	public void setProject(final Project project) {
+		this.project = project;
+	}
+
+	public Jdbc getJdbc() {
+		return jdbc;
+	}
+
+	public void setJdbc(final Jdbc jdbc) {
+		this.jdbc = jdbc;
+	}
+
+	public Swagger getSwagger() {
+		return swagger;
+	}
+
+	public void setSwagger(final Swagger swagger) {
+		this.swagger = swagger;
+	}
+}
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/NotFoundException.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/NotFoundException.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/NotFoundException.java	(revision 48492)
@@ -0,0 +1,9 @@
+package eu.dnetlib.openaire.exporter.datasource;
+
+public class NotFoundException extends ApiException {
+	private int code;
+	public NotFoundException (int code, String msg) {
+		super(code, msg);
+		this.code = code;
+	}
+}

Property changes on: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/NotFoundException.java
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/resources/logback-spring.xml
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/resources/logback-spring.xml	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/resources/logback-spring.xml	(revision 48492)
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration>
+	<include resource="org/springframework/boot/logging/logback/base.xml"/>
+	<logger name="org.springframework" level="INFO" additivity="false">
+		<appender-ref ref="CONSOLE" />
+	</logger>
+	<logger name="root" level="OFF" additivity="false">
+		<appender-ref ref="CONSOLE" />
+	</logger>
+	<logger name="eu.dnetlib" level="INFO" additivity="false">
+		<appender-ref ref="CONSOLE" />
+	</logger>
+	<logger name="eu.dnetlib.openaire.exporter" level="DEBUG" additivity="false">
+		<appender-ref ref="CONSOLE" />
+	</logger>
+</configuration>
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/resources/eu/dnetlib/openaire/exporter/st/projects_dspace_header.st
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/resources/eu/dnetlib/openaire/exporter/st/projects_dspace_header.st	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/resources/eu/dnetlib/openaire/exporter/st/projects_dspace_header.st	(revision 48492)
@@ -0,0 +1,4 @@
+<?xml version='1.0' encoding='UTF-8'?>
+
+<form-value-pairs>
+	<value-pairs value-pairs-name='$fundingProgramme$projects' dc-term='relation'>
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/DNetOpenaireExporterBeanFactory.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/DNetOpenaireExporterBeanFactory.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/DNetOpenaireExporterBeanFactory.java	(revision 48492)
@@ -0,0 +1,62 @@
+package eu.dnetlib;
+
+import com.mongodb.MongoClient;
+import com.mongodb.MongoClientOptions;
+import com.mongodb.ServerAddress;
+import eu.dnetlib.OpenaireExporterConfig.Jdbc;
+import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService;
+import org.apache.commons.dbcp2.BasicDataSource;
+import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * Created by claudio on 07/07/2017.
+ */
+@Configuration
+public class DNetOpenaireExporterBeanFactory {
+
+	@Autowired
+	private OpenaireExporterConfig config;
+
+	@Bean
+	public ISLookUpService getLookUpService() {
+		final JaxWsProxyFactoryBean jaxWsProxyFactory = new JaxWsProxyFactoryBean();
+		jaxWsProxyFactory.setServiceClass(ISLookUpService.class);
+		jaxWsProxyFactory.setAddress(config.getIsLookupUrl());
+		return (ISLookUpService) jaxWsProxyFactory.create();
+	}
+
+	@Bean
+	public BasicDataSource getProjectDataSource() {
+		final Jdbc jdbc = config.getJdbc();
+		return getDatasource(
+				jdbc.getDriverClassName(),
+				jdbc.getUrl(),
+				jdbc.getUser(),
+				jdbc.getPwd(),
+				jdbc.getMinIdle(),
+				jdbc.getMaxRows());
+	}
+
+	private BasicDataSource getDatasource(String driverClassName, String jdbcUrl, String jdbcUser, String jdbcPwd, int jdbcMinIdle, int jdbcMaxIdle) {
+		final BasicDataSource d = new BasicDataSource();
+		d.setDriverClassName(driverClassName);
+		d.setUrl(jdbcUrl);
+		d.setUsername(jdbcUser);
+		d.setPassword(jdbcPwd);
+		d.setMinIdle(jdbcMinIdle);
+		d.setMaxIdle(jdbcMaxIdle);
+		return d;
+	}
+
+	@Bean
+	public MongoClient getMongoClient() {
+		return new MongoClient(
+				new ServerAddress(config.getDatasource().getMongoHost(), config.getDatasource().getMongoPort()),
+				MongoClientOptions.builder().connectionsPerHost(config.getDatasource().getMongoConnectionsPerHost()).build());
+	}
+
+
+}
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/svn-prop.tmp~
===================================================================
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/db/ApiParamKey.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/db/ApiParamKey.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/db/ApiParamKey.java	(revision 48492)
@@ -0,0 +1,67 @@
+package eu.dnetlib.openaire.exporter.model.datasource.db;
+
+import java.io.Serializable;
+import java.util.Objects;
+import javax.persistence.Embeddable;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.google.common.collect.ComparisonChain;
+
+/**
+ * Created by claudio on 13/04/2017.
+ */
+@Embeddable
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class ApiParamKey implements Serializable {
+
+	@JsonIgnore
+	@ManyToOne
+	@JoinColumn(name = "api")
+	private Api api = null;
+
+	private String param;
+
+	public ApiParamKey() {}
+
+	public String getParam() {
+		return param;
+	}
+
+	public ApiParamKey setParam(final String param) {
+		this.param = param;
+		return this;
+	}
+
+	public Api getApi() {
+		return api;
+	}
+
+	public void setApi(final Api api) {
+		this.api = api;
+	}
+
+	@Override
+	public int hashCode() {
+		return Objects.hash(getParam(), getApi().getId());
+	}
+
+	@Override
+	public boolean equals(final Object o) {
+		if (this == o) {
+			return true;
+		}
+		if (o == null || getClass() != o.getClass()) {
+			return false;
+		}
+		ApiParamKey apk = (ApiParamKey) o;
+		return ComparisonChain.start()
+				.compare(getParam(), apk.getParam())
+				.compare(getApi(), apk.getApi())
+				.result() == 0;
+	}
+
+
+}
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/resources/eu/dnetlib/openaire/exporter/sql/projects_fundings.sql.st
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/resources/eu/dnetlib/openaire/exporter/sql/projects_fundings.sql.st	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/resources/eu/dnetlib/openaire/exporter/sql/projects_fundings.sql.st	(revision 48492)
@@ -0,0 +1,11 @@
+SELECT
+	funder,
+	jurisdiction,
+	fundingpathid,
+	acronym,
+	title,
+	code,
+	startdate,
+	enddate
+FROM projects_api
+WHERE fundingpathid like '$fundingprefix$%'
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/resources/eu/dnetlib/openaire/exporter/st/projects_dspace_tail.st
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/resources/eu/dnetlib/openaire/exporter/st/projects_dspace_tail.st	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/resources/eu/dnetlib/openaire/exporter/st/projects_dspace_tail.st	(revision 48492)
@@ -0,0 +1,2 @@
+ </value-pairs>
+</form-value-pairs>
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/db/Organization.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/db/Organization.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/db/Organization.java	(revision 48492)
@@ -0,0 +1,251 @@
+package eu.dnetlib.openaire.exporter.model.datasource.db;
+
+import java.sql.Date;
+import java.util.Set;
+
+import javax.persistence.*;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import io.swagger.annotations.ApiModel;
+
+/**
+ * Created by claudio on 13/04/2017.
+ */
+@Entity
+@Table(name = "dsm_organizations")
+//@JsonAutoDetect
+@ApiModel(value = "Organization model", description = "provides organization details")
+public class Organization {
+
+	@Id
+	private String id;
+	private String legalshortname;
+	private String legalname;
+	private String websiteurl;
+	private String logourl;
+
+	@Column(name = "ec_legalbody")
+	private Boolean eclegalbody;
+
+	@Column(name = "ec_legalperson")
+	private Boolean eclegalperson;
+
+	@Column(name = "ec_nonprofit")
+	private Boolean ecnonprofit;
+
+	@Column(name = "ec_researchorganization")
+	private Boolean ecresearchorganization;
+
+	@Column(name = "ec_highereducation")
+	private Boolean echighereducation;
+
+	@Column(name = "ec_internationalorganizationeurinterests")
+	private Boolean ecinternationalorganizationeurinterests;
+
+	@Column(name = "ec_internationalorganization")
+	private Boolean ecinternationalorganization;
+
+	@Column(name = "ec_enterprise")
+	private Boolean ecenterprise;
+
+	@Column(name = "ec_smevalidated")
+	private Boolean ecsmevalidated;
+
+	@Column(name = "ec_nutscode")
+	private Boolean ecnutscode;
+
+	private String country;
+	private String collectedfrom;
+
+	private Date dateofcollection;
+	private String provenanceaction;
+
+	@JsonIgnore
+	@ManyToMany(
+			cascade = { CascadeType.PERSIST, CascadeType.MERGE },
+			fetch = FetchType.EAGER,
+			mappedBy = "organizations")
+	private Set<Datasource> datasources;
+
+	public Organization() {}
+
+	public String getId() {
+		return id;
+	}
+
+	public String getLegalshortname() {
+		return legalshortname;
+	}
+
+	public String getLegalname() {
+		return legalname;
+	}
+
+	public String getWebsiteurl() {
+		return websiteurl;
+	}
+
+	public String getLogourl() {
+		return logourl;
+	}
+
+	public Boolean isEclegalbody() {
+		return eclegalbody;
+	}
+
+	public Boolean isEclegalperson() {
+		return eclegalperson;
+	}
+
+	public Boolean isEcnonprofit() {
+		return ecnonprofit;
+	}
+
+	public Boolean isEcresearchorganization() {
+		return ecresearchorganization;
+	}
+
+	public Boolean isEchighereducation() {
+		return echighereducation;
+	}
+
+	public Boolean isEcinternationalorganizationeurinterests() {
+		return ecinternationalorganizationeurinterests;
+	}
+
+	public Boolean isEcinternationalorganization() {
+		return ecinternationalorganization;
+	}
+
+	public Boolean isEcenterprise() {
+		return ecenterprise;
+	}
+
+	public Boolean isEcsmevalidated() {
+		return ecsmevalidated;
+	}
+
+	public Boolean isEcnutscode() {
+		return ecnutscode;
+	}
+
+	public String getCountry() {
+		return country;
+	}
+
+	public String getCollectedfrom() {
+		return collectedfrom;
+	}
+
+	public Date getDateofcollection() {
+		return dateofcollection;
+	}
+
+	public String getProvenanceaction() {
+		return provenanceaction;
+	}
+
+	public Organization setId(final String id) {
+		this.id = id;
+		return this;
+	}
+
+	public Organization setLegalshortname(final String legalshortname) {
+		this.legalshortname = legalshortname;
+		return this;
+	}
+
+	public Organization setLegalname(final String legalname) {
+		this.legalname = legalname;
+		return this;
+	}
+
+	public Organization setWebsiteurl(final String websiteurl) {
+		this.websiteurl = websiteurl;
+		return this;
+	}
+
+	public Organization setLogourl(final String logourl) {
+		this.logourl = logourl;
+		return this;
+	}
+
+	public Organization setEclegalbody(final Boolean eclegalbody) {
+		this.eclegalbody = eclegalbody;
+		return this;
+	}
+
+	public Organization setEclegalperson(final Boolean eclegalperson) {
+		this.eclegalperson = eclegalperson;
+		return this;
+	}
+
+	public Organization setEcnonprofit(final Boolean ecnonprofit) {
+		this.ecnonprofit = ecnonprofit;
+		return this;
+	}
+
+	public Organization setEcresearchorganization(final Boolean ecresearchorganization) {
+		this.ecresearchorganization = ecresearchorganization;
+		return this;
+	}
+
+	public Organization setEchighereducation(final Boolean echighereducation) {
+		this.echighereducation = echighereducation;
+		return this;
+	}
+
+	public Organization setEcinternationalorganizationeurinterests(final Boolean ecinternationalorganizationeurinterests) {
+		this.ecinternationalorganizationeurinterests = ecinternationalorganizationeurinterests;
+		return this;
+	}
+
+	public Organization setEcinternationalorganization(final Boolean ecinternationalorganization) {
+		this.ecinternationalorganization = ecinternationalorganization;
+		return this;
+	}
+
+	public Organization setEcenterprise(final Boolean ecenterprise) {
+		this.ecenterprise = ecenterprise;
+		return this;
+	}
+
+	public Organization setEcsmevalidated(final Boolean ecsmevalidated) {
+		this.ecsmevalidated = ecsmevalidated;
+		return this;
+	}
+
+	public Organization setEcnutscode(final Boolean ecnutscode) {
+		this.ecnutscode = ecnutscode;
+		return this;
+	}
+
+	public Organization setCountry(final String country) {
+		this.country = country;
+		return this;
+	}
+
+	public Organization setCollectedfrom(final String collectedfrom) {
+		this.collectedfrom = collectedfrom;
+		return this;
+	}
+
+	public Organization setDateofcollection(final Date dateofcollection) {
+		this.dateofcollection = dateofcollection;
+		return this;
+	}
+
+	public Organization setProvenanceaction(final String provenanceaction) {
+		this.provenanceaction = provenanceaction;
+		return this;
+	}
+
+	public Set<Datasource> getDatasources() {
+		return datasources;
+	}
+
+	public void setDatasources(final Set<Datasource> datasources) {
+		this.datasources = datasources;
+	}
+
+}
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/db/ActivationTerm.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/db/ActivationTerm.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/db/ActivationTerm.java	(revision 48492)
@@ -0,0 +1,47 @@
+package eu.dnetlib.openaire.exporter.model.datasource.db;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+import com.fasterxml.jackson.annotation.JsonAutoDetect;
+import eu.dnetlib.openaire.exporter.model.datasource.BrowseTerm;
+import io.swagger.annotations.ApiModel;
+
+/**
+ * Created by claudio on 20/04/2017.
+ */
+@Entity
+@Table(name = "browse_activation")
+@ApiModel
+@JsonAutoDetect
+public class ActivationTerm implements Comparable<ActivationTerm>, BrowseTerm {
+
+	@Id
+	private String term;
+	private long total;
+
+	@Override
+	public String getTerm() {
+		return term;
+	}
+
+	public void setTerm(final String term) {
+		this.term = term;
+	}
+
+	@Override
+	public long getTotal() {
+		return total;
+	}
+
+	public void setTotal(final long total) {
+		this.total = total;
+	}
+
+	@Override
+	public int compareTo(final ActivationTerm o) {
+		return getTerm().compareTo(o.getTerm());
+	}
+
+}
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/db/Identity.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/db/Identity.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/db/Identity.java	(revision 48492)
@@ -0,0 +1,44 @@
+package eu.dnetlib.openaire.exporter.model.datasource.db;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+import io.swagger.annotations.ApiModel;
+
+/**
+ * Created by claudio on 13/04/2017.
+ */
+
+@Entity
+@Table(name = "dsm_identities")
+//@JsonAutoDetect
+@ApiModel(value = "Identities model", description = "provides identity details")
+public class Identity {
+
+	@Id
+	private String pid;
+
+	private String issuertype;
+
+	public Identity() {}
+
+	public String getPid() {
+		return this.pid;
+	}
+
+	public String getIssuertype() {
+		return this.issuertype;
+	}
+
+	public Identity setPid(final String pid) {
+		this.pid = pid;
+		return this;
+	}
+
+	public Identity setIssuertype(final String issuertype) {
+		this.issuertype = issuertype;
+		return this;
+	}
+
+}
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/db/Apiparam.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/db/Apiparam.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/db/Apiparam.java	(revision 48492)
@@ -0,0 +1,53 @@
+package eu.dnetlib.openaire.exporter.model.datasource.db;
+
+import javax.persistence.EmbeddedId;
+import javax.persistence.Entity;
+import javax.persistence.Table;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import io.swagger.annotations.ApiModel;
+
+/**
+ * Created by claudio on 13/04/2017.
+ */
+@Entity
+@Table(name = "dsm_apiparams")
+@JsonIgnoreProperties(ignoreUnknown = true)
+@ApiModel(value = "Datasource Api params model", description = "describes the datasource api params")
+public class Apiparam {
+
+	@JsonIgnore
+	@EmbeddedId
+	private ApiParamKey id;
+
+	private String value;
+
+	public Apiparam() {}
+
+	public ApiParamKey getId() {
+		return id;
+	}
+
+	public Apiparam setId(final ApiParamKey id) {
+		this.id = id;
+		return this;
+	}
+
+	public String getValue() {
+		return value;
+	}
+
+	public void setValue(final String value) {
+		this.value = value;
+	}
+
+	public String getParam() {
+		return id.getParam();
+	}
+
+	public void setParam(final String param) {
+		getId().setParam(param);
+	}
+
+}
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/db/CountryTerm.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/db/CountryTerm.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/db/CountryTerm.java	(revision 48492)
@@ -0,0 +1,47 @@
+package eu.dnetlib.openaire.exporter.model.datasource.db;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+import com.fasterxml.jackson.annotation.JsonAutoDetect;
+import eu.dnetlib.openaire.exporter.model.datasource.BrowseTerm;
+import io.swagger.annotations.ApiModel;
+
+/**
+ * Created by claudio on 20/04/2017.
+ */
+@Entity
+@Table(name = "browse_countries")
+@ApiModel
+@JsonAutoDetect
+public class CountryTerm implements Comparable<CountryTerm>, BrowseTerm {
+
+	@Id
+	private String term;
+	private long total;
+
+	@Override
+	public String getTerm() {
+		return term;
+	}
+
+	public void setTerm(final String term) {
+		this.term = term;
+	}
+
+	@Override
+	public long getTotal() {
+		return total;
+	}
+
+	public void setTotal(final long total) {
+		this.total = total;
+	}
+
+	@Override
+	public int compareTo(final CountryTerm o) {
+		return getTerm().compareTo(o.getTerm());
+	}
+
+}
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/db/TypologyTerm.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/db/TypologyTerm.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/db/TypologyTerm.java	(revision 48492)
@@ -0,0 +1,47 @@
+package eu.dnetlib.openaire.exporter.model.datasource.db;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+import com.fasterxml.jackson.annotation.JsonAutoDetect;
+import eu.dnetlib.openaire.exporter.model.datasource.BrowseTerm;
+import io.swagger.annotations.ApiModel;
+
+/**
+ * Created by claudio on 20/04/2017.
+ */
+@Entity
+@Table(name = "browse_typologies")
+@ApiModel
+@JsonAutoDetect
+public class TypologyTerm implements Comparable<TypologyTerm>, BrowseTerm {
+
+	@Id
+	private String term;
+	private long total;
+
+	@Override
+	public String getTerm() {
+		return term;
+	}
+
+	public void setTerm(final String term) {
+		this.term = term;
+	}
+
+	@Override
+	public long getTotal() {
+		return total;
+	}
+
+	public void setTotal(final long total) {
+		this.total = total;
+	}
+
+	@Override
+	public int compareTo(final TypologyTerm o) {
+		return getTerm().compareTo(o.getTerm());
+	}
+
+}
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/BrowseTerm.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/BrowseTerm.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/BrowseTerm.java	(revision 48492)
@@ -0,0 +1,12 @@
+package eu.dnetlib.openaire.exporter.model.datasource;
+
+/**
+ * Created by claudio on 10/05/2017.
+ */
+public interface BrowseTerm {
+
+	public String getTerm();
+
+	public long getTotal();
+
+}
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/Response.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/Response.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/model/datasource/Response.java	(revision 48492)
@@ -0,0 +1,30 @@
+package eu.dnetlib.openaire.exporter.model.datasource;
+
+import com.fasterxml.jackson.annotation.JsonAutoDetect;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * Created by claudio on 01/12/2016.
+ */
+@JsonAutoDetect
+@ApiModel(value = "Api response model", description = "Api response model, provides a response header")
+public abstract class Response {
+
+	@ApiModelProperty(position = 0)
+	private Header responseHeader;
+
+	public Response() {
+		responseHeader =  new Header();
+	}
+
+	public Header getResponseHeader() {
+		return responseHeader;
+	}
+
+	public Response setResponseHeader(final Header responseHeader) {
+		this.responseHeader = responseHeader;
+		return this;
+	}
+
+}
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/project/repository/ProjectApiRepository.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/project/repository/ProjectApiRepository.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/project/repository/ProjectApiRepository.java	(revision 48492)
@@ -0,0 +1,16 @@
+package eu.dnetlib.openaire.exporter.project.repository;
+
+import eu.dnetlib.openaire.exporter.model.project.ProjectApi;
+import eu.dnetlib.openaire.exporter.model.project.ProjectTsv;
+import org.springframework.data.repository.PagingAndSortingRepository;
+import org.springframework.stereotype.Repository;
+
+/**
+ * Created by claudio on 06/07/2017.
+ */
+@Repository
+public interface ProjectApiRepository extends PagingAndSortingRepository<ProjectApi, Integer> {
+
+	Iterable<ProjectTsv> findByFundingpathidStartingWith(String fundingpathid);
+
+}
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/project/ProjectQueryParams.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/project/ProjectQueryParams.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/project/ProjectQueryParams.java	(revision 48492)
@@ -0,0 +1,85 @@
+package eu.dnetlib.openaire.exporter.project;
+
+import java.util.regex.Pattern;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+public class ProjectQueryParams {
+
+	private String fundingProgramme = null;
+	/** Whatever is following the fundingProgramme **/
+	private String fundingPath = null;
+
+	private String startFrom = null;
+	private String startUntil = null;
+	private String endFrom = null;
+	private String endUntil = null;
+
+	private static final Log log = LogFactory.getLog(ProjectQueryParams.class); // NOPMD by marko on 11/24/08 5:02 PM
+
+	public String getFundingProgramme() {
+		return fundingProgramme;
+	}
+
+	public void setFundingProgramme(final String fundingProgramme) {
+		this.fundingProgramme = verifyParam(fundingProgramme);
+	}
+
+	public String getFundingPath() {
+		return fundingPath;
+	}
+
+	public void setFundingPath(final String fundingPath) {
+		this.fundingPath = verifyParam(fundingPath);
+	}
+
+	public String getStartFrom() {
+		return startFrom;
+	}
+
+	public void setStartFrom(final String startFrom) {
+		this.startFrom = verifyDateParam(startFrom);
+	}
+
+	public String getStartUntil() {
+		return startUntil;
+	}
+
+	public void setStartUntil(final String startUntil) {
+		this.startUntil = verifyDateParam(startUntil);
+	}
+
+	public String getEndFrom() {
+		return endFrom;
+	}
+
+	public void setEndFrom(final String endFrom) {
+		this.endFrom = verifyDateParam(endFrom);
+	}
+
+	public String getEndUntil() {
+		return endUntil;
+	}
+
+	public void setEndUntil(final String endUntil) {
+		this.endUntil = verifyDateParam(endUntil);
+	}
+
+	protected String verifyParam(final String p) {
+		Pattern pattern = Pattern.compile("(\\w*(::|%| )*)*");
+		log.debug("TESTING SQL PARAM: " + p);
+		if ((p != null) && !pattern.matcher(p).matches()) throw new IllegalArgumentException("Parameter contains an invalid character");
+		log.debug("TEST OK");
+		return p;
+	}
+
+	protected String verifyDateParam(final String date){
+		Pattern pattern = Pattern.compile("\\d\\d\\d\\d-\\d\\d-\\d\\d");
+		log.debug("TESTING SQL DATE PARAM: " + date);
+		if ((date != null) && !pattern.matcher(date).matches()) throw new IllegalArgumentException("Parameter date contains an invalid character. Accepted pattern is "+pattern.toString());
+		log.debug("TEST OK");
+		return date;
+
+	}
+}
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/clients/MongoLoggerClient.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/clients/MongoLoggerClient.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/clients/MongoLoggerClient.java	(revision 48492)
@@ -0,0 +1,147 @@
+package eu.dnetlib.openaire.exporter.datasource.clients;
+
+import java.util.List;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+import com.google.common.primitives.Ints;
+import com.mongodb.BasicDBObject;
+import com.mongodb.MongoClient;
+import com.mongodb.client.MongoCollection;
+import com.mongodb.client.model.Projections;
+import eu.dnetlib.OpenaireExporterConfig;
+import eu.dnetlib.OpenaireExporterConfig.Datasource;
+import eu.dnetlib.Utils;
+import eu.dnetlib.miscutils.datetime.DateUtils;
+import eu.dnetlib.openaire.exporter.datasource.ApiException;
+import eu.dnetlib.openaire.exporter.datasource.clients.utils.DatasourceFunctions;
+import eu.dnetlib.openaire.exporter.model.datasource.*;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang.time.DateFormatUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.bson.Document;
+import org.bson.conversions.Bson;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.Cacheable;
+import org.springframework.stereotype.Component;
+
+import static com.mongodb.client.model.Filters.*;
+
+/**
+ * Created by claudio on 20/10/2016.
+ */
+@Component
+public class MongoLoggerClient {
+
+	private static final Log log = LogFactory.getLog(MongoLoggerClient.class);
+
+	@Autowired
+	private MongoClient datasourcePublisherMongoClient;
+
+	@Autowired
+	private OpenaireExporterConfig config;
+
+	private static Bson fields = getFields();
+
+	private static MongoCollection<Document> collection = null;
+
+	private Bson getQuery(final String dsId) {
+		return and(
+				eq("parentDatasourceId", dsId),
+				eq("system:profileFamily", "aggregator"),
+				eq("system:isCompletedSuccessfully", "true"),
+				regex("system:wfName", "(collect|transform)", "i"));
+	}
+
+	private synchronized MongoCollection<Document> getCollection() {
+		if (collection == null) {
+			log.info("inizializing mongodb collection ...");
+			final Datasource conf = config.getDatasource();
+			collection = datasourcePublisherMongoClient.getDatabase(conf.getMongoDbName()).getCollection(conf.getMongoCollectionName());
+		}
+		return collection;
+	}
+
+	@Cacheable("datasources-mongo-cache")
+	public List<AggregationInfo> getAggregationHistory(final String dsId) throws ApiException {
+
+		log.warn(String.format("getAggregationHistory(dsId = %s): not using cache", dsId));
+		final Datasource conf = config.getDatasource();
+		final Bson query = getQuery(dsId);
+		return Utils.stream(getCollection().find(query).projection(fields).limit(conf.getMongoQueryLimit()).sort(dbo("system:startHumanDate", -1)).iterator())
+				.map(getMapper())
+				.filter(ai -> ai.getNumberOfRecords() >= 0 && StringUtils.isNotBlank(ai.getDate()))
+				.collect(Collectors.toList());
+	}
+
+	private Function<Document, AggregationInfo> getMapper() {
+		return new Function<Document, AggregationInfo>() {
+
+			@Override
+			public AggregationInfo apply(final Document d) {
+
+				AggregationInfo info = null;
+				final AggregationStage stage = AggregationStage.parse(d.getString("system:wfName"));
+				switch (stage) {
+
+				case COLLECT:
+					CollectionInfo cInfo = new CollectionInfo();
+					cInfo.setAggregationStage(stage);
+					final String collectionMode = d.getString("system:node:SELECT_MODE:selection");
+					cInfo.setCollectionMode(StringUtils.isNotBlank(collectionMode) ? CollectionMode.valueOf(collectionMode) : null);
+					cInfo.setNumberOfRecords(getNumberOfRecords(d));
+					cInfo.setDate(getDate(d));
+					info = cInfo;
+					break;
+				case TRANSFORM:
+					TransformationInfo tInfo = new TransformationInfo();
+					tInfo.setAggregationStage(stage);
+					tInfo.setNumberOfRecords(getNumberOfRecords(d));
+					tInfo.setDate(getDate(d));
+					info = tInfo;
+					break;
+				}
+				return info;
+			}
+
+			private String getDate(final Document d) {
+				final String dateString = d.getString("system:startHumanDate");
+				if (StringUtils.isBlank(dateString)) {
+					return "";
+				}
+				return DateFormatUtils.format(new DateUtils().parse(dateString), DatasourceFunctions.DATE_FORMAT);
+			}
+
+			private Integer getNumberOfRecords(final Document d) {
+				final String sinkSize = d.getString("mainlog:sinkSize");
+				final String total = d.getString("mainlog:total");
+
+				if(StringUtils.isNotBlank(sinkSize)) {
+					return Ints.tryParse(sinkSize);
+				} else if(StringUtils.isNotBlank(total)) {
+					return Ints.tryParse(total);
+				} else {
+					return -1;
+				}
+			}
+		};
+	}
+
+	private static Bson getFields() {
+		return Projections.fields(
+				eq("system:wfName", 1),
+				eq("system:node:SELECT_MODE:selection", 1),
+				eq("mainlog:sinkSize", 1),
+				eq("mainlog:writeOps", 1),
+				eq("mainlog:total", 1),
+				eq("system:startHumanDate", 1),
+				eq("system:profileName", 1));
+	}
+
+	private static BasicDBObject dbo(final String key, final Object value) {
+		return new BasicDBObject(key, value);
+	}
+
+
+}
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/clients/utils/DatasourceParams.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/clients/utils/DatasourceParams.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/clients/utils/DatasourceParams.java	(revision 48492)
@@ -0,0 +1,5 @@
+package eu.dnetlib.openaire.exporter.datasource.clients.utils;
+
+public enum DatasourceParams {
+	baseUrl, metadata_identifier_path;
+}
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/repository/SearchInterfaceRepository.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/repository/SearchInterfaceRepository.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/repository/SearchInterfaceRepository.java	(revision 48492)
@@ -0,0 +1,26 @@
+package eu.dnetlib.openaire.exporter.datasource.repository;
+
+import java.util.List;
+
+import eu.dnetlib.openaire.exporter.model.datasource.db.SearchInterfacesEntry;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+/**
+ * Created by claudio on 12/04/2017.
+ */
+@Repository
+public interface SearchInterfaceRepository extends JpaRepository<SearchInterfacesEntry, String> {
+
+	SearchInterfacesEntry findOneById(String id);
+
+	List<SearchInterfacesEntry> findByRepoidContainingOrRepoNameContainingOrAlternativeNameContainingOrRepoPrefixContainingOrRepoOrganizationContainingAllIgnoreCase(
+			String repoId,
+			String repoName,
+			String alternativeName,
+			String repoPrefix,
+			String repoOrganization);
+
+}
+
+
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/repository/DatasourceRepository.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/repository/DatasourceRepository.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/repository/DatasourceRepository.java	(revision 48492)
@@ -0,0 +1,60 @@
+package eu.dnetlib.openaire.exporter.datasource.repository;
+
+import javax.transaction.Transactional;
+
+import eu.dnetlib.openaire.exporter.model.datasource.db.Datasource;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Slice;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Repository;
+import org.springframework.util.concurrent.ListenableFuture;
+
+/**
+ * Created by claudio on 12/04/2017.
+ */
+@Repository
+public interface DatasourceRepository extends JpaRepository<Datasource, String> {
+
+	@Async
+	ListenableFuture<Datasource> findOneById(String id);
+
+	@Async
+	ListenableFuture<Slice<Datasource>> findByOfficialnameContainingOrEnglishnameContainingAllIgnoreCase(String officialname,
+			String englishname,
+			Pageable pageable);
+
+	@Async
+	ListenableFuture<Slice<Datasource>> findByContactemailContainingAllIgnoreCase(String contactemail, Pageable pageable);
+
+	@Async
+	ListenableFuture<Slice<Datasource>> findByOrganizationsCountryIgnoreCase(String country, Pageable pageable);
+
+	@Modifying
+	@Transactional
+	@Query("update Datasource d set d.managed = ?2 where d.id = ?1")
+	void setManaged(String id, boolean managed);
+
+	@Modifying
+	@Transactional
+	@Query("update Datasource d set d.officialname = ?2 where d.id = ?1")
+	void setOfficialname(String id, String officialname);
+
+	@Modifying
+	@Transactional
+	@Query("update Datasource d set d.englishname = ?2 where d.id = ?1")
+	void setEnglishname(String id, String englishname);
+
+	@Modifying
+	@Transactional
+	@Query("update Datasource d set d.latitude = ?2 where d.id = ?1")
+	void setLatitude(String id, Double latitude);
+
+	@Modifying
+	@Transactional
+	@Query("update Datasource d set d.longitude = ?2 where d.id = ?1")
+	void setLongitude(String id, Double longitude);
+
+}
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/ApiException.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/ApiException.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/ApiException.java	(revision 48492)
@@ -0,0 +1,16 @@
+package eu.dnetlib.openaire.exporter.datasource;
+
+public class ApiException extends Exception {
+
+	private int code;
+
+	public ApiException (int code, String msg) {
+		super(msg);
+		this.code = code;
+	}
+
+	public ApiException (int code, String msg, Throwable e) {
+		super(msg, e);
+		this.code = code;
+	}
+}

Property changes on: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/openaire/exporter/datasource/ApiException.java
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/swagger/configuration/RFC3339DateFormat.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/swagger/configuration/RFC3339DateFormat.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/swagger/configuration/RFC3339DateFormat.java	(revision 48492)
@@ -0,0 +1,19 @@
+package eu.dnetlib.swagger.configuration;
+
+import java.text.FieldPosition;
+import java.util.Date;
+
+import com.fasterxml.jackson.databind.util.ISO8601DateFormat;
+import com.fasterxml.jackson.databind.util.ISO8601Utils;
+
+public class RFC3339DateFormat extends ISO8601DateFormat {
+
+  // Same as ISO8601DateFormat but serializing milliseconds.
+  @Override
+  public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition fieldPosition) {
+    String value = ISO8601Utils.format(date, true);
+    toAppendTo.append(value);
+    return toAppendTo;
+  }
+
+}
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/DNetOpenaireExporterApplication.java
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/DNetOpenaireExporterApplication.java	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/java/eu/dnetlib/DNetOpenaireExporterApplication.java	(revision 48492)
@@ -0,0 +1,46 @@
+package eu.dnetlib;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
+
+@RestController
+@SpringBootApplication
+public class DNetOpenaireExporterApplication {
+
+	private static final Log log = LogFactory.getLog(DNetOpenaireExporterApplication.class);
+
+	@Autowired
+	private List<RequestMappingHandlerMapping> handlerMappings;
+
+	@RequestMapping(value = { "/", "/docs" })
+	public void index(final HttpServletResponse response) throws IOException {
+		response.sendRedirect("swagger-ui.html");
+	}
+
+	@RequestMapping(value = "/endpointdoc", method = RequestMethod.GET)
+	public Set<String> show() {
+		return handlerMappings.stream()
+				.map(handler -> handler.getHandlerMethods().keySet())
+				.map(rmInfo -> rmInfo.toString())
+				.collect(Collectors.toSet());
+	}
+
+	public static void main(String[] args) throws Exception {
+		SpringApplication.run(DNetOpenaireExporterApplication.class, args);
+	}
+
+}
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/resources/eu/dnetlib/openaire/exporter/st/projects_dspace_project.st
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/resources/eu/dnetlib/openaire/exporter/st/projects_dspace_project.st	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/src/main/resources/eu/dnetlib/openaire/exporter/st/projects_dspace_project.st	(revision 48492)
@@ -0,0 +1,4 @@
+<pair>
+	<displayed-value>$p.code$ - $p.acronym$ - $p.title$</displayed-value>
+	<stored-value>$p.idnamespace$</stored-value>
+</pair>
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/dnet-openaire-exporter.iml
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/dnet-openaire-exporter.iml	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0/dnet-openaire-exporter.iml	(revision 48492)
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
+  <component name="FacetManager">
+    <facet type="Spring" name="Spring">
+      <configuration />
+    </facet>
+  </component>
+  <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
+    <output url="file://$MODULE_DIR$/target/classes" />
+    <output-test url="file://$MODULE_DIR$/target/test-classes" />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
+      <excludeFolder url="file://$MODULE_DIR$/target" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="library" name="Maven: eu.dnetlib:cnr-rmi-api:2.6.1" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.cxf:cxf-core:3.1.5" level="project" />
+    <orderEntry type="library" name="Maven: org.codehaus.woodstox:woodstox-core-asl:4.4.1" level="project" />
+    <orderEntry type="library" name="Maven: org.codehaus.woodstox:stax2-api:3.1.4" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.ws.xmlschema:xmlschema-core:2.2.1" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.cxf:cxf-rt-frontend-jaxws:3.1.5" level="project" />
+    <orderEntry type="library" name="Maven: xml-resolver:xml-resolver:1.2" level="project" />
+    <orderEntry type="library" name="Maven: org.ow2.asm:asm:5.0.4" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.cxf:cxf-rt-bindings-soap:3.1.5" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.cxf:cxf-rt-wsdl:3.1.5" level="project" />
+    <orderEntry type="library" name="Maven: wsdl4j:wsdl4j:1.6.3" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.cxf:cxf-rt-databinding-jaxb:3.1.5" level="project" />
+    <orderEntry type="library" name="Maven: com.sun.xml.bind:jaxb-impl:2.2.11" level="project" />
+    <orderEntry type="library" name="Maven: com.sun.xml.bind:jaxb-core:2.2.11" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.cxf:cxf-rt-bindings-xml:3.1.5" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.cxf:cxf-rt-frontend-simple:3.1.5" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.cxf:cxf-rt-ws-addr:3.1.5" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.cxf:cxf-rt-ws-policy:3.1.5" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.neethi:neethi:3.0.3" level="project" />
+    <orderEntry type="library" name="Maven: log4j:log4j:1.2.17" level="project" />
+    <orderEntry type="library" name="Maven: eu.dnetlib:cnr-service-common:2.1.6" level="project" />
+    <orderEntry type="library" name="Maven: org.quartz-scheduler:quartz:2.2.2" level="project" />
+    <orderEntry type="library" name="Maven: c3p0:c3p0:0.9.1.1" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-tx:4.3.7.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-beans:4.3.7.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: eu.dnetlib:cnr-misc-utils:1.0.4" level="project" />
+    <orderEntry type="library" name="Maven: commons-lang:commons-lang:2.6" level="project" />
+    <orderEntry type="library" name="Maven: jaxen:jaxen:1.1.6" level="project" />
+    <orderEntry type="library" name="Maven: saxonica:saxon:9.1.0.8" level="project" />
+    <orderEntry type="library" name="Maven: saxonica:saxon-dom:9.1.0.8" level="project" />
+    <orderEntry type="library" name="Maven: jgrapht:jgrapht:0.7.2" level="project" />
+    <orderEntry type="library" name="Maven: net.sf.ehcache:ehcache:2.10.3" level="project" />
+    <orderEntry type="library" name="Maven: eu.dnetlib:cnr-service-utils:1.0.2" level="project" />
+    <orderEntry type="library" name="Maven: apache:oro:2.0.8" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-context:4.3.7.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: eu.dnetlib:cnr-spring-utils:1.0.1" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-aop:4.3.7.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: jparsec:jparsec:2.0" level="project" />
+    <orderEntry type="library" name="Maven: runcc:runcc:0.7" level="project" />
+    <orderEntry type="module" module-name="dnet-openaireplus-mapping-utils" />
+    <orderEntry type="library" name="Maven: commons-codec:commons-codec:1.10" level="project" />
+    <orderEntry type="library" name="Maven: dom4j:dom4j:1.6.1" level="project" />
+    <orderEntry type="library" name="Maven: eu.dnetlib:dnet-openaire-data-protos:3.7.7" level="project" />
+    <orderEntry type="library" name="Maven: com.google.protobuf:protobuf-java:2.4.1" level="project" />
+    <orderEntry type="library" name="Maven: eu.dnetlib:dnet-pace-core:2.5.1" level="project" />
+    <orderEntry type="library" name="Maven: edu.cmu:secondstring:1.0.0" level="project" />
+    <orderEntry type="library" name="Maven: commons-collections:commons-collections:3.2.2" level="project" />
+    <orderEntry type="library" name="Maven: eu.dnetlib:dnet-index-solr-common:1.3.1" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.solr:solr-solrj:5.5.4" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.httpcomponents:httpclient:4.5.3" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.httpcomponents:httpcore:4.4.6" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.httpcomponents:httpmime:4.5.3" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.zookeeper:zookeeper:3.4.6" level="project" />
+    <orderEntry type="library" name="Maven: org.noggit:noggit:0.6" level="project" />
+    <orderEntry type="library" name="Maven: com.googlecode.protobuf-java-format:protobuf-java-format:1.2" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-web:1.5.2.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter:1.5.2.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot:1.5.2.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-autoconfigure:1.5.2.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-logging:1.5.2.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: ch.qos.logback:logback-classic:1.1.11" level="project" />
+    <orderEntry type="library" name="Maven: ch.qos.logback:logback-core:1.1.11" level="project" />
+    <orderEntry type="library" name="Maven: org.slf4j:jul-to-slf4j:1.7.24" level="project" />
+    <orderEntry type="library" name="Maven: org.slf4j:log4j-over-slf4j:1.7.24" level="project" />
+    <orderEntry type="library" scope="RUNTIME" name="Maven: org.yaml:snakeyaml:1.17" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-tomcat:1.5.2.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-core:8.5.11" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-el:8.5.11" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-websocket:8.5.11" level="project" />
+    <orderEntry type="library" name="Maven: org.hibernate:hibernate-validator:5.3.4.Final" level="project" />
+    <orderEntry type="library" name="Maven: javax.validation:validation-api:1.1.0.Final" level="project" />
+    <orderEntry type="library" name="Maven: org.jboss.logging:jboss-logging:3.3.0.Final" level="project" />
+    <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.8.7" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-web:4.3.7.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-webmvc:4.3.7.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-expression:4.3.7.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-jdbc:1.5.2.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.tomcat:tomcat-jdbc:8.5.11" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.tomcat:tomcat-juli:8.5.11" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-jdbc:4.3.7.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-data-jpa:1.5.2.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-aop:1.5.2.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.aspectj:aspectjweaver:1.8.9" level="project" />
+    <orderEntry type="library" name="Maven: org.hibernate:hibernate-core:5.0.12.Final" level="project" />
+    <orderEntry type="library" name="Maven: org.hibernate.javax.persistence:hibernate-jpa-2.1-api:1.0.0.Final" level="project" />
+    <orderEntry type="library" name="Maven: org.javassist:javassist:3.21.0-GA" level="project" />
+    <orderEntry type="library" name="Maven: org.jboss:jandex:2.0.0.Final" level="project" />
+    <orderEntry type="library" name="Maven: org.hibernate.common:hibernate-commons-annotations:5.0.1.Final" level="project" />
+    <orderEntry type="library" name="Maven: org.hibernate:hibernate-entitymanager:5.0.12.Final" level="project" />
+    <orderEntry type="library" name="Maven: javax.transaction:javax.transaction-api:1.2" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.data:spring-data-jpa:1.11.1.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.data:spring-data-commons:1.13.1.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-orm:4.3.7.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.slf4j:jcl-over-slf4j:1.7.24" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-aspects:4.3.7.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.postgresql:postgresql:42.0.0" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.commons:commons-dbcp2:2.1" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.commons:commons-pool2:2.4.2" level="project" />
+    <orderEntry type="library" name="Maven: commons-logging:commons-logging:1.2" level="project" />
+    <orderEntry type="library" name="Maven: org.antlr:stringtemplate:3.2.1" level="project" />
+    <orderEntry type="library" name="Maven: antlr:antlr:2.7.7" level="project" />
+    <orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.5" level="project" />
+    <orderEntry type="library" name="Maven: commons-io:commons-io:2.5" level="project" />
+    <orderEntry type="library" name="Maven: com.google.guava:guava:21.0" level="project" />
+    <orderEntry type="library" name="Maven: net.sf.supercsv:super-csv:2.4.0" level="project" />
+    <orderEntry type="library" name="Maven: com.google.code.gson:gson:2.8.0" level="project" />
+    <orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-joda:2.6.6" level="project" />
+    <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.8.0" level="project" />
+    <orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.8.7" level="project" />
+    <orderEntry type="library" name="Maven: joda-time:joda-time:2.8.2" level="project" />
+    <orderEntry type="library" name="Maven: org.mongodb:mongo-java-driver:3.4.2" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-swagger2:2.7.0" level="project" />
+    <orderEntry type="library" name="Maven: io.swagger:swagger-annotations:1.5.13" level="project" />
+    <orderEntry type="library" name="Maven: io.swagger:swagger-models:1.5.13" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-spi:2.7.0" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-core:2.7.0" level="project" />
+    <orderEntry type="library" name="Maven: net.bytebuddy:byte-buddy:1.6.14" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-schema:2.7.0" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-swagger-common:2.7.0" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-spring-web:2.7.0" level="project" />
+    <orderEntry type="library" name="Maven: org.reflections:reflections:0.9.11" level="project" />
+    <orderEntry type="library" name="Maven: com.fasterxml:classmate:1.3.3" level="project" />
+    <orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.24" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.plugin:spring-plugin-core:1.2.0.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework.plugin:spring-plugin-metadata:1.2.0.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.mapstruct:mapstruct:1.1.0.Final" level="project" />
+    <orderEntry type="library" name="Maven: io.springfox:springfox-swagger-ui:2.7.0" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-starter-test:1.5.2.RELEASE" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-test:1.5.2.RELEASE" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-test-autoconfigure:1.5.2.RELEASE" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: com.jayway.jsonpath:json-path:2.2.0" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: net.minidev:json-smart:2.2.1" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: net.minidev:accessors-smart:1.1" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.12" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.assertj:assertj-core:2.6.0" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.mockito:mockito-core:1.10.19" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.objenesis:objenesis:2.1" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-library:1.3" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.skyscreamer:jsonassert:1.4.0" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: com.vaadin.external.google:android-json:0.0.20131108.vaadin1" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-core:4.3.7.RELEASE" level="project" />
+    <orderEntry type="library" name="Maven: org.springframework:spring-test:4.3.7.RELEASE" level="project" />
+  </component>
+</module>
\ No newline at end of file
Index: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0
===================================================================
--- modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0	(nonexistent)
+++ modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0	(revision 48492)

Property changes on: modules/dnet-openaire-exporter/tags/dnet-openaire-exporter-1.0.0
___________________________________________________________________
Added: svn:ignore
## -0,0 +1 ##
+target
