Project

General

Profile

Download (12 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.HashMap;
15
import java.util.HashSet;
16
import java.util.List;
17
import java.util.Map;
18
import java.util.Set;
19
import java.util.UUID;
20

    
21
import org.apache.log4j.Logger;
22
import org.joda.time.DateTime;
23
import org.joda.time.format.DateTimeFormatter;
24
import org.springframework.context.ApplicationListener;
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.CdmRepository;
35
import eu.etaxonomy.cdm.api.application.RunAsAuthenticator;
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.Role;
47
import eu.etaxonomy.cdm.persistence.query.MatchMode;
48
import eu.etaxonomy.cdm.vaadin.model.registration.DerivationEventTypes;
49
import eu.etaxonomy.cdm.vaadin.security.RolesAndPermissions;
50

    
51
/**
52
 * @author a.kohlbecker
53
 * @since May 9, 2017
54
 *
55
 */
56
public class RegistrationRequiredDataInserter extends RunAsAuthenticator implements ApplicationListener<ContextRefreshedEvent>{
57

    
58
    protected static final String PARAM_NAME_CREATE = "registrationCreate";
59

    
60
    protected static final String PARAM_NAME_WIPEOUT = "registrationWipeout";
61

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

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

    
66
    private static final Logger logger = Logger.getLogger(RegistrationRequiredDataInserter.class);
67

    
68
    private ExtensionType extensionTypeIAPTRegData;
69

    
70
    Map<String, Institution> instituteMap = new HashMap<>();
71

    
72
    public static boolean commandsExecuted = false;
73

    
74
    private CdmRepository repo;
75

    
76
    private boolean hasRun = false;
77

    
78
    public void setCdmRepository(CdmRepository repo){
79
      this.repo = repo;
80
    }
81

    
82

    
83
 // ==================== Registration creation ======================= //
84

    
85
    /**
86
     * {@inheritDoc}
87
     */
88
    @Override
89
    public void onApplicationEvent(ContextRefreshedEvent event) {
90

    
91
        if(hasRun){
92
            return;
93
        }
94

    
95
        runAsAuthentication(Role.ROLE_ADMIN);
96

    
97
        insertRequiredData();
98
        executeSuppliedCommands();
99

    
100
        restoreAuthentication();
101

    
102
        hasRun = true;
103
    }
104

    
105
    /**
106
     *
107
     */
108
    private void insertRequiredData() {
109

    
110
        Role roleCuration = RolesAndPermissions.ROLE_CURATION;
111
        if(repo.getGrantedAuthorityService().find(roleCuration.getUuid()) == null){
112
            repo.getGrantedAuthorityService().saveOrUpdate(roleCuration.asNewGrantedAuthority());
113
        }
114

    
115
        Group groupCurator = repo.getGroupService().load(GROUP_CURATOR_UUID, Arrays.asList("grantedAuthorities"));
116
        if(groupCurator == null){
117
            groupCurator = Group.NewInstance();
118
            groupCurator.setUuid(GROUP_CURATOR_UUID);
119
            groupCurator.setName("Curator");
120
        }
121
        assureGroupHas(groupCurator, "REGISTRATION[CREATE,READ,UPDATE,DELETE]");
122
        repo.getGroupService().saveOrUpdate(groupCurator);
123

    
124
        Group groupEditor = repo.getGroupService().load(Group.groupEditorUuid, Arrays.asList("grantedAuthorities"));
125
        assureGroupHas(groupEditor, "REGISTRATION[CREATE,READ]");
126
        assureGroupHas(groupEditor, "PERSON[CREATE,READ]");
127
        repo.getGroupService().saveOrUpdate(groupEditor);
128

    
129
        if(repo.getTermService().find(DerivationEventTypes.PUBLISHED_IMAGE().getUuid()) == null){
130
            repo.getTermService().save(DerivationEventTypes.PUBLISHED_IMAGE());
131
        }
132
        if(repo.getTermService().find(DerivationEventTypes.UNPUBLISHED_IMAGE().getUuid()) == null){
133
            repo.getTermService().save(DerivationEventTypes.UNPUBLISHED_IMAGE());
134
        }
135
        if(repo.getTermService().find(DerivationEventTypes.CULTURE_METABOLIC_INACTIVE().getUuid()) == null){
136
            repo.getTermService().save(DerivationEventTypes.CULTURE_METABOLIC_INACTIVE());
137
        }
138
        repo.getSession().flush();
139

    
140
    }
141

    
142
    private void assureGroupHas(Group group, String authorityString){
143
        boolean authorityExists = false;
144

    
145
        for(GrantedAuthority ga : group.getGrantedAuthorities()){
146
            if((authorityExists = ga.getAuthority().equals(authorityString)) == true){
147
                break;
148
            }
149
        }
150
        if(!authorityExists){
151
            group.addGrantedAuthority(findGrantedAuthority(authorityString));
152
        }
153
    }
154

    
155
    private GrantedAuthorityImpl findGrantedAuthority(String authorityString){
156
        GrantedAuthorityImpl ga = null;
157
        try{
158
            ga = repo.getGrantedAuthorityService().findAuthorityString(authorityString);
159
        } catch (AuthenticationCredentialsNotFoundException e){
160
            e.printStackTrace();
161
        }
162
        if(ga == null){
163
            ga = GrantedAuthorityImpl.NewInstance(authorityString);
164
            repo.getGrantedAuthorityService().save(ga);
165
        }
166
        return ga;
167
    }
168

    
169
    /**
170
     *
171
     */
172

    
173
    private void executeSuppliedCommands() {
174

    
175
        if(commandsExecuted){
176
            // do not run twice
177
            // a second run could take place during initialization of the web context
178
            return;
179
        }
180
        commandsExecuted  = true;
181

    
182
        String wipeoutCmd = System.getProperty(PARAM_NAME_WIPEOUT);
183
        String createCmd = System.getProperty(PARAM_NAME_CREATE);
184

    
185
        // ============ DELETE
186
        if(wipeoutCmd != null && wipeoutCmd.matches("iapt|all")){
187

    
188
            boolean onlyIapt = wipeoutCmd.equals("iapt");
189
            List<UUID> deleteCandidates = new ArrayList<UUID>();
190

    
191
            TransactionStatus tx = repo.startTransaction(true);
192
            List<Registration> allRegs = repo.getRegistrationService().list(null, null, null, null, null);
193
            for(Registration reg : allRegs){
194
                if(onlyIapt){
195
                    try {
196
                        @SuppressWarnings("unchecked")
197
                        Set<String> extensions = reg.getName().getExtensions(getExtensionTypeIAPTRegData());
198
                        deleteCandidates.add(reg.getUuid());
199
                    } catch(NullPointerException e){
200
                        // IGNORE
201
                    }
202
                } else {
203
                    deleteCandidates.add(reg.getUuid());
204
                }
205
            }
206
            repo.commitTransaction(tx);
207
            repo.getRegistrationService().delete(deleteCandidates);
208
        }
209

    
210
        // ============ CREATE
211
        int pageIndex = 0;
212
        if(createCmd != null && createCmd.equals("iapt")){
213

    
214
            DateTimeFormatter dateFormat = org.joda.time.format.DateTimeFormat.forPattern("dd.MM.yy").withPivotYear(1950);
215

    
216
            TransactionStatus tx = repo.startTransaction(false);
217
            while(true) {
218
                Pager<TaxonName> pager = repo.getNameService().page(null, 1000, pageIndex, null, null);
219
                if(pager.getRecords().isEmpty()){
220
                    break;
221
                }
222
                List<Registration> newRegs = new ArrayList<>(pager.getRecords().size());
223
                for(TaxonName name : pager.getRecords()){
224

    
225
                    Set<String> extensionValues = name.getExtensions(getExtensionTypeIAPTRegData());
226

    
227
                    // there is for sure only one
228
                    if(extensionValues.isEmpty()){
229
                        continue;
230
                    }
231
                    String iaptJson = extensionValues.iterator().next();
232
                    try {
233

    
234
                        IAPTRegData iaptData = new ObjectMapper().readValue(iaptJson, IAPTRegData.class);
235

    
236
                        if(iaptData.getRegId() == null){
237
                            continue;
238
                        }
239

    
240
                        DateTime regDate = null;
241
                        if(iaptData.getDate() != null){
242
                            try {
243
                                regDate = dateFormat.parseDateTime(iaptData.getDate());
244
                                regDate.getYear();
245
                            } catch (Exception e) {
246
                                logger.error("Error parsing date: " + iaptData.getDate(), e);
247
                                continue;
248
                            }
249
                        }
250

    
251
                        Registration reg = Registration.NewInstance();
252
                        reg.setStatus(RegistrationStatus.PUBLISHED);
253
                        reg.setIdentifier("http://phycobank/" + iaptData.getRegId());
254
                        reg.setSpecificIdentifier(iaptData.getRegId().toString());
255
                        reg.setInstitution(getInstitution(iaptData.getOffice()));
256
                        reg.setName(name);
257
                        if(name.getTypeDesignations() != null && !name.getTypeDesignations().isEmpty()){
258
                            // do not add the collection directly to avoid "Found shared references to a collection" problem
259
                            HashSet<TypeDesignationBase> typeDesignations = new HashSet<>(name.getTypeDesignations().size());
260
                            typeDesignations.addAll(name.getTypeDesignations());
261
                            reg.setTypeDesignations(typeDesignations);
262
                        }
263
                        reg.setRegistrationDate(regDate);
264
                        logger.debug("IAPT Registraion for " + name.getTitleCache());
265
                        newRegs.add(reg);
266

    
267
                    } catch (JsonParseException e) {
268
                        logger.error("Error parsing IAPTRegData from extension", e);
269
                    } catch (JsonMappingException e) {
270
                        logger.error("Error mapping json from extension to IAPTRegData", e);
271
                    } catch (IOException e) {
272
                        logger.error(e);
273
                    }
274

    
275
                }
276
                repo.getRegistrationService().save(newRegs);
277
                repo.getRegistrationService().getSession().flush();
278
                logger.debug("Registrations saved");
279
                pageIndex++;
280
            }
281
            repo.commitTransaction(tx);
282
        }
283
    }
284

    
285

    
286
    /**
287
     * @param office
288
     * @return
289
     */
290
    private Institution getInstitution(String office) {
291
        Institution institution;
292
        if(instituteMap.containsKey(office)){
293
            institution = instituteMap.get(office);
294
        } else {
295

    
296
            Pager<AgentBase> pager = repo.getAgentService().findByTitle(Institution.class, office, MatchMode.EXACT, null, null, null, null, null);
297
            if(!pager.getRecords().isEmpty()){
298
                institution =  (Institution) pager.getRecords().get(0);
299
            } else {
300
                Institution institute = (Institution) repo.getAgentService().save(Institution.NewNamedInstance(office));
301
                institution = institute;
302
            }
303
            instituteMap.put(office, institution);
304
        }
305
        return institution;
306
    }
307

    
308

    
309
    private ExtensionType getExtensionTypeIAPTRegData() {
310
        if(extensionTypeIAPTRegData == null){
311
            extensionTypeIAPTRegData = (ExtensionType) repo.getTermService().load(UUID.fromString("9be1bfe3-6ba0-4560-af15-86971ab96e09"));
312
        }
313
        return extensionTypeIAPTRegData;
314
    }
315

    
316

    
317

    
318
}
(2-2/2)