ref #6241 change @date to @since in appimport
[cdmlib-apps.git] / app-import / src / main / java / eu / etaxonomy / cdm / io / mexico / MexicoBorhidiExcelImport.java
1 /**
2 * Copyright (C) 2016 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.io.mexico;
10
11 import java.net.URI;
12 import java.net.URISyntaxException;
13 import java.util.Arrays;
14 import java.util.HashMap;
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.springframework.stereotype.Component;
21
22 import eu.etaxonomy.cdm.common.CdmUtils;
23 import eu.etaxonomy.cdm.common.UTF8;
24 import eu.etaxonomy.cdm.model.common.DefinedTerm;
25 import eu.etaxonomy.cdm.model.common.Extension;
26 import eu.etaxonomy.cdm.model.common.ExtensionType;
27 import eu.etaxonomy.cdm.model.common.Identifier;
28 import eu.etaxonomy.cdm.model.common.TermVocabulary;
29 import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
30 import eu.etaxonomy.cdm.model.description.Feature;
31 import eu.etaxonomy.cdm.model.description.TaxonNameDescription;
32 import eu.etaxonomy.cdm.model.description.TextData;
33 import eu.etaxonomy.cdm.model.media.Media;
34 import eu.etaxonomy.cdm.model.name.IBotanicalName;
35 import eu.etaxonomy.cdm.model.name.NomenclaturalCode;
36 import eu.etaxonomy.cdm.model.name.Rank;
37 import eu.etaxonomy.cdm.model.name.TaxonName;
38 import eu.etaxonomy.cdm.model.name.TaxonNameFactory;
39 import eu.etaxonomy.cdm.model.reference.Reference;
40 import eu.etaxonomy.cdm.model.reference.ReferenceFactory;
41 import eu.etaxonomy.cdm.model.taxon.Classification;
42 import eu.etaxonomy.cdm.model.taxon.Taxon;
43 import eu.etaxonomy.cdm.model.taxon.TaxonNode;
44 import eu.etaxonomy.cdm.strategy.parser.TimePeriodParser;
45
46 /**
47 * @author a.mueller
48 * @since 16.06.2016
49 *
50 */
51 @Component
52 public class MexicoBorhidiExcelImport<CONFIG extends MexicoBorhidiImportConfigurator>
53 extends SimpleExcelTaxonImport<CONFIG>{
54 private static final Logger logger = Logger.getLogger(MexicoBorhidiExcelImport.class);
55 private static final long serialVersionUID = -3607776356577606657L;
56
57 private static List<String> expectedKeys= Arrays.asList(new String[]{
58 "FullnameNoAuthors","OutputNameID","OutputFullNameWithAuthors","RefType"
59 ,"OutputAbbreviatedTitle","OutputCollation","OutputVolume",
60 "OutputIssue","OutputPage","OutputTitlePageYear","OutputYearPublished",
61 "OutputBHLLink"});
62
63
64 @Override
65 protected void firstPass(SimpleExcelTaxonImportState<CONFIG> state) {
66 String line = state.getCurrentLine() + ": ";
67 HashMap<String, String> record = state.getOriginalRecord();
68
69 Set<String> keys = record.keySet();
70 checkAllKeysExist(line, keys, expectedKeys);
71
72 if (record.get("FullnameNoAuthors") == null ){
73 logger.warn("No FullnameNoAuthors given: " + line);
74 return;
75 }
76
77 //Name
78 IBotanicalName speciesName = makeName(record, state);
79
80 //Taxon
81 Reference sec = state.getConfig().getSecReference();
82 Taxon taxon = Taxon.NewInstance(speciesName, sec);
83 TaxonNode rubiaceae = getHighestNode(state);
84
85 taxon.addSource(makeOriginalSource(state));
86
87
88 //make genus
89 makeGenus(state, speciesName, sec, taxon, rubiaceae);
90 }
91
92
93 private Classification classification;
94 private TaxonNode rubiaceaeNode;
95 /**
96 * @return
97 */
98 private TaxonNode getHighestNode(SimpleExcelTaxonImportState<CONFIG> state) {
99 if (rubiaceaeNode == null){
100 MexicoBorhidiImportConfigurator config = state.getConfig();
101 classification = Classification.NewInstance(state.getConfig().getClassificationName());
102 classification.setUuid(config.getClassificationUuid());
103 classification.setReference(config.getSecReference());
104 IBotanicalName nameRubiaceae = TaxonNameFactory.NewBotanicalInstance(Rank.FAMILY());
105 nameRubiaceae.setGenusOrUninomial("Rubiaceae");
106 Taxon rubiaceaeTaxon = Taxon.NewInstance(nameRubiaceae, classification.getReference());
107 rubiaceaeNode = classification.addChildTaxon(rubiaceaeTaxon, null, null);
108 getClassificationService().save(classification);
109 }
110 return rubiaceaeNode;
111 }
112
113 /**
114 * @param record
115 * @param state
116 * @return
117 */
118 private IBotanicalName makeName(HashMap<String, String> record, SimpleExcelTaxonImportState<CONFIG> state) {
119 String line = state.getCurrentLine() + ": ";
120
121 String fullNameStr = getValue(record, "OutputFullNameWithAuthors");
122 // String volume = getValue(record, "OutputVolume");
123 // String issue = getValue(record, "OutputIssue");
124 // String page = getValue(record, "OutputPage");
125 String titleYear = getValue(record, "OutputTitlePageYear");
126 String publishedYear = getValue(record, "OutputYearPublished");
127 String refAbbrevTitle = getValue(record, "OutputAbbreviatedTitle");
128 String outputCollation = getValue(record, "OutputCollation");
129 String refType = getValue(record, "RefType");
130
131
132 TaxonName name = (TaxonName)nameParser.parseFullName(fullNameStr, NomenclaturalCode.ICNAFP, Rank.SPECIES());
133 if (name.isProtectedTitleCache()){
134 //for the 2 ined. names
135 name = (TaxonName)nameParser.parseReferencedName(fullNameStr, NomenclaturalCode.ICNAFP, Rank.SPECIES());
136 }
137 if (name.isProtectedTitleCache()){
138 logger.warn(line + "Name could not be parsed: " + fullNameStr );
139 }else{
140 replaceAuthorNamesAndNomRef(state, name);
141 }
142
143 if (refAbbrevTitle != null){
144 String[] volumeDetail = makeVolumeDetail(outputCollation);
145 String detail;
146 String volume = null;
147 if (volumeDetail.length > 1){
148 volume = volumeDetail[0].trim();
149 detail = volumeDetail[1].trim();
150 }else{
151 detail = volumeDetail[0].trim();
152 }
153
154 refAbbrevTitle = refAbbrevTitle.trim();
155 boolean isArticle = "A".equalsIgnoreCase(refType);
156
157 if (isArticle){
158 if (! "A".equalsIgnoreCase(refType)){
159 logger.warn(line + "RefType problem with article " + refType);
160 }
161
162 Reference journal = state.getReference(refAbbrevTitle);
163 if (journal == null){
164 journal = ReferenceFactory.newJournal();
165 journal.setAbbrevTitle(refAbbrevTitle);
166 state.putReference(refAbbrevTitle, journal);
167 journal.addSource(makeOriginalSource(state));
168
169 }
170 Reference article = ReferenceFactory.newArticle();
171
172
173 // String detail = page;
174 name.setNomenclaturalMicroReference(detail);
175
176 article.setVolume(CdmUtils.Ne(volume));
177 article.setInReference(journal);
178
179 titleYear = (isBlank(publishedYear)? titleYear : UTF8.QUOT_DBL_LOW9 + titleYear + UTF8.QUOT_DBL_HIGH_REV9 + "[" + publishedYear + "]");
180 article.setDatePublished(TimePeriodParser.parseString(titleYear));
181
182 article.setAuthorship(name.getCombinationAuthorship());
183
184 Reference existingArticle = state.getReference(article.getTitleCache());
185 if (existingArticle != null){
186 name.setNomenclaturalReference(existingArticle);
187 }else{
188 name.setNomenclaturalReference(article);
189 state.putReference(article.getTitleCache(), article);
190 article.addSource(makeOriginalSource(state));
191 }
192 }else{
193 if (! "B".equalsIgnoreCase(refType)){
194 logger.warn(line + "RefType problem with book" + refType);
195 }
196
197 Reference book = ReferenceFactory.newBook();
198 book.setAbbrevTitle(refAbbrevTitle);
199
200 //year
201 titleYear = (isBlank(publishedYear)? titleYear : UTF8.QUOT_DBL_LOW9 + titleYear + UTF8.QUOT_DBL_HIGH_REV9 + "[" + publishedYear + "]");
202 book.setDatePublished(TimePeriodParser.parseString(titleYear));
203
204 book.setAuthorship(name.getCombinationAuthorship());
205
206 //deduplicate
207 Reference existingBook = state.getReference(book.getTitleCache());
208 if (existingBook != null){
209 name.setNomenclaturalReference(existingBook);
210 }else{
211 name.setNomenclaturalReference(book);
212 state.putReference(book.getTitleCache(), book);
213 }
214
215 book.setVolume(volume);
216
217 //String detail = page;
218 name.setNomenclaturalMicroReference(detail);
219 }
220 }
221
222 addNomRefExtension(state, name);
223
224 //add protologue
225 String bhlLink = record.get("OutputBHLLink");
226 if (isNotBlank(bhlLink)){
227 URI uri;
228 try {
229 uri = new URI(bhlLink);
230 Media media = Media.NewInstance(uri, null, null, null);
231 TaxonNameDescription desc = TaxonNameDescription.NewInstance(name);
232 desc.setTitleCache("Protologue for " + name.getNameCache(), true);
233 DescriptionElementBase elem = TextData.NewInstance(Feature.PROTOLOGUE());
234 elem.addMedia(media);
235 desc.addElement(elem);
236 } catch (URISyntaxException e) {
237 logger.warn(line + "URI could not be parsed: " + e.getMessage());
238 }
239 }
240
241 //add tropicos identifier
242 String tropicosId = record.get("OutputNameID");
243 if (isNotBlank(tropicosId)){
244 String tropicosIdTypeLabel = "Tropicos Name Identifier";
245 UUID uuid = DefinedTerm.uuidTropicosNameIdentifier;
246 TermVocabulary<DefinedTerm> voc = null; //for now it goes to user defined voc
247 DefinedTerm identifierType = this.getIdentiferType(state, uuid, tropicosIdTypeLabel, tropicosIdTypeLabel, null, voc);
248 Identifier<Taxon> identifier = Identifier.NewInstance(tropicosId, identifierType);
249 name.addIdentifier(identifier);
250 }
251
252 name.addSource(makeOriginalSource(state));
253
254
255 return name;
256 }
257
258 /**
259 * @param outputCollation
260 * @return
261 */
262 private String[] makeVolumeDetail(String outputCollation) {
263 if (outputCollation == null){
264 return new String[0];
265 }else{
266 String[] split = outputCollation.split(":");
267 return split;
268 }
269 }
270
271 /**
272 * @param state
273 * @param referencedName
274 */
275 private void addNomRefExtension(SimpleExcelTaxonImportState<CONFIG> state, IBotanicalName name) {
276 String newExtensionStr = name.getFullTitleCache() + " - BORHIDI";
277 UUID uuidNomRefExtension = MexicoConabioTransformer.uuidNomRefExtension;
278 for (Extension extension : name.getExtensions()){
279 if (extension.getType().getUuid().equals(uuidNomRefExtension)){
280 extension.setValue(extension.getValue() + "\n" + newExtensionStr);
281 return;
282 }
283 }
284 String label = "Nomenclatural reference in Sources";
285 String abbrev = "Nom. ref. src.";
286 ExtensionType extensionType = getExtensionType(state, uuidNomRefExtension, label, label, abbrev);
287 Extension.NewInstance((TaxonName)name, newExtensionStr, extensionType);
288 }
289
290
291 }