Project

General

Profile

Download (13.4 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2017 EDIT
3
* European Distributed Institute of Taxonomy
4
* http://www.e-taxonomy.eu
5
*
6
* The contents of this file are subject to the Mozilla Public License Version 1.1
7
* See LICENSE.TXT at the top of this package for the full license terms.
8
*/
9
package eu.etaxonomy.cdm.dataInserter;
10

    
11
import java.io.IOException;
12
import java.util.ArrayList;
13
import java.util.Arrays;
14
import java.util.EnumSet;
15
import java.util.HashMap;
16
import java.util.HashSet;
17
import java.util.List;
18
import java.util.Map;
19
import java.util.Set;
20
import java.util.UUID;
21

    
22
import org.apache.log4j.Logger;
23
import org.joda.time.DateTime;
24
import org.joda.time.format.DateTimeFormatter;
25
import org.springframework.context.event.ContextRefreshedEvent;
26
import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException;
27
import org.springframework.security.core.GrantedAuthority;
28
import org.springframework.transaction.TransactionStatus;
29

    
30
import com.fasterxml.jackson.core.JsonParseException;
31
import com.fasterxml.jackson.databind.JsonMappingException;
32
import com.fasterxml.jackson.databind.ObjectMapper;
33

    
34
import eu.etaxonomy.cdm.api.application.AbstractDataInserter;
35
import eu.etaxonomy.cdm.api.application.CdmRepository;
36
import eu.etaxonomy.cdm.api.service.pager.Pager;
37
import eu.etaxonomy.cdm.model.agent.AgentBase;
38
import eu.etaxonomy.cdm.model.agent.Institution;
39
import eu.etaxonomy.cdm.model.common.ExtensionType;
40
import eu.etaxonomy.cdm.model.common.GrantedAuthorityImpl;
41
import eu.etaxonomy.cdm.model.common.Group;
42
import eu.etaxonomy.cdm.model.name.Registration;
43
import eu.etaxonomy.cdm.model.name.RegistrationStatus;
44
import eu.etaxonomy.cdm.model.name.TaxonName;
45
import eu.etaxonomy.cdm.model.name.TypeDesignationBase;
46
import eu.etaxonomy.cdm.persistence.hibernate.permission.CRUD;
47
import eu.etaxonomy.cdm.persistence.hibernate.permission.CdmAuthority;
48
import eu.etaxonomy.cdm.persistence.hibernate.permission.CdmPermissionClass;
49
import eu.etaxonomy.cdm.persistence.hibernate.permission.Role;
50
import eu.etaxonomy.cdm.persistence.query.MatchMode;
51
import eu.etaxonomy.cdm.vaadin.model.registration.DerivationEventTypes;
52
import eu.etaxonomy.cdm.vaadin.security.RolesAndPermissions;
53

    
54
/**
55
 * @author a.kohlbecker
56
 * @since May 9, 2017
57
 *
58
 */
59
public class RegistrationRequiredDataInserter extends AbstractDataInserter {
60

    
61
    protected static final String PARAM_NAME_CREATE = "registrationCreate";
62

    
63
    protected static final String PARAM_NAME_WIPEOUT = "registrationWipeout";
64

    
65
    protected static final UUID GROUP_SUBMITTER_UUID = UUID.fromString("c468c6a7-b96c-4206-849d-5a825f806d3e");
66

    
67
    protected static final UUID GROUP_CURATOR_UUID = UUID.fromString("135210d3-3db7-4a81-ab36-240444637d45");
68

    
69
    private static final EnumSet<CRUD> CREATE_READ = EnumSet.of(CRUD.CREATE, CRUD.READ);
70
    private static final EnumSet<CRUD> CREATE_READ_UPDATE_DELETE = EnumSet.of(CRUD.CREATE, CRUD.READ, CRUD.UPDATE, CRUD.DELETE);
71

    
72
    private static final Logger logger = Logger.getLogger(RegistrationRequiredDataInserter.class);
73

    
74
    private ExtensionType extensionTypeIAPTRegData;
75

    
76
    Map<String, Institution> instituteMap = new HashMap<>();
77

    
78
    public static boolean commandsExecuted = false;
79

    
80
    private CdmRepository repo;
81

    
82
    private boolean hasRun = false;
83

    
84
    public void setCdmRepository(CdmRepository repo){
85
      this.repo = repo;
86
    }
87

    
88

    
89
 // ==================== Registration creation ======================= //
90

    
91
    /**
92
     * {@inheritDoc}
93
     */
94
    @Override
95
    public void onApplicationEvent(ContextRefreshedEvent event) {
96

    
97
        if(hasRun){
98
            return;
99
        }
100

    
101
        runAsAuthentication(Role.ROLE_ADMIN);
102

    
103
        insertRequiredData();
104
        executeSuppliedCommands();
105

    
106
        restoreAuthentication();
107

    
108
        hasRun = true;
109
    }
110

    
111
    /**
112
     *
113
     */
114
    private void insertRequiredData() {
115

    
116
        Role roleCuration = RolesAndPermissions.ROLE_CURATION;
117
        if(repo.getGrantedAuthorityService().find(roleCuration.getUuid()) == null){
118
            repo.getGrantedAuthorityService().saveOrUpdate(roleCuration.asNewGrantedAuthority());
119
        }
120

    
121
        Group groupCurator = repo.getGroupService().load(GROUP_CURATOR_UUID, Arrays.asList("grantedAuthorities"));
122
        if(groupCurator == null){
123
            groupCurator = Group.NewInstance();
124
            groupCurator.setUuid(GROUP_CURATOR_UUID);
125
            groupCurator.setName("Curator");
126
        }
127
        assureGroupHas(groupCurator, new CdmAuthority(CdmPermissionClass.REGISTRATION, CREATE_READ_UPDATE_DELETE).toString());
128
        repo.getGroupService().saveOrUpdate(groupCurator);
129

    
130
        Group groupSubmitter = repo.getGroupService().load(GROUP_SUBMITTER_UUID, Arrays.asList("grantedAuthorities"));
131
        if(groupSubmitter == null){
132
            groupSubmitter = Group.NewInstance();
133
            groupSubmitter.setUuid(GROUP_SUBMITTER_UUID);
134
            groupSubmitter.setName("Submitter");
135
        }
136
        assureGroupHas(groupSubmitter, new CdmAuthority(CdmPermissionClass.TAXONNAME, CREATE_READ).toString());
137
        assureGroupHas(groupSubmitter, new CdmAuthority(CdmPermissionClass.TEAMORPERSONBASE, CREATE_READ).toString());
138
        assureGroupHas(groupSubmitter, new CdmAuthority(CdmPermissionClass.REGISTRATION, CREATE_READ).toString());
139
        assureGroupHas(groupSubmitter, new CdmAuthority(CdmPermissionClass.SPECIMENOROBSERVATIONBASE, CREATE_READ).toString());
140
        repo.getGroupService().saveOrUpdate(groupSubmitter);
141

    
142
        if(repo.getTermService().find(DerivationEventTypes.PUBLISHED_IMAGE().getUuid()) == null){
143
            repo.getTermService().save(DerivationEventTypes.PUBLISHED_IMAGE());
144
        }
145
        if(repo.getTermService().find(DerivationEventTypes.UNPUBLISHED_IMAGE().getUuid()) == null){
146
            repo.getTermService().save(DerivationEventTypes.UNPUBLISHED_IMAGE());
147
        }
148
        if(repo.getTermService().find(DerivationEventTypes.CULTURE_METABOLIC_INACTIVE().getUuid()) == null){
149
            repo.getTermService().save(DerivationEventTypes.CULTURE_METABOLIC_INACTIVE());
150
        }
151
        repo.getSession().flush();
152

    
153
    }
154

    
155
    private void assureGroupHas(Group group, String authorityString){
156
        boolean authorityExists = false;
157

    
158
        for(GrantedAuthority ga : group.getGrantedAuthorities()){
159
            if((authorityExists = ga.getAuthority().equals(authorityString)) == true){
160
                break;
161
            }
162
        }
163
        if(!authorityExists){
164
            group.addGrantedAuthority(findGrantedAuthority(authorityString));
165
        }
166
    }
167

    
168
    private GrantedAuthorityImpl findGrantedAuthority(String authorityString){
169
        GrantedAuthorityImpl ga = null;
170
        try{
171
            ga = repo.getGrantedAuthorityService().findAuthorityString(authorityString);
172
        } catch (AuthenticationCredentialsNotFoundException e){
173
            e.printStackTrace();
174
        }
175
        if(ga == null){
176
            ga = GrantedAuthorityImpl.NewInstance(authorityString);
177
            repo.getGrantedAuthorityService().save(ga);
178
        }
179
        return ga;
180
    }
181

    
182
    /**
183
     *
184
     */
185

    
186
    private void executeSuppliedCommands() {
187

    
188
        if(commandsExecuted){
189
            // do not run twice
190
            // a second run could take place during initialization of the web context
191
            return;
192
        }
193
        commandsExecuted  = true;
194

    
195
        String wipeoutCmd = System.getProperty(PARAM_NAME_WIPEOUT);
196
        String createCmd = System.getProperty(PARAM_NAME_CREATE);
197

    
198
        // ============ DELETE
199
        if(wipeoutCmd != null && wipeoutCmd.matches("iapt|all")){
200

    
201
            boolean onlyIapt = wipeoutCmd.equals("iapt");
202
            List<UUID> deleteCandidates = new ArrayList<UUID>();
203

    
204
            TransactionStatus tx = repo.startTransaction(true);
205
            List<Registration> allRegs = repo.getRegistrationService().list(null, null, null, null, null);
206
            for(Registration reg : allRegs){
207
                if(onlyIapt){
208
                    try {
209
                        @SuppressWarnings("unchecked")
210
                        Set<String> extensions = reg.getName().getExtensions(getExtensionTypeIAPTRegData());
211
                        deleteCandidates.add(reg.getUuid());
212
                    } catch(NullPointerException e){
213
                        // IGNORE
214
                    }
215
                } else {
216
                    deleteCandidates.add(reg.getUuid());
217
                }
218
            }
219
            repo.commitTransaction(tx);
220
            repo.getRegistrationService().delete(deleteCandidates);
221
        }
222

    
223
        // ============ CREATE
224
        int pageIndex = 0;
225
        if(createCmd != null && createCmd.equals("iapt")){
226

    
227
            DateTimeFormatter dateFormat1 = org.joda.time.format.DateTimeFormat.forPattern("dd.MM.yy").withPivotYear(1950);
228
            DateTimeFormatter dateFormat2 = org.joda.time.format.DateTimeFormat.forPattern("yyyy-MM-dd").withPivotYear(1950);
229

    
230
            TransactionStatus tx = repo.startTransaction(false);
231
            while(true) {
232
                Pager<TaxonName> pager = repo.getNameService().page(null, 1000, pageIndex, null, null);
233
                if(pager.getRecords().isEmpty()){
234
                    break;
235
                }
236
                List<Registration> newRegs = new ArrayList<>(pager.getRecords().size());
237
                for(TaxonName name : pager.getRecords()){
238

    
239
                    Set<String> extensionValues = name.getExtensions(getExtensionTypeIAPTRegData());
240

    
241
                    // there is for sure only one
242
                    if(extensionValues.isEmpty()){
243
                        continue;
244
                    }
245
                    String iaptJson = extensionValues.iterator().next();
246
                    try {
247

    
248
                        IAPTRegData iaptData = new ObjectMapper().readValue(iaptJson, IAPTRegData.class);
249

    
250
                        if(iaptData.getRegId() == null){
251
                            continue;
252
                        }
253

    
254
                        DateTime regDate = null;
255
                        if(iaptData.getDate() != null){
256
                            DateTimeFormatter dateFormat;
257
                            if(iaptData.getDate().matches("\\d{4}-\\d{2}-\\d{2}")){
258
                                dateFormat = dateFormat2;
259
                            } else {
260
                                dateFormat = dateFormat1;
261
                            }
262
                            try {
263
                                regDate = dateFormat.parseDateTime(iaptData.getDate());
264
                                regDate.getYear();
265
                            } catch (Exception e) {
266
                                logger.error("Error parsing date : " + iaptData.getDate(), e);
267
                                continue;
268
                            }
269
                        }
270

    
271
                        Registration reg = Registration.NewInstance();
272
                        reg.setStatus(RegistrationStatus.PUBLISHED);
273
                        reg.setIdentifier("http://phycobank.org/" + iaptData.getRegId());
274
                        reg.setSpecificIdentifier(iaptData.getRegId().toString());
275
                        reg.setInstitution(getInstitution(iaptData.getOffice()));
276
                        reg.setName(name);
277
                        if(name.getTypeDesignations() != null && !name.getTypeDesignations().isEmpty()){
278
                            // do not add the collection directly to avoid "Found shared references to a collection" problem
279
                            HashSet<TypeDesignationBase> typeDesignations = new HashSet<>(name.getTypeDesignations().size());
280
                            typeDesignations.addAll(name.getTypeDesignations());
281
                            reg.setTypeDesignations(typeDesignations);
282
                        }
283
                        reg.setRegistrationDate(regDate);
284
                        logger.debug("IAPT Registraion for " + name.getTitleCache());
285
                        newRegs.add(reg);
286

    
287
                    } catch (JsonParseException e) {
288
                        logger.error("Error parsing IAPTRegData from extension", e);
289
                    } catch (JsonMappingException e) {
290
                        logger.error("Error mapping json from extension to IAPTRegData", e);
291
                    } catch (IOException e) {
292
                        logger.error(e);
293
                    }
294

    
295
                }
296
                repo.getRegistrationService().save(newRegs);
297
                repo.getRegistrationService().getSession().flush();
298
                logger.debug("Registrations saved");
299
                pageIndex++;
300
            }
301
            repo.commitTransaction(tx);
302
        }
303
    }
304

    
305

    
306
    /**
307
     * @param office
308
     * @return
309
     */
310
    private Institution getInstitution(String office) {
311
        Institution institution;
312
        if(instituteMap.containsKey(office)){
313
            institution = instituteMap.get(office);
314
        } else {
315

    
316
            Pager<AgentBase> pager = repo.getAgentService().findByTitle(Institution.class, office, MatchMode.EXACT, null, null, null, null, null);
317
            if(!pager.getRecords().isEmpty()){
318
                institution =  (Institution) pager.getRecords().get(0);
319
            } else {
320
                Institution institute = (Institution) repo.getAgentService().save(Institution.NewNamedInstance(office));
321
                institution = institute;
322
            }
323
            instituteMap.put(office, institution);
324
        }
325
        return institution;
326
    }
327

    
328

    
329
    private ExtensionType getExtensionTypeIAPTRegData() {
330
        if(extensionTypeIAPTRegData == null){
331
            extensionTypeIAPTRegData = (ExtensionType) repo.getTermService().load(UUID.fromString("9be1bfe3-6ba0-4560-af15-86971ab96e09"));
332
        }
333
        return extensionTypeIAPTRegData;
334
    }
335

    
336

    
337

    
338
}
(2-2/2)