smaller changes in ABCD import - continue
[cdmlib.git] / cdmlib-io / src / main / java / eu / etaxonomy / cdm / io / specimen / abcd206 / in / Abcd206Import.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.specimen.abcd206.in;
11
12 import java.io.IOException;
13 import java.io.InputStream;
14 import java.net.MalformedURLException;
15 import java.net.URI;
16 import java.util.ArrayList;
17 import java.util.HashMap;
18 import java.util.List;
19 import java.util.Map;
20 import java.util.Set;
21 import java.util.UUID;
22
23 import org.apache.commons.lang.StringUtils;
24 import org.apache.log4j.Logger;
25 import org.springframework.stereotype.Component;
26 import org.w3c.dom.Element;
27 import org.w3c.dom.NodeList;
28
29 import eu.etaxonomy.cdm.api.application.ICdmRepository;
30 import eu.etaxonomy.cdm.api.facade.DerivedUnitFacade;
31 import eu.etaxonomy.cdm.api.service.DeleteResult;
32 import eu.etaxonomy.cdm.api.service.config.SpecimenDeleteConfigurator;
33 import eu.etaxonomy.cdm.common.StreamUtils;
34 import eu.etaxonomy.cdm.ext.occurrence.OccurenceQuery;
35 import eu.etaxonomy.cdm.ext.occurrence.bioCase.BioCaseQueryServiceWrapper;
36 import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
37 import eu.etaxonomy.cdm.io.common.ICdmIO;
38 import eu.etaxonomy.cdm.io.common.MapWrapper;
39 import eu.etaxonomy.cdm.io.specimen.SpecimenImportBase;
40 import eu.etaxonomy.cdm.io.specimen.SpecimenUserInteraction;
41 import eu.etaxonomy.cdm.io.specimen.UnitsGatheringArea;
42 import eu.etaxonomy.cdm.io.specimen.UnitsGatheringEvent;
43 import eu.etaxonomy.cdm.io.specimen.abcd206.in.molecular.AbcdDnaParser;
44 import eu.etaxonomy.cdm.model.agent.Institution;
45 import eu.etaxonomy.cdm.model.agent.Person;
46 import eu.etaxonomy.cdm.model.agent.Team;
47 import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
48 import eu.etaxonomy.cdm.model.common.Annotation;
49 import eu.etaxonomy.cdm.model.common.CdmBase;
50 import eu.etaxonomy.cdm.model.common.IdentifiableSource;
51 import eu.etaxonomy.cdm.model.common.Language;
52 import eu.etaxonomy.cdm.model.common.LanguageString;
53 import eu.etaxonomy.cdm.model.location.NamedArea;
54 import eu.etaxonomy.cdm.model.media.Media;
55 import eu.etaxonomy.cdm.model.media.Rights;
56 import eu.etaxonomy.cdm.model.media.RightsType;
57 import eu.etaxonomy.cdm.model.molecular.DnaSample;
58 import eu.etaxonomy.cdm.model.occurrence.Collection;
59 import eu.etaxonomy.cdm.model.occurrence.DerivationEvent;
60 import eu.etaxonomy.cdm.model.occurrence.DerivationEventType;
61 import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;
62 import eu.etaxonomy.cdm.model.occurrence.FieldUnit;
63 import eu.etaxonomy.cdm.model.occurrence.GatheringEvent;
64 import eu.etaxonomy.cdm.model.occurrence.MediaSpecimen;
65 import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
66 import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationType;
67 import eu.etaxonomy.cdm.model.reference.OriginalSourceBase;
68 import eu.etaxonomy.cdm.model.reference.OriginalSourceType;
69 import eu.etaxonomy.cdm.model.reference.Reference;
70 import eu.etaxonomy.cdm.model.reference.ReferenceFactory;
71 import eu.etaxonomy.cdm.model.taxon.Classification;
72 import eu.etaxonomy.cdm.model.term.DefinedTerm;
73 import eu.etaxonomy.cdm.model.term.DefinedTermBase;
74 import eu.etaxonomy.cdm.model.term.TermType;
75 import eu.etaxonomy.cdm.model.term.TermVocabulary;
76 import eu.etaxonomy.cdm.strategy.parser.TimePeriodParser;
77
78 /**
79 * @author p.kelbert
80 * @author p.plitzner
81 * @author k.luther
82 * @since 20.10.2008
83 */
84 @Component
85 public class Abcd206Import extends SpecimenImportBase<Abcd206ImportConfigurator, Abcd206ImportState> {
86
87 private static final long serialVersionUID = 3918095362150986307L;
88
89 private static final UUID SPECIMEN_SCAN_TERM = UUID.fromString("acda15be-c0e2-4ea8-8783-b9b0c4ad7f03");
90
91 private static final Logger logger = Logger.getLogger(Abcd206Import.class);
92
93 public Abcd206Import() {
94 super();
95 }
96
97 @Override
98 // @SuppressWarnings("rawtypes")
99 public void doInvoke(Abcd206ImportState state) {
100 Abcd206ImportConfigurator config = state.getConfig();
101 Map<String, MapWrapper<? extends CdmBase>> stores = state.getStores();
102 MapWrapper<TeamOrPersonBase<?>> authorStore = (MapWrapper<TeamOrPersonBase<?>>) stores.get(ICdmIO.TEAM_STORE);
103 state.setPersonStore(authorStore);
104 MapWrapper<Reference> referenceStore = (MapWrapper<Reference>) stores.get(ICdmIO.REFERENCE_STORE);
105 createKindOfUnitsMap(state);
106 URI sourceUri = config.getSourceUri();
107 try {
108 state.setTx(startTransaction());
109 logger.info("INVOKE Specimen Import from ABCD2.06 XML ");
110 InputStream response = null;
111 // init cd repository
112 if (state.getCdmRepository() == null) {
113 state.setCdmRepository(this);
114 }
115 if (config.getOccurenceQuery() != null) {
116 BioCaseQueryServiceWrapper queryService = new BioCaseQueryServiceWrapper();
117 try {
118
119 response = queryService.query(config.getOccurenceQuery(), sourceUri);
120 state.setActualAccessPoint(sourceUri);
121
122 } catch (Exception e) {
123 logger.error("An error during ABCD import");
124 }
125 }
126 SpecimenUserInteraction sui = state.getConfig().getSpecimenUserInteraction();
127
128 // init import reference
129 // List<Reference> references =
130 // getReferenceService().list(Reference.class, null, null, null,
131 // null);
132 // List<Reference> references = new ArrayList<Reference>();
133
134 // if (state.getConfig().isInteractWithUser()){
135 // Map<String,Reference> refMap = new HashMap<String, Reference>();
136 // for (Reference reference : references) {
137 // if (! StringUtils.isBlank(reference.getTitleCache())) {
138 // refMap.put(reference.getTitleCache(),reference);
139 // }
140 // }
141 // state.setRef(sui.askForReference(refMap));
142 //
143 // if (state.getRef() == null){
144 // String cla = sui.createNewReference();
145 // if (refMap.get(cla)!= null) {
146 // state.setRef(refMap.get(cla));
147 // } else {
148 // state.setRef(ReferenceFactory.newGeneric());
149 // state.getRef().setTitle(cla);
150 // }
151 // }
152 // else{
153 // state.setRef(getReferenceService().find(state.getRef().getUuid()));
154 // }
155 // }else{
156 if (state.getRef() == null) {
157 String name = NB(state.getConfig().getSourceReferenceTitle());
158 for (Reference reference : referenceStore.getAllValues()) {
159 if (!StringUtils.isBlank(reference.getTitleCache())) {
160 if (reference.getTitleCache().equalsIgnoreCase(name)) {
161 state.setRef(reference);
162 }
163 }
164 }
165 if (state.getRef() == null) {
166 if (state.getConfig().getSourceReference() != null) {
167 state.setRef(state.getConfig().getSourceReference());
168 } else {
169 state.setRef(ReferenceFactory.newGeneric());
170 state.getRef().setUri(sourceUri);
171 if (sourceUri != null) {
172 state.getRef().setTitle(StringUtils.substringAfter(sourceUri.toString(), "dsa="));
173 }
174
175 if (!StringUtils.isBlank(state.getConfig().getSourceReferenceTitle())) {
176 state.getRef().setTitle(state.getConfig().getSourceReferenceTitle());
177 }
178 }
179
180 }
181 }
182 // }
183
184 save(state.getRef(), state);
185 state.getConfig().setSourceReference(state.getRef());
186
187 if (state.getConfig().getClassificationUuid() != null) {
188 // load classification from config if it exists
189 state.setClassification(getClassificationService().load(state.getConfig().getClassificationUuid()));
190 }
191 if (state.getClassification() == null) {// no existing
192 // classification was set in
193 // config
194 List<Classification> classificationList = getClassificationService().list(Classification.class, null,
195 null, null, null);
196 // get classification via user interaction
197 if (state.getConfig().isUseClassification() && state.getConfig().isInteractWithUser()) {
198 Map<String, Classification> classMap = new HashMap<>();
199 for (Classification tree : classificationList) {
200 if (!StringUtils.isBlank(tree.getTitleCache())) {
201 classMap.put(tree.getTitleCache(), tree);
202 }
203 }
204 state.setClassification(sui.askForClassification(classMap));
205 if (state.getClassification() == null) {
206 String cla = sui.createNewClassification();
207 if (classMap.get(cla) != null) {
208 state.setClassification(classMap.get(cla));
209 } else {
210 state.setClassification(
211 Classification.NewInstance(cla, state.getRef(), Language.DEFAULT()));
212 }
213 }
214 save(state.getClassification(), state);
215 }
216 // use default classification as the classification to import
217 // into
218 if (state.getClassification() == null) {
219 String name = NB(state.getConfig().getClassificationName());
220 for (Classification classif : classificationList) {
221 if (classif.getTitleCache() != null && classif.getTitleCache().equalsIgnoreCase(name)) {
222 state.setClassification(classif);
223 }
224 }
225 if (state.getClassification() == null) {
226 state.setClassification(Classification.NewInstance(name, state.getRef(), Language.DEFAULT()));
227 // we do not need a default classification when creating
228 // an empty new one
229 state.setDefaultClassification(state.getClassification());
230 save(state.getDefaultClassification(false), state);
231 }
232 save(state.getClassification(), state);
233 }
234 }
235
236 if (response == null) {
237 response = state.getConfig().getSource();
238 }
239 UnitAssociationWrapper unitAssociationWrapper = AbcdParseUtility.parseUnitsNodeList(response,
240 state.getReport());
241 NodeList unitsList = unitAssociationWrapper.getAssociatedUnits();
242 state.setPrefix(unitAssociationWrapper.getPrefix());
243
244 if (unitsList != null) {
245 String message = "nb units to insert: " + unitsList.getLength();
246 logger.info(message);
247 state.getConfig().getProgressMonitor().beginTask("Importing ABCD file", unitsList.getLength() + 3);
248 updateProgress(state, message);
249
250 state.setDataHolder(new Abcd206DataHolder());
251 state.getDataHolder().reset();
252
253 Abcd206XMLFieldGetter abcdFieldGetter = new Abcd206XMLFieldGetter(state.getDataHolder(),
254 state.getPrefix());
255 if (config.getNomenclaturalCode() != null) {
256 state.getDataHolder().setNomenclatureCode(config.getNomenclaturalCode().getKey());
257 }
258 prepareCollectors(state, unitsList, abcdFieldGetter);
259
260 // save authors
261 getAgentService().saveOrUpdate((java.util.Collection) state.getPersonStore().objects());
262
263 commitTransaction(state.getTx());
264 state.setTx(startTransaction());
265 if (state.getDefaultClassification(false) != null) {
266 state.setDefaultClassification(
267 getClassificationService().load(state.getDefaultClassification(false).getUuid()));
268 }
269 if (state.getClassification() != null) {
270 state.setClassification(getClassificationService().load(state.getClassification().getUuid()));
271 }
272 state.setAssociationRefs(new ArrayList<>());
273 state.setDescriptionRefs(new ArrayList<>());
274 state.setDerivedUnitSources(new ArrayList<>());
275 for (int i = 0; i < unitsList.getLength(); i++) {
276 commitTransaction(state.getTx());
277 state.setTx(startTransaction());
278
279 if (state.getConfig().getProgressMonitor().isCanceled()) {
280 break;
281 }
282
283 state.reset();
284
285 Element item = (Element) unitsList.item(i);
286 Abcd206ImportParser.setUnitPropertiesXML(item, abcdFieldGetter, state);
287 updateProgress(state, "Importing data for unit " + state.getDataHolder().getUnitID() + " (" + i
288 + "/" + unitsList.getLength() + ")");
289
290 // import unit + field unit data
291 state.setAssociatedUnitIds(state.getDataHolder().getAssociatedUnitIds());
292 this.handleSingleUnit(state, item, true);
293
294 }
295 commitTransaction(state.getTx());
296 state.setTx(startTransaction());
297 if (state.getConfig().isDeduplicateReferences()) {
298 getReferenceService().deduplicate(Reference.class, null, null);
299 }
300 if (state.getConfig().isDeduplicateClassifications()) {
301 getClassificationService().deduplicate(Classification.class, null, null);
302 }
303 }
304 commitTransaction(state.getTx());
305 } catch (Exception e) {
306 String errorDuringImport = "Exception during import!";
307 logger.error(errorDuringImport, e);
308 state.getReport().addException(errorDuringImport, e);
309 } finally {
310 state.getReport().printReport(state.getConfig().getReportUri());
311 }
312 if (state.getConfig().isDownloadSequenceData()) {
313 for (URI uri : state.getSequenceDataStableIdentifier()) {
314 // Files.createDirectories(file.getParent()); // optional, make
315 // sure parent dir exists
316 try {
317 StreamUtils.downloadFile(uri.toURL(), "temp");
318 } catch (IOException e) {
319 // TODO Auto-generated catch block
320 e.printStackTrace();
321 }
322
323 }
324 }
325
326
327
328 return;
329 }
330
331 /**
332 *
333 */
334 private void createKindOfUnitsMap(Abcd206ImportState state) {
335
336 ICdmRepository cdmRepository = state.getConfig().getCdmAppController();
337 if (cdmRepository == null) {
338 cdmRepository = this;
339 }
340
341 List<DefinedTerm> terms = cdmRepository.getTermService().listByTermType(TermType.KindOfUnit, null, 0, null,
342 null);
343 kindOfUnitsMap = new HashMap<>();
344 for (DefinedTerm kindOfUnit : terms) {
345 String kindOfUnitLabel = kindOfUnit.getLabel().toLowerCase();
346 kindOfUnitsMap.put(kindOfUnit.getLabel().toLowerCase(), kindOfUnit);
347 }
348 }
349
350 /**
351 * @param state
352 * @param item
353 */
354 private void getSiblings(Abcd206ImportState state, Object item, DerivedUnitFacade facade) {
355 String unitId = facade.getCatalogNumber();
356 if (unitId == null) {
357 unitId = facade.getAccessionNumber();
358 }
359
360 UnitAssociationParser unitParser = new UnitAssociationParser(state.getPrefix(), state.getReport(),
361 state.getCdmRepository());
362 UnitAssociationWrapper unitAssociationWrapper = null;
363 for (URI accessPoint : state.getActualAccesPoint()) {
364 unitAssociationWrapper = unitParser.parseSiblings(unitId, accessPoint);
365 if (unitAssociationWrapper != null && unitAssociationWrapper.getAssociatedUnits() != null) {
366 break;
367 }
368 }
369
370 DerivedUnit currentUnit = state.getDerivedUnitBase();
371 // DerivationEvent currentDerivedFrom = currentUnit.getDerivedFrom();
372 FieldUnit currentFieldUnit = facade.getFieldUnit(false);
373 if (unitAssociationWrapper != null) {
374 NodeList associatedUnits = unitAssociationWrapper.getAssociatedUnits();
375 if (associatedUnits != null) {
376 for (int m = 0; m < associatedUnits.getLength(); m++) {
377 if (associatedUnits.item(m) instanceof Element) {
378 state.reset();
379 String associationType = AbcdParseUtility
380 .parseFirstTextContent(((Element) associatedUnits.item(m))
381 .getElementsByTagName(state.getPrefix() + "AssociationType"));
382
383 Abcd206ImportParser.setUnitPropertiesXML((Element) associatedUnits.item(m),
384 new Abcd206XMLFieldGetter(state.getDataHolder(), unitAssociationWrapper.getPrefix()),
385 state);
386 // logger.debug("derived unit: " +
387 // state.getDerivedUnitBase().toString() + " associated
388 // unit: " +state.getDataHolder().getKindOfUnit() + ", "
389 // + state.getDataHolder().accessionNumber + ", " +
390 // state.getDataHolder().getRecordBasis() + ", " +
391 // state.getDataHolder().getUnitID());
392
393 handleSingleUnit(state, associatedUnits.item(m), false);
394
395 DerivedUnit associatedUnit = state.getDerivedUnitBase();
396 FieldUnit associatedFieldUnit = null;
397 commitTransaction(state.getTx());
398 state.setTx(startTransaction());
399 java.util.Collection<FieldUnit> associatedFieldUnits = null;
400 try{
401 associatedFieldUnits = state.getCdmRepository()
402 .getOccurrenceService().findFieldUnits(associatedUnit.getUuid(), null);
403 }catch (NullPointerException e){
404 logger.error("Search for associated field unit creates a NPE" + e.getMessage());
405 }
406 // ignore field unit if associated unit has more than
407 // one
408 if (associatedFieldUnits != null && associatedFieldUnits.size() > 1) {
409 state.getReport()
410 .addInfoMessage(String.format("%s has more than one field unit.", associatedUnit));
411 } else if (associatedFieldUnits != null && associatedFieldUnits.size() == 1) {
412 associatedFieldUnit = associatedFieldUnits.iterator().next();
413 }
414 // parent-child relation:
415 if (associationType.contains("individual") || associationType.contains("culture")
416 || associationType.contains("sample") || associationType.contains("isolated")) {
417 DerivationEvent updatedDerivationEvent = DerivationEvent.NewSimpleInstance(currentUnit,
418 associatedUnit, DerivationEventType.ACCESSIONING());
419
420 updatedDerivationEvent.setDescription(associationType);
421 if (associatedFieldUnit != null && associatedFieldUnit != currentFieldUnit) {
422 //associatedFieldUnit.removeDerivationEvent(updatedDerivationEvent);
423 //save(associatedFieldUnit, state);
424 // if (associatedFieldUnit.getDerivationEvents().isEmpty()){
425 SpecimenDeleteConfigurator config = new SpecimenDeleteConfigurator();
426 config.setDeleteChildren(false);
427 DeleteResult result = state.getCdmRepository().getOccurrenceService().delete(associatedFieldUnit,config);
428 if (!result.isOk()) {
429 logger.debug("Deletion of field unit " + associatedFieldUnit.getFieldNumber() + " not successfull");
430 }
431 state.setFieldUnit(currentFieldUnit);
432
433 //}
434
435 }
436 state.getReport().addDerivate(associatedUnit, currentUnit, state.getConfig());
437 }
438 save(associatedUnit, state);
439
440 }
441 }
442 }
443 }
444 state.reset();
445 state.setDerivedUnitBase(currentUnit);
446
447 }
448
449 /**
450 * Handle a single unit
451 *
452 * @param state
453 * @param item
454 */
455 @Override
456 public void handleSingleUnit(Abcd206ImportState state, Object itemObject) {
457 handleSingleUnit(state, itemObject, true);
458 }
459
460 @SuppressWarnings("rawtypes")
461 public void handleSingleUnit(Abcd206ImportState state, Object itemObject, boolean handleAssociatedUnits) {
462 Element item = (Element) itemObject;
463
464 Abcd206ImportConfigurator config = state.getConfig();
465 if (logger.isDebugEnabled()) {
466 logger.info("handleSingleUnit " + state.getRef());
467 }
468 try {
469 ICdmRepository cdmAppController = state.getConfig().getCdmAppController();
470 if (cdmAppController == null) {
471 cdmAppController = this;
472 }
473 // check if unit already exists
474 DerivedUnitFacade derivedUnitFacade = null;
475 if (state.getConfig().isIgnoreImportOfExistingSpecimen() && state.getDataHolder().getUnitID() != null) {
476
477 SpecimenOrObservationBase<?> existingSpecimen = findExistingSpecimen(state.getDataHolder().getUnitID(),
478 state);
479 if (existingSpecimen != null && existingSpecimen.isInstanceOf(DerivedUnit.class)) {
480 DerivedUnit derivedUnit = HibernateProxyHelper.deproxy(existingSpecimen, DerivedUnit.class);
481 state.setDerivedUnitBase(derivedUnit);
482 derivedUnitFacade = DerivedUnitFacade.NewInstance(state.getDerivedUnitBase());
483 if (handleAssociatedUnits) {
484 importAssociatedUnits(state, item, derivedUnitFacade);
485 }
486 if (state.getConfig().getDnaSoure() != null) {
487 importAssociatedDna(state, item, derivedUnitFacade);
488 }
489
490 state.getReport().addAlreadyExistingSpecimen(SpecimenImportUtility.getUnitID(derivedUnit, config),
491 derivedUnit);
492
493 return;
494 }
495 }else{
496 System.err.println("dataholder does not contain unit id");
497 }
498 // TODO: implement overwrite/merge specimen
499 // else if(state.getConfig().isOverwriteExistingSpecimens()){
500 // Pager<SpecimenOrObservationBase> existingSpecimens =
501 // cdmAppController.getOccurrenceService().findByTitle(config);
502 // if(!existingSpecimens.getRecords().isEmpty()){
503 // derivedUnitFacade = DerivedUnitFacade.NewInstance(derivedUnit);
504 // derivedUnitBase = derivedUnitFacade.innerDerivedUnit();
505 // fieldUnit = derivedUnitFacade.getFieldUnit(true);
506 // }
507 // }
508 // import new specimen
509
510 // import DNA unit
511 if (state.getDataHolder().getKindOfUnit() != null
512 && state.getDataHolder().getKindOfUnit().equalsIgnoreCase("dna")) {
513 AbcdDnaParser dnaParser = new AbcdDnaParser(state.getPrefix(), state.getReport(),
514 state.getCdmRepository());
515 DnaSample dnaSample = dnaParser.parse(item, state);
516 save(dnaSample, state);
517 // set dna as derived unit to avoid creating an extra specimen
518 // for this dna sample (instead just the field unit will be
519 // created)
520 state.setDerivedUnitBase(dnaSample);
521 derivedUnitFacade = DerivedUnitFacade.NewInstance(state.getDerivedUnitBase());
522 } else {
523 // create facade
524 derivedUnitFacade = getFacade(state);
525 state.setDerivedUnitBase(derivedUnitFacade.innerDerivedUnit());
526
527 }
528
529 /**
530 * GATHERING EVENT
531 */
532
533 // look for existing fieldUnit
534
535 FieldUnit fieldUnit = state.getFieldUnit(state.getDataHolder().getFieldNumber());
536
537 // gathering event
538 UnitsGatheringEvent unitsGatheringEvent = new UnitsGatheringEvent(cdmAppController.getTermService(),
539 state.getDataHolder().locality, state.getDataHolder().languageIso, state.getDataHolder().longitude,
540 state.getDataHolder().latitude, state.getDataHolder().getGatheringCoordinateErrorMethod(),
541 state.getDataHolder().getGatheringElevationText(), state.getDataHolder().getGatheringElevationMin(),
542 state.getDataHolder().getGatheringElevationMax(), state.getDataHolder().getGatheringElevationUnit(),
543 state.getDataHolder().getGatheringDateText(), state.getDataHolder().getGatheringNotes(),
544 state.getDataHolder().getGatheringMethod(),
545 state.getTransformer().getReferenceSystemByKey(state.getDataHolder().getGatheringSpatialDatum()),
546 state.getConfig());
547
548 unitsGatheringEvent.setGatheringDepth(state.getDataHolder().getGatheringDepthText(),
549 state.getDataHolder().getGatheringDepthMin(), state.getDataHolder().getGatheringDepthMax(),
550 state.getDataHolder().getGatheringDepthUnit());
551 // unitsGatheringEvent.setHeight(heightText, heightMin, heightMax,
552 // heightUnit);
553 if (state.getDataHolder().gatheringAgentsList.isEmpty()) {
554 unitsGatheringEvent.setCollector(state.getPersonStore().get(state.getDataHolder().gatheringAgentsText),
555 config);
556 } else {
557 unitsGatheringEvent.setCollector(
558 state.getPersonStore().get(state.getDataHolder().gatheringAgentsList.toString()), config);
559 }
560 // count
561 UnitsGatheringArea unitsGatheringArea = new UnitsGatheringArea();
562 // unitsGatheringArea.setConfig(state.getConfig(),getOccurrenceService(),
563 // getTermService());
564 unitsGatheringArea.setParams(state.getDataHolder().isocountry, state.getDataHolder().country,
565 (state.getConfig()), cdmAppController.getTermService(), cdmAppController.getOccurrenceService(),
566 cdmAppController.getVocabularyService());
567
568 DefinedTermBase<?> areaCountry = unitsGatheringArea.getCountry();
569
570 // other areas
571 unitsGatheringArea = new UnitsGatheringArea();
572 // unitsGatheringArea.setConfig(state.getConfig(),getOccurrenceService(),getTermService());
573
574 unitsGatheringArea.setAreas(state.getDataHolder().getNamedAreaList(), (state.getConfig()),
575 cdmAppController.getTermService(), cdmAppController.getVocabularyService());
576
577 ArrayList<DefinedTermBase> nas = unitsGatheringArea.getAreas();
578 for (DefinedTermBase namedArea : nas) {
579 unitsGatheringEvent.addArea(namedArea);
580 }
581
582 // copy gathering event to facade
583 GatheringEvent gatheringEvent = unitsGatheringEvent.getGatheringEvent();
584 if (fieldUnit != null) {
585 derivedUnitFacade.setFieldUnit(fieldUnit);
586 }
587
588 derivedUnitFacade.setLocality(gatheringEvent.getLocality());
589 derivedUnitFacade.setExactLocation(gatheringEvent.getExactLocation());
590 derivedUnitFacade.setCollector(gatheringEvent.getCollector());
591 derivedUnitFacade.setCountry((NamedArea) areaCountry);
592 derivedUnitFacade.setAbsoluteElevationText(gatheringEvent.getAbsoluteElevationText());
593 derivedUnitFacade.setAbsoluteElevation(gatheringEvent.getAbsoluteElevation());
594 derivedUnitFacade.setAbsoluteElevationMax(gatheringEvent.getAbsoluteElevationMax());
595 derivedUnitFacade.setDistanceToGroundText(gatheringEvent.getDistanceToGroundText());
596 derivedUnitFacade.setDistanceToGroundMax(gatheringEvent.getDistanceToGroundMax());
597 derivedUnitFacade.setDistanceToGround(gatheringEvent.getDistanceToGround());
598 derivedUnitFacade.setDistanceToWaterSurfaceText(gatheringEvent.getDistanceToWaterSurfaceText());
599 derivedUnitFacade.setDistanceToWaterSurfaceMax(gatheringEvent.getDistanceToWaterSurfaceMax());
600 derivedUnitFacade.setDistanceToWaterSurface(gatheringEvent.getDistanceToWaterSurface());
601 derivedUnitFacade.setGatheringPeriod(gatheringEvent.getTimeperiod());
602 derivedUnitFacade.setCollectingMethod(gatheringEvent.getCollectingMethod());
603
604 for (DefinedTermBase<?> area : unitsGatheringArea.getAreas()) {
605 derivedUnitFacade.addCollectingArea((NamedArea) area);
606 }
607 // derivedUnitFacade.addCollectingAreas(unitsGatheringArea.getAreas());
608 // TODO exsiccatum
609
610 // add fieldNumber
611 String fieldNumber = null;
612 if (derivedUnitFacade.getFieldUnit(false) != null){
613 fieldNumber = derivedUnitFacade.getFieldUnit(false).getFieldNumber();
614 }
615
616 derivedUnitFacade.setFieldNumber(NB(state.getDataHolder().getFieldNumber()));
617 save(unitsGatheringEvent.getLocality(), state);
618
619 // add unitNotes
620 if (state.getDataHolder().getUnitNotes() != null) {
621 derivedUnitFacade
622 .addAnnotation(Annotation.NewDefaultLanguageInstance(NB(state.getDataHolder().getUnitNotes())));
623 }
624 if (gatheringEvent.getAnnotations() != null) {
625 for (Annotation annotation : gatheringEvent.getAnnotations()) {
626 derivedUnitFacade.getGatheringEvent(true).addAnnotation(annotation);
627 }
628 }
629
630 // //add Multimedia URLs
631 if (state.getDataHolder().getMultimediaObjects().size() != -1) {
632 for (String multimediaObject : state.getDataHolder().getMultimediaObjects().keySet()) {
633 Media media;
634 try {
635 media = extractMedia(state, multimediaObject);
636 if (media == null){
637 continue;
638 }
639 derivedUnitFacade.addDerivedUnitMedia(media);
640 if (state.getConfig().isAddMediaAsMediaSpecimen()) {
641 // add media also as specimen scan
642 MediaSpecimen mediaSpecimen = MediaSpecimen
643 .NewInstance(SpecimenOrObservationType.StillImage);
644 mediaSpecimen.setMediaSpecimen(media);
645 // do it only once!!
646 DefinedTermBase specimenScanTerm = getTermService().load(SPECIMEN_SCAN_TERM);
647 if (specimenScanTerm instanceof DefinedTerm) {
648 mediaSpecimen.setKindOfUnit((DefinedTerm) specimenScanTerm);
649 }
650 DerivationEvent derivationEvent = DerivationEvent
651 .NewInstance(DerivationEventType.PREPARATION());
652 derivationEvent.addDerivative(mediaSpecimen);
653 derivedUnitFacade.innerDerivedUnit().addDerivationEvent(derivationEvent);
654 }
655
656 } catch (MalformedURLException e) {
657 // TODO Auto-generated catch block
658 e.printStackTrace();
659 }
660
661 }
662 }
663 // multimedia for fieldUnit
664 if (state.getDataHolder().getGatheringMultimediaObjects().size() != -1) {
665 for (String multimediaObject : state.getDataHolder().getGatheringMultimediaObjects().keySet()) {
666 Media media;
667 try {
668 media = extractMedia(state, multimediaObject);
669 if (media == null){
670 continue;
671 }
672 derivedUnitFacade.addFieldObjectMedia(media);
673
674 } catch (MalformedURLException e) {
675 // TODO Auto-generated catch block
676 e.printStackTrace();
677 }
678
679 }
680 }
681
682 // /*
683 // * merge AND STORE DATA
684 // */
685 // getTermService().saveOrUpdate(areaCountry);// TODO save area
686 // sooner
687 //
688 // for (NamedArea area : otherAreas) {
689 // getTermService().saveOrUpdate(area);// merge it sooner (foreach
690 // area)
691 // }
692 // save(derivedUnitFacade.getFieldUnit(false), state);
693 if (derivedUnitFacade.getFieldUnit(false) != null) {
694 state.setFieldUnit(derivedUnitFacade.getFieldUnit(false));
695 }
696
697 // handle collection data
698 setCollectionData(state, derivedUnitFacade);
699
700 // Reference stuff
701 SpecimenUserInteraction sui = config.getSpecimenUserInteraction();
702 Map<String, OriginalSourceBase<?>> sourceMap = new HashMap<>();
703
704 state.getDataHolder().setDocSources(new ArrayList<>());
705 for (String[] fullReference : state.getDataHolder().getReferenceList()) {
706 String strReference = fullReference[0];
707 String citationDetail = fullReference[1];
708 String citationURL = fullReference[2];
709
710 if (!citationURL.isEmpty()) {
711 citationDetail += ", " + citationURL;
712 }
713
714 Reference reference;
715 if (strReference.equals(state.getRef().getTitleCache())) {
716 reference = state.getRef();
717 } else {
718 reference = ReferenceFactory.newGeneric();
719 reference.setTitle(strReference);
720 }
721
722 save(reference, state);
723 IdentifiableSource sour = getIdentifiableSource(reference, citationDetail);
724 sour.getCitation().setUri(state.getActualAccessPoint());
725 sour.setType(OriginalSourceType.PrimaryTaxonomicSource);
726 try {
727 if (sour.getCitation() != null) {
728 if (StringUtils.isNotBlank(sour.getCitationMicroReference())) {
729 state.getDataHolder().getDocSources()
730 .add(sour.getCitation().getTitleCache() + "---" + sour.getCitationMicroReference());
731 } else {
732 state.getDataHolder().getDocSources().add(sour.getCitation().getTitleCache());
733 }
734 }
735 } catch (Exception e) {
736 logger.warn("oups");
737 }
738 derivedUnitFacade.addSource(sour);
739
740 }
741 // List<IdentifiableSource> issTmp = new
742 // ArrayList<IdentifiableSource>();//getCommonService().list(IdentifiableSource.class,
743 // null, null, null, null);
744 // List<DescriptionElementSource> issTmp2 = new
745 // ArrayList<DescriptionElementSource>();//getCommonService().list(DescriptionElementSource.class,
746 // null, null, null, null);
747 //
748 // Set<OriginalSourceBase> osbSet = new
749 // HashSet<OriginalSourceBase>();
750 // if(issTmp2!=null) {
751 // osbSet.addAll(issTmp2);
752 // }
753 // if(issTmp!=null) {
754 // osbSet.addAll(issTmp);
755 // }
756
757 IdentifiableSource sour = getIdentifiableSource(state.getRef(), null);
758 String idInSource = derivedUnitFacade.getAccessionNumber() != null ? derivedUnitFacade.getAccessionNumber()
759 : derivedUnitFacade.getCatalogNumber();
760 sour.getCitation().setUri(state.getActualAccessPoint());
761 sour.setIdInSource(idInSource);
762 try {
763 if (sour.getCitation() != null) {
764 if (StringUtils.isNotBlank(sour.getCitationMicroReference())) {
765 state.getDataHolder().getDocSources()
766 .add(sour.getCitation().getTitleCache() + "---" + sour.getCitationMicroReference());
767 } else {
768 state.getDataHolder().getDocSources().add(sour.getCitation().getTitleCache());
769 }
770 }
771 } catch (Exception e) {
772 logger.warn("oups");
773 }
774
775 derivedUnitFacade.addSource(sour);
776 // sourceMap.put(sour.getCitation().getTitleCache()+
777 // "---"+sour.getCitationMicroReference(),sour);
778
779 // if( state.getConfig().isInteractWithUser()){
780 // List<OriginalSourceBase<?>>sources=null;
781 // if(!state.isDerivedUnitSourcesSet()){
782 // sources= sui.askForSource(sourceMap, "the unit
783 // itself","",getReferenceService(),
784 // state.getDataHolder().getDocSources());
785 // state.setDerivedUnitSources(sources);
786 // state.setDerivedUnitSourcesSet(true);
787 // }
788 // else{
789 // sources=state.getDerivedUnitSources();
790 // }
791 //// for (OriginalSourceBase<?> source:sources){
792 //// if(source.isInstanceOf(IdentifiableSource.class)){
793 //// if(sourceNotLinkedToElement(derivedUnitFacade,source)) {
794 //// derivedUnitFacade.addSource((IdentifiableSource)source.clone());
795 //// }
796 //// }else{
797 //// if(sourceNotLinkedToElement(derivedUnitFacade,sour)) {
798 //// derivedUnitFacade.addSource(OriginalSourceType.Import,source.getCitation(),source.getCitationMicroReference(),
799 // ioName);
800 //// }
801 //// }
802 //// }
803 // }else{
804 // for (OriginalSourceBase<?> sr : sourceMap.values()){
805 // if(sr.isInstanceOf(IdentifiableSource.class)){
806 // if(sourceNotLinkedToElement(derivedUnitFacade,sr)) {
807 // derivedUnitFacade.addSource((IdentifiableSource)sr.clone());
808 // }
809 // }else{
810 // if(sourceNotLinkedToElement(derivedUnitFacade,sr)) {
811 // derivedUnitFacade.addSource(OriginalSourceType.Import,sr.getCitation(),sr.getCitationMicroReference(),
812 // ioName);
813 // }
814 // }
815 // }
816 // }
817
818 save(state.getDerivedUnitBase(), state);
819
820 if (logger.isDebugEnabled()) {
821 logger.info("saved ABCD specimen ...");
822 }
823
824 // handle identifications
825 handleIdentifications(state, derivedUnitFacade);
826
827 // associatedUnits
828 if (handleAssociatedUnits) {
829 importAssociatedUnits(state, item, derivedUnitFacade);
830 }
831 if (state.getConfig().getDnaSoure() != null) {
832 importAssociatedDna(state, item, derivedUnitFacade);
833 }
834 // siblings/ other children
835 if (derivedUnitFacade.getType() != null
836 && (derivedUnitFacade.getType().equals(SpecimenOrObservationType.LivingSpecimen)
837 || derivedUnitFacade.getType().equals(SpecimenOrObservationType.TissueSample)
838 || derivedUnitFacade.getType().equals(SpecimenOrObservationType.OtherSpecimen)
839 || derivedUnitFacade.getType().equals(SpecimenOrObservationType.MaterialSample))
840 && state.getConfig().isGetSiblings()) {
841 getSiblings(state, item, derivedUnitFacade);
842 }
843
844 } catch (Exception e) {
845 String message = "Error when reading record! " + itemObject.toString();
846 logger.warn(message);
847 state.getReport().addException(message, e);
848 e.printStackTrace();
849 state.setUnsuccessfull();
850 }
851
852 return;
853 }
854
855 /**
856 * @param state
857 * @param multimediaObject
858 * @return
859 * @throws MalformedURLException
860 */
861 private Media extractMedia(Abcd206ImportState state, String multimediaObject) throws MalformedURLException {
862 Media media;
863 media = getImageMedia(multimediaObject, READ_MEDIA_DATA);
864
865 Map<String, String> attributes = state.getDataHolder().getMultimediaObjects().get(multimediaObject);
866 if (attributes == null){
867 attributes = state.getDataHolder().getGatheringMultimediaObjects().get(multimediaObject);
868 if (attributes == null){
869 logger.error(multimediaObject + " does not exist in dataHolder");
870 state.getResult().addError(multimediaObject + " does not exist in dataHolder");
871 return null;
872 }
873 }
874 if (attributes.containsKey("Context")) {
875 LanguageString description = LanguageString.NewInstance(attributes.get("Context"), Language.ENGLISH());
876 media.addDescription(description);
877 }
878 if (attributes.containsKey("Comment")) {
879 LanguageString description = LanguageString.NewInstance(attributes.get("Comment"), Language.ENGLISH());
880 media.addDescription(description);
881 }
882 if (attributes.containsKey("Creators")) {
883 String creators = attributes.get("Creators");
884 Person artist;
885 Team artistTeam;
886 String[] artists;
887 if (creators != null) {
888 if (creators.contains("&")) {
889 artists = creators.split("&");
890 artistTeam = new Team();
891 for (String creator : artists) {
892 artist = Person.NewTitledInstance(creator);
893 artistTeam.addTeamMember(artist);
894 }
895 media.setArtist(artistTeam);
896 } else {
897
898 artist = Person.NewTitledInstance(creators);
899 media.setArtist(artist);
900 }
901 }
902
903 }
904 if (attributes.containsKey("CreateDate")) {
905 String createDate = attributes.get("CreateDate");
906
907 if (createDate != null) {
908
909 media.setMediaCreated(TimePeriodParser.parseString(createDate));
910 }
911
912 }
913
914 if (attributes.containsKey("License")) {
915 String licence = attributes.get("License");
916
917 if (licence != null) {
918 Rights right = Rights.NewInstance(licence, Language.ENGLISH(), RightsType.LICENSE());
919 media.addRights(right);
920 }
921
922 }
923 return media;
924 }
925
926 @Override
927 protected void importAssociatedUnits(Abcd206ImportState state, Object itemObject,
928 DerivedUnitFacade derivedUnitFacade) {
929 SpecimenDeleteConfigurator deleteConfig = new SpecimenDeleteConfigurator();
930 deleteConfig.setDeleteChildren(false);
931 Abcd206ImportConfigurator config = state.getConfig();
932 // import associated units
933 FieldUnit currentFieldUnit = derivedUnitFacade.innerFieldUnit();
934 // TODO: push state (think of implementing stack architecture for state
935 DerivedUnit currentUnit = state.getDerivedUnitBase();
936 DerivationEvent currentDerivedFrom = currentUnit.getDerivedFrom();
937 URI currentAccessPoint = state.getActualAccessPoint();
938 String currentPrefix = state.getPrefix();
939 Element item = null;
940 if (itemObject instanceof Element) {
941 item = (Element) itemObject;
942 }
943 NodeList unitAssociationList = null;
944 if (item != null) {
945 unitAssociationList = item.getElementsByTagName(currentPrefix + "UnitAssociation");
946 for (int k = 0; k < unitAssociationList.getLength(); k++) {
947 if (unitAssociationList.item(k) instanceof Element) {
948 Element unitAssociation = (Element) unitAssociationList.item(k);
949 UnitAssociationParser unitAssociationParser = new UnitAssociationParser(currentPrefix,
950 state.getReport(), state.getCdmRepository());
951 UnitAssociationWrapper associationWrapper = unitAssociationParser.parse(unitAssociation);
952 if (associationWrapper != null) {
953 state.setActualAccessPoint(associationWrapper.getAccesPoint());
954 NodeList associatedUnits = associationWrapper.getAssociatedUnits();
955 if (associatedUnits != null) {
956 for (int m = 0; m < associatedUnits.getLength(); m++) {
957 if (associatedUnits.item(m) instanceof Element) {
958 state.reset();
959 state.setPrefix(associationWrapper.getPrefix());
960 Abcd206ImportParser.setUnitPropertiesXML((Element) associatedUnits.item(m),
961 new Abcd206XMLFieldGetter(state.getDataHolder(), state.getPrefix()), state);
962 // logger.debug("derived unit: " + state.getDerivedUnitBase().toString()
963 // + " associated unit: " + state.getDataHolder().getKindOfUnit() + ", "
964 // + state.getDataHolder().accessionNumber + ", "
965 // + state.getDataHolder().getRecordBasis() + ", "
966 // + state.getDataHolder().getUnitID());
967 handleSingleUnit(state, associatedUnits.item(m), true);
968
969 DerivedUnit associatedUnit = state.getDerivedUnitBase();
970 FieldUnit associatedFieldUnit = null;
971 java.util.Collection<FieldUnit> associatedFieldUnits = state.getCdmRepository()
972 .getOccurrenceService().findFieldUnits(associatedUnit.getUuid(), null);
973 // ignore field unit if associated unit has
974 // more than one
975 if (associatedFieldUnits != null && associatedFieldUnits.size() > 1) {
976 state.getReport().addInfoMessage(
977 String.format("%s has more than one field unit.", associatedUnit));
978 } else if (associatedFieldUnits != null && associatedFieldUnits.size() == 1) {
979 associatedFieldUnit = associatedFieldUnits.iterator().next();
980 }
981
982 // attach current unit and associated unit
983 // depending on association type
984
985 // parent-child relation:
986 // copy derivation event and connect parent
987 // and sub derivative
988 // if(associationWrapper.getAssociationType().contains("individual")
989 // ||
990 // associationWrapper.getAssociationType().contains("culture")
991 // ||
992 // associationWrapper.getAssociationType().contains("sample")
993 // ||
994 // associationWrapper.getAssociationType().contains("same
995 // in situ")){
996 if (currentDerivedFrom == null) {
997 state.getReport()
998 .addInfoMessage(String.format(
999 "No derivation event found for unit %s. Defaulting to ACCESSIONING event.",
1000 SpecimenImportUtility.getUnitID(currentUnit, config)));
1001 DerivationEvent.NewSimpleInstance(associatedUnit, currentUnit,
1002 DerivationEventType.ACCESSIONING());
1003 } else {
1004 DerivationEvent updatedDerivationEvent = DerivationEvent.NewSimpleInstance(
1005 associatedUnit, currentUnit, currentDerivedFrom.getType());
1006 updatedDerivationEvent.setActor(currentDerivedFrom.getActor());
1007 updatedDerivationEvent.setDescription(currentDerivedFrom.getDescription());
1008 updatedDerivationEvent.setInstitution(currentDerivedFrom.getInstitution());
1009 updatedDerivationEvent.setTimeperiod(currentDerivedFrom.getTimeperiod());
1010
1011 }
1012 state.getReport().addDerivate(associatedUnit, currentUnit, config);
1013 // }
1014 // siblings relation
1015 // connect current unit to field unit of
1016 // associated unit
1017 // else
1018 // if(associationWrapper.getAssociationType().contains("population")||
1019 // associationWrapper.getAssociationType().contains("sample")){
1020 // //no associated field unit -> using
1021 // current one
1022 // if(associatedFieldUnit==null){
1023 // if(currentFieldUnit!=null){
1024 // DerivationEvent.NewSimpleInstance(currentFieldUnit,
1025 // associatedUnit,
1026 // DerivationEventType.ACCESSIONING());
1027 // }
1028 // }
1029 // else{
1030 // if(currentDerivedFrom==null){
1031 // state.getReport().addInfoMessage("No
1032 // derivation event found for unit
1033 // "+SpecimenImportUtility.getUnitID(currentUnit,
1034 // config)+". Defaulting to ACCESIONING
1035 // event.");
1036 // DerivationEvent.NewSimpleInstance(associatedFieldUnit,
1037 // currentUnit,
1038 // DerivationEventType.ACCESSIONING());
1039 // }
1040 // if(currentDerivedFrom!=null &&
1041 // associatedFieldUnit==currentFieldUnit){
1042 // DerivationEvent updatedDerivationEvent =
1043 // DerivationEvent.NewSimpleInstance(associatedFieldUnit,
1044 // currentUnit,
1045 // currentDerivedFrom.getType());
1046 // updatedDerivationEvent.setActor(currentDerivedFrom.getActor());
1047 // updatedDerivationEvent.setDescription(currentDerivedFrom.getDescription());
1048 // updatedDerivationEvent.setInstitution(currentDerivedFrom.getInstitution());
1049 // updatedDerivationEvent.setTimeperiod(currentDerivedFrom.getTimeperiod());
1050 // }
1051 // }
1052 // }
1053
1054 // delete current field unit if replaced
1055 if (currentFieldUnit != null && currentDerivedFrom != null
1056 && currentFieldUnit.getDerivationEvents().size() == 1
1057 && currentFieldUnit.getDerivationEvents().contains(currentDerivedFrom) // making
1058 // sure
1059 // that
1060 // the
1061 // field
1062 // unit
1063 && currentDerivedFrom.getDerivatives().size() == 1
1064 && currentDerivedFrom.getDerivatives().contains(currentUnit) // is
1065 // not
1066 // attached
1067 // to
1068 // other
1069 // derived
1070 // units
1071 && currentDerivedFrom != currentUnit.getDerivedFrom() // <-
1072 // derivation
1073 // has
1074 // been
1075 // replaced
1076 // and
1077 // can
1078 // be
1079 // deleted
1080 ) {
1081 currentFieldUnit.removeDerivationEvent(currentDerivedFrom);
1082
1083 if (currentFieldUnit.getDerivationEvents().isEmpty()){
1084 DeleteResult result = state.getCdmRepository().getOccurrenceService().delete(currentFieldUnit, deleteConfig);
1085
1086 }else{
1087
1088 logger.debug("there are still derivation events in fieldUnit " + currentFieldUnit.getId());
1089 }
1090
1091 }
1092
1093 save(associatedUnit, state);
1094 }
1095 }
1096 }
1097 }
1098 }
1099 }
1100 }
1101 // TODO: pop state
1102 state.reset();
1103 state.setDerivedUnitBase(currentUnit);
1104 state.setActualAccessPoint(currentAccessPoint);
1105 state.setPrefix(currentPrefix);
1106 }
1107
1108 private void importAssociatedDna(Abcd206ImportState state, Object itemObject, DerivedUnitFacade derivedUnitFacade) {
1109 URI dnaSource = state.getConfig().getDnaSoure();
1110 String unitId = derivedUnitFacade.getCatalogNumber();
1111 if (unitId == null) {
1112 unitId = derivedUnitFacade.getAccessionNumber();
1113 }
1114
1115 UnitAssociationParser unitParser = new UnitAssociationParser(state.getPrefix(), state.getReport(),
1116 state.getCdmRepository());
1117 UnitAssociationWrapper unitAssociationWrapper = null;
1118
1119 unitAssociationWrapper = unitParser.parseSiblings(unitId, dnaSource);
1120
1121 DerivedUnit currentUnit = state.getDerivedUnitBase();
1122 // DerivationEvent currentDerivedFrom = currentUnit.getDerivedFrom();
1123 FieldUnit currentFieldUnit = derivedUnitFacade.getFieldUnit(false);
1124 if (unitAssociationWrapper != null) {
1125 NodeList associatedUnits = unitAssociationWrapper.getAssociatedUnits();
1126 if (associatedUnits != null) {
1127 for (int m = 0; m < associatedUnits.getLength(); m++) {
1128 if (associatedUnits.item(m) instanceof Element) {
1129 state.reset();
1130 String associationType = AbcdParseUtility
1131 .parseFirstTextContent(((Element) associatedUnits.item(m))
1132 .getElementsByTagName(state.getPrefix() + "AssociationType"));
1133
1134 Abcd206ImportParser.setUnitPropertiesXML((Element) associatedUnits.item(m),
1135 new Abcd206XMLFieldGetter(state.getDataHolder(), unitAssociationWrapper.getPrefix()),
1136 state);
1137 // logger.debug("derived unit: " +
1138 // state.getDerivedUnitBase().toString() + " associated
1139 // unit: " +state.getDataHolder().getKindOfUnit() + ", "
1140 // + state.getDataHolder().accessionNumber + ", " +
1141 // state.getDataHolder().getRecordBasis() + ", " +
1142 // state.getDataHolder().getUnitID());
1143
1144 handleSingleUnit(state, associatedUnits.item(m), false);
1145
1146 DerivedUnit associatedUnit = state.getDerivedUnitBase();
1147 FieldUnit associatedFieldUnit = null;
1148 java.util.Collection<FieldUnit> associatedFieldUnits = state.getCdmRepository()
1149 .getOccurrenceService().findFieldUnits(associatedUnit.getUuid(), null);
1150 // ignore field unit if associated unit has more than
1151 // one
1152 if (associatedFieldUnits.size() > 1) {
1153 state.getReport()
1154 .addInfoMessage(String.format("%s has more than one field unit.", associatedUnit));
1155 } else if (associatedFieldUnits.size() == 1) {
1156 associatedFieldUnit = associatedFieldUnits.iterator().next();
1157 }
1158 // parent-child relation:
1159 if (associationType != null && (associationType.contains("individual")
1160 || associationType.contains("culture") || associationType.contains("sample")
1161 || associationType.contains("isolated"))) {
1162 DerivationEvent updatedDerivationEvent = DerivationEvent.NewSimpleInstance(currentUnit,
1163 associatedUnit, DerivationEventType.ACCESSIONING());
1164
1165 updatedDerivationEvent.setDescription(associationType);
1166 if (associatedFieldUnit != null && associatedFieldUnit != currentFieldUnit) {
1167 associatedFieldUnit.removeDerivationEvent(updatedDerivationEvent);
1168 // if (associatedFieldUnit.getDerivationEvents().isEmpty()){
1169 SpecimenDeleteConfigurator deleteConfig = new SpecimenDeleteConfigurator();
1170 deleteConfig.setDeleteChildren(false);
1171 DeleteResult result = state.getCdmRepository().getOccurrenceService().delete(associatedFieldUnit, deleteConfig);
1172 state.setFieldUnit(currentFieldUnit);
1173
1174 // }
1175 if (updatedDerivationEvent.getOriginals().isEmpty()){
1176 // state.getCdmRepository().getOccurrenceService().deleteDerivationEvent(updatedDerivationEvent);
1177 }
1178 }
1179 state.getReport().addDerivate(associatedUnit, currentUnit, state.getConfig());
1180 }
1181 save(associatedUnit, state);
1182
1183 }
1184 }
1185 }
1186 }
1187 state.reset();
1188 state.setDerivedUnitBase(currentUnit);
1189
1190 }
1191
1192 /**
1193 * @param derivedUnitFacade
1194 * @param sour
1195 * @return
1196 */
1197 private boolean sourceNotLinkedToElement(DerivedUnitFacade derivedUnitFacade, OriginalSourceBase<?> source) {
1198 Set<IdentifiableSource> linkedSources = derivedUnitFacade.getSources();
1199 for (IdentifiableSource is : linkedSources) {
1200 if (is.getCitation() != null && source.getCitation() != null
1201 && is.getCitation().getTitleCache().equalsIgnoreCase(source.getCitation().getTitleCache())) {
1202 String isDetail = is.getCitationMicroReference();
1203 if ((StringUtils.isBlank(isDetail) && StringUtils.isBlank(source.getCitationMicroReference()))
1204 || (isDetail != null && isDetail.equalsIgnoreCase(source.getCitationMicroReference()))) {
1205 return false;
1206 }
1207 }
1208 }
1209 return true;
1210 }
1211
1212 // /**
1213 // * @param reference
1214 // * @param citationDetail
1215 // * @return
1216 // */
1217 // private DescriptionElementSource getDescriptionSource(Reference
1218 // reference, String citationDetail) {
1219 //
1220 // List<OriginalSourceBase> issTmp2 =
1221 // getCommonService().list(DescriptionElementSource.class, null, null, null,
1222 // null);
1223 //
1224 // try {
1225 // for (OriginalSourceBase<?> osb:issTmp2){
1226 // if (osb.getCitation().equals(reference) &&
1227 // osb.getCitationMicroReference().equalsIgnoreCase(citationDetail)) {
1228 // return (DescriptionElementSource) osb.clone();
1229 // }
1230 // }
1231 // } catch (CloneNotSupportedException e) {
1232 // // TODO Auto-generated catch block
1233 // e.printStackTrace();
1234 // }
1235 //
1236 // DescriptionElementSource sour =
1237 // DescriptionElementSource.NewInstance(OriginalSourceType.Import,null,null,
1238 // reference,citationDetail);
1239 // return sour;
1240 // }
1241
1242 /**
1243 * setCollectionData : store the collection object into the
1244 * derivedUnitFacade
1245 *
1246 * @param state
1247 */
1248 protected void setCollectionData(Abcd206ImportState state, DerivedUnitFacade derivedUnitFacade) {
1249 Abcd206ImportConfigurator config = state.getConfig();
1250 SpecimenImportUtility.setUnitID(derivedUnitFacade.innerDerivedUnit(), state.getDataHolder().getUnitID(),
1251 config);
1252 if (!config.isMapUnitIdToAccessionNumber()) {
1253 derivedUnitFacade.setAccessionNumber(NB(state.getDataHolder().accessionNumber));
1254 }
1255 // derivedUnitFacade.setCollectorsNumber(NB(state.getDataHolder().collectorsNumber));
1256
1257 /*
1258 * INSTITUTION & COLLECTION
1259 */
1260 // manage institution
1261 Institution institution = this.getInstitution(NB(state.getDataHolder().institutionCode), state);
1262 // manage collection
1263 Collection collection = this.getCollection(institution, NB(state.getDataHolder().collectionCode), state);
1264 // link specimen & collection
1265 derivedUnitFacade.setCollection(collection);
1266 }
1267
1268 /**
1269 * getFacade : get the DerivedUnitFacade based on the recordBasis
1270 *
1271 * @param state
1272 *
1273 * @return DerivedUnitFacade
1274 */
1275 @Override
1276 protected DerivedUnitFacade getFacade(Abcd206ImportState state) {
1277 if (logger.isDebugEnabled()) {
1278 logger.info("getFacade()");
1279 }
1280 SpecimenOrObservationType type = null;
1281 DefinedTerm kindOfUnit = null;
1282
1283 // create specimen
1284 if (NB((state.getDataHolder()).getRecordBasis()) != null) {
1285 if (state.getDataHolder().getRecordBasis().toLowerCase().indexOf("living") > -1) {
1286 type = SpecimenOrObservationType.LivingSpecimen;
1287 } else if (state.getDataHolder().getRecordBasis().toLowerCase().startsWith("s")
1288 || state.getDataHolder().getRecordBasis().toLowerCase().indexOf("specimen") > -1) {// specimen
1289 type = SpecimenOrObservationType.PreservedSpecimen;
1290 } else if (state.getDataHolder().getRecordBasis().toLowerCase().startsWith("o")
1291 || state.getDataHolder().getRecordBasis().toLowerCase().indexOf("observation") > -1) {
1292 if (state.getDataHolder().getRecordBasis().toLowerCase().contains("machine")
1293 && state.getDataHolder().getRecordBasis().toLowerCase().contains("observation")) {
1294 type = SpecimenOrObservationType.MachineObservation;
1295 } else if (state.getDataHolder().getRecordBasis().toLowerCase().contains("human")
1296 && state.getDataHolder().getRecordBasis().toLowerCase().contains("observation")) {
1297 type = SpecimenOrObservationType.HumanObservation;
1298 } else {
1299 type = SpecimenOrObservationType.Observation;
1300 }
1301 } else if (state.getDataHolder().getRecordBasis().toLowerCase().indexOf("fossil") > -1) {
1302 type = SpecimenOrObservationType.Fossil;
1303 } else if (state.getDataHolder().getRecordBasis().toLowerCase().indexOf("materialsample") > -1) {
1304 type = SpecimenOrObservationType.MaterialSample;
1305 } else if (state.getDataHolder().getRecordBasis().toLowerCase().indexOf("sample") > -1) {
1306 type = SpecimenOrObservationType.TissueSample;
1307 }
1308
1309 if (type == null) {
1310 logger.info("The basis of record does not seem to be known: " + state.getDataHolder().getRecordBasis());
1311 type = SpecimenOrObservationType.DerivedUnit;
1312 }
1313 } else {
1314 logger.info("The basis of record is null");
1315 type = SpecimenOrObservationType.DerivedUnit;
1316 }
1317
1318 if (NB((state.getDataHolder()).getKindOfUnit()) != null) {
1319 kindOfUnit = getKindOfUnit(state, null, state.getDataHolder().getKindOfUnit().toLowerCase(), null, null,
1320 null);
1321 if (kindOfUnit == null) {
1322 if (state.getDataHolder().getKindOfUnit().toLowerCase().indexOf("clone") > -1) {
1323 kindOfUnit = getKindOfUnit(state, null, "clone culture", "clone culture", "cc", null);
1324 } else if (state.getDataHolder().getKindOfUnit().toLowerCase().startsWith("live")) {
1325 kindOfUnit = getKindOfUnit(state, null, "live sample", "live sample", "ls", null);
1326 } else if (state.getDataHolder().getKindOfUnit().toLowerCase().startsWith("microscopic slide")) {
1327 kindOfUnit = getKindOfUnit(state, null, "microscopic slide", "microscopic slide", "ms", null);
1328 }
1329
1330 if (kindOfUnit == null) {
1331 logger.info("The kind of unit does not seem to be known: " + state.getDataHolder().getKindOfUnit());
1332
1333 }
1334 }
1335 } else {
1336 logger.info("The kind of unit is null");
1337
1338 }
1339 DerivedUnitFacade derivedUnitFacade = DerivedUnitFacade.NewInstance(type);
1340 derivedUnitFacade.setFieldUnit(state.getFieldUnit(state.getDataHolder().getFieldNumber()));
1341 derivedUnitFacade.setDerivedUnitKindOfUnit(kindOfUnit);
1342 // derivedUnitFacade.setDerivedUnitKindOfUnit(kindOfUnit);
1343 return derivedUnitFacade;
1344 }
1345
1346 private void getCollectorsFromXML(Element root, Abcd206XMLFieldGetter abcdFieldGetter, Abcd206ImportState state) {
1347 NodeList group;
1348
1349 group = root.getChildNodes();
1350 for (int i = 0; i < group.getLength(); i++) {
1351 if (group.item(i).getNodeName().equals(state.getPrefix() + "Identifications")) {
1352 group = group.item(i).getChildNodes();
1353 break;
1354 }
1355 }
1356 // state.getDataHolder().gatheringAgents = "";
1357
1358 abcdFieldGetter.getType(root);
1359 abcdFieldGetter.getGatheringPeople(root);
1360 }
1361
1362 // private void compareABCDtoCDM(URI urlFileName, List<String> knownElts,
1363 // Abcd206XMLFieldGetter abcdFieldGetter) {
1364 // try {
1365 // DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
1366 // DocumentBuilder constructeur = factory.newDocumentBuilder();
1367 // URL url = urlFileName.toURL();
1368 // Object o = url.getContent();
1369 // InputStream is = (InputStream) o;
1370 // Document document = constructeur.parse(is);
1371 // Element root = document.getDocumentElement();
1372 // abcdFieldGetter.traverse(root);
1373 // }
1374 // catch (ParserConfigurationException e){
1375 // e.printStackTrace();
1376 // }
1377 // catch (SAXException e) {
1378 // e.printStackTrace();
1379 // }
1380 // catch (IOException e) {
1381 // e.printStackTrace();
1382 // }
1383 // Set<String> elts = state.getDataHolder().allABCDelements.keySet();
1384 // Iterator<String> it = elts.iterator();
1385 // String elt;
1386 // while (it.hasNext()) {
1387 // elt = it.next();
1388 // if (knownElts.indexOf(elt) == -1) {
1389 // if(DEBUG) {
1390 // logger.info("Unmerged ABCD element: " + elt + " - "+
1391 // state.getDataHolder().allABCDelements.get(elt));
1392 // }
1393 // }
1394 // }
1395 // }
1396
1397 /**
1398 * Load the list of names from the ABCD file and save them
1399 *
1400 * @param state
1401 * : the current ABCD import state
1402 * @param unitsList
1403 * : the unit list from the ABCD file
1404 * @param abcdFieldGetter
1405 * : the ABCD parser
1406 */
1407 private void prepareCollectors(Abcd206ImportState state, NodeList unitsList,
1408 Abcd206XMLFieldGetter abcdFieldGetter) {
1409
1410 TeamOrPersonBase<?> teamOrPerson = null;
1411 Team team = null;
1412 // ImportHelper.setOriginalSource(teamOrPerson,
1413 // state.getConfig().getSourceReference(), collector, "Collector");
1414 for (int i = 0; i < unitsList.getLength(); i++) {
1415 this.getCollectorsFromXML((Element) unitsList.item(i), abcdFieldGetter, state);
1416 if (!(state.getDataHolder().gatheringAgentsList.isEmpty())) {
1417 if (state.getDataHolder().gatheringAgentsList.size() == 1) {
1418 teamOrPerson = parseAuthorString(state.getDataHolder().gatheringAgentsList.get(0));
1419 } else {
1420 team = new Team();
1421 for (String collector : state.getDataHolder().gatheringAgentsList) {
1422 teamOrPerson = parseAuthorString(collector);
1423 if (teamOrPerson instanceof Person) {
1424 team.addTeamMember((Person) teamOrPerson);
1425 } else {
1426 for (Person person : ((Team) teamOrPerson).getTeamMembers()) {
1427 team.addTeamMember(person);
1428 }
1429 }
1430 }
1431 }
1432 if (!state.getPersonStore().containsId(state.getDataHolder().gatheringAgentsList.toString())) {
1433 state.getPersonStore().put(state.getDataHolder().gatheringAgentsList.toString(), teamOrPerson);
1434 if (logger.isDebugEnabled()) {
1435 logger.debug("Stored author " + state.getDataHolder().gatheringAgentsList.toString());
1436 }
1437 logger.warn("Not imported author with duplicated aut_id "
1438 + state.getDataHolder().gatheringAgentsList.toString());
1439 }
1440 }
1441 if (!StringUtils.isBlank(state.getDataHolder().gatheringAgentsText)
1442 && state.getDataHolder().gatheringAgentsList.isEmpty()) {
1443 teamOrPerson = parseAuthorString(state.getDataHolder().gatheringAgentsText);
1444 // if (teamOrPerson instanceof Person) {
1445 // //team.addTeamMember((Person) teamOrPerson);
1446 // } else {
1447 // team = new Team();
1448 // for (Person person : ((Team) teamOrPerson).getTeamMembers())
1449 // {
1450 // team.addTeamMember(person);
1451 // }
1452 // }
1453 if (!state.getPersonStore().containsId(state.getDataHolder().gatheringAgentsText)) {
1454 state.getPersonStore().put(state.getDataHolder().gatheringAgentsText, teamOrPerson);
1455 if (logger.isDebugEnabled()) {
1456 logger.debug("Stored author " + state.getDataHolder().gatheringAgentsText);
1457 }
1458 logger.warn("Not imported author with duplicated aut_id "
1459 + state.getDataHolder().gatheringAgentsList.toString());
1460 }
1461 }
1462
1463 }
1464
1465 // List<String> collectorsU = new ArrayList<String>(new
1466 // HashSet<String>(collectors));
1467 // List<String> teamsU = new ArrayList<String>(new
1468 // HashSet<String>(teams));
1469 //
1470 //
1471 // //existing teams in DB
1472 // Map<String,Team> titleCacheTeam = new HashMap<String, Team>();
1473 // List<UuidAndTitleCache<Team>> hiberTeam = new
1474 // ArrayList<UuidAndTitleCache<Team>>();//getAgentService().getTeamUuidAndTitleCache();
1475
1476 // Set<UUID> uuids = new HashSet<UUID>();
1477 // for (UuidAndTitleCache<Team> hibernateT:hiberTeam){
1478 // uuids.add(hibernateT.getUuid());
1479 // }
1480 // if (!uuids.isEmpty()){
1481 // List<AgentBase> existingTeams = getAgentService().find(uuids);
1482 // for (AgentBase<?> existingP:existingTeams){
1483 // titleCacheTeam.put(existingP.getTitleCache(),CdmBase.deproxy(existingP,Team.class));
1484 // }
1485 // }
1486
1487 // Map<String,UUID> teamMap = new HashMap<String, UUID>();
1488 // for (UuidAndTitleCache<Team> uuidt:hiberTeam){
1489 // teamMap.put(uuidt.getTitleCache(), uuidt.getUuid());
1490 // }
1491
1492 // existing persons in DB
1493 // List<UuidAndTitleCache<Person>> hiberPersons = new
1494 // ArrayList<UuidAndTitleCache<Person>>();//getAgentService().getPersonUuidAndTitleCache();
1495 // Map<String,Person> titleCachePerson = new HashMap<String, Person>();
1496 // uuids = new HashSet<UUID>();
1497 // for (UuidAndTitleCache<Person> hibernateP:hiberPersons){
1498 // uuids.add(hibernateP.getUuid());
1499 // }
1500 //
1501 // if (!uuids.isEmpty()){
1502 // List<AgentBase> existingPersons = getAgentService().find(uuids);
1503 // for (AgentBase<?> existingP:existingPersons){
1504 // titleCachePerson.put(existingP.getTitleCache(),CdmBase.deproxy(existingP,Person.class));
1505 // }
1506 // }
1507 //
1508 // Map<String,UUID> personMap = new HashMap<String, UUID>();
1509 // for (UuidAndTitleCache<Person> person:hiberPersons){
1510 // personMap.put(person.getTitleCache(), person.getUuid());
1511 // }
1512 //
1513 // java.util.Collection<Person> personToadd = new ArrayList<Person>();
1514 // java.util.Collection<Team> teamToAdd = new ArrayList<Team>();
1515 //
1516 // for (String collector:collectorsU){
1517 // Person p = Person.NewInstance();
1518 // p.setTitleCache(collector,true);
1519 // if (!personMap.containsKey(p.getTitleCache())){
1520 // personToadd.add(p);
1521 // }
1522 // }
1523 // for (String team:teamsU){
1524 // Team p = Team.NewInstance();
1525 // p.setTitleCache(team,true);
1526 // if (!teamMap.containsKey(p.getTitleCache())){
1527 // teamToAdd.add(p);
1528 // }
1529 // }
1530 //
1531 // if(!personToadd.isEmpty()){
1532 // for (Person agent: personToadd){
1533 // save(agent, state);
1534 // titleCachePerson.put(agent.getTitleCache(),CdmBase.deproxy(agent,
1535 // Person.class) );
1536 // }
1537 // }
1538 //
1539 // Person ptmp ;
1540 // Map <String,Integer>teamdone = new HashMap<String, Integer>();
1541 // for (List<String> collteam: collectorinteams){
1542 // if (!teamdone.containsKey(StringUtils.join(collteam.toArray(),"-"))){
1543 // Team team = new Team();
1544 // boolean em =true;
1545 // for (String collector:collteam){
1546 // ptmp = Person.NewInstance();
1547 // ptmp.setTitleCache(collector,true);
1548 // Person p2 = titleCachePerson.get(ptmp.getTitleCache());
1549 // team.addTeamMember(p2);
1550 // em=false;
1551 // }
1552 // if (!em) {
1553 // teamToAdd.add(team);
1554 // }
1555 // teamdone.put(StringUtils.join(collteam.toArray(),"-"),0);
1556 // }
1557 // }
1558 //
1559 // if(!teamToAdd.isEmpty()){
1560 // for (Team agent: teamToAdd){
1561 // save(agent, state);
1562 // titleCacheTeam.put(agent.getTitleCache(), CdmBase.deproxy(
1563 // agent,Team.class) );
1564 // }
1565 // }
1566
1567 // ((Abcd206ImportConfigurator)
1568 // state.getConfig()).setTeams(titleCacheTeam);
1569 // ((Abcd206ImportConfigurator)
1570 // state.getConfig()).setPersons(titleCachePerson);
1571 }
1572
1573 @Override
1574 protected boolean doCheck(Abcd206ImportState state) {
1575 logger.warn("Checking not yet implemented for " + this.getClass().getSimpleName());
1576 return true;
1577 }
1578
1579 @Override
1580 protected boolean isIgnore(Abcd206ImportState state) {
1581 return false;
1582 }
1583
1584 @Override
1585 protected DefinedTerm getKindOfUnit(Abcd206ImportState state, UUID uuid, String label, String description,
1586 String labelAbbrev, TermVocabulary<DefinedTerm> voc) {
1587
1588 DefinedTerm unit = null;
1589
1590 if (uuid == null) {
1591 unit = this.kindOfUnitsMap.get(label.toLowerCase());
1592 } else {
1593 unit = state.getKindOfUnit(uuid);
1594
1595 }
1596 if (unit == null) {
1597 unit = (DefinedTerm) getTermService().find(uuid);
1598 if (unit == null) {
1599 if (uuid == null) {
1600 uuid = UUID.randomUUID();
1601 }
1602 unit = DefinedTerm.NewKindOfUnitInstance(description, label, labelAbbrev);
1603 unit.setUuid(uuid);
1604 if (voc == null) {
1605 boolean isOrdered = false;
1606 voc = getVocabulary(state, TermType.KindOfUnit, uuidUserDefinedKindOfUnitVocabulary,
1607 "User defined vocabulary for kind-of-units", "User Defined Measurement kind-of-units", null,
1608 null, isOrdered, unit);
1609 }
1610 voc.addTerm(unit);
1611 getTermService().save(unit);
1612 }
1613 state.putKindOfUnit(unit);
1614 kindOfUnitsMap.put(unit.getLabel().toLowerCase(), unit);
1615 }
1616 return unit;
1617 }
1618
1619 }