Project

General

Profile

1
package eu.dnetlib.openaire.project;
2

    
3
import java.io.BufferedOutputStream;
4
import java.io.IOException;
5
import java.io.OutputStream;
6
import java.sql.SQLException;
7
import java.text.SimpleDateFormat;
8
import java.util.Date;
9
import java.util.Map;
10
import java.util.zip.ZipOutputStream;
11
import javax.servlet.ServletResponse;
12
import javax.servlet.http.HttpServletRequest;
13
import javax.servlet.http.HttpServletResponse;
14

    
15
import com.google.common.xml.XmlEscapers;
16
import eu.dnetlib.OpenaireExporterConfig;
17
import eu.dnetlib.OpenaireExporterConfig.Project;
18
import eu.dnetlib.openaire.common.AbstractExporterController;
19
import eu.dnetlib.openaire.common.ExporterConstants;
20
import eu.dnetlib.openaire.project.domain.db.ProjectTsv;
21
import eu.dnetlib.openaire.project.domain.db.ProjectDetails;
22
import eu.dnetlib.openaire.project.dao.JdbcApiDao;
23
import eu.dnetlib.openaire.project.dao.ValueCleaner;
24
import io.swagger.annotations.ApiOperation;
25
import io.swagger.annotations.ApiResponse;
26
import io.swagger.annotations.ApiResponses;
27
import org.antlr.stringtemplate.StringTemplate;
28
import org.apache.commons.io.IOUtils;
29
import org.apache.commons.lang3.StringUtils;
30
import org.apache.commons.logging.Log;
31
import org.apache.commons.logging.LogFactory;
32
import org.springframework.beans.factory.annotation.Autowired;
33
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
34
import org.springframework.core.io.Resource;
35
import org.springframework.stereotype.Controller;
36
import org.springframework.web.bind.annotation.CrossOrigin;
37
import org.springframework.web.bind.annotation.RequestMapping;
38
import org.springframework.web.bind.annotation.RequestMethod;
39
import org.springframework.web.bind.annotation.RequestParam;
40

    
41
@Controller
42
@CrossOrigin(origins = { "*" })
43
@ConditionalOnProperty(value = "openaire.exporter.enable.project", havingValue = "true")
44
@io.swagger.annotations.Api(tags = "OpenAIRE projects API", description = "the OpenAIRE projects API")
45
public class ProjectsController extends AbstractExporterController {
46

    
47
	private static final Log log = LogFactory.getLog(ProjectsController.class); // NOPMD by marko on 11/24/08 5:02 PM
48

    
49
	public final static String UTF8 = "UTF-8";
50

    
51
	@Autowired
52
	private OpenaireExporterConfig config;
53

    
54
	@Autowired
55
	private JdbcApiDao dao;
56

    
57
	@Autowired
58
	private ProjectQueryParamsFactory projectQueryParamsFactory;
59

    
60
	@RequestMapping(value = "/export/**/project/dspace.do", method = RequestMethod.GET)
61
	@ApiOperation(
62
			value = "DSpace",
63
			notes = "return project information in compatible with the OpenAIRE plugin for DSpace",
64
			tags = { ExporterConstants.DSPACE },
65
			response = String.class)
66
	@ApiResponses(value = {
67
			@ApiResponse(code = 200, message = "OK", response = String.class),
68
			@ApiResponse(code = 500, message = "unexpected error", response = ErrorMessage.class) })
69
	public void processDspace(final HttpServletRequest request, final ServletResponse response,
70
			@RequestParam(value = "startFrom", required = false) final String startFrom,
71
			@RequestParam(value = "startUntil", required = false) final String startUntil,
72
			@RequestParam(value = "endFrom", required = false) final String endFrom,
73
			@RequestParam(value = "endUntil", required = false) final String endUntil) throws Exception {
74

    
75
		final Project conf = config.getProject();
76

    
77
		final ProjectQueryParams params = projectQueryParamsFactory.generateParams(request, startFrom, startUntil, endFrom, endUntil);
78
		final StringTemplate headSt = new StringTemplate(IOUtils.toString(conf.getDspaceHeadTemplate().getInputStream(), UTF8));
79

    
80
		headSt.setAttribute("fundingProgramme", params.getFundingProgramme());
81

    
82
		final StringTemplate tailSt = new StringTemplate(IOUtils.toString(conf.getDspaceTailTemplate().getInputStream(), UTF8));
83

    
84
		response.setContentType("text/xml");
85
		doProcess(response, params, headSt.toString(), conf.getDspaceTemplate(), tailSt.toString(), s -> XmlEscapers.xmlContentEscaper().escape(oneLiner(s)));
86
	}
87

    
88
	@RequestMapping(value = "/export/**/project/eprints.do", method = RequestMethod.GET)
89
	@ApiOperation(
90
			value = "EPrints",
91
			notes = "return project information in compatible with the OpenAIRE plugin for Eprints",
92
			tags = { ExporterConstants.EPRINT },
93
			response = String.class)
94
	@ApiResponses(value = {
95
			@ApiResponse(code = 200, message = "OK", response = String.class),
96
			@ApiResponse(code = 500, message = "unexpected error", response = ErrorMessage.class) })
97
	public void processEprints(final HttpServletRequest request, final ServletResponse response,
98
			@RequestParam(value = "startFrom", required = false) final String startFrom,
99
			@RequestParam(value = "startUntil", required = false) final String startUntil,
100
			@RequestParam(value = "endFrom", required = false) final String endFrom,
101
			@RequestParam(value = "endUntil", required = false) final String endUntil) throws Exception {
102

    
103
		final ProjectQueryParams params = projectQueryParamsFactory.generateParams(request, startFrom, startUntil, endFrom, endUntil);
104
		response.setContentType("text/html");
105
		doProcess(response, params, null, config.getProject().getEprintsTemplate(), null, s -> oneLiner(s));
106
	}
107

    
108
	private String oneLiner(final String s) {
109
		return StringUtils.isNotBlank(s) ? s.replaceAll("\\n", " ").trim() : "";
110
	}
111

    
112
	private void doProcess(
113
			final ServletResponse response,
114
			final ProjectQueryParams params,
115
			final String head, final Resource projectTemplate, final String tail,
116
			final ValueCleaner cleaner) throws IOException, SQLException {
117

    
118
		final StringTemplate st = new StringTemplate(IOUtils.toString(projectTemplate.getInputStream(), UTF8));
119
		try(final OutputStream out = new BufferedOutputStream(response.getOutputStream())) {
120
			dao.streamProjects(obtainQuery(params), out, head, st, tail, cleaner);
121
		}
122
	}
123

    
124
	@RequestMapping(value = "/export/project2tsv.do", method = RequestMethod.GET)
125
	@ApiOperation(
126
			value = "TSV",
127
			notes = "download project information in TSV format",
128
			tags = { ExporterConstants.TSV },
129
			response = ProjectTsv[].class)
130
	@ApiResponses(value = {
131
			@ApiResponse(code = 200, message = "OK", response = ProjectTsv[].class),
132
			@ApiResponse(code = 500, message = "unexpected error", response = ErrorMessage.class) })
133
	public void processTsv(final HttpServletResponse response,
134
			@RequestParam(value = "funding", required = true) final String funding,
135
			@RequestParam(value = "article293", required = false) final Boolean article293) throws Exception {
136

    
137
		final String fundingPrefix = getFundingPrefix(funding, null);
138

    
139
		final String date = new SimpleDateFormat("yyyyMMdd").format(new Date());
140
		final String filename = "projects_" + funding + "_" + date + ".tsv";
141
		response.setContentType("text/tab-separated-values");
142
		response.setHeader("Content-Disposition", "attachment; filename=\"" + filename + ".zip\"");
143
		try(final ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(response.getOutputStream()))) {
144
			dao.processTsvRequest(out, article293, fundingPrefix, filename);
145
		} catch (Throwable e) {
146
			throw new RuntimeException("Error processing the request", e);
147
		}
148
	}
149

    
150
	@RequestMapping(value = "/export/streamProjectDetails.do", method = RequestMethod.GET)
151
	@ApiOperation(
152
			value = "Stream projects",
153
			notes = "stream project information",
154
			tags = { ExporterConstants.STREAMING },
155
			response = ProjectDetails[].class)
156
	@ApiResponses(value = {
157
			@ApiResponse(code = 200, message = "OK", response = ProjectDetails[].class),
158
			@ApiResponse(code = 500, message = "unexpected error", response = ErrorMessage.class) })
159
	public void streamProjectDetails(final HttpServletResponse response,
160
			@RequestParam(value = "format", required = true) final String format,
161
			@RequestParam(value = "compress", required = false) final Boolean compress) throws IOException, SQLException {
162

    
163
		if (compress != null && compress) {
164
			response.setHeader("Content-Encoding", "gzip");
165
		}
166
		switch (format) {
167
			case "csv":
168
				response.setContentType("text/csv");
169
				break;
170
			case "json":
171
				response.setContentType("text/plain");
172
				break;
173
			default: throw new IllegalArgumentException("unsupported format: " + format);
174
		}
175

    
176
		dao.processProjectDetails(response.getOutputStream(), format, compress);
177
	}
178

    
179
	/**
180
	 * Creates the query on the fundingProgramme specified in the given parameters.
181
	 *
182
	 * @param params
183
	 *            request parameters
184
	 * @return the query string
185
	 * @throws IllegalArgumentException
186
	 *             if the funding program is not recognized
187
	 * @throws IOException
188
	 *             if there are problem loading the query temlate
189
	 * @throws IllegalArgumentException
190
	 *             if the funding program is not recognized
191
	 */
192
	protected String obtainQuery(final ProjectQueryParams params) throws IllegalArgumentException, IOException {
193
		String funding = params.getFundingProgramme();
194
		String suffix = params.getFundingPath();
195

    
196
		final StringTemplate st = new StringTemplate(IOUtils.toString(config.getProject().getProjectsFundingQueryTemplate().getInputStream(), UTF8));
197
		st.setAttribute("fundingprefix", getFundingPrefix(funding, suffix));
198
		String theQuery = setDateParameters(st.toString(), params);
199
		log.debug("Generated query: " + theQuery);
200
		return theQuery;
201
	}
202

    
203
	private String getFundingPrefix(final String funding, final String suffix) {
204
		final Map<String, String> fundingIds = dao.readFundingpathIds();
205
		if (!fundingIds.containsKey(funding.toUpperCase())) {
206
			throw new IllegalArgumentException("invalid funding " + funding);
207
		}
208
		String fundingPrefix = fundingIds.get(funding.toUpperCase());
209
		return StringUtils.isBlank(suffix) ? fundingPrefix : fundingPrefix + "::" + suffix.toUpperCase();
210
	}
211

    
212
	private String setDateParameters(final String query, final ProjectQueryParams params) {
213
		String queryWithDates = query;
214
		if (params.getStartFrom() != null) {
215
			queryWithDates += " AND startdate >= '" + params.getStartFrom() + "'";
216
		}
217
		if (params.getStartUntil() != null) {
218
			queryWithDates += " AND startdate <= '" + params.getStartUntil() + "'";
219
		}
220
		if (params.getEndFrom() != null) {
221
			queryWithDates += " AND enddate >= '" + params.getEndFrom() + "'";
222
		}
223
		if (params.getEndUntil() != null) {
224
			queryWithDates += " AND enddate <= '" + params.getEndUntil() + "'";
225
		}
226
		return queryWithDates;
227
	}
228

    
229
}
(3-3/3)