Project

General

Profile

1
package eu.dnetlib.goldoa.service;
2

    
3
import com.fasterxml.jackson.databind.JsonNode;
4
import com.fasterxml.jackson.databind.ObjectMapper;
5
import eu.dnetlib.goldoa.domain.*;
6
import eu.dnetlib.goldoa.service.dao.JournalDAO;
7
import eu.dnetlib.goldoa.service.dao.PublicationDAO;
8
import eu.dnetlib.goldoa.service.dao.PublisherDAO;
9
import org.apache.commons.codec.digest.DigestUtils;
10
import org.apache.log4j.Logger;
11
import org.springframework.beans.factory.annotation.Autowired;
12
import org.springframework.transaction.annotation.Transactional;
13

    
14
import java.io.InputStream;
15
import java.net.URL;
16
import java.util.*;
17

    
18
/**
19
 * Created by antleb on 3/13/15.
20
 */
21
@Transactional
22
public class PublicationManagerImpl implements PublicationManager {
23

    
24
    private static Logger logger = Logger.getLogger(PublicationManagerImpl.class);
25

    
26
    @Autowired
27
    private PublicationDAO publicationDAO;
28
    @Autowired
29
    private JournalDAO journalDAO;
30
    @Autowired
31
    private PublisherDAO publisherDAO;
32
    @Autowired
33
    private PersonManager personManager;
34
    @Autowired
35
    private OrganizationManager organizationManager;
36

    
37
    @Override
38
    public Publication getPublication(String publicationId) {
39
        Publication publication = publicationDAO.getPublication(publicationId);
40

    
41
        loadPublicationRelations(publication);
42

    
43
        if (publication.getJournal() != null && publication.getJournal().getId() != null)
44
            publication.setJournal(journalDAO.getJournal(publication.getJournal().getId()));
45
        else
46
            publication.setJournal(null);
47

    
48
        if (publication.getPublisher() != null && publication.getPublisher().getId() != null)
49
            publication.setPublisher(publisherDAO.getPublisher(publication.getPublisher().getId()));
50
        else
51
            publication.setPublisher(null);
52

    
53
        return publication;
54
    }
55

    
56
    private void loadPublicationRelations(Publication publication) {
57
        publicationDAO.loadAffiliations(publication);
58
    }
59

    
60
    @Override
61
    public Publication savePublication(Publication publication) {
62

    
63
        if (publication.getId() == null) {
64
            publication.setSource("portal");
65
            publication.setId("portal::" + DigestUtils.md5Hex(publication.getTitle()));
66
        }
67

    
68
        publicationDAO.savePublication(publication);
69
        deletePublicationRelations(publication);
70
        try {
71
            insertPublicationRelations(publication);
72
        } catch (PersonManagerException e) {
73
            e.printStackTrace();
74
        } catch (OrganizationManagerException e) {
75
            e.printStackTrace();
76
        }
77

    
78
        if (publication.getJournal() != null && publication.getJournal().getId() != null)
79
            publication.setJournal(journalDAO.getJournal(publication.getJournal().getId()));
80
        else
81
            publication.setJournal(null);
82

    
83
        if (publication.getPublisher() != null && publication.getPublisher().getId() != null)
84
            publication.setPublisher(publisherDAO.getPublisher(publication.getPublisher().getId()));
85
        else
86
            publication.setPublisher(null);
87

    
88
        return publication;
89
    }
90

    
91
    private void insertPublicationRelations(Publication publication) throws PersonManagerException, OrganizationManagerException {
92
        publicationDAO.insertIdentifiers(publication);
93

    
94
        if (publication.getAuthors() != null)
95
            for (Affiliation aff:publication.getAuthors()) {
96
                if (aff.getOrganization() != null && aff.getOrganization().getId() == null)
97
                   aff.getOrganization().setId(organizationManager.saveOrganization(aff.getOrganization()));
98

    
99
                if (aff.getPerson() != null) {
100
                    String personId = personManager.generateId(aff.getPerson());
101

    
102
                    try {
103
                        boolean affiliationExists = false;
104
                        Person temp = personManager.getById(personId);
105

    
106
                        for (Affiliation a:temp.getAffiliations()) {
107
                            if (a.getOrganization() != null && aff.getOrganization() != null && a.getOrganization().getId().equals(aff.getOrganization().getId()))
108
                               affiliationExists = true;
109
                        }
110

    
111
                        if (!affiliationExists) {
112
                            temp.getAffiliations().add(aff);
113

    
114
                            personManager.savePerson(temp);
115
                        }
116

    
117
                        aff.setPerson(temp);
118
                    } catch (PersonManagerException e) {
119
                        if (e.getErrorCause() == PersonManagerException.ErrorCause.NOT_EXISTS)
120
                            personManager.savePerson(aff.getPerson());
121
                    }
122
                }
123
            }
124

    
125
        publicationDAO.saveAffiliations(publication);
126
    }
127

    
128
    private void deletePublicationRelations(Publication publication) {
129
        publicationDAO.deleteIdentifiers(publication);
130
        publicationDAO.deleteAffiliations(publication);
131
    }
132

    
133
    @Override
134
    public Publication resolveDOI(String doi) throws ManagerException {
135
        Publication publication = new Publication();
136
        InputStream is = null;
137

    
138
        try {
139
            is = new URL("http://api.crossref.org/works/" + doi).openStream();
140
            ObjectMapper mapper = new ObjectMapper();
141
            JsonNode root = mapper.readTree(is);
142

    
143
            if (root.get("status").textValue().equals("ok")) {
144
                publication.setTitle(root.path("message").path("title").path(0).textValue());
145
                publication.setDoi(doi);
146
                publication.setSubjects(root.path("message").path("subject").textValue());
147

    
148
                publication.setSource("crossref");
149
                publication.setId("crossref::"  + DigestUtils.md5Hex(doi));
150

    
151
                if ("journal-article".equals(root.path("message").path("type").textValue()))
152
                    publication.setType(Publication.Type.ARTICLE);
153
                else
154
                    publication.setType(Publication.Type.MONOGRAPH);
155

    
156
                publication.setPublicationDate(this.parsePublicationDate(root.path("message").path("issued")));
157
                publication.setJournal(this.parseJournal(root.path("message").path("container-title"), root.path("message").path("ISSN")));
158
                publication.getJournal().setPublisher(this.parsePublisher(root.path("message").path("publisher")));
159

    
160
                publication.setAuthors(new ArrayList<Affiliation>());
161
                for (JsonNode author : root.path("message").path("author")) {
162
                    publication.getAuthors().add(this.parseAffiliation(author));
163
                }
164

    
165
                publication.setIdentifiers(new ArrayList<PublicationIdentifier>());
166
                publication.getIdentifiers().add(new PublicationIdentifier("doi", doi));
167
            } else {
168
                throw new ManagerException(ManagerException.ErrorCause.NOT_EXISTS);
169
            }
170
        } catch (ManagerException e) {
171
            throw e;
172
        } catch (Exception e) {
173
            logger.error("Error resolving doi", e);
174

    
175
            throw new ManagerException(ManagerException.ErrorCause.UNKNOWN);
176
        } finally {
177
            try {
178
                if (is != null)
179
                    is.close();
180
            } catch (Exception e) {}
181
        }
182

    
183
        return publication;
184
    }
185

    
186
    private Affiliation parseAffiliation(JsonNode author) {
187
        Person person = new Person();
188

    
189
        person.setName(author.path("given").textValue());
190
        person.setLastname(author.path("family").textValue());
191
        person.setAffiliations(new ArrayList<Affiliation>());
192

    
193
        Affiliation affiliation = new Affiliation();
194
        affiliation.setPerson(person);
195

    
196
        person.getAffiliations().add(affiliation);
197

    
198
        return affiliation;
199
    }
200

    
201
    private Publisher parsePublisher(JsonNode publisherName) {
202
        Publisher publisher = new Publisher();
203

    
204
        publisher.setName(publisherName.textValue());
205

    
206
        publisher.setId("crossref::" + DigestUtils.md5Hex(publisher.getName()));
207
        publisher.setSource("crossref");
208

    
209
        return publisher;
210
    }
211

    
212
    private Journal parseJournal(JsonNode name, JsonNode issn) {
213
        Journal journal;
214
        List<Vocabulary> journals = journalDAO.search(name.path(0).textValue());
215

    
216
        if (journals.size() > 0) {
217
            journal = journalDAO.getJournal(journals.get(0).getId());
218
        } else {
219
            journal = new Journal();
220

    
221
            journal.setTitle(name.path(0).textValue());
222
            journal.setAlternativeTitle(name.path(1).textValue());
223

    
224
            StringBuilder sb = new StringBuilder();
225
            Iterator<JsonNode> ssn = issn.elements();
226
            while (ssn.hasNext()) {
227
                sb.append(ssn.next().textValue()).append(",");
228
            }
229

    
230
            if (sb.length() > 0)
231
                sb.deleteCharAt(sb.length() - 1);
232

    
233
            journal.setIssn(sb.toString());
234

    
235
            journal.setSource("crossref");
236
            journal.setId("crossref::" + DigestUtils.md5Hex(journal.getTitle()));
237
        }
238

    
239
        return journal;
240
    }
241

    
242
    private Date parsePublicationDate(JsonNode node) {
243
        Calendar c = Calendar.getInstance();
244

    
245
        c.clear();
246
        c.setTimeZone(TimeZone.getTimeZone("UTC"));
247

    
248
        c.set(Calendar.YEAR, node.path("date-parts").path(0).path(0).intValue());
249
        c.set(Calendar.MONTH, node.path("date-parts").path(0).path(1).intValue() - 1);
250
        c.set(Calendar.DAY_OF_MONTH, 1 + node.path("date-parts").path(0).path(2).intValue());
251
        c.set(Calendar.HOUR_OF_DAY, 0);
252

    
253

    
254
        return c.getTime();
255
    }
256

    
257
    public PublicationDAO getPublicationDAO() {
258
        return publicationDAO;
259
    }
260

    
261
    public void setPublicationDAO(PublicationDAO publicationDAO) {
262
        this.publicationDAO = publicationDAO;
263
    }
264

    
265
    public JournalDAO getJournalDAO() {
266
        return journalDAO;
267
    }
268

    
269
    public void setJournalDAO(JournalDAO journalDAO) {
270
        this.journalDAO = journalDAO;
271
    }
272

    
273
    public PublisherDAO getPublisherDAO() {
274
        return publisherDAO;
275
    }
276

    
277
    public void setPublisherDAO(PublisherDAO publisherDAO) {
278
        this.publisherDAO = publisherDAO;
279
    }
280
}
(17-17/24)