merge-update from trunk
[cdmlib.git] / cdmlib-io / src / main / java / eu / etaxonomy / cdm / io / berlinModel / in / BerlinModelCommonNamesImport.java
1 /**
2 * Copyright (C) 2007 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
10 package eu.etaxonomy.cdm.io.berlinModel.in;
11
12 import java.sql.ResultSet;
13 import java.sql.SQLException;
14 import java.util.ArrayList;
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.SortedSet;
21 import java.util.TreeSet;
22 import java.util.UUID;
23
24 import org.apache.commons.lang.StringUtils;
25 import org.apache.log4j.Logger;
26 import org.springframework.stereotype.Component;
27
28 import eu.etaxonomy.cdm.common.CdmUtils;
29 import eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer;
30 import eu.etaxonomy.cdm.io.berlinModel.in.validation.BerlinModelCommonNamesImportValidator;
31 import eu.etaxonomy.cdm.io.common.IOValidator;
32 import eu.etaxonomy.cdm.io.common.ResultSetPartitioner;
33 import eu.etaxonomy.cdm.io.common.Source;
34 import eu.etaxonomy.cdm.io.common.TdwgAreaProvider;
35 import eu.etaxonomy.cdm.model.common.Annotation;
36 import eu.etaxonomy.cdm.model.common.AnnotationType;
37 import eu.etaxonomy.cdm.model.common.CdmBase;
38 import eu.etaxonomy.cdm.model.common.Extension;
39 import eu.etaxonomy.cdm.model.common.ExtensionType;
40 import eu.etaxonomy.cdm.model.common.Language;
41 import eu.etaxonomy.cdm.model.common.Marker;
42 import eu.etaxonomy.cdm.model.common.MarkerType;
43 import eu.etaxonomy.cdm.model.common.Representation;
44 import eu.etaxonomy.cdm.model.description.CommonTaxonName;
45 import eu.etaxonomy.cdm.model.description.DescriptionElementSource;
46 import eu.etaxonomy.cdm.model.description.TaxonDescription;
47 import eu.etaxonomy.cdm.model.location.NamedArea;
48 import eu.etaxonomy.cdm.model.location.Country;
49 import eu.etaxonomy.cdm.model.name.TaxonNameBase;
50 import eu.etaxonomy.cdm.model.reference.Reference;
51 import eu.etaxonomy.cdm.model.taxon.Taxon;
52 import eu.etaxonomy.cdm.model.taxon.TaxonBase;
53
54 /**
55 *
56 * @author a.mueller
57 * @created 20.03.2008
58 * @version 1.0
59 */
60 @Component
61 public class BerlinModelCommonNamesImport extends BerlinModelImportBase {
62 private static final Logger logger = Logger.getLogger(BerlinModelCommonNamesImport.class);
63
64 public static final UUID REFERENCE_LANGUAGE_ISO639_2_UUID = UUID.fromString("40c4f8dd-3d9c-44a4-b77a-76e137a89a5f");
65 public static final UUID REFERENCE_LANGUAGE_STRING_UUID = UUID.fromString("2a1b678f-c27d-48c1-b43e-98fd0d426305");
66 public static final UUID STATUS_ANNOTATION_UUID = UUID.fromString("e3f7b80a-1286-458d-812c-5e818f731968");
67
68 public static final String NAMESPACE = "common name";
69
70
71 private static final String pluralString = "common names";
72 private static final String dbTableName = "emCommonName";
73
74
75 //map that stores the regions (named areas) and makes them accessible via the regionFk
76 private Map<String, NamedArea> regionMap = new HashMap<String, NamedArea>();
77
78
79
80 public BerlinModelCommonNamesImport(){
81 super(dbTableName, pluralString);
82 }
83
84
85
86 @Override
87 protected String getIdQuery(BerlinModelImportState state) {
88 String result = " SELECT CommonNameId FROM emCommonName WHERE (1=1) ";
89 if (StringUtils.isNotBlank(state.getConfig().getCommonNameFilter())){
90 result += " AND " + state.getConfig().getCommonNameFilter();
91 }
92
93 return result;
94 }
95
96
97
98 /* (non-Javadoc)
99 * @see eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportBase#getRecordQuery(eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportConfigurator)
100 */
101 @Override
102 protected String getRecordQuery(BerlinModelImportConfigurator config) {
103 String recordQuery = "";
104 recordQuery =
105 " SELECT cn.CommonNameId, cn.CommonName, PTaxon.RIdentifier AS taxonId, cn.PTNameFk, cn.RefFk AS refId, cn.Status, cn.RegionFks, cn.MisNameRefFk, " +
106 " cn.NameInSourceFk, cn.Created_When, cn.Updated_When, cn.Created_Who, cn.Updated_Who, cn.Note AS Notes, languageCommonName.Language, " +
107 " languageCommonName.LanguageOriginal, languageCommonName.ISO639_1, languageCommonName.ISO639_2, " +
108 " emLanguageReference.RefFk AS languageRefRefFk, emLanguageReference.ReferenceShort, emLanguageReference.ReferenceLong, " +
109 " emLanguageReference.LanguageFk, languageReferenceLanguage.Language AS refLanguage, languageReferenceLanguage.ISO639_2 AS refLanguageIso639_2, "+
110 " misappliedTaxon.RIdentifier AS misappliedTaxonId " +
111 " FROM PTaxon AS misappliedTaxon RIGHT OUTER JOIN " +
112 " emLanguage AS languageReferenceLanguage RIGHT OUTER JOIN " +
113 " emLanguageReference ON languageReferenceLanguage.LanguageId = emLanguageReference.LanguageFk RIGHT OUTER JOIN " +
114 " emCommonName AS cn INNER JOIN " +
115 " PTaxon ON cn.PTNameFk = PTaxon.PTNameFk AND cn.PTRefFk = PTaxon.PTRefFk ON " +
116 " emLanguageReference.ReferenceId = cn.LanguageRefFk LEFT OUTER JOIN " +
117 " emLanguage AS languageCommonName ON cn.LanguageFk = languageCommonName.LanguageId ON misappliedTaxon.PTNameFk = cn.NameInSourceFk AND " +
118 " misappliedTaxon.PTRefFk = cn.MisNameRefFk " +
119 " WHERE cn.CommonNameId IN (" + ID_LIST_TOKEN + ")";
120 return recordQuery;
121 }
122
123
124
125 @Override
126 protected void doInvoke(BerlinModelImportState state) {
127 try {
128 makeRegions(state);
129 } catch (Exception e) {
130 logger.error("Error when creating common name regions:" + e.getMessage());
131 e.printStackTrace();
132 state.setUnsuccessfull();
133 }
134 super.doInvoke(state);
135 return;
136 }
137
138 /**
139 * @param state
140 *
141 */
142 private void makeRegions(BerlinModelImportState state) {
143 try {
144 SortedSet<Integer> regionFks = new TreeSet<Integer>();
145 Source source = state.getConfig().getSource();
146
147 //fill set with all regionFk from emCommonName.regionFks
148 getRegionFks(state, regionFks, source);
149 //concat filter string
150 String sqlWhere = getSqlWhere(regionFks);
151
152 //get E+M - TDWG Mapping
153 Map<String, String> emTdwgMap = getEmTdwgMap(source);
154 //fill regionMap
155 fillRegionMap(state, sqlWhere, emTdwgMap);
156
157 return;
158 } catch (NumberFormatException e) {
159 e.printStackTrace();
160 state.setUnsuccessfull();
161 return;
162 } catch (SQLException e) {
163 e.printStackTrace();
164 state.setUnsuccessfull();
165 return;
166 }
167 }
168
169
170 /* (non-Javadoc)
171 * @see eu.etaxonomy.cdm.io.berlinModel.in.IPartitionedIO#doPartition(eu.etaxonomy.cdm.io.berlinModel.in.ResultSetPartitioner, eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportState)
172 */
173 public boolean doPartition(ResultSetPartitioner partitioner, BerlinModelImportState state) {
174 boolean success = true ;
175 BerlinModelImportConfigurator config = state.getConfig();
176 Set<TaxonBase> taxaToSave = new HashSet<TaxonBase>();
177 Map<String, Taxon> taxonMap = (Map<String, Taxon>) partitioner.getObjectMap(BerlinModelTaxonImport.NAMESPACE);
178 Map<String, TaxonNameBase> taxonNameMap = (Map<String, TaxonNameBase>) partitioner.getObjectMap(BerlinModelTaxonNameImport.NAMESPACE);
179
180 Map<String, Reference> biblioRefMap = (Map<String, Reference>) partitioner.getObjectMap(BerlinModelReferenceImport.BIBLIO_REFERENCE_NAMESPACE);
181 Map<String, Reference> nomRefMap = (Map<String, Reference>) partitioner.getObjectMap(BerlinModelReferenceImport.NOM_REFERENCE_NAMESPACE);
182
183 Map<String, Language> iso6392Map = new HashMap<String, Language>();
184
185 // logger.warn("MisappliedNameRefFk not yet implemented for Common Names");
186
187 ResultSet rs = partitioner.getResultSet();
188 try{
189 while (rs.next()){
190
191 //create TaxonName element
192 Object commonNameId = rs.getObject("CommonNameId");
193 int taxonId = rs.getInt("taxonId");
194 Object refId = rs.getObject("refId");
195 Object ptNameFk = rs.getObject("PTNameFk");
196 String commonNameString = rs.getString("CommonName");
197 String iso639_2 = rs.getString("ISO639_2");
198 String iso639_1 = rs.getString("ISO639_1");
199 String languageString = rs.getString("Language");
200 String originalLanguageString = rs.getString("LanguageOriginal");
201 Object misNameRefFk = rs.getObject("MisNameRefFk");
202 Object languageRefRefFk = rs.getObject("languageRefRefFk");
203 String refLanguage = rs.getString("refLanguage");
204 String refLanguageIso639_2 = rs.getString("refLanguageIso639_2");
205 String status = rs.getString("Status");
206 Object nameInSourceFk = rs.getObject("NameInSourceFk");
207 Object misappliedTaxonId = rs.getObject("misappliedTaxonId");
208
209 //regions
210 String regionFks = rs.getString("RegionFks");
211 String[] regionFkSplit = regionFks.split(",");
212
213 //commonNameString
214 if (CdmUtils.isBlank(commonNameString)){
215 String message = "CommonName is empty or null. Do not import record for taxon " + taxonId;
216 logger.warn(message);
217 continue;
218 }
219
220 //taxon
221 Taxon taxon = null;
222 TaxonBase taxonBase = taxonMap.get(String.valueOf(taxonId));
223 if (taxonBase == null){
224 logger.warn("Taxon (" + taxonId + ") could not be found. Common name " + commonNameString + "(" + commonNameId + ") not imported");
225 continue;
226 }else if (! taxonBase.isInstanceOf(Taxon.class)){
227 logger.warn("taxon (" + taxonId + ") is not accepted. Can't import common name " + commonNameId);
228 continue;
229 }else{
230 taxon = CdmBase.deproxy(taxonBase, Taxon.class);
231 }
232
233 //Language
234 Language language = getAndHandleLanguage(iso6392Map, iso639_2, iso639_1, languageString, originalLanguageString, state);
235
236 //CommonTaxonName
237 List<CommonTaxonName> commonTaxonNames = new ArrayList<CommonTaxonName>();
238 for (String regionFk : regionFkSplit){ //
239 CommonTaxonName commonTaxonName;
240 if (commonTaxonNames.size() == 0){
241 commonTaxonName = CommonTaxonName.NewInstance(commonNameString, language);
242 }else{
243 commonTaxonName = (CommonTaxonName)commonTaxonNames.get(0).clone();
244 }
245 commonTaxonNames.add(commonTaxonName);
246 regionFk = regionFk.trim();
247 NamedArea area = regionMap.get(regionFk);
248 if (area == null){
249 if (regionFkSplit.length > 1 && StringUtils.isNotBlank(regionFk)){
250 logger.warn("Area for " + regionFk + " not defined in regionMap.");
251 }else{
252 //no region is defined
253 }
254 }else{
255 commonTaxonName.setArea(area);
256 TaxonDescription description = getDescription(taxon);
257 description.addElement(commonTaxonName);
258 }
259 }
260
261 //Reference/Source
262 String strRefId = String.valueOf(refId);
263 String languageRefFk = String.valueOf(languageRefRefFk);
264 if (! CdmUtils.nullSafeEqual(strRefId, languageRefFk)){
265 //use strRefId if languageRefFk is null
266 if (languageRefRefFk == null){
267 languageRefFk = strRefId;
268 }else{
269 logger.warn("CommonName.RefFk (" + CdmUtils.Nz(strRefId) + ") and LanguageReference.RefFk " + CdmUtils.Nz(languageRefFk) + " are not equal. I will import only languageReference.RefFk");
270 }
271 }
272
273 Reference<?> reference = getReferenceOnlyFromMaps(biblioRefMap, nomRefMap, String.valueOf(languageRefRefFk));
274 String microCitation = null;
275 String originalNameString = null;
276
277 TaxonNameBase<?,?> nameUsedInSource = taxonNameMap.get(String.valueOf(nameInSourceFk));
278 if (nameInSourceFk != null && nameUsedInSource == null){
279 logger.warn("Name used in source (" + nameInSourceFk + ") was not found for common name " + commonNameId);
280 }
281 DescriptionElementSource source = DescriptionElementSource.NewPrimarySourceInstance(reference, microCitation, nameUsedInSource, originalNameString);
282 for (CommonTaxonName commonTaxonName : commonTaxonNames){
283 commonTaxonName.addSource(source);
284 }
285
286
287 //MisNameRef
288 if (misNameRefFk != null){
289 //Taxon misappliedName = getMisappliedName(biblioRefMap, nomRefMap, misNameRefFk, taxon);
290 Taxon misappliedNameTaxon = null;
291 if (misappliedTaxonId != null){
292 TaxonBase misTaxonBase = taxonMap.get(String.valueOf(misappliedTaxonId));
293 if (misTaxonBase == null){
294 logger.warn("MisappliedName not found for misappliedTaxonId " + misappliedTaxonId + "; commonNameId: " + commonNameId);
295 }else if (misTaxonBase.isInstanceOf(Taxon.class)){
296 misappliedNameTaxon = CdmBase.deproxy(misTaxonBase, Taxon.class);
297 }else{
298 logger.warn("Misapplied name taxon is not of type Taxon but " + misTaxonBase.getClass().getSimpleName());
299 }
300 }else{
301
302 Reference<?> sec = getReferenceOnlyFromMaps(biblioRefMap, nomRefMap, String.valueOf(misNameRefFk));
303 if (nameUsedInSource == null || sec == null){
304 logger.warn("Taxon name or misapplied name reference is null for common name " + commonNameId);
305 }else{
306 misappliedNameTaxon = Taxon.NewInstance(nameUsedInSource, sec);
307 MarkerType misCommonNameMarker = getMarkerType(state, BerlinModelTransformer.uuidMisappliedCommonName,"Misapplied Common Name in Berlin Model", "Misapplied taxon was automatically created by Berlin Model import for a common name with a misapplied name reference", "MCN");
308 Marker marker = Marker.NewInstance(misCommonNameMarker, true);
309 misappliedNameTaxon.addMarker(marker);
310 taxaToSave.add(misappliedNameTaxon);
311 logger.warn("Misapplied name taxon could not be found in database but misapplied name reference exists for common name. " +
312 "New misapplied name for misapplied reference common name was added. CommonNameId: " + commonNameId);
313 }
314 }
315 if (misappliedNameTaxon != null){
316
317 if (! taxon.getMisappliedNames().contains(misappliedNameTaxon)){
318 taxon.addMisappliedName(misappliedNameTaxon,state.getTransactionalSourceReference(), null);
319 logger.warn("Misapplied name for common name was not found related to the accepted taxon. Created new relationship. CommonNameId: " + commonNameId);
320 }
321
322 TaxonDescription misappliedNameDescription = getDescription(misappliedNameTaxon);
323 for (CommonTaxonName commonTaxonName : commonTaxonNames){
324 CommonTaxonName commonNameClone = (CommonTaxonName)commonTaxonName.clone();
325 misappliedNameDescription.addElement(commonNameClone);
326 }
327 }else{
328 logger.warn("Misapplied name is null for common name " + commonNameId);
329 }
330
331 }
332
333
334 //reference extensions
335 if (reference != null){
336 if (CdmUtils.isNotEmpty(refLanguage)){
337 ExtensionType refLanguageExtensionType = getExtensionType( state, REFERENCE_LANGUAGE_STRING_UUID, "reference language","The language of the reference","ref. lang.");
338 Extension.NewInstance(reference, refLanguage, refLanguageExtensionType);
339 }
340
341 if (CdmUtils.isNotEmpty(refLanguageIso639_2)){
342 ExtensionType refLanguageIsoExtensionType = getExtensionType( state, REFERENCE_LANGUAGE_ISO639_2_UUID, "reference language iso 639-2","The iso 639-2 code of the references language","ref. lang. 639-2");
343 Extension.NewInstance(reference, refLanguageIso639_2, refLanguageIsoExtensionType);
344 }
345 }else if (CdmUtils.isNotEmpty(refLanguage) || CdmUtils.isNotEmpty(refLanguageIso639_2)){
346 logger.warn("Reference is null (" + languageRefRefFk + ") but refLanguage (" + CdmUtils.Nz(refLanguage) + ") or iso639_2 (" + CdmUtils.Nz(refLanguageIso639_2) + ") was not null for common name ("+ commonNameId +")");
347 }
348
349 //status
350 if (CdmUtils.isNotEmpty(status)){
351 AnnotationType statusAnnotationType = getAnnotationType( state, STATUS_ANNOTATION_UUID, "status","The status of this object","status", null);
352 Annotation annotation = Annotation.NewInstance(status, statusAnnotationType, Language.DEFAULT());
353 for (CommonTaxonName commonTaxonName : commonTaxonNames){
354 commonTaxonName.addAnnotation(annotation);
355 }
356
357 }
358
359 //Notes
360 for (CommonTaxonName commonTaxonName : commonTaxonNames){
361 doIdCreatedUpdatedNotes(state, commonTaxonName, rs, String.valueOf(commonNameId), NAMESPACE);
362 }
363 partitioner.startDoSave();
364 taxaToSave.add(taxon);
365
366 }
367 } catch (SQLException e) {
368 logger.error("SQLException:" + e);
369 return false;
370 } catch (ClassCastException e) {
371 e.printStackTrace();
372 }
373
374 // logger.info( i + " names handled");
375 getTaxonService().save(taxaToSave);
376 return success;
377
378 }
379
380
381
382 /**
383 * Not used anymore. Use MisappliedName RIdentifier instead
384 * @param biblioRefMap
385 * @param nomRefMap
386 * @param misNameRefFk
387 * @param taxon
388 */
389 private boolean isFirstMisappliedName = true;
390 private Taxon getMisappliedName(Map<String, Reference> biblioRefMap, Map<String, Reference> nomRefMap, Object misNameRefFk, Taxon taxon) {
391 Taxon misappliedTaxon = null;
392 Reference<?> misNameRef = getReferenceOnlyFromMaps(biblioRefMap, nomRefMap, String.valueOf(misNameRefFk));
393 misappliedTaxon = Taxon.NewInstance(taxon.getName(), misNameRef);
394 Set<String> includeProperty = new HashSet<String>();
395 try {
396 // //IMatchStrategy matchStrategy = DefaultMatchStrategy.NewInstance(TaxonBase.class);
397 // //List<TaxonBase> misappliedList1 = getCommonService().findMatching(misappliedTaxon, matchStrategy);
398 List<TaxonBase> misappliedList = getTaxonService().list(misappliedTaxon, includeProperty, null, null, null, null);
399 if (misappliedList.size() > 0){
400 misappliedTaxon = CdmBase.deproxy(misappliedList.get(0), Taxon.class);
401 }
402 } catch (ClassCastException e) {
403 logger.error(e.getMessage());
404 if (isFirstMisappliedName){
405 e.printStackTrace();
406 isFirstMisappliedName = false;
407 }
408 }
409 return misappliedTaxon;
410 }
411
412
413
414 /**
415 * @param iso6392Map
416 * @param iso639_2
417 * @param languageString
418 * @param originalLanguageString
419 * @param state
420 * @return
421 */
422 private Language getAndHandleLanguage(Map<String, Language> iso639Map, String iso639_2, String iso639_1, String languageString, String originalLanguageString, BerlinModelImportState state) {
423 Language language;
424 if (CdmUtils.isNotEmpty(iso639_2)|| CdmUtils.isNotEmpty(iso639_1) ){
425 //TODO test performance, implement in state
426 language = getLanguageFromIsoMap(iso639Map, iso639_2, iso639_1);
427
428 if (language == null){
429 language = getTermService().getLanguageByIso(iso639_2);
430 iso639Map.put(iso639_2, language);
431 if (language == null){
432 language = getTermService().getLanguageByIso(iso639_1);
433 iso639Map.put(iso639_1, language);
434 }
435 if (language == null){
436 logger.warn("Language for code ISO693-2 '" + iso639_2 + "' and ISO693-1 '" + iso639_1 + "' was not found");
437 }
438 }
439 } else if ("unknown".equals(languageString)){
440 language = Language.UNKNOWN_LANGUAGE();
441 } else if ("Majorcan".equalsIgnoreCase(languageString)){
442 language = getLanguage(state, BerlinModelTransformer.uuidLangMajorcan, "Majorcan", "Majorcan (original 'mallorqu\u00EDn')", null);
443 }else{
444 logger.warn("language ISO 639_1 and ISO 639_2 were empty for " + languageString);
445 language = null;
446 }
447 addOriginalLanguage(language, originalLanguageString);
448 return language;
449 }
450
451
452 /**
453 * @param iso639Map
454 * @param iso639_2
455 * @param iso639_1
456 * @return
457 */
458 private Language getLanguageFromIsoMap(Map<String, Language> iso639Map, String iso639_2, String iso639_1) {
459 Language language;
460 language = iso639Map.get(iso639_2);
461 if (language == null){
462 language = iso639Map.get(iso639_1);
463 }
464 return language;
465 }
466
467 /**
468 * @param language
469 * @param originalLanguageString
470 */
471 private void addOriginalLanguage(Language language, String originalLanguageString) {
472 if (CdmUtils.isBlank(originalLanguageString)){
473 return;
474 }else if (language == null){
475 logger.warn("Language could not be defined, but originalLanguageString exists: " + originalLanguageString);
476 }else {
477 Representation representation = language.getRepresentation(language);
478 if (representation == null){
479 language.addRepresentation(Representation.NewInstance(originalLanguageString, originalLanguageString, originalLanguageString, language));
480 getTermService().saveOrUpdate(language);
481 }
482 }
483
484 }
485
486
487
488 /**
489 * Fills the regionFks with all regionFks from emCommonName. Comma separated regionFks will be split.
490 * @param state
491 * @param regionFks
492 * @param source
493 * @return
494 * @throws SQLException
495 *
496 */
497 private void getRegionFks(BerlinModelImportState state, SortedSet<Integer> regionFks, Source source) throws SQLException {
498 String sql = " SELECT DISTINCT RegionFks FROM emCommonName";
499 if (state.getConfig().getCommonNameFilter() != null){
500 sql += " WHERE " + state.getConfig().getCommonNameFilter();
501 }
502
503 ResultSet rs = source.getResultSet(sql);
504 while (rs.next()){
505 String strRegionFks = rs.getString("RegionFks");
506 if (StringUtils.isBlank(strRegionFks)){
507 continue;
508 }
509
510 String[] regionFkArray = strRegionFks.split(",");
511 for (String regionFk: regionFkArray){
512 regionFk = regionFk.trim();
513 if (! StringUtils.isNumeric(regionFk) || "".equals(regionFk) ){
514 state.setUnsuccessfull();
515 logger.warn("RegionFk is not numeric: " + regionFk + " ( part of " + strRegionFks + ")");
516 }else{
517 regionFks.add(Integer.valueOf(regionFk));
518 }
519 }
520 }
521 return;
522 }
523
524
525
526 /**
527 * Fills the {@link #regionMap} by all emLanguageRegion regions defined in the sql filter.
528 * {@link #regionMap} maps emLanguageRegion.RegionId to named areas.
529 * @param state
530 * @param sqlWhere
531 * @param emTdwgMap
532 * @throws SQLException
533 */
534 private void fillRegionMap(BerlinModelImportState state, String sqlWhere,
535 Map<String, String> emTdwgMap) throws SQLException {
536 Source source = state.getConfig().getSource();
537 String sql;
538 ResultSet rs;
539 sql = " SELECT RegionId, Region FROM emLanguageRegion WHERE RegionId IN ("+ sqlWhere+ ") ";
540 rs = source.getResultSet(sql);
541 while (rs.next()){
542 Object regionId = rs.getObject("RegionId");
543 String region = rs.getString("Region");
544 String[] splitRegion = region.split("-");
545 if (splitRegion.length <= 1){
546 NamedArea newArea = getNamedArea(state, null, region, "Language region '" + region + "'", null, null, null);
547 // getTermService().save(newArea);
548 regionMap.put(String.valueOf(regionId), newArea);
549 logger.warn("Found new area: " + region);
550 }else if (splitRegion.length == 2){
551 String emCode = splitRegion[1].trim();
552 String tdwgCode = emTdwgMap.get(emCode);
553 if (StringUtils.isNotBlank(tdwgCode) ){
554 NamedArea tdwgArea = getNamedArea(state, tdwgCode);
555 regionMap.put(String.valueOf(regionId), tdwgArea);
556 }else {
557 NamedArea area = getOtherAreas(state, emCode, tdwgCode);
558 if (area != null){
559 regionMap.put(String.valueOf(regionId), area);
560 }else{
561 logger.warn("emCode did not map to valid tdwgCode: " + CdmUtils.Nz(emCode) + "->" + CdmUtils.Nz(tdwgCode));
562 }
563 }
564 }
565 }
566 }
567
568
569 /**
570 * Returns the are for a given TDWG code. See {@link #getEmTdwgMap(Source)} for exceptions from
571 * the TDWG code
572 * @param state
573 * @param tdwgCode
574 */
575 private NamedArea getNamedArea(BerlinModelImportState state, String tdwgCode) {
576 NamedArea area;
577 if (tdwgCode.equalsIgnoreCase("Ab")){
578 area = getNamedArea(state, BerlinModelTransformer.uuidAzerbaijanNakhichevan, "Azerbaijan & Nakhichevan", "Azerbaijan (including Nakhichevan)", "Ab", null, null);
579 getTermService().saveOrUpdate(area);
580 }else if (tdwgCode.equalsIgnoreCase("Uk")){
581 area = getNamedArea(state, BerlinModelTransformer.uuidUkraineAndCrimea , "Ukraine & Crimea", "Ukraine (including Crimea)", "Uk", null, null);
582 getTermService().saveOrUpdate(area);
583 }else if (tdwgCode.equalsIgnoreCase("Rf")){
584 area = Country.RUSSIANFEDERATION();
585 }else if (tdwgCode.equalsIgnoreCase("Gg")){
586 area = Country.GEORGIA();
587 }else{
588 area = TdwgAreaProvider.getAreaByTdwgAbbreviation(tdwgCode);
589 }
590 if (area == null){
591 logger.warn("Area is null for " + tdwgCode);
592 }
593 return area;
594 }
595
596 /**
597 * @param regionFks
598 * @return
599 */
600 private String getSqlWhere(SortedSet<Integer> regionFks) {
601 String sqlWhere = "";
602 for (Integer regionFk : regionFks){
603 sqlWhere += regionFk + ",";
604 }
605 sqlWhere = sqlWhere.substring(0, sqlWhere.length()-1);
606 return sqlWhere;
607 }
608
609
610
611 /**
612 * Returns a map which is filled by the emCode->TdwgCode mapping defined in emArea.
613 * Some exceptions are defined for emCode 'Ab','Rf','Uk' and some additional mapping is added
614 * for 'Ab / Ab(A)', 'Ga / Ga(F)', 'It / It(I)', 'Ar / Ar(A)','Hs / Hs(S)'
615 * @param source
616 * @throws SQLException
617 */
618 private Map<String, String> getEmTdwgMap(Source source) throws SQLException {
619 String sql;
620 ResultSet rs;
621 Map<String, String> emTdwgMap = new HashMap<String, String>();
622 sql = " SELECT EmCode, TDWGCode FROM emArea ";
623 rs = source.getResultSet(sql);
624 while (rs.next()){
625 String emCode = rs.getString("EMCode");
626 String TDWGCode = rs.getString("TDWGCode");
627 if (StringUtils.isNotBlank(emCode) ){
628 emCode = emCode.trim();
629 if (emCode.equalsIgnoreCase("Ab") || emCode.equalsIgnoreCase("Rf")||
630 emCode.equalsIgnoreCase("Uk") || emCode.equalsIgnoreCase("Gg")){
631 emTdwgMap.put(emCode, emCode);
632 }else if (StringUtils.isNotBlank(TDWGCode)){
633 emTdwgMap.put(emCode, TDWGCode.trim());
634 }
635 }
636 }
637 emTdwgMap.put("Ab / Ab(A)", "Ab");
638 emTdwgMap.put("Ga / Ga(F)", "FRA-FR");
639 emTdwgMap.put("It / It(I)", "ITA");
640 emTdwgMap.put("Uk / Uk(U)", "Uk");
641 emTdwgMap.put("Ar / Ar(A)", "TCS-AR");
642 emTdwgMap.put("Hs / Hs(S)", "SPA-SP");
643
644 return emTdwgMap;
645 }
646
647
648
649
650 /**
651 * Returns the first non-image gallery description. Creates a new one if no description exists.
652 * @param taxon
653 * @return
654 */
655 private TaxonDescription getDescription(Taxon taxon) {
656 TaxonDescription result = null;
657 for (TaxonDescription taxonDescription : taxon.getDescriptions()){
658 if (! taxonDescription.isImageGallery()){
659 result = taxonDescription;
660 }
661 }
662 if (result == null){
663 result = TaxonDescription.NewInstance(taxon);
664 }
665 return result;
666 }
667
668 /* (non-Javadoc)
669 * @see eu.etaxonomy.cdm.io.berlinModel.in.IPartitionedIO#getRelatedObjectsForPartition(java.sql.ResultSet)
670 */
671 public Map<Object, Map<String, ? extends CdmBase>> getRelatedObjectsForPartition(ResultSet rs) {
672 String nameSpace;
673 Class<?> cdmClass;
674 Set<String> idSet;
675 Map<Object, Map<String, ? extends CdmBase>> result = new HashMap<Object, Map<String, ? extends CdmBase>>();
676
677 int pos = -1;
678 try{
679 Set<String> taxonIdSet = new HashSet<String>();
680 Set<String> nameIdSet = new HashSet<String>();
681 Set<String> referenceIdSet = new HashSet<String>();
682 while (rs.next()){
683 pos = 0;
684 handleForeignKey(rs, taxonIdSet, "taxonId");
685 pos = 1;
686 handleForeignKey(rs, taxonIdSet, "misappliedTaxonId");
687 pos = 2;
688 handleForeignKey(rs, referenceIdSet, "refId");
689 pos = 3;
690 handleForeignKey(rs, referenceIdSet, "languageRefRefFk");
691 pos = 4;
692 handleForeignKey(rs, nameIdSet, "NameInSourceFk");
693 pos = 5;
694 handleForeignKey(rs, nameIdSet, "PTNameFk");
695 pos = 6;
696 handleForeignKey(rs, referenceIdSet, "MisNameRefFk");
697 pos = -2;
698
699 }
700
701 pos = 7;
702
703 //name map
704 nameSpace = BerlinModelTaxonNameImport.NAMESPACE;
705 cdmClass = TaxonNameBase.class;
706 idSet = nameIdSet;
707 Map<String, TaxonNameBase<?,?>> nameMap = (Map<String, TaxonNameBase<?,?>>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
708 result.put(nameSpace, nameMap);
709
710 pos = 8;
711
712 //taxon map
713 nameSpace = BerlinModelTaxonImport.NAMESPACE;
714 cdmClass = TaxonBase.class;
715 idSet = taxonIdSet;
716 Map<String, TaxonBase<?>> taxonMap = (Map<String, TaxonBase<?>>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
717 result.put(nameSpace, taxonMap);
718
719 pos = 9;
720
721 //nom reference map
722 nameSpace = BerlinModelReferenceImport.NOM_REFERENCE_NAMESPACE;
723 cdmClass = Reference.class;
724 idSet = referenceIdSet;
725 Map<String, Reference> nomReferenceMap = (Map<String, Reference>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
726 result.put(nameSpace, nomReferenceMap);
727
728 pos = 10;
729
730 //biblio reference map
731 nameSpace = BerlinModelReferenceImport.BIBLIO_REFERENCE_NAMESPACE;
732 cdmClass = Reference.class;
733 idSet = referenceIdSet;
734 Map<String, Reference<?>> biblioReferenceMap = (Map<String, Reference<?>>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
735 result.put(nameSpace, biblioReferenceMap);
736
737 pos = 11;
738
739 } catch (SQLException e) {
740 throw new RuntimeException("pos: " +pos, e);
741 } catch (NullPointerException nep){
742 logger.error("NullPointerException in getRelatedObjectsForPartition()");
743 }
744 return result;
745 }
746
747
748
749 /* (non-Javadoc)
750 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#doCheck(eu.etaxonomy.cdm.io.common.IoStateBase)
751 */
752 @Override
753 protected boolean doCheck(BerlinModelImportState state){
754 IOValidator<BerlinModelImportState> validator = new BerlinModelCommonNamesImportValidator();
755 return validator.validate(state);
756 }
757
758 /* (non-Javadoc)
759 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#isIgnore(eu.etaxonomy.cdm.io.common.IImportConfigurator)
760 */
761 protected boolean isIgnore(BerlinModelImportState state){
762 return ! state.getConfig().isDoCommonNames();
763 }
764
765 }