Project

General

Profile

Download (10.8 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.mock;
10

    
11
import java.io.IOException;
12
import java.util.ArrayList;
13
import java.util.Collection;
14
import java.util.HashSet;
15
import java.util.List;
16
import java.util.Set;
17
import java.util.UUID;
18

    
19
import org.apache.log4j.Logger;
20
import org.joda.time.DateTime;
21
import org.joda.time.format.DateTimeFormatter;
22
import org.springframework.beans.factory.annotation.Autowired;
23
import org.springframework.beans.factory.annotation.Qualifier;
24
import org.springframework.context.ApplicationListener;
25
import org.springframework.context.event.ContextRefreshedEvent;
26
import org.springframework.stereotype.Service;
27
import org.springframework.transaction.TransactionStatus;
28
import org.springframework.transaction.annotation.Transactional;
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.service.pager.Pager;
36
import eu.etaxonomy.cdm.model.agent.AgentBase;
37
import eu.etaxonomy.cdm.model.agent.Institution;
38
import eu.etaxonomy.cdm.model.common.Extension;
39
import eu.etaxonomy.cdm.model.common.ExtensionType;
40
import eu.etaxonomy.cdm.model.name.Registration;
41
import eu.etaxonomy.cdm.model.name.RegistrationStatus;
42
import eu.etaxonomy.cdm.model.name.TaxonNameBase;
43
import eu.etaxonomy.cdm.model.name.TypeDesignationBase;
44
import eu.etaxonomy.cdm.persistence.query.MatchMode;
45
import eu.etaxonomy.cdm.vaadin.model.registration.RegistrationWorkingSet;
46
import eu.etaxonomy.cdm.vaadin.view.registration.RegistrationDTO;
47
import eu.etaxonomy.cdm.vaadin.view.registration.RegistrationValidationException;
48

    
49
/**
50
 * Provides RegistrationDTOs and RegistrationWorkingsets for Registrations in the database.
51
 * <p>
52
 * Can create missing registrations for names which have Extensions of the Type <code>IAPTRegdata.json</code>.
53
 * See https://dev.e-taxonomy.eu/redmine/issues/6621 for further details.
54
 * This feature can be activated by by supplying one of the following jvm command line arguments:
55
 * <ul>
56
 * <li><code>-DregistrationCreate=iapt</code>: create all iapt Registrations if missing</li>
57
 * <li><code>-DregistrationWipeout=iapt</code>: remove all iapt Registrations</li>
58
 * <li><code>-DregistrationWipeout=all</code>: remove all Registrations</li>
59
 * </ul>
60
 * The <code>-DregistrationWipeout</code> commands are executed before the <code>-DregistrationCreate</code> and will not change the name and type designations.
61
 *
62
 *
63
 * @author a.kohlbecker
64
 * @since Mar 10, 2017
65
 *
66
 */
67
@Service("registrationWorkingSetService")
68
@Transactional(readOnly=true)
69
public class RegistrationWorkingSetService implements IRegistrationWorkingSetService, ApplicationListener<ContextRefreshedEvent> {
70

    
71
    protected static final String PARAM_NAME_CREATE = "registrationCreate";
72

    
73
    protected static final String PARAM_NAME_WIPEOUT = "registrationWipeout";
74

    
75
    private static final Logger logger = Logger.getLogger(RegistrationWorkingSetService.class);
76

    
77
    @Autowired
78
    @Qualifier("cdmRepository")
79
    private CdmRepository repo;
80

    
81
    private ExtensionType extensionTypeIAPTRegData;
82

    
83
    public RegistrationWorkingSetService() {
84

    
85
    }
86

    
87

    
88
    /**
89
     *
90
     */
91

    
92
    private void executeSuppliedCommands() {
93

    
94
        String wipeoutCmd = System.getProperty(PARAM_NAME_WIPEOUT);
95
        String createCmd = System.getProperty(PARAM_NAME_CREATE);
96

    
97
        // ============ DELETE
98
        if(wipeoutCmd != null && wipeoutCmd.matches("iapt|all")){
99

    
100
            boolean onlyIapt = wipeoutCmd.equals("iapt");
101
            List<UUID> deleteCandidates = new ArrayList<UUID>();
102

    
103
            TransactionStatus tx = repo.startTransaction(true);
104
            List<Registration> allRegs = repo.getRegistrationService().list(null, null, null, null, null);
105
            for(Registration reg : allRegs){
106
                if(onlyIapt){
107
                    try {
108
                        @SuppressWarnings("unchecked")
109
                        Set<Extension> extensions = reg.getName().getExtensions(getExtensionTypeIAPTRegData());
110
                        deleteCandidates.add(reg.getUuid());
111
                    } catch(NullPointerException e){
112
                        // IGNORE
113
                    }
114
                } else {
115
                    deleteCandidates.add(reg.getUuid());
116
                }
117
            }
118
            repo.commitTransaction(tx);
119
            repo.getRegistrationService().delete(deleteCandidates);
120
        }
121

    
122
        // ============ CREATE
123
        int pageIndex = 0;
124
        if(createCmd != null && createCmd.equals("iapt")){
125

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

    
128
            TransactionStatus tx = repo.startTransaction(false);
129
            while(true) {
130
                Pager<TaxonNameBase> pager = repo.getNameService().page(null, 1000, pageIndex, null, null);
131
                if(pager.getRecords().isEmpty()){
132
                    break;
133
                }
134
                List<Registration> newRegs = new ArrayList<>(pager.getRecords().size());
135
                for(TaxonNameBase name : pager.getRecords()){
136

    
137
                    Set<String> extensionValues = name.getExtensions(getExtensionTypeIAPTRegData());
138

    
139
                    // there is for sure only one
140
                    if(extensionValues.isEmpty()){
141
                        continue;
142
                    }
143
                    String iaptJson = extensionValues.iterator().next();
144
                    try {
145

    
146
                        IAPTRegData iaptData = new ObjectMapper().readValue(iaptJson, IAPTRegData.class);
147

    
148
                        if(iaptData.getRegId() == null){
149
                            continue;
150
                        }
151

    
152
                        DateTime regDate = null;
153
                        if(iaptData.getDate() != null){
154
                            try {
155
                                regDate = dateFormat.parseDateTime(iaptData.getDate());
156
                                regDate.getYear();
157
                            } catch (Exception e) {
158
                                logger.error("Error parsing date: " + iaptData.getDate(), e);
159
                                continue;
160
                            }
161
                        }
162

    
163
                        Registration reg = Registration.NewInstance();
164
                        reg.setStatus(RegistrationStatus.PUBLISHED);
165
                        reg.setIdentifier("http://phycobank/" + iaptData.getRegId());
166
                        reg.setSpecificIdentifier(iaptData.getRegId().toString());
167
                        reg.setInstitution(getInstitution(iaptData.getOffice()));
168
                        reg.setName(name);
169
                        if(name.getTypeDesignations() != null && !name.getTypeDesignations().isEmpty()){
170
                            // do not add the collection directly to avoid "Found shared references to a collection" problem
171
                            HashSet<TypeDesignationBase> typeDesignations = new HashSet<>(name.getTypeDesignations().size());
172
                            typeDesignations.addAll(name.getTypeDesignations());
173
                            reg.setTypeDesignations(typeDesignations);
174
                        }
175
                        reg.setRegistrationDate(regDate);
176
                        logger.debug("IAPT Registraion for " + name.getTitleCache());
177
                        newRegs.add(reg);
178

    
179
                    } catch (JsonParseException e) {
180
                        logger.error("Error parsing IAPTRegData from extension", e);
181
                    } catch (JsonMappingException e) {
182
                        logger.error("Error mapping json from extension to IAPTRegData", e);
183
                    } catch (IOException e) {
184
                        logger.error(e);
185
                    }
186

    
187
                }
188
                repo.getRegistrationService().save(newRegs);
189
                repo.getRegistrationService().getSession().flush();
190
                logger.debug("Registrations saved");
191
                pageIndex++;
192
            }
193
            repo.commitTransaction(tx);
194
        }
195
    }
196

    
197
    /**
198
     * @param office
199
     * @return
200
     */
201
    private Institution getInstitution(String office) {
202
        Pager<AgentBase> pager = repo.getAgentService().findByTitle(Institution.class, office, MatchMode.EXACT, null, null, null, null, null);
203
        if(!pager.getRecords().isEmpty()){
204
            return (Institution) pager.getRecords().get(0);
205
        } else {
206
            Institution institute = (Institution) repo.getAgentService().save(Institution.NewNamedInstance(office));
207
            return institute;
208
        }
209
    }
210

    
211

    
212
    private ExtensionType getExtensionTypeIAPTRegData() {
213
        if(extensionTypeIAPTRegData == null){
214
            extensionTypeIAPTRegData = (ExtensionType) repo.getTermService().load(UUID.fromString("9be1bfe3-6ba0-4560-af15-86971ab96e09"));
215
        }
216
        return extensionTypeIAPTRegData;
217
    }
218

    
219

    
220
    int minTypeDesignationCount = 1;
221

    
222

    
223
    @Override
224
    public Collection<RegistrationDTO> listDTOs() {
225

    
226
        List<Registration> regs = repo.getRegistrationService().list(null, 50, 0, null, null);
227

    
228
        List<RegistrationDTO> dtos = makeDTOs(regs);
229
        return dtos;
230
    }
231

    
232

    
233
    /**
234
     * @param regs
235
     * @return
236
     */
237
    private List<RegistrationDTO> makeDTOs(List<Registration> regs) {
238
        List<RegistrationDTO> dtos = new ArrayList<>(regs.size());
239
        regs.forEach(reg -> {dtos.add(new RegistrationDTO(reg));});
240
        return dtos;
241
    }
242

    
243
    /**
244
     * @param id the CDM Entity id
245
     * @return
246
     */
247
    @Override
248
    public RegistrationDTO loadDtoById(Integer id) {
249
        Registration reg = repo.getRegistrationService().find(id);
250
        return new RegistrationDTO(reg);
251
    }
252

    
253
    /**
254
     * @param  id the CDM Entity id
255
     * @return
256
     * @throws RegistrationValidationException
257
     */
258
    @Override
259
    public RegistrationWorkingSet loadWorkingSetByRegistrationID(Integer id) throws RegistrationValidationException {
260

    
261
        RegistrationDTO dto = loadDtoById(id);
262

    
263
        Pager<Registration> pager = null;
264

    
265
        List<Registration> workingSetRegs;
266

    
267
        if (pager == null){
268
            //FIXME remove below mock function once the service if fully working
269
            workingSetRegs = new ArrayList<>();
270
            workingSetRegs.add(dto.registration());
271
        } else {
272
            pager = repo.getRegistrationService().page(null, null, dto.getCitation(), null, null, null);
273
            workingSetRegs = pager.getRecords();
274
        }
275

    
276
        return new RegistrationWorkingSet(makeDTOs(workingSetRegs));
277
    }
278

    
279
    /**
280
     * {@inheritDoc}
281
     */
282
    @Override
283
    public void onApplicationEvent(ContextRefreshedEvent event) {
284
        executeSuppliedCommands();
285
    }
286

    
287

    
288
}
(4-4/4)