#5448 Remove non-exisiting hybrid category
[cdmlib-apps.git] / app-import / src / main / java / eu / etaxonomy / cdm / io / mexico / SimpleExcelTaxonImport.java
1 // $Id$
2 /**
3 * Copyright (C) 2016 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
6 *
7 * The contents of this file are subject to the Mozilla Public License Version 1.1
8 * See LICENSE.TXT at the top of this package for the full license terms.
9 */
10 package eu.etaxonomy.cdm.io.mexico;
11
12 import java.util.Arrays;
13 import java.util.HashMap;
14 import java.util.List;
15 import java.util.Map;
16 import java.util.Set;
17
18 import org.apache.commons.lang.StringUtils;
19 import org.apache.log4j.Logger;
20
21 import eu.etaxonomy.cdm.common.CdmUtils;
22 import eu.etaxonomy.cdm.io.excel.common.ExcelImportConfiguratorBase;
23 import eu.etaxonomy.cdm.io.excel.common.ExcelImporterBase;
24 import eu.etaxonomy.cdm.model.agent.Person;
25 import eu.etaxonomy.cdm.model.agent.Team;
26 import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
27 import eu.etaxonomy.cdm.model.common.IdentifiableSource;
28 import eu.etaxonomy.cdm.model.name.BotanicalName;
29 import eu.etaxonomy.cdm.model.name.Rank;
30 import eu.etaxonomy.cdm.model.reference.INomenclaturalReference;
31 import eu.etaxonomy.cdm.model.reference.Reference;
32 import eu.etaxonomy.cdm.model.taxon.Taxon;
33 import eu.etaxonomy.cdm.model.taxon.TaxonNode;
34 import eu.etaxonomy.cdm.strategy.parser.INonViralNameParser;
35 import eu.etaxonomy.cdm.strategy.parser.NonViralNameParserImpl;
36
37 /**
38 * Simple Excel import class that works without default state class
39 * {@link SimpleExcelTaxonImportState}
40 * @author a.mueller
41 * @date 16.06.2016
42 */
43 public abstract class SimpleExcelTaxonImport<CONFIG extends ExcelImportConfiguratorBase>
44 extends ExcelImporterBase<SimpleExcelTaxonImportState<CONFIG>>{
45
46 private static final long serialVersionUID = -4345647703312616421L;
47
48 private static final Logger logger = Logger.getLogger(SimpleExcelTaxonImport.class);
49
50 protected static INonViralNameParser<?> nameParser = NonViralNameParserImpl.NewInstance();
51
52
53 @Override
54 protected void analyzeRecord(HashMap<String, String> record, SimpleExcelTaxonImportState<CONFIG> state) {
55 //override only if needed
56 }
57
58 @Override
59 protected void secondPass(SimpleExcelTaxonImportState<CONFIG> state) {
60 //override only if needed
61 }
62
63 @Override
64 protected boolean isIgnore(SimpleExcelTaxonImportState<CONFIG> state) {
65 return false;
66 }
67
68 //***************************** METHODS *********************************/
69 /**
70 * Returns the value of the record map for the given key.
71 * The value is trimmed and empty values are set to <code>null</code>.
72 * @param record
73 * @param originalKey
74 * @return
75 */
76 protected String getValue(Map<String, String> record, String originalKey) {
77 String value = record.get(originalKey);
78 if (! StringUtils.isBlank(value)) {
79 if (logger.isDebugEnabled()) { logger.debug(originalKey + ": " + value); }
80 value = CdmUtils.removeDuplicateWhitespace(value.trim()).toString();
81 return value;
82 }else{
83 return null;
84 }
85 }
86
87 /**
88 * @param state
89 * @return
90 */
91 protected IdentifiableSource makeOriginalSource(SimpleExcelTaxonImportState<CONFIG> state) {
92 return IdentifiableSource.NewDataImportInstance("line: " + state.getCurrentLine(), null, state.getConfig().getSourceReference());
93 }
94
95 /**
96 * @param state
97 * @param speciesName
98 * @param sec
99 * @param taxon
100 * @param familyNode
101 */
102 protected void makeGenus(SimpleExcelTaxonImportState<CONFIG> state,
103 BotanicalName speciesName,
104 Reference sec,
105 Taxon taxon,
106 TaxonNode familyNode) {
107
108 TaxonNode higherNode;
109 if (speciesName.isProtectedTitleCache()){
110 higherNode = familyNode;
111 }else{
112 String genusStr = speciesName.getGenusOrUninomial();
113 Taxon genus = state.getHigherTaxon(genusStr);
114 if (genus != null){
115 higherNode = genus.getTaxonNodes().iterator().next();
116 }else{
117 BotanicalName genusName = BotanicalName.NewInstance(Rank.GENUS());
118 genusName.addSource(makeOriginalSource(state));
119 genusName.setGenusOrUninomial(genusStr);
120 genus = Taxon.NewInstance(genusName, sec);
121 genus.addSource(makeOriginalSource(state));
122 higherNode = familyNode.addChildTaxon(genus, null, null);
123 state.putHigherTaxon(genusStr, genus);
124 }
125 }
126
127 higherNode.addChildTaxon(taxon, null, null);
128 }
129
130 /**
131 * @param line
132 * @param keys
133 * @param expectedKeys
134 */
135 protected void checkAllKeysExist(String line, Set<String> keys, List<String> expectedKeys) {
136 for (String key: keys) {
137 if (! expectedKeys.contains(key)){
138 logger.warn(line + "Unexpected Key: " + key);
139 }
140 }
141 }
142
143
144 /**
145 * @param state
146 * @param name
147 */
148 protected void replaceAuthorNamesAndNomRef(SimpleExcelTaxonImportState<CONFIG> state, BotanicalName name) {
149 TeamOrPersonBase<?> combAuthor = name.getCombinationAuthorship();
150 name.setCombinationAuthorship(getExistingAuthor(state, combAuthor));
151
152 TeamOrPersonBase<?> exAuthor = name.getExCombinationAuthorship();
153 name.setExCombinationAuthorship(getExistingAuthor(state, exAuthor));
154
155 TeamOrPersonBase<?> basioAuthor = name.getBasionymAuthorship();
156 name.setBasionymAuthorship(getExistingAuthor(state, basioAuthor));
157
158 TeamOrPersonBase<?> exBasioAuthor = name.getExBasionymAuthorship();
159 name.setExBasionymAuthorship(getExistingAuthor(state, exBasioAuthor));
160
161 INomenclaturalReference nomRef = name.getNomenclaturalReference();
162 if (nomRef != null){
163 TeamOrPersonBase<?> refAuthor = nomRef.getAuthorship();
164 nomRef.setAuthorship(getExistingAuthor(state, refAuthor));
165
166 Reference existingRef = getExistingReference(state, (Reference)nomRef);
167 if (existingRef != null){
168 name.setNomenclaturalReference(existingRef);
169 }
170 }
171 }
172
173 /**
174 * @param state
175 * @param nomRef
176 */
177 private Reference getExistingReference(SimpleExcelTaxonImportState<CONFIG> state, Reference ref) {
178 if (ref == null){
179 return null;
180 }else{
181 initRerenceMap(state);
182 Reference result = state.getReference(ref.getTitleCache());
183 if (result == null){
184 result = ref;
185 Reference inRef = result.getInReference();
186 if (inRef != null){
187 result.setInReference(getExistingReference(state, result.getInReference()));
188 }
189 state.putReference(result.getTitleCache(), result);
190 }
191 return result;
192 }
193 }
194
195 boolean referenceMapIsInitialized;
196
197 /**
198 * @param state
199 */
200 private void initRerenceMap(SimpleExcelTaxonImportState<CONFIG> state) {
201 if (!referenceMapIsInitialized){
202 List<String> propertyPaths = Arrays.asList("");
203 List<Reference> existingReferences = this.getReferenceService().list(null, null, null, null, propertyPaths);
204 for (Reference ref : existingReferences){
205 state.putReference(ref.getTitleCache(), ref);
206 }
207 referenceMapIsInitialized = true;
208 }
209
210 }
211
212 boolean agentMapIsInitialized = false;
213
214 /**
215 * @param state
216 *
217 */
218 @SuppressWarnings("rawtypes")
219 private void initAgentMap(SimpleExcelTaxonImportState<CONFIG> state) {
220 if (!agentMapIsInitialized){
221 List<String> propertyPaths = Arrays.asList("");
222 List<TeamOrPersonBase> existingAgents = this.getAgentService().list(null, null, null, null, propertyPaths);
223 for (TeamOrPersonBase agent : existingAgents){
224 state.putAgentBase(agent.getTitleCache(), agent);
225 }
226 agentMapIsInitialized = true;
227 }
228 }
229
230 /**
231 * @param state
232 * @param combAuthor
233 * @return
234 */
235 protected TeamOrPersonBase<?> getExistingAuthor(SimpleExcelTaxonImportState<CONFIG> state,
236 TeamOrPersonBase<?> author) {
237 if (author == null){
238 return null;
239 }else{
240 initAgentMap(state);
241 TeamOrPersonBase<?> result = state.getAgentBase(author.getTitleCache());
242 if (result == null){
243 state.putAgentBase(author.getTitleCache(), author);
244 if (author instanceof Team){
245 handleTeam(state, (Team)author);
246 }
247 result = author;
248 }
249 return result;
250 }
251 }
252
253
254 /**
255 * @param state
256 * @param author
257 */
258 private void handleTeam(SimpleExcelTaxonImportState<CONFIG> state, Team team) {
259 List<Person> members = team.getTeamMembers();
260 for (int i =0; i< members.size(); i++){
261 Person person = members.get(i);
262 //FIXME cast find a better way to guarantee that only persons are returned
263 Person existingPerson = (Person)state.getAgentBase(person.getTitleCache());
264 if (existingPerson != null){
265 members.set(i, existingPerson);
266 }else{
267 state.putAgentBase(person.getTitleCache(), person);
268 }
269 }
270
271 }
272
273
274 }