Project

General

Profile

1
package eu.dnetlib.goldoa.service.stats;
2

    
3
import eu.dnetlib.goldoa.domain.Request;
4
import eu.dnetlib.goldoa.domain.stats.*;
5
import eu.dnetlib.goldoa.service.RequestManager;
6
import org.apache.log4j.Logger;
7
import org.hibernate.SessionFactory;
8
import org.springframework.beans.factory.annotation.Autowired;
9
import org.springframework.stereotype.Service;
10
import org.springframework.transaction.annotation.Transactional;
11

    
12
import java.text.ParseException;
13
import java.text.SimpleDateFormat;
14
import java.util.*;
15

    
16
/*
17
 * Created by antleb on 11/19/15.
18
*/
19

    
20

    
21
@Transactional(readOnly = true)
22
@Service("statsManager")
23
public class StatsManagerImpl implements StatsManager {
24

    
25
	private static Logger logger = Logger.getLogger(StatsManagerImpl.class);
26

    
27
	public static final String SERIES_COUNTRY = "select c.name as category, count(r.id) as count, sum(apcpaid) as apc, avg(apcpaid) as avgapc " +
28
			"from request r join organization o on r.organization=o.id join country c on c.id=o.country %WHERE% group by c.name";
29

    
30
	public static final String SERIES_STATUS = "select r.status as category, count(r.id) as count, sum(apcpaid) as apc, avg(apcpaid) as avgapc " +
31
			"from request r %WHERE% group by r.status";
32
	public static final String SERIES_TYPE = "select p.type as category, count(r.id) as count, sum(apcpaid) as apc, avg(apcpaid) as avgapc " +
33
			"from request r join publication p on p.id=r.publication %WHERE% group by p.type";
34
	public static final String SERIES_ORGANIZATION = "select o.name as category, count(r.id) as count, sum(apcpaid) as apc, avg(apcpaid) as avgapc " +
35
			"from request r join organization o on r.organization=o.id %WHERE% group by o.shortname, o.name";
36
	public static final String SERIES_PUBLISHER = "select p.name as category, count(r.id) as count, sum(apcpaid) as apc, avg(apcpaid) as avgapc " +
37
			"from (select r.id, r.status, r.apcpaid, j.publisher, 'j' from request r join journal j on r.journal=j.id " +
38
			"where j.publisher is not null " +
39
			"union select r.id, r.status, r.apcpaid, p.id, 'p' from request r join publisher p on r.publisher=p.id) " +
40
			"as r join publisher p on r.publisher=p.id %WHERE% group by p.name";
41

    
42

    
43
	public static final String BROWSE_SCIENTIFIC_AREA = "select distinct p.scientificarea as id, p.scientificarea as category, count(r.id) as count from request r join project p on r.project=p.id group by p.scientificarea order by category";
44
	public static final String BROWSE_COUNTRY = "select c.id as id, c.name as category, count(r.id) as count from request r join organization o on r.organization=o.id join country c on c.id=o.country group by c.name, c.id order by category";
45
	public static final String BROWSE_ORGANIZATION = "select o.id as id, case when o.shortname is not null then o.shortname else o.name end  as category, count(r.id) as count from request r join organization o on o.id=r.organization group by o.shortname, o.name, o.id order by category";
46
	public static final String BROWSE_PUBLISHER = "select p.id as id, p.name as category, count(r.id) as count from (select r.id, r.status, j.publisher, 'j' from request r join journal j on r.journal=j.id where j.publisher is not null union select r.id, r.status, p.id, 'p' from request r join publisher p on r.publisher=p.id) as r join publisher p on r.publisher=p.id group by p.name, p.id order by category";
47
	public static final String BROWSE_STATUS = "select r.status as id, r.status as category, count(r.id) as count from request r group by status";
48

    
49
	@Autowired
50
	private RequestManager requestManager;
51

    
52
	@Autowired
53
	private SessionFactory sessionFactory;
54

    
55
	@Override
56
	public Numbers getNumbers(Numbers.Category[] categories) {
57

    
58
		Map<Numbers.Category, Number> map = new HashMap<>();
59

    
60
		for (Numbers.Category category:categories) {
61
			switch (category) {
62
				case REQUESTS:
63
					map.put(Numbers.Category.REQUESTS, requestManager.getActiveNumber());
64
					break;
65
				case PAID_REQUESTS:
66
					map.put(Numbers.Category.PAID_REQUESTS,requestManager.getPaidNumber() );
67
					break;
68
				case PROJECTS:
69
					map.put(Numbers.Category.PROJECTS,requestManager.getNumberOfProjects());
70
					break;
71
				case TOTAL_AMOUNT:
72
					map.put(Numbers.Category.TOTAL_AMOUNT,requestManager.getTotalAmount() );
73
					break;
74
				case AVERAGE_AMOUNT:
75
					map.put(Numbers.Category.AVERAGE_AMOUNT,requestManager.getAverageAmount() );
76
					break;
77
				case AVERAGE_PER_ARTICLE:
78
					map.put(Numbers.Category.AVERAGE_PER_ARTICLE,requestManager.getAverageAmountPerArticle() );
79
					break;
80
				case AVERAGE_PER_MONOGRAPH:
81
					map.put(Numbers.Category.AVERAGE_PER_MONOGRAPH,requestManager.getAverageAmountPerMonograph());
82
					break;
83
				case AVERAGE_PER_BOOK_CHAPTER:
84
					map.put(Numbers.Category.AVERAGE_PER_BOOK_CHAPTER,requestManager.getAverageAmountPerBookChapter()  );
85
					break;
86
				case PAID_REQUESTS_WITH_DOI:
87
					map.put(Numbers.Category.PAID_REQUESTS_WITH_DOI,requestManager.getNumberOfPaidRequestsWithDOI());
88
					break;
89
				case APPROVED_REQUESTS_WITH_DOI:
90
					map.put(Numbers.Category.APPROVED_REQUESTS_WITH_DOI,requestManager.getNumberOfApprovedRequestsWithDOI());
91
					break;
92
				case PAID_ARTICLE_REQUESTS:
93
					map.put(Numbers.Category.PAID_ARTICLE_REQUESTS,requestManager.getNumberOfPaidPublicationPerArticle());
94
					break;
95
				case PAID_MONOGRAPH_REQUESTS:
96
					map.put(Numbers.Category.PAID_MONOGRAPH_REQUESTS, requestManager.getNumberOfPaidPublicationPerMonograph());
97
					break;
98
				case PAID_BOOK_CHAPTER_REQUESTS:
99
					map.put(Numbers.Category.PAID_BOOK_CHAPTER_REQUESTS, requestManager.getNumberOfPaidPublicationPerBookChapter());
100
					break;
101
			}
102
		}
103

    
104
		return new Numbers(map);
105
	}
106

    
107
	@Override
108
	@SuppressWarnings("unchecked")
109
	public Series getSeries(Series.Category[] categories, Request.RequestStatus[] statuses) {
110
		Map<Series.Category, List<Quadruple<String, Integer, Float, Float>>> map = new HashMap<Series.Category, List<Quadruple<String, Integer, Float, Float>>>();
111

    
112
		for (final Series.Category category:categories) {
113
			String query = null;
114

    
115
			switch (category) {
116
				case COUNTRY:
117
					query = SERIES_COUNTRY;
118
					break;
119
				case ORGANIZATION:
120
					query = SERIES_ORGANIZATION;
121
					break;
122
				case PUBLISHER:
123
					query = SERIES_PUBLISHER;
124
					break;
125
				case STATUS:
126
					query = SERIES_STATUS;
127
					break;
128
				case PUBLICATION_TYPE:
129
					query = SERIES_TYPE;
130
			}
131

    
132
			if (statuses != null) {
133
				StringBuilder ssb = new StringBuilder();
134

    
135
				for (Request.RequestStatus status:statuses) {
136
					String clause;
137
					int code = status.getCode();
138

    
139
					switch (code) {
140
						case 0:
141
							clause = " r.status=0";
142
							break;
143
						default:
144
							clause = " (r.status = " + code + ")";
145
							break;
146
					}
147

    
148
					ssb.append(ssb.length()==0?clause:" or " + clause);
149
				}
150

    
151
				query = query.replace("%WHERE%", " where " + ssb.toString());
152
			} else {
153
				query = query.replace("%WHERE%", "");
154
			}
155

    
156

    
157
			List<Object[]> resultSet = sessionFactory.getCurrentSession().createSQLQuery(query).list();
158
			Quadruple<String, Integer, Float, Float> q = null;
159
			List<Quadruple<String, Integer, Float, Float>> l = new ArrayList<>();
160
			for(Object[] rs : resultSet){
161
				if(rs[0] == null) rs[0] = "";
162
				if(rs[2] == null) rs[2] = "0.0";
163
				if(rs[3] == null) rs[3] = "0.0";
164
				
165
				if(category != Series.Category.STATUS)
166
					q = new Quadruple<>(rs[0].toString(),
167
							Integer.parseInt(rs[1].toString()), Float.parseFloat(rs[2].toString()), Float.parseFloat(rs[3].toString()));
168
				else
169
					q = new Quadruple<>(rs[0].toString(),
170
							Integer.parseInt(rs[1].toString()), Float.parseFloat(rs[2].toString()), Float.parseFloat(rs[3].toString()));
171
				l.add(q);
172
			}
173
			map.put(category,l);
174
		}
175

    
176
		return new Series(map);
177
	}
178

    
179
	@Override
180
	@SuppressWarnings("unchecked")
181
	public DateSeries getDateSeries(DateSeries.Over over, boolean cumulative, Date from, Date to, String[] publishers, String[] organizations, String[] countries, String[] scientificAreas) {
182

    
183
		StringBuilder sb = new StringBuilder();
184
		String dateColumn = null;
185
		String windowKeyword ;
186
		List<String> clauses = new ArrayList<String>();
187

    
188
		switch (over) {
189
			case DAY:
190
				dateColumn = "date_trunc('day', submissiondate)";
191
				break;
192
			case MONTH:
193
				dateColumn = "date_trunc('month', submissiondate)";
194
				break;
195
			case YEAR:
196
				dateColumn = "date_trunc('year', submissiondate)";
197
				break;
198
		}
199

    
200
		if (cumulative)
201
			windowKeyword = "order";
202
		else
203
			windowKeyword = "partition";
204

    
205
		if (from != null) {
206
			clauses.add(" r.submissiondate >= '" + new SimpleDateFormat("yyyy-MM-dd").format(from) + "' ");
207
		}
208
		if (to != null) {
209
			clauses.add(" r.submissiondate <= '" + new SimpleDateFormat("yyyy-MM-dd").format(to) + "' ");
210
		}
211

    
212
		if (publishers != null && publishers.length > 0) {
213
			String clause = "pub.id in (";
214

    
215
			for (int i = 0; i < publishers.length; i++) {
216
				if (i > 0)
217
					clause += ", ";
218

    
219
				clause += "'" + publishers[i] + "'";
220
			}
221

    
222
			clause += ")";
223

    
224
			clauses.add(clause);
225
		}
226

    
227
		if (organizations != null && organizations.length > 0) {
228
			String clause = "o.id in (";
229

    
230
			for (int i = 0; i < organizations.length; i++) {
231
				if (i > 0)
232
					clause += ", ";
233

    
234
				clause += "'" + organizations[i] + "'";
235
			}
236

    
237
			clause += ")";
238

    
239
			clauses.add(clause);
240
		}
241

    
242
		if (countries != null && countries.length > 0) {
243
			String clause = "c.id in (";
244

    
245
			for (int i = 0; i < countries.length; i++) {
246
				if (i > 0)
247
					clause += ", ";
248

    
249
				clause += "'" + countries[i] + "'";
250
			}
251

    
252
			clause += ")";
253

    
254
			clauses.add(clause);
255
		}
256

    
257
		if (scientificAreas != null && scientificAreas.length > 0) {
258
			String clause = "p.scientificarea in (";
259

    
260
			for (int i = 0; i < scientificAreas.length; i++) {
261
				if (i > 0)
262
					clause += ", ";
263

    
264
				clause += "'" + scientificAreas[i] + "'";
265
			}
266

    
267
			clause += ")";
268

    
269
			clauses.add(clause);
270
		}
271

    
272
		sb.append("select distinct ").append(dateColumn).append(" as date, count(r.id) over (").append(windowKeyword).append(" by ").append(dateColumn).append(") as count, sum(apcpaid) over (").append(windowKeyword).append(" by ").append(dateColumn).append(") as apc ");
273
		sb.append("from request r left join project p on r.project=p.id left join organization o on r.organization=o.id left join country c on c.id=o.country left join (select r.id as rid,  p.id, p.name from request r join journal j on r.journal=j.id join publisher p on p.id=j.publisher  union select r.id, p.id, p.name from request r join publisher p on r.publisher=p.id) as pub on pub.rid=r.id");
274

    
275
		if (clauses.size() > 0)
276
			sb.append(" where ");
277

    
278
		for (int i = 0; i < clauses.size(); i++) {
279
			if (i > 0)
280
				sb.append(" and ");
281

    
282
			sb.append(" (").append(clauses.get(i)).append(") ");
283
		}
284

    
285
		sb.append(" order by ").append(dateColumn);
286

    
287
//		System.out.println(sb.toString());return null;
288

    
289
		List<Object[]> resultSet = sessionFactory.getCurrentSession().createSQLQuery(sb.toString()).list();
290
		List<Triple<Date, Integer, Float>> l = new ArrayList<>();
291

    
292
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.s");
293
		for(Object[] rs : resultSet){
294
			Date date = null;
295
			try {
296
				if(rs[0] == null)
297
					date = null;
298
				else
299
					date = formatter.parse(rs[0].toString());
300
				if(rs[2] == null)
301
					rs[2] = "0.0";
302
				Triple<Date, Integer, Float> t = new Triple<Date,Integer, Float>(date,
303
						Integer.parseInt(rs[1].toString()),Float.parseFloat(rs[2].toString()));
304
				l.add(t);
305
			} catch (ParseException e) {
306
				e.printStackTrace();
307
			}
308
		}
309
		return new DateSeries(l);
310
	}
311

    
312
	public static void main(String[] args) {
313
		System.out.println(new StatsManagerImpl().getDateSeries(DateSeries.Over.DAY, true, null,null,null,null,null,null));
314
	}
315

    
316
	@Override
317
	@SuppressWarnings("unchecked")
318
	public Browse browse(Browse.Category[] categories) {
319
		Map<Browse.Category, List<Triple<String, String, Integer>>> map = new HashMap<Browse.Category, List<Triple<String, String, Integer>>>();
320

    
321
		for (final Browse.Category category:categories) {
322
			String query = null;
323

    
324
			switch (category) {
325
				case COUNTRY:
326
					query = BROWSE_COUNTRY;
327
					break;
328
				case ORGANIZATION:
329
					query = BROWSE_ORGANIZATION;
330
					break;
331
				case PUBLISHER:
332
					query = BROWSE_PUBLISHER;
333
					break;
334
				case SCIENTIFIC_AREA:
335
					query = BROWSE_SCIENTIFIC_AREA;
336
					break;
337
				case STATUS:
338
					query =  BROWSE_STATUS;
339
					break;
340
			}
341

    
342
			List<Object[]> resultSet = sessionFactory.getCurrentSession().createSQLQuery(query).list();
343
			Triple<String, String, Integer> t;
344
			List<Triple<String, String, Integer>> l = new ArrayList<>();
345
			for(Object[] rs : resultSet){
346
				if(rs[0] == null ) rs[0] = "";
347
				if(rs[1] == null ) rs[1] = "";
348
				if(rs[2] == null ) rs[2] = 0;
349

    
350
				if(category != Browse.Category.STATUS)
351
					t = new Triple<>(rs[0].toString(),rs[1].toString(), Integer.parseInt(rs[2].toString()));
352
				else
353
					t = new Triple<>(Request.RequestStatus.forStatus(Integer.parseInt(rs[0].toString())).getValue(),
354
							Request.RequestStatus.forStatus(Integer.parseInt(rs[0].toString())).getValue(),
355
							Integer.parseInt(rs[2].toString()));
356
				l.add(t);
357
			}
358
			map.put(category,l);
359
		}
360

    
361
		return new Browse(map);
362
	}
363

    
364
	@Override
365
	public MapData getMapData() {
366
		return null;
367
	}
368
}
(2-2/2)