Project

General

Profile

1
package eu.dnetlib.repos;
2

    
3
import eu.dnetlib.api.data.DatasourceManagerService;
4
import eu.dnetlib.api.data.DatasourceManagerServiceException;
5
import eu.dnetlib.domain.data.Repository;
6
import eu.dnetlib.domain.data.RepositoryInterface;
7
import eu.dnetlib.repos.ehcacher.CacheProvider;
8
import gr.uoa.di.driver.util.ServiceLocator;
9
import net.sf.ehcache.Element;
10
import net.sf.ehcache.constructs.blocking.SelfPopulatingCache;
11
import org.apache.log4j.Logger;
12

    
13
import javax.annotation.PostConstruct;
14
import javax.annotation.PreDestroy;
15
import java.io.*;
16
import java.sql.SQLException;
17
import java.util.*;
18

    
19
public class RepoApiDmsImpl implements RepoApiExtended {
20
    private static Logger logger = Logger.getLogger(RepoApiDmsImpl.class);
21
    public CacheProvider cacheProvider;
22
    public String[] cacheKeys = {"opendoar", "re3data", "jour_aggr"};
23
    private ServiceLocator<DatasourceManagerService> dmService = null;
24

    
25
    @PostConstruct
26
    public void initCaches() {
27
        logger.info("initializing caches");
28
        Thread initializingCachesThread = new Thread() {
29
            public void run() {
30
                boolean initialized = false;
31
                while (!initialized) {
32
                    for (String cacheKey : cacheKeys) {
33
                        try {
34
                            if (!cacheProvider.getCache().isKeyInCache(cacheKey)) {
35
                                File cacheBackup = new File("/tmp/cache-" + cacheKey + ".bak");
36
                                if (cacheBackup.exists()) {
37
                                    logger.info("initializing key: " + cacheKey + " from disk");
38
                                    FileInputStream fis = new FileInputStream("/tmp/cache-" + cacheKey + ".bak");
39

    
40
                                    ObjectInputStream ois = new ObjectInputStream(fis);
41
                                    Map<String, Repository> repositories = (Map<String, Repository>) ois.readObject();
42
                                    ois.close();
43
                                    cacheProvider.getCache().put(new Element(cacheKey, (Map<String, Repository>) repositories));
44
                                } else {
45
                                    logger.info("initializing key: " + cacheKey + " from dms");
46
                                    cacheProvider.getCache().get(cacheKey).getObjectValue();
47
                                }
48
                            }
49
                        } catch (Exception e) {
50
                            logger.error("Error while initializing cache for key: " + cacheKey, e);
51
                            logger.info("initializing key: " + cacheKey + " from dms");
52
                            cacheProvider.getCache().get(cacheKey).getObjectValue();
53
                        }
54
                    }
55
                    logger.info("caches initialized successfully");
56
                    initialized = true;
57
                }
58
            }
59
        };
60
        initializingCachesThread.setDaemon(true);
61
        initializingCachesThread.start();
62
    }
63

    
64
    @PreDestroy
65
    public void persistCaches() {
66
        logger.info("persisting caches");
67
        try {
68
            for (String cacheKey : cacheKeys) {
69
                FileOutputStream fos = new FileOutputStream("/tmp/cache-" + cacheKey + ".bak");
70
                ObjectOutputStream oos = new ObjectOutputStream(fos);
71
                if (cacheProvider.getCache().isKeyInCache(cacheKey)) {
72
                    logger.info("persisting cache: " + cacheKey);
73
                    oos.writeObject((Map<String, Repository>) cacheProvider.getCache().get(cacheKey).getObjectValue());
74
                    oos.close();
75
                }
76
            }
77
            logger.info("caches stored in disk");
78
        } catch (Exception e) {
79
            logger.error("Error while persisting caches", e);
80
            for (String cacheKey : cacheKeys) {
81
                File cacheBackup = new File("/tmp/cache-" + cacheKey + ".bak");
82
                if (cacheBackup.exists())
83
                    cacheBackup.delete();
84
            }
85
        }
86
    }
87

    
88
    @Override
89
    public Repository getRepository(String id) throws Exception {
90
        return this.getRepository(null, id);
91
    }
92

    
93
    @Override
94
    public Repository getRepository(String officialName, String id) throws Exception {
95
        logger.info("getting repository with name " + officialName + " and id: " + id + " from dms");
96
        Repository retRepo = null;
97
        try {
98

    
99
            for (String cacheKey : cacheKeys) {
100
                if (((Map<String, Repository>) cacheProvider.getCache().get(cacheKey).getObjectValue()).containsKey(id))
101
                    return ((Map<String, Repository>) cacheProvider.getCache().get(cacheKey).getObjectValue()).get(id);
102
            }
103
            retRepo = dmService.getService().getDatasource(id);
104
        } catch (DatasourceManagerServiceException e) {
105
            logger.error("Error getting repository with name " + officialName + " and id: " + id + " from dms", e);
106
        }
107
        return retRepo;
108
    }
109

    
110
    @Override
111
    public void getRepositoryStats(Repository repo) throws Exception {
112
        logger.info("getting repository stats for : " + repo.getOfficialName() + " from dms");
113

    
114
        try {
115
            dmService.getService().findNextScheduledExecution(repo.getId(), repo.getInterfaces().get(0).getId());
116

    
117
        } catch (DatasourceManagerServiceException e) {
118
            logger.error("Error getting repo stats for : " + repo.getOfficialName() + " from openaire db", e);
119
        }
120
    }
121

    
122
    @Override
123
    public String getListLatestUpdate(String mode) throws Exception {
124
        String date = null;
125
        try {
126
            logger.info("getting last collection date for " + mode);
127

    
128
            date = dmService.getService().getDatasource("openaire____::" + mode).getInterfaces().get(0).getExtraFields().get("last_collection_date");
129
            logger.debug("last collection date for opendoar: " + date);
130

    
131
        } catch (DatasourceManagerServiceException e) {
132
            logger.error("Error getting last update date", e);
133
        }
134
        return date;
135
    }
136

    
137
    @Override
138
    public String getNextScheduledExecution(String mode) throws Exception {
139
        String date = null;
140
        try {
141
            date = dmService.getService().getDatasource("openaire____::" + mode).getInterfaces().get(0).getExtraFields().get("last_collection_date");
142
            logger.debug("last collection date for opendoar: " + date);
143

    
144
//				Date date1 = dmService.getService().findNextScheduledExecution("openaire____::opendoar", "api_________::opendoar::0");
145
            Date date1 = dmService.getService().findNextScheduledExecution("opendoar____::2367", "api_________::opendoar____::2367::0");
146

    
147
            logger.debug("next scheduled for opendoar: " + date1);
148

    
149
        } catch (DatasourceManagerServiceException e) {
150
            logger.error("Error getting repo stats for opendoar", e);
151
        }
152
        return date;
153
    }
154

    
155
    @Override
156
    public String storeRepository(Repository repo, String datatype, List<RepositoryInterface> interfacesToRegister) throws Exception {
157
        String retMessage = null;
158
        logger.info("storing " + datatype + " repository with id: " + repo.getId());
159
        try {
160
            java.util.Date utilDate = new java.util.Date();
161
            java.sql.Timestamp date = new java.sql.Timestamp(utilDate.getTime());
162

    
163
            if (datatype.equalsIgnoreCase("opendoar") || datatype.equalsIgnoreCase("re3data")) {
164

    
165
                String updateQuery = "UPDATE datasources SET englishname = '" + repo.getEnglishName() + "'," +
166
                        " logourl = '" + repo.getLogoUrl() + "'," +
167
                        " timezone = '" + repo.getTimezone() + "'," +
168
                        " registeredby = '" + repo.getRegisteredBy() + "'," +
169
                        " activationid = '" + repo.getActivationId() + "'," +
170
                        " contactemail = '" + repo.getContactEmail() + "'," +
171
                        " datasourceclass = '" + repo.getDatasourceClass() + "'" +
172
                        " WHERE id = '" + repo.getId() + "'";
173

    
174
                if (dmService.getService().updateSQL(repo.getId(), updateQuery, false))
175
                    logger.debug("updated successfully");
176
                else
177
                    logger.error("error while updating: " + updateQuery);
178

    
179
            } else if (datatype.equalsIgnoreCase("journal") || datatype.equalsIgnoreCase("aggregator")) {
180

    
181
                logger.debug("looking if " + datatype + " " + repo.getOfficialName() + " is already in datasources");
182
                if (dmService.getService().getDatasource(repo.getId()) != null) {
183
                    retMessage = datatype + " '" + repo.getOfficialName() + "' is already in datasources.";
184
                    repo.getInterfaces().clear();
185
                    logger.debug(retMessage);
186
                } else {
187
                    logger.debug(datatype + " " + repo.getOfficialName() + " is not in datasources. Inserting..");
188

    
189
                    repo.setDateOfCollection(date);
190
                    repo.setAggregator("OPENAIRE");
191
                    try {
192
                        if (dmService.getService().addDatasource(repo))
193
                            logger.debug("inserted successfully");
194
                        else
195
                            logger.error("error while inserting");
196
                    } catch (DatasourceManagerServiceException e) {
197
                        logger.error("error while inserting" + e);
198
                    }
199
                }
200
            }
201
            logger.debug("Inserting Interfaces");
202
            for (RepositoryInterface iFace : repo.getInterfaces()) {
203
                if (!iFace.getBaseUrl().isEmpty() && !iFace.getDesiredCompatibilityLevel().isEmpty()) {
204
                    if (iFace.getId() != null && !iFace.getId().isEmpty()) {
205
                        logger.debug("updating iface..");
206
                        dmService.getService().updateBaseUrl(repo.getId(), iFace.getId(), iFace.getBaseUrl());
207
                        if (!iFace.getAccessSet().isEmpty()) {
208
                            logger.debug("set not empty: " + iFace.getAccessSet());
209
                            dmService.getService().updateAccessParam(repo.getId(), iFace.getId(), "set", iFace.getAccessSet(), false);
210
                        } else
211
                            dmService.getService().deleteAccessParamOrExtraField(repo.getId(), iFace.getId(), "set");
212

    
213
                        dmService.getService().updateContentDescription(repo.getId(), iFace.getId(), "metadata");
214
                        if (datatype.equals("re3data")) {
215
                            dmService.getService().updateAccessParam(repo.getId(), iFace.getId(), "format", "oai_datacite", false);
216
                            iFace.setAccessFormat("oai_datacite");
217
                        } else {
218
                            dmService.getService().updateAccessParam(repo.getId(), iFace.getId(), "format", "oai_dc", false);
219
                            iFace.setAccessFormat("oai_dc");
220
                        }
221

    
222
                        logger.debug("updated successfully");
223
                    } else {
224
                        logger.debug("adding new iface..");
225
                        iFace.setContentDescription("metadata");
226
                        iFace.setCompliance("UNKNOWN");
227
                        if (datatype.equals("re3data"))
228
                            iFace.setAccessFormat("oai_datacite");
229
                        else
230
                            iFace.setAccessFormat("oai_dc");
231
                        if (repo.getDatasourceClass() != null && !repo.getDatasourceClass().isEmpty())
232
                            iFace.setTypology(repo.getDatasourceClass());
233
                        else {
234
                            if (datatype.equalsIgnoreCase("journal"))
235
                                iFace.setTypology("pubsrepository::journal");
236
                            else if (datatype.equalsIgnoreCase("aggregator"))
237
                                iFace.setTypology("aggregator::pubsrepository::unknown");
238
                            else if (datatype.equalsIgnoreCase("opendoar"))
239
                                iFace.setTypology("pubsrepository::unknown");
240
                            else if (datatype.equalsIgnoreCase("re3data"))
241
                                iFace.setTypology("datarepository::unknown");
242
                        }
243
                        iFace.setRemovable(true);
244
                        iFace.setAccessProtocol("oai");
245
                        iFace.setMetadataIdentifierPath("//*[local-name()='header']/*[local-name()='identifier']");
246
                        iFace.setId("api_________::" + repo.getId() + "::" + UUID.randomUUID().toString().substring(0, 8));
247
                        if (iFace.getAccessSet().isEmpty()) {
248
                            logger.debug("set is empty: " + iFace.getAccessSet());
249
                            iFace.removeAccessSet();
250
                        }
251
                        logger.debug("new ifaceId :" + iFace.getId());
252
                        if (dmService.getService().addInterface(repo.getId(), iFace))
253
                            logger.debug("added successfully");
254
                        else
255
                            logger.error("error while adding");
256
                    }
257
                    interfacesToRegister.add(iFace);
258
                }
259
            }
260
        } catch (Exception e) {
261
            logger.error("Error storing repo " + repo.getOfficialName() + " in dms", e);
262
            throw e;
263
        } finally {
264
            forceUpdateCache(datatype, repo.getId());
265
        }
266
        logger.debug("Finished storing " + datatype + " repository with id: " + repo.getId());
267
        return retMessage;
268
    }
269

    
270
    public List<Repository> getRepositories(String collectedFrom) throws Exception {
271
        List<Repository> repoList = new ArrayList<Repository>();
272
        try {
273
            logger.info("getting repos from dms with collected from value: " + collectedFrom);
274

    
275
            repoList = dmService.getService().listDatasourcesUsingFilter(null, null, null, collectedFrom);
276

    
277
        } catch (DatasourceManagerServiceException e) {
278
            logger.error("Error getting repos from dms with collected from value: " + collectedFrom, e);
279
            throw e;
280
        }
281
        return repoList;
282
    }
283

    
284
    public Map<String, Repository> getRepositoriesAsMap(String collectedFrom) throws Exception {
285
        List<Repository> repoList = new ArrayList<Repository>();
286
        Map<String, Repository> repoMap = new HashMap<String, Repository>();
287
        try {
288
            logger.info("getting repos from dms with collected from value: " + collectedFrom);
289

    
290
            repoList = dmService.getService().listDatasourcesUsingFilter(null, null, null, collectedFrom);
291
            for (Repository repo : repoList) {
292
                repoMap.put(repo.getId(), repo);
293
            }
294

    
295
        } catch (DatasourceManagerServiceException e) {
296
            logger.error("Error getting repos from dms with collected from value: " + collectedFrom, e);
297
            throw e;
298
        }
299
        return repoMap;
300
    }
301

    
302
    @Override
303
    public List<Map<String, String>> getRegisteredReposByOthers(String user_mail) {
304
        List<Map<String, String>> res = new ArrayList<Map<String, String>>();
305

    
306
        try {
307
            logger.info("getting repos by others for user : " + user_mail);
308

    
309
            res = this.getReposAsMap(user_mail, true);
310
        } catch (Exception e) {
311
            logger.error("Error getting repos by others for user : " + user_mail, e);
312

    
313
        }
314
        return res;
315
    }
316

    
317
    public List<Map<String, String>> getReposOfUser(String user_mail) throws Exception {
318
        logger.info("getting repos for user : " + user_mail);
319
        return this.getReposAsMap(user_mail, false);
320
    }
321

    
322
    private List<Map<String, String>> getReposAsMap(String user_mail, Boolean isAdmin) throws Exception {
323

    
324
        logger.info("getting repos as map for user: " + user_mail);
325
        List<Map<String, String>> res = new ArrayList<Map<String, String>>();
326
        try {
327
            this.getRepos(user_mail, false);
328
            for (Repository repo : this.getRepos(user_mail, isAdmin)) {
329
                Map<String, String> rep = new HashMap<String, String>();
330
                rep.put("name", repo.getOfficialName());
331
                rep.put("id", repo.getId());
332
                rep.put("url", repo.getWebsiteUrl());
333
                rep.put("mode", repo.getDatasourceType());
334
                rep.put("registered", repo.isRegistered() ? "yes" : "no");
335
                res.add(rep);
336
            }
337
        } catch (Exception e) {
338
            logger.error("getting repos as map for user: " + user_mail, e);
339
        }
340
        return res;
341
    }
342

    
343
    @SuppressWarnings("unchecked")
344
    public TreeMap<String, List<Map<String, String>>> getRepositoriesByCountry(String collectedFrom) throws Exception {
345
        List<Repository> repoList = new ArrayList<Repository>();
346
        TreeMap<String, List<Map<String, String>>> res = new TreeMap<String, List<Map<String, String>>>();
347

    
348
        try {
349
            logger.info("getting repos by country from dms with key: " + collectedFrom);
350
            Map<String, Repository> repoMap = (Map<String, Repository>) cacheProvider.getCache().get(collectedFrom).getObjectValue();
351
            repoList = new ArrayList<Repository>(repoMap.values());
352

    
353
            for (Repository repo : repoList) {
354

    
355
                List<Map<String, String>> repos;
356
                if (!repo.getCountryName().isEmpty())
357
                    repos = res.get(repo.getCountryName());
358
                else
359
                    repos = res.get("Without Country");
360
                if (repos == null) {
361
                    repos = new ArrayList<Map<String, String>>();
362
                    if (!repo.getCountryName().isEmpty())
363
                        res.put(repo.getCountryName(), repos);
364
                    else
365
                        res.put("Without Country", repos);
366
                }
367

    
368
                Map<String, String> rep = new HashMap<String, String>();
369
                rep.put("name", repo.getOfficialName());
370
                rep.put("id", repo.getId());
371
                rep.put("url", repo.getWebsiteUrl());
372
                rep.put("registered", repo.isRegistered() ? "yes" : "no");
373
                repos.add(rep);
374
            }
375
        } catch (Exception e) {
376
            logger.error("Error getting repositories from dms with key: " + collectedFrom, e);
377
            throw e;
378
        }
379
        return res;
380
    }
381

    
382
    @Override
383
    public Map<String, List<Repository>> getRepositoriesPerCountry(String collectedFrom) throws Exception {
384
        List<Repository> repoList;
385
        Map<String, List<Repository>> res = new TreeMap<String, List<Repository>>();
386

    
387
        try {
388
            logger.info("getting repos by country from dms with key: " + collectedFrom);
389
            Map<String, Repository> repoMap = (Map<String, Repository>) cacheProvider.getCache().get(collectedFrom).getObjectValue();
390
            repoList = new ArrayList<Repository>(repoMap.values());
391

    
392
            for (Repository repo : repoList) {
393

    
394
                List<Repository> repos;
395
                if (!repo.getCountryName().isEmpty())
396
                    repos = res.get(repo.getCountryName());
397
                else
398
                    repos = res.get("Without Country");
399
                if (repos == null) {
400
                    repos = new ArrayList<Repository>();
401
                    if (!repo.getCountryName().isEmpty())
402
                        res.put(repo.getCountryName(), repos);
403
                    else
404
                        res.put("Without Country", repos);
405
                }
406

    
407
                repos.add(repo);
408
            }
409
        } catch (Exception e) {
410
            logger.error("Error getting repositories from dms with key: " + collectedFrom, e);
411
            throw e;
412
        }
413
        return res;
414
    }
415

    
416
    @Override
417
    public List<Repository> getRepositoriesOfCountry(String collectedFrom, String country) throws Exception {
418
        try {
419
            logger.info("getting repos for country " + country + " from dms with key: " + collectedFrom);
420
            return this.getRepositoriesPerCountry(collectedFrom).get(country);
421
        } catch (Exception e) {
422
            logger.error("Error getting repos for country " + country + " from dms with key: " + collectedFrom, e);
423
            throw e;
424
        }
425
    }
426

    
427
    @Override
428
    public Map<String, String> getRepoCompatibility(String officialName, String datasourceId) throws Exception {
429
        Map<String, String> compMap = null;
430

    
431
        Repository repo = dmService.getService().getDatasource(datasourceId);
432
        try {
433
            logger.debug("getting repository " + officialName + " compatibility from dms");
434

    
435
            compMap = new HashMap<String, String>();
436
            if (repo.getInterfaces().size() > 0) {
437
                for (RepositoryInterface iFace : repo.getInterfaces()) {
438
                    compMap.put(iFace.getCompliance(), iFace.getAccessSet());
439
                    if (iFace.getCompliance().equalsIgnoreCase("openaire2.0")) {
440
                        compMap.put("openaire2.0_data", "openaire_data");
441
                    }
442
                }
443
            }
444
        } catch (Exception e) {
445
            logger.error("Error getting repo " + officialName + " compatibility from dms", e);
446
            throw e;
447
        }
448

    
449
        return compMap;
450
    }
451

    
452
    @Override
453
    public List<Repository> getReposByIds(List<String> datasourceIds) throws Exception {
454
        List<Repository> retRepos = new ArrayList<Repository>();
455
        try {
456
            logger.info("getting repos by ids from dms");
457
            for (String cacheKey : cacheKeys) {
458
                Map<String, Repository> repoMap = (Map<String, Repository>) cacheProvider.getCache().get(cacheKey).getObjectValue();
459
                List<Repository> repoList = new ArrayList<Repository>(repoMap.values());
460
                for (Repository rep : repoList) {
461
                    if (datasourceIds.contains(rep.getId())) {
462
                        retRepos.add(rep);
463
                    }
464
                }
465
            }
466
        } catch (Exception e) {
467
            logger.error("error getting repos by ids from dms", e);
468
        }
469
        return retRepos;
470
    }
471

    
472
    @SuppressWarnings("unchecked")
473
    @Override
474
    public List<Repository> getRepos(String user_mail, Boolean repoAdmin) throws SQLException {
475
        List<Repository> retRepos = new ArrayList<Repository>();
476
        try {
477
            if (!repoAdmin) {
478
                logger.info("getting repositories registered by user: " + user_mail + " from dms");
479
                for (String cacheKey : cacheKeys) {
480
                    Map<String, Repository> repoMap = (Map<String, Repository>) cacheProvider.getCache().get(cacheKey).getObjectValue();
481
                    List<Repository> repoList = new ArrayList<Repository>(repoMap.values());
482
                    for (Repository rep : repoList) {
483
                        if (rep.getRegisteredBy().equalsIgnoreCase(user_mail) || rep.getContactEmail().equalsIgnoreCase(user_mail)) {
484
                            retRepos.add(rep);
485
                        }
486
                    }
487
                }
488
            } else {
489
                logger.debug("getting journal /agreg  registered by others  from dms");
490
                Map<String, Repository> repoMap = (Map<String, Repository>) cacheProvider.getCache().get("jour_aggr").getObjectValue();
491
                List<Repository> repoList = new ArrayList<Repository>(repoMap.values());
492
                for (Repository rep : repoList) {
493
                    if (!rep.getRegisteredBy().equalsIgnoreCase(user_mail) && !rep.getContactEmail().equalsIgnoreCase(user_mail)) {
494
                        retRepos.add(rep);
495
                    }
496
                }
497
            }
498

    
499
        } catch (Exception e) {
500
            logger.error("error getting repositories registered by user: " + user_mail + " from dms", e);
501
        }
502
        return retRepos;
503
    }
504

    
505
    @Override
506
    public boolean updateRepositoryInterfaceCompliance(String officialName,
507
                                                       String datasourceId, String interfaceId, String desiredCompliance, String set, String baseUrl, String oldId)
508
            throws Exception {
509
        boolean ret = true;
510
        try {
511
            if (desiredCompliance.equalsIgnoreCase("openaire2.0_data"))
512
                desiredCompliance = "openaire2.0";
513
            logger.info("updating repository " + officialName + " compliance to : " + desiredCompliance);
514
            if (oldId == null) {
515
                dmService.getService().updateLevelOfCompliance(datasourceId, interfaceId, desiredCompliance);
516
            } else {
517
                logger.debug("Checking if old interface should be updated");
518
                if (!desiredCompliance.equalsIgnoreCase("UNKNOWN") && (!desiredCompliance.equalsIgnoreCase("notCompatible"))) {
519
                    logger.debug("updating old interface with new set/url");
520
                    dmService.getService().updateBaseUrl(datasourceId, oldId, baseUrl);
521
                    if (set.equalsIgnoreCase("none"))
522
                        dmService.getService().deleteAccessParamOrExtraField(datasourceId, oldId, "set");
523
                    else
524
                        dmService.getService().updateAccessParam(datasourceId, oldId, "set", set, false);
525
                    logger.debug("deleting new interface");
526
                    dmService.getService().deleteInterface(datasourceId, interfaceId);
527

    
528
                }
529
                logger.debug("updating repository " + officialName + " compliance to : " + desiredCompliance);
530
            }
531
            java.util.Date utilDate = new java.util.Date();
532
            java.sql.Timestamp date = new java.sql.Timestamp(utilDate.getTime());
533

    
534
            String updateQuery = "UPDATE datasources SET activationid = " + null + "," +
535
                    " dateofvalidation = '" + date + "'" +
536
                    " WHERE id = '" + datasourceId + "'";
537

    
538
            if (dmService.getService().updateSQL(datasourceId, updateQuery, false))
539
                logger.debug("updated successfully");
540
            else
541
                logger.error("error while updating: " + updateQuery);
542

    
543
        } catch (Exception e) {
544
            logger.error("error connecting to dms to set a repo interface as openaire compliant " + officialName, e);
545
            ret = false;
546
            throw e;
547
        }
548
        return ret;
549
    }
550

    
551
    @Override
552
    public boolean insertPubFileInterface(String dsId, RepositoryInterface iFace)
553
            throws Exception {
554
        boolean ret = true;
555
        try {
556

    
557
            logger.info("storing pdf interface for repository: " + dsId);
558
            dmService.getService().addInterface(dsId, iFace);
559
        } catch (Exception e) {
560
            logger.error("error storing pdf interface for repository: " + dsId, e);
561
            ret = false;
562
            throw e;
563
        }
564
        return ret;
565
    }
566

    
567
    @Override
568
    public boolean updatePubFileInterface(String dsId, RepositoryInterface iFace)
569
            throws Exception {
570
        boolean ret = true;
571
        try {
572

    
573
            logger.info("updating pdf interface for repository: " + dsId);
574
            dmService.getService().deleteInterface(dsId, iFace.getId());
575
            dmService.getService().addInterface(dsId, iFace);
576
        } catch (Exception e) {
577
            logger.error("error updating pdf interface for repository: " + dsId, e);
578
            ret = false;
579
            throw e;
580
        }
581
        return ret;
582
    }
583

    
584
    @Override
585
    public List<String> getUrlsOfRepos(String user_mail, Boolean repoAdmin) throws Exception {
586
        List<String> urls = new ArrayList<String>();
587
        try {
588
            logger.info("getting url from repositories registered by user: " + user_mail + " from dms");
589
            for (Repository repo : this.getRepos(user_mail, repoAdmin)) {
590
                repo = this.getRepository(repo.getOfficialName(), repo.getId());
591
                logger.debug("repo: " + repo.getOfficialName());
592
//				logger.debug("#interfaces: " + repo.getInterfaces().size());
593
                for (RepositoryInterface iFace : repo.getInterfaces()) {
594
//					logger.debug("url: " + iFace.getBaseUrl() );
595
                    if (iFace.getContentDescription().equalsIgnoreCase("metadata")) {
596
                        if (iFace.getBaseUrl() != null && !iFace.getBaseUrl().isEmpty() && !urls.contains(iFace.getBaseUrl()) && iFace.getAccessProtocol().equalsIgnoreCase("oai"))
597
                            urls.add(iFace.getBaseUrl());
598
                    }
599
                }
600
            }
601
        } catch (Exception e) {
602
            logger.error("error getting url from repositories registered by user: " + user_mail + " from dms", e);
603
            throw e;
604
        }
605
        return urls;
606
    }
607

    
608
    @Override
609
    public String editRepository(Repository repo, String officialNameOld,
610
                                 String idOld, String datatype) throws Exception {
611
        // TODO Auto-generated method stub
612
        return null;
613
    }
614

    
615
    @Override
616
    public boolean repoIsCompliant(String officialName) throws Exception {
617
        // TODO Auto-generated method stub
618
        return false;
619
    }
620

    
621
    @Override
622
    public String updateRepositoryInformation(Repository repo) throws Exception {
623
        try {
624
            logger.info("updating repository information");
625
            String updateQuery = "UPDATE datasources SET englishname = '" + repo.getEnglishName() + "'," +
626
                    " logourl = '" + repo.getLogoUrl() + "'," +
627
                    " timezone = '" + repo.getTimezone() + "'," +
628
                    " registeredby = '" + repo.getRegisteredBy() + "'," +
629
                    " contactemail = '" + repo.getContactEmail() + "'," +
630
                    " datasourceclass = '" + repo.getDatasourceClass() + "'" +
631
                    " WHERE id = '" + repo.getId() + "'";
632

    
633
            if (dmService.getService().updateSQL(repo.getId(), updateQuery, false)) {
634
                logger.debug("updated successfully");
635
                return "The information about your repository is successfully updated.";
636
            } else {
637
                logger.error("error while updating: " + updateQuery);
638
                return "The information of your repository couldn't be updated. Please try again.";
639
            }
640
        } catch (Exception e) {
641
            logger.error("error updating repository information", e);
642
            throw e;
643
        } finally {
644
            forceUpdateCache(repo.getDatasourceType(), repo.getId());
645
        }
646

    
647
    }
648

    
649
    @Override
650
    public String deleteRepositoryInterfaces(String dsId, List<RepositoryInterface> interfaces) throws Exception {
651
        String retMessage = "";
652
        try {
653
            logger.info("deleting repository interfaces");
654
            int countSelected = 0;
655
            int countRemoved = 0;
656
            for (RepositoryInterface iFace : interfaces) {
657
                if (iFace.isDeleteApi())
658
                    countSelected++;
659
            }
660
            if (countSelected == 0)
661
                return "None interface was selected.";
662
            if (countSelected == interfaces.size())
663
                return "You cannot delete all interfaces! There must be at least one left.";
664

    
665
            for (RepositoryInterface iFace : interfaces) {
666
                logger.debug("delete API: " + iFace.isDeleteApi() + "--" + "removable API: " + iFace.isRemovable());
667
                if (iFace.isDeleteApi()) {
668
                    if (iFace.isRemovable()) {
669
                        if (dmService.getService().deleteInterface(dsId, iFace.getId())) {
670
                            logger.debug("iface deleted: " + iFace.getId());
671
                            countRemoved++;
672
                        } else {
673
                            logger.error("error while deleting iFace: " + iFace.getId());
674
                            retMessage += "Interface for url/set: " + iFace.getBaseUrl() + " / " + iFace.getAccessSet() + " couldn't be delete. Please try again.<br>";
675
                        }
676
                    } else {
677
                        retMessage += "Interface for url/set: " + iFace.getBaseUrl() + " / " + iFace.getAccessSet() + " couldn't be deleted because it is the one registered in OpenDoar. <br>";
678
                    }
679
                }
680
            }
681
            retMessage += "You have successfully deleted " + countRemoved + " interface(s).";
682
        } catch (Exception e) {
683
            logger.error("error deleting repository interfaces", e);
684
            throw e;
685
        }
686
        return retMessage;
687
    }
688

    
689
    @Override
690
    public void deleteRepositoryInterfacesWithoutChecks(String dsId, List<RepositoryInterface> interfaces) throws Exception {
691
        try {
692
            logger.info("deleting repository interfaces without checks");
693
            for (RepositoryInterface iFace : interfaces) {
694
                logger.info("deleting repository interface with url/set/id: " + iFace.getBaseUrl() + "/" + iFace.getAccessSet() + "/" + iFace.getId());
695
                if (dmService.getService().deleteInterface(dsId, iFace.getId())) {
696
                    logger.debug("iface deleted: " + iFace.getId());
697
                } else {
698
                    logger.error("error while deleting iFace: " + iFace.getId());
699
                    throw new Exception("error on dms while deleting iFace: " + iFace.getId());
700
                }
701
            }
702
        } catch (Exception e) {
703
            logger.error("error deleting repository interfaces", e);
704
            throw e;
705
        } finally {
706
            forceUpdateCache(null, dsId);
707
        }
708
    }
709

    
710
    @Override
711
    public String updateRepositoryInterfaces(String dsId,
712
                                             List<RepositoryInterface> interfaces,
713
                                             List<RepositoryInterface> interfacesOld, String datatype, List<RepositoryInterface> interfacesToRegister) throws Exception {
714
        String importResult = "";
715
        try {
716
            logger.info("updating repository interfaces for datasource: " + dsId);
717
            for (RepositoryInterface iFace : interfaces) {
718
                if (iFace.isDeleteApi()) {
719
                    for (RepositoryInterface iFaceOld : interfacesOld) {
720
                        if (iFaceOld.getId().equals(iFace.getId())) {
721
                            logger.error("old inteface found:");
722
                            this.printInterface(iFaceOld);
723
                            logger.error("new inteface:");
724
                            this.printInterface(iFace);
725
                            if (!(iFace.getDesiredCompatibilityLevel().equals("openaire2.0_data") && iFace.getCompliance().equals("openaire2.0")) && !iFace.getCompliance().equals(iFace.getDesiredCompatibilityLevel())) {
726
                                logger.debug("Iface desired combatibility level changed.");
727
                                if ((iFace.getBaseUrl().equals(iFaceOld.getBaseUrl())) && (iFace.getAccessSet().equals(iFaceOld.getAccessSet()))) {
728
                                    logger.debug("Set and Url are the same.");
729
                                    if (iFace.isRemovable()) {
730
                                        logger.debug("deleting old iface..");
731
                                        if (dmService.getService().deleteInterface(dsId, iFaceOld.getId()))
732
                                            logger.debug("deleted successfully");
733
                                        else
734
                                            logger.error("error while deleting");
735
                                        logger.debug("adding new iface..");
736
                                        iFace.setContentDescription("metadata");
737
                                        iFace.setCompliance("UNKNOWN");
738
                                        iFace.setId("api_________::" + dsId + "::" + UUID.randomUUID().toString().substring(0, 8));
739
                                        iFace.setMetadataIdentifierPath("//*[local-name()='header']/*[local-name()='identifier']");
740
                                        if (iFace.getAccessSet().isEmpty()) {
741
                                            logger.debug("set is empty: " + iFace.getAccessSet());
742
                                            iFace.removeAccessSet();
743
                                        }
744
                                        logger.debug("new ifaceId :" + iFace.getId());
745
                                        if (dmService.getService().addInterface(dsId, iFace)) {
746
                                            logger.debug("added successfully");
747
                                            interfacesToRegister.add(iFace);
748
                                        } else
749
                                            logger.error("error while adding");
750
                                    } else {
751
                                        logger.debug("Cannot delete old iface.. Values of old interface will be updated");
752
                                        logger.debug("updating iface.. :" + iFace.getId());
753
                                        dmService.getService().updateBaseUrl(dsId, iFace.getId(), iFace.getBaseUrl());
754
                                        if (!iFace.getAccessSet().isEmpty())
755
                                            dmService.getService().updateAccessParam(dsId, iFace.getId(), "set", iFace.getAccessSet(), false);
756
                                        else
757
                                            dmService.getService().deleteAccessParamOrExtraField(dsId, iFace.getId(), "set");
758
                                        dmService.getService().updateContentDescription(dsId, iFace.getId(), "metadata");
759
                                        if (datatype.equals("re3data")) {
760
                                            dmService.getService().updateAccessParam(dsId, iFace.getId(), "format", "oai_datacite", false);
761
                                            iFace.setAccessFormat("oai_datacite");
762
                                        } else {
763
                                            dmService.getService().updateAccessParam(dsId, iFace.getId(), "format", "oai_dc", false);
764
                                            iFace.setAccessFormat("oai_dc");
765
                                        }
766
                                        logger.debug("added successfully");
767
                                        interfacesToRegister.add(iFace);
768
                                    }
769
                                } else if ((!iFace.getBaseUrl().equals(iFaceOld.getBaseUrl())) || (!iFace.getAccessSet().equals(iFaceOld.getAccessSet()))) {
770
                                    logger.debug("Set and/or Url changed. A new interface will be created");
771
                                    logger.debug("adding new iface..The old one will be kept untouched.");
772
                                    importResult += "Interface for url/set: " + iFace.getBaseUrl() + " / " + iFace.getAccessSet() + " seems to be completely new. As a result, a new interface will be created. If you wish, you can remove the old one later.<br>";
773
                                    iFace.setContentDescription("metadata");
774
                                    iFace.setCompliance("UNKNOWN");
775
                                    iFace.setRemovable(true);
776
                                    iFace.setMetadataIdentifierPath("//*[local-name()='header']/*[local-name()='identifier']");
777
                                    if (!iFace.isRemovable())
778
                                        iFace.getExtraFields().put("oldId", iFace.getId());
779
                                    iFace.setId("api_________::" + dsId + "::" + UUID.randomUUID().toString().substring(0, 8));
780
                                    if (iFace.getAccessSet().isEmpty()) {
781
                                        logger.debug("set is empty: " + iFace.getAccessSet());
782
                                        iFace.removeAccessSet();
783
                                    }
784
                                    logger.debug("new ifaceId :" + iFace.getId());
785
                                    if (dmService.getService().addInterface(dsId, iFace)) {
786
                                        logger.debug("added successfully");
787
                                        interfacesToRegister.add(iFace);
788
                                    } else
789
                                        logger.error("error while adding");
790
                                }
791
                            } else if ((!iFace.getBaseUrl().equals(iFaceOld.getBaseUrl())) || (!iFace.getAccessSet().equals(iFaceOld.getAccessSet()))) {
792
                                logger.debug("Iface url/set changed.");
793
                                importResult += "Interface for url/set: " + iFace.getBaseUrl() + " / " + iFace.getAccessSet() + " is already compliant. As a result, a new interface will be created. If the new interface becomes compliant, then the old interface will be replaced. If not, both interfaces will be available. <br>";
794

    
795
                                logger.debug("adding new iface..but keeping the old id to update later.");
796
                                logger.debug("import result: " + importResult);
797
                                iFace.setContentDescription("metadata");
798
                                iFace.setCompliance("UNKNOWN");
799
                                iFace.setRemovable(true);
800
                                iFace.setMetadataIdentifierPath("//*[local-name()='header']/*[local-name()='identifier']");
801
                                iFace.getExtraFields().put("oldId", iFace.getId());
802
                                iFace.setId("api_________::" + dsId + "::" + UUID.randomUUID().toString().substring(0, 8));
803
                                if (iFace.getAccessSet().isEmpty()) {
804
                                    logger.debug("set is empty: " + iFace.getAccessSet());
805
                                    iFace.removeAccessSet();
806
                                }
807
                                logger.debug("new ifaceId :" + iFace.getId());
808
                                if (dmService.getService().addInterface(dsId, iFace)) {
809
                                    logger.debug("added successfully");
810
                                    interfacesToRegister.add(iFace);
811
                                } else
812
                                    logger.error("error while adding");
813
                            }
814
                            break;
815
                        }
816
                    }
817
                }
818
            }
819
            logger.debug("import result final: " + importResult);
820
        } catch (Exception e) {
821
            logger.error("error updating repository interfaces for datasource: " + dsId, e);
822
            throw e;
823
        } finally {
824
            forceUpdateCache(datatype, dsId);
825
        }
826
        return importResult;
827

    
828
    }
829

    
830
    @Override
831
    public String insertRepositoryInterfaces(String dsId,
832
                                             List<RepositoryInterface> interfaces, List<RepositoryInterface> interfacesOld, String datatype, List<RepositoryInterface> interfacesToRegister)
833
            throws Exception {
834
        String importResult = "";
835
        try {
836
            logger.info("inserting repository interfaces for datasource: " + dsId);
837
            logger.debug("interfacesNew size: " + interfaces.size());
838
            logger.debug("cleaning up interfacesNew list from empty rows");
839
            for (RepositoryInterface iFace : interfaces) {
840
                if (!iFace.getBaseUrl().isEmpty() && !iFace.getDesiredCompatibilityLevel().isEmpty()) {
841
                    logger.debug("adding new iface..");
842
                    logger.debug("checking if there exists an interface with same url/set..");
843
                    boolean exists = false;
844
                    for (RepositoryInterface iFaceOld : interfacesOld) {
845
                        if (iFaceOld.getBaseUrl().equals(iFace.getBaseUrl()) && iFaceOld.getAccessSet().equals(iFace.getAccessSet())) {
846
                            logger.debug("there exists an interface with same url/set..");
847
                            importResult += "Interface for url/set: " + iFace.getBaseUrl() + " / " + iFace.getAccessSet() + " could not be added. There already exists an interface with same url/set. You have to update he existing one or remove it before adding a new one.<br>";
848
                            exists = true;
849
                            break;
850
                        }
851
                    }
852
                    iFace.setContentDescription("metadata");
853
                    iFace.setCompliance("UNKNOWN");
854
                    if (datatype.equalsIgnoreCase("journal"))
855
                        iFace.setTypology("pubsrepository::journal");
856
                    else if (datatype.equalsIgnoreCase("aggregator"))
857
                        iFace.setTypology("aggregator::pubsrepository::unknown");
858
                    else
859
                        iFace.setTypology("pubsrepository::unknown");
860
                    if (datatype.equals("re3data"))
861
                        iFace.setAccessFormat("oai_datacite");
862
                    else
863
                        iFace.setAccessFormat("oai_dc");
864
                    iFace.setAccessProtocol("oai");
865
                    iFace.setRemovable(true);
866
                    iFace.setMetadataIdentifierPath("//*[local-name()='header']/*[local-name()='identifier']");
867
                    iFace.setId("api_________::" + dsId + "::" + UUID.randomUUID().toString().substring(0, 8));
868
                    if (iFace.getAccessSet().isEmpty()) {
869
                        logger.debug("set is empty: " + iFace.getAccessSet());
870
                        iFace.removeAccessSet();
871
                    }
872
                    logger.debug("new ifaceId :" + iFace.getId());
873
                    if (!exists) {
874
                        if (dmService.getService().addInterface(dsId, iFace)) {
875
                            logger.debug("added successfully");
876
                            interfacesToRegister.add(iFace);
877
                        } else
878
                            logger.error("error while adding");
879
                    }
880
                }
881
            }
882
            logger.debug("interfaces size after cleanup: " + interfacesToRegister.size());
883
        } catch (Exception e) {
884
            logger.error("error inserting repository interfaces for datasource: " + dsId, e);
885
            throw e;
886
        }
887
        return importResult;
888
    }
889

    
890
    @Override
891
    public boolean unregisterRepository(Repository repo) throws Exception {
892
        logger.info("unregistering repository " + repo.getOfficialName());
893
        try {
894
            for (RepositoryInterface iFace : repo.getInterfaces()) {
895
                if (iFace.isRemovable()) {
896
                    logger.debug("deleting iface..");
897
                    if (dmService.getService().deleteInterface(repo.getId(), iFace.getId()))
898
                        logger.debug("deleted successfully");
899
                    else
900
                        logger.error("error while deleting");
901
                } else {
902
                    logger.debug("updating iface compliance to UNKNOWN");
903
                    dmService.getService().updateLevelOfCompliance(repo.getId(), iFace.getId(), "UNKNOWN");
904
                }
905
            }
906
        } catch (Exception e) {
907
            logger.error("Error unregistering repository " + repo.getOfficialName(), e);
908
            return false;
909
        }
910
        return true;
911

    
912
    }
913

    
914
    private void printInterface(RepositoryInterface iFace) {
915
        logger.debug("baseUrl: " + iFace.getBaseUrl());
916
        logger.debug("format: " + iFace.getAccessFormat());
917
        logger.debug("typology: " + iFace.getTypology());
918
        logger.debug("set: " + iFace.getAccessSet());
919
        logger.debug("des_comp_level: " + iFace.getDesiredCompatibilityLevel());
920
        logger.debug("cur_comp_level: " + iFace.getCompliance());
921
        logger.debug("protocol: " + iFace.getAccessProtocol());
922
        logger.debug("api_id: " + iFace.getId());
923
        logger.debug("removable: " + iFace.isRemovable());
924
        logger.debug("deleteApi: " + iFace.isDeleteApi());
925
    }
926

    
927
    private void forceUpdateCache(final String datatype, final String repoId) {
928
        Thread updatingThread = new Thread() {
929
            public void run() {
930
                logger.info("Updating cache for key: " + datatype + " after adding/editing repository");
931
                try {
932
                    String key = "";
933
                    if (datatype == null) {
934
                        for (String cacheKey : cacheKeys) {
935
                            if (((Map<String, Repository>) cacheProvider.getCache().get(cacheKey).getObjectValue()).containsKey(repoId)) {
936
                                key = cacheKey;
937
                                break;
938
                            }
939
                        }
940
                    } else {
941
                        key = datatype;
942
                    }
943
                    if (datatype.equalsIgnoreCase("journal") || datatype.equalsIgnoreCase("aggregator")) {
944
                        key = "jour_aggr";
945
                    }
946

    
947
                    Map<String, Repository> oldMap = (Map<String, Repository>) cacheProvider.getCache().get(key).getObjectValue();
948
                    oldMap.put(repoId, dmService.getService().getDatasource(repoId));
949
                    cacheProvider.getCache().replace(new Element(key, (Map<String, Repository>) oldMap), new Element(key, (Map<String, Repository>) oldMap));
950
                    logger.info("cache updated");
951
                    //((SelfPopulatingCache) cacheProvider.getCache()).refresh(key);
952
                } catch (Exception e) {
953
                    logger.error("Error while updating cache. Retry in 250000min", e);
954
                    try {
955
                        Thread.sleep(250000);
956
                    } catch (Exception e1) {
957
                        logger.error("Error while updating cache", e1);
958
                    }
959
                }
960
            }
961
        };
962
        updatingThread.setDaemon(true);
963
        updatingThread.start();
964
    }
965

    
966
    public ServiceLocator<DatasourceManagerService> getDmService() {
967
        return dmService;
968
    }
969

    
970
    public void setDmService(ServiceLocator<DatasourceManagerService> dmService) {
971
        this.dmService = dmService;
972
    }
973

    
974
    public CacheProvider getCacheProvider() {
975
        return cacheProvider;
976
    }
977

    
978
    public void setCacheProvider(CacheProvider cacheProvider) {
979
        this.cacheProvider = cacheProvider;
980
    }
981

    
982
}
(3-3/5)