Project

General

Profile

Download (33.3 KB) Statistics
| Branch: | Revision:
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 static eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer.REF_ARTICLE;
13
import static eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer.REF_BOOK;
14
import static eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer.REF_CONFERENCE_PROCEEDINGS;
15
import static eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer.REF_DATABASE;
16
import static eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer.REF_INFORMAL;
17
import static eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer.REF_JOURNAL;
18
import static eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer.REF_JOURNAL_VOLUME;
19
import static eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer.REF_PART_OF_OTHER_TITLE;
20
import static eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer.REF_PRINT_SERIES;
21
import static eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer.REF_UNKNOWN;
22
import static eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer.REF_WEBSITE;
23
import static eu.etaxonomy.cdm.io.common.ImportHelper.NO_OVERWRITE;
24
import static eu.etaxonomy.cdm.io.common.ImportHelper.OBLIGATORY;
25
import static eu.etaxonomy.cdm.io.common.ImportHelper.OVERWRITE;
26

    
27
import java.net.URI;
28
import java.net.URISyntaxException;
29
import java.sql.ResultSet;
30
import java.sql.SQLException;
31
import java.util.ArrayList;
32
import java.util.Arrays;
33
import java.util.HashMap;
34
import java.util.HashSet;
35
import java.util.List;
36
import java.util.Map;
37
import java.util.Set;
38
import java.util.UUID;
39

    
40
import org.apache.commons.lang.StringUtils;
41
import org.apache.log4j.Logger;
42
import org.springframework.stereotype.Component;
43

    
44
import eu.etaxonomy.cdm.common.CdmUtils;
45
import eu.etaxonomy.cdm.common.DOI;
46
import eu.etaxonomy.cdm.io.berlinModel.in.validation.BerlinModelReferenceImportValidator;
47
import eu.etaxonomy.cdm.io.common.ICdmImport;
48
import eu.etaxonomy.cdm.io.common.IImportConfigurator;
49
import eu.etaxonomy.cdm.io.common.ImportHelper;
50
import eu.etaxonomy.cdm.io.common.ResultSetPartitioner;
51
import eu.etaxonomy.cdm.io.common.Source;
52
import eu.etaxonomy.cdm.io.common.mapping.CdmAttributeMapperBase;
53
import eu.etaxonomy.cdm.io.common.mapping.CdmIoMapping;
54
import eu.etaxonomy.cdm.io.common.mapping.CdmSingleAttributeMapperBase;
55
import eu.etaxonomy.cdm.io.common.mapping.DbImportExtensionMapper;
56
import eu.etaxonomy.cdm.io.common.mapping.DbImportMarkerMapper;
57
import eu.etaxonomy.cdm.io.common.mapping.DbSingleAttributeImportMapperBase;
58
import eu.etaxonomy.cdm.io.common.mapping.berlinModel.CdmOneToManyMapper;
59
import eu.etaxonomy.cdm.io.common.mapping.berlinModel.CdmStringMapper;
60
import eu.etaxonomy.cdm.io.common.mapping.berlinModel.CdmUriMapper;
61
import eu.etaxonomy.cdm.model.agent.Team;
62
import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
63
import eu.etaxonomy.cdm.model.common.CdmBase;
64
import eu.etaxonomy.cdm.model.common.ExtensionType;
65
import eu.etaxonomy.cdm.model.common.IdentifiableSource;
66
import eu.etaxonomy.cdm.model.common.Marker;
67
import eu.etaxonomy.cdm.model.common.MarkerType;
68
import eu.etaxonomy.cdm.model.reference.IArticle;
69
import eu.etaxonomy.cdm.model.reference.IBookSection;
70
import eu.etaxonomy.cdm.model.reference.IPrintSeries;
71
import eu.etaxonomy.cdm.model.reference.Reference;
72
import eu.etaxonomy.cdm.model.reference.ReferenceFactory;
73

    
74
/**
75
 * @author a.mueller
76
 * @created 20.03.2008
77
 */
78
@Component
79
public class BerlinModelReferenceImport extends BerlinModelImportBase {
80
    private static final long serialVersionUID = -3667566958769967591L;
81

    
82
    private static final Logger logger = Logger.getLogger(BerlinModelReferenceImport.class);
83

    
84
	public static final String REFERENCE_NAMESPACE = "Reference";
85
	private static final String REF_AUTHOR_NAMESPACE = "Reference.refAuthorString";
86

    
87

    
88
	public static final UUID REF_DEPOSITED_AT_UUID = UUID.fromString("23ca88c7-ce73-41b2-8ca3-2cb22f013beb");
89
	public static final UUID REF_SOURCE_UUID = UUID.fromString("d6432582-2216-4b08-b0db-76f6c1013141");
90
	public static final UUID DATE_STRING_UUID = UUID.fromString("e4130eae-606e-4b0c-be4f-e93dc161be7d");
91
	public static final UUID IS_PAPER_UUID = UUID.fromString("8a326129-d0d0-4f9d-bbdf-8d86b037c65e");
92

    
93

    
94
	private final int modCount = 1000;
95
	private static final String pluralString = "references";
96
	private static final String dbTableName = "reference";
97

    
98

    
99
	public BerlinModelReferenceImport(){
100
		super(dbTableName, pluralString);
101
	}
102

    
103
	protected void initializeMappers(BerlinModelImportState state){
104
		for (CdmAttributeMapperBase mapper: classMappers){
105
			if (mapper instanceof DbSingleAttributeImportMapperBase){
106
				DbSingleAttributeImportMapperBase singleMapper = (DbSingleAttributeImportMapperBase)mapper;
107
				singleMapper.initialize(state, Reference.class);
108
			}
109
		}
110
		return;
111
	}
112

    
113
	protected static CdmAttributeMapperBase[] classMappers = new CdmAttributeMapperBase[]{
114
		new CdmStringMapper("edition", "edition"),
115
		new CdmStringMapper("volume", "volume"),
116
		new CdmStringMapper("publisher", "publisher"),
117
		new CdmStringMapper("publicationTown", "placePublished"),
118
		new CdmStringMapper("isbn", "isbn"),
119
		new CdmStringMapper("isbn", "isbn"),
120
		new CdmStringMapper("pageString", "pages"),
121
		new CdmStringMapper("series", "seriesPart"),
122
		new CdmStringMapper("issn", "issn"),
123
		new CdmUriMapper("url", "uri"),
124
		DbImportExtensionMapper.NewInstance("NomStandard", ExtensionType.NOMENCLATURAL_STANDARD()),
125
		DbImportExtensionMapper.NewInstance("DateString", DATE_STRING_UUID, "Date String", "Date String", "dates"),
126
		DbImportExtensionMapper.NewInstance("RefDepositedAt", REF_DEPOSITED_AT_UUID, "RefDepositedAt", "reference is deposited at", "at"),
127
		DbImportExtensionMapper.NewInstance("RefSource", REF_SOURCE_UUID, "RefSource", "reference source", "source"),
128
		DbImportMarkerMapper.NewInstance("isPaper", IS_PAPER_UUID, "is paper", "is paper", "paper", false)
129
	};
130

    
131

    
132
	protected static String[] operationalAttributes = new String[]{
133
		"refId", "refCache", "nomRefCache", "preliminaryFlag", "inRefFk", "title", "nomTitleAbbrev",
134
		"refAuthorString", "nomAuthorTeamFk",
135
		"refCategoryFk", "thesisFlag", "informalRefCategory", "idInSource"
136
	};
137

    
138
	protected static String[] createdAndNotesAttributes = new String[]{
139
			"created_When", "updated_When", "created_Who", "updated_Who", "notes"
140
	};
141

    
142
	protected static String[] unclearMappers = new String[]{
143
			/*"isPaper",*/ "exportDate",
144
	};
145

    
146
	//TODO isPaper
147
	//
148

    
149

    
150

    
151
	//type to count the references nomReferences that have been created and saved
152
	private class RefCounter{
153
		RefCounter() {refCount = 0;}
154
		int refCount;
155

    
156
		@Override
157
        public String toString(){return String.valueOf(refCount) ;};
158
	}
159

    
160
	@Override
161
	protected String getRecordQuery(BerlinModelImportConfigurator config) {
162
		return null;  //not needed
163
	}
164

    
165
	@Override
166
	protected void doInvoke(BerlinModelImportState state){
167
		logger.info("start make " + getPluralString() + " ...");
168

    
169
		boolean success = true;
170
		initializeMappers(state);
171
		BerlinModelImportConfigurator config = state.getConfig();
172
		Source source = config.getSource();
173

    
174
		String strSelectId = " SELECT Reference.RefId as refId ";
175
		String strSelectFull =
176
			" SELECT Reference.* ,InReference.RefCategoryFk as InRefCategoryFk, RefSource.RefSource " ;
177
		String strFrom =  " FROM %s  " +
178
		    	" LEFT OUTER JOIN Reference as InReference ON InReference.refId = Reference.inRefFk " +
179
				" LEFT OUTER JOIN RefSource ON Reference.RefSourceFk = RefSource.RefSourceId " +
180
		    	" WHERE (1=1) ";
181
		String strWherePartitioned = " AND (Reference.refId IN ("+ ID_LIST_TOKEN + ") ) ";
182

    
183
		String referenceTable = CdmUtils.Nz(state.getConfig().getReferenceIdTable());
184
		referenceTable = referenceTable.isEmpty() ? " Reference"  : referenceTable + " as Reference ";
185
		String strIdFrom = String.format(strFrom, referenceTable );
186

    
187
		String referenceFilter = CdmUtils.Nz(state.getConfig().getReferenceIdTable());
188
		if (! referenceFilter.isEmpty()){
189
			referenceFilter = " AND " + referenceFilter + " ";
190
		}
191
		referenceFilter = "";  //don't use it for now
192

    
193
		String strIdQueryFirstPath = strSelectId + strIdFrom ;
194
		String strIdQuerySecondPath = strSelectId + strIdFrom + " AND (Reference.InRefFk is NOT NULL) ";
195

    
196
//		if (config.getDoReferences() == CONCEPT_REFERENCES){
197
//			strIdQueryNoInRef += " AND ( Reference.refId IN ( SELECT ptRefFk FROM PTaxon) ) " + referenceFilter;
198
//		}
199

    
200
		String strRecordQuery = strSelectFull + String.format(strFrom, " Reference ") + strWherePartitioned;
201

    
202
		int recordsPerTransaction = config.getRecordsPerTransaction();
203
		try{
204
			//firstPath
205
			ResultSetPartitioner<BerlinModelImportState> partitioner =
206
			        ResultSetPartitioner.NewInstance(source, strIdQueryFirstPath, strRecordQuery, recordsPerTransaction);
207
			while (partitioner.nextPartition()){
208
				partitioner.doPartition(this, state);
209
			}
210
			logger.info("end make references without in-references ... " + getSuccessString(success));
211
			state.setReferenceSecondPath(true);
212

    
213
//			if (config.getDoReferences() == ALL || config.getDoReferences() == NOMENCLATURAL){
214

    
215
			//secondPath
216
			partitioner = ResultSetPartitioner.NewInstance(source, strIdQuerySecondPath, strRecordQuery, recordsPerTransaction);
217
			while (partitioner.nextPartition()){
218
				partitioner.doPartition(this, state);
219
			}
220
			logger.info("end make references with no 1 in-reference ... " + getSuccessString(success));
221
			state.setReferenceSecondPath(false);
222

    
223
//			}
224

    
225
		} catch (SQLException e) {
226
			logger.error("SQLException:" +  e);
227
			state.setUnsuccessfull();
228
			return;
229
		}
230
		logger.info("end make " + getPluralString() + " ... " + getSuccessString(success));
231
		if (! success){
232
			state.setUnsuccessfull();
233
		}
234
		return;
235
	}
236

    
237
	@Override
238
	public boolean doPartition(ResultSetPartitioner partitioner, BerlinModelImportState state) {
239
		if (state.isReferenceSecondPath()){
240
			return doPartitionSecondPath(partitioner, state);
241
		}
242
		boolean success = true;
243

    
244
		Map<Integer, Reference> refToSave = new HashMap<>();
245

    
246
		@SuppressWarnings("unchecked")
247
        Map<String, Reference> relatedReferences = partitioner.getObjectMap(REFERENCE_NAMESPACE);
248

    
249
		BerlinModelImportConfigurator config = state.getConfig();
250

    
251
		try {
252

    
253
				int i = 0;
254
				RefCounter refCounter  = new RefCounter();
255

    
256
				ResultSet rs = partitioner.getResultSet();
257

    
258
				//for each resultset
259
				while (rs.next()){
260
					if ((i++ % modCount) == 0 && i!= 1 ){ logger.info("References handled: " + (i-1) + " in round -" );}
261

    
262
					success &= makeSingleReferenceRecord(rs, state, partitioner, refToSave, relatedReferences, refCounter);
263
				} // end resultSet
264

    
265
				//for the concept reference a fixed uuid may be needed -> change uuid
266
				Integer sourceSecId = (Integer)config.getSourceSecId();
267
				Reference sec = refToSave.get(sourceSecId);
268

    
269
				if (sec != null){
270
					sec.setUuid(config.getSecUuid());
271
					logger.info("SecUuid changed to: " + config.getSecUuid());
272
				}
273

    
274
				//save and store in map
275
				logger.info("Save references (" + refCounter.refCount + ")");
276
				getReferenceService().saveOrUpdate(refToSave.values());
277

    
278
//			}//end resultSetList
279

    
280
//			logger.info("end makeReferences ..." + getSuccessString(success));;
281
			return success;
282
		} catch (SQLException e) {
283
			logger.error("SQLException:" +  e);
284
			return false;
285
		}
286
	}
287

    
288

    
289

    
290
	/**
291
	 * Adds the inReference to the according references.
292
	 * @param partitioner
293
	 * @param state
294
	 * @return
295
	 */
296
	private boolean doPartitionSecondPath(ResultSetPartitioner partitioner, BerlinModelImportState state) {
297
		boolean success = true;
298

    
299
		Map<Integer, Reference> refToSave = new HashMap<Integer, Reference>();
300

    
301
		Map<String, Reference> relatedReferencesMap = partitioner.getObjectMap(REFERENCE_NAMESPACE);
302

    
303
		try {
304
				int i = 0;
305
				RefCounter refCounter  = new RefCounter();
306

    
307
				ResultSet rs = partitioner.getResultSet();
308
				//for each resultset
309
				while (rs.next()){
310
					if ((i++ % modCount) == 0 && i!= 1 ){ logger.info("References handled: " + (i-1) + " in round -" );}
311

    
312
					Integer refId = rs.getInt("refId");
313
					Integer inRefFk = rs.getInt("inRefFk");
314

    
315
					if (inRefFk != null){
316

    
317
						Reference thisRef = relatedReferencesMap.get(String.valueOf(refId));
318

    
319
						Reference inRef = relatedReferencesMap.get(String.valueOf(inRefFk));
320

    
321
						if (thisRef != null){
322
							if (inRef == null){
323
								logger.warn("No InRef found for nomRef: " + thisRef.getTitleCache() + "; RefId: " +  refId + "; inRefFK: " +  inRefFk);
324
							}
325
							thisRef.setInReference(inRef);
326
							refToSave.put(refId, thisRef);
327
							thisRef.setTitleCache(null);
328
							thisRef.getTitleCache();
329
						}
330
					}
331

    
332
				} // end resultSet
333

    
334
				//save and store in map
335
				logger.info("Save references (" + refCounter.refCount + ")");
336
				getReferenceService().saveOrUpdate(refToSave.values());
337

    
338
//			}//end resultSetList
339

    
340
//			logger.info("end makeReferences ..." + getSuccessString(success));;
341
			return success;
342
		} catch (SQLException e) {
343
			logger.error("SQLException:" +  e);
344
			return false;
345
		}
346
	}
347

    
348

    
349
	@Override
350
	public Map<Object, Map<String, ? extends CdmBase>> getRelatedObjectsForPartition(ResultSet rs, BerlinModelImportState state) {
351
		String nameSpace;
352
		Class<?> cdmClass;
353
		Set<String> idSet;
354

    
355
		Map<Object, Map<String, ? extends CdmBase>> result = new HashMap<>();
356

    
357
		try{
358
			Set<String> teamIdSet = new HashSet<>();
359
			Set<String> referenceIdSet = new HashSet<>();
360
			Set<String> teamStringSet = new HashSet<>();
361

    
362
			while (rs.next()){
363
				handleForeignKey(rs, teamIdSet, "NomAuthorTeamFk");
364
				handleForeignKey(rs, referenceIdSet, "InRefFk");
365
				handleForeignKey(rs, teamStringSet, "refAuthorString");
366
				//TODO only needed in second path but state not available here to check if state is second path
367
				handleForeignKey(rs, referenceIdSet, "refId");
368
			}
369

    
370
			Set<String> teamStringSet2 = new HashSet<>();
371
			for (String teamString : teamStringSet){
372
			    teamStringSet2.add(teamString.replace("'", "´"));
373
			}
374

    
375
			//team map
376
			nameSpace = BerlinModelAuthorTeamImport.NAMESPACE;
377
			cdmClass = Team.class;
378
			idSet = teamIdSet;
379
			@SuppressWarnings("unchecked")
380
            Map<String, Team> teamMap = (Map<String, Team>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
381
			result.put(nameSpace, teamMap);
382

    
383
            //refAuthor map
384
            nameSpace = REF_AUTHOR_NAMESPACE;
385
            cdmClass = Team.class;
386
            idSet = teamStringSet2;
387
            @SuppressWarnings("unchecked")
388
            Map<String, Team> refAuthorMap = (Map<String, Team>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
389
            result.put(nameSpace, refAuthorMap);
390

    
391
			//reference map
392
			nameSpace = BerlinModelReferenceImport.REFERENCE_NAMESPACE;
393
			cdmClass = Reference.class;
394
			idSet = referenceIdSet;
395
			Map<String, Reference> referenceMap = (Map<String, Reference>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
396
			result.put(nameSpace, referenceMap);
397

    
398
		} catch (SQLException e) {
399
			throw new RuntimeException(e);
400
		}
401
		return result;
402
	}
403

    
404

    
405
	/**
406
	 * Handles a single reference record
407
	 * @param rs
408
	 * @param state
409
	 * @param biblioRefToSave
410
	 * @param nomRefToSave
411
	 * @param relatedBiblioReferences
412
	 * @param relatedNomReferences
413
	 * @param refCounter
414
	 * @return
415
	 */
416
	private boolean makeSingleReferenceRecord(
417
				ResultSet rs,
418
				BerlinModelImportState state,
419
				ResultSetPartitioner<BerlinModelImportState> partitioner,
420
				Map<Integer, Reference> refToSave,
421
				Map<String, Reference> relatedReferences,
422
				RefCounter refCounter){
423

    
424
	    boolean success = true;
425

    
426
		Integer refId = null;
427
		try {
428
			Map<String, Object> valueMap = getValueMap(rs);
429

    
430
			Integer categoryFk = (Integer)valueMap.get("refCategoryFk".toLowerCase());
431
			refId = (Integer)valueMap.get("refId".toLowerCase());
432
			Boolean thesisFlag = (Boolean)valueMap.get("thesisFlag".toLowerCase());
433

    
434

    
435
			Reference referenceBase;
436
			logger.debug("RefCategoryFk: " + categoryFk);
437

    
438
			if (thesisFlag){
439
				referenceBase = makeThesis(valueMap);
440
			}else if (categoryFk == REF_JOURNAL){
441
				referenceBase = makeJournal(valueMap);
442
			}else if(categoryFk == REF_BOOK){
443
				referenceBase = makeBook(valueMap);
444
			}else if(categoryFk == REF_DATABASE){
445
				referenceBase = makeDatabase(valueMap);
446
			}else if(categoryFk == REF_INFORMAL){
447
				referenceBase = makeInformal(valueMap);
448
			}else if(categoryFk == REF_WEBSITE){
449
				referenceBase = makeWebSite(valueMap);
450
			}else if(categoryFk == REF_UNKNOWN){
451
				referenceBase = makeUnknown(valueMap);
452
			}else if(categoryFk == REF_PRINT_SERIES){
453
				referenceBase = makePrintSeries(valueMap);
454
			}else if(categoryFk == REF_CONFERENCE_PROCEEDINGS){
455
				referenceBase = makeProceedings(valueMap);
456
			}else if(categoryFk == REF_ARTICLE){
457
				referenceBase = makeArticle(valueMap);
458
			}else if(categoryFk == REF_JOURNAL_VOLUME){
459
				referenceBase = makeJournalVolume(valueMap);
460
			}else if(categoryFk == REF_PART_OF_OTHER_TITLE){
461
				referenceBase = makePartOfOtherTitle(valueMap);
462
			}else{
463
				logger.warn("Unknown categoryFk (" + categoryFk + "). Create 'Generic instead'");
464
				referenceBase = ReferenceFactory.newGeneric();
465
				success = false;
466
			}
467

    
468
			//refYear
469
			String refYear = (String)valueMap.get("refYear".toLowerCase());
470
			referenceBase.setDatePublished(ImportHelper.getDatePublished(refYear));
471

    
472
			//created, updated, notes
473
			doCreatedUpdatedNotes(state, referenceBase, rs);
474

    
475
			//idInSource
476
			String idInSource = (String)valueMap.get("IdInSource".toLowerCase());
477
			if (isNotBlank(idInSource)){
478
				IdentifiableSource source = IdentifiableSource.NewDataImportInstance(idInSource);
479
				source.setIdNamespace("import to Berlin Model");
480
				referenceBase.addSource(source);
481
			}
482

    
483
			//nom&BiblioReference  - must be last because a clone is created
484
			success &= makeNomAndBiblioReference(rs, state, partitioner, refId, referenceBase, refCounter, refToSave);
485

    
486

    
487
		} catch (Exception e) {
488
			logger.warn("Reference with BM refId '" + CdmUtils.Nz(refId) +  "' threw Exception and could not be saved");
489
			e.printStackTrace();
490
			success = false;
491
		}
492
		return success;
493
	}
494

    
495

    
496
	/**
497
	 * Creates and saves a nom. reference and a biblio. reference after checking necessity
498
	 * @param rs
499
	 * @param refId
500
	 * @param ref
501
	 * @param refCounter
502
	 * @param biblioRefToSave
503
	 * @param nomRefToSave
504
	 * @param teamMap
505
	 * @param stores
506
	 * @return
507
	 * @throws SQLException
508
	 */
509
	private boolean makeNomAndBiblioReference(
510
				ResultSet rs,
511
				BerlinModelImportState state,
512
				ResultSetPartitioner partitioner,
513
				int refId,
514
				Reference ref,
515
				RefCounter refCounter,
516
				Map<Integer, Reference> refToSave
517
				) throws SQLException{
518

    
519
		@SuppressWarnings("unchecked")
520
        Map<String, Team> teamMap = partitioner.getObjectMap(BerlinModelAuthorTeamImport.NAMESPACE);
521

    
522
		String refCache = rs.getString("refCache");
523
		String nomRefCache = rs.getString("nomRefCache");
524
		String title = rs.getString("title");
525
		String nomTitleAbbrev = rs.getString("nomTitleAbbrev");
526
		boolean isPreliminary = rs.getBoolean("PreliminaryFlag");
527
		String refAuthorString = rs.getString("refAuthorString");
528
		Integer nomAuthorTeamFk = rs.getInt("NomAuthorTeamFk");
529
		String strNomAuthorTeamFk = String.valueOf(nomAuthorTeamFk);
530
		TeamOrPersonBase<?> nomAuthor = teamMap.get(strNomAuthorTeamFk);
531

    
532
		Reference sourceReference = state.getTransactionalSourceReference();
533

    
534
		//preliminary
535
		if (isPreliminary){
536
			ref.setAbbrevTitleCache(nomRefCache, true);
537
			ref.setTitleCache(refCache, true);
538
		}
539

    
540
		//title/abbrevTitle
541
		if (isNotBlank(nomTitleAbbrev)){
542
			ref.setAbbrevTitle(nomTitleAbbrev);
543
		}
544
		if (isNotBlank(title)){
545
			ref.setTitle(title);
546
		}
547

    
548
		//author
549
		TeamOrPersonBase<?> author = getAuthorship(state, refAuthorString , nomAuthor);
550
		ref.setAuthorship(author);
551

    
552
		//save
553
		if (! refToSave.containsKey(refId)){
554
			refToSave.put(refId, ref);
555
		}else{
556
			logger.warn("Duplicate refId in Berlin Model database. Second reference was not imported !!");
557
		}
558
		refCounter.refCount++;
559

    
560
		//refId
561
		ImportHelper.setOriginalSource(ref, sourceReference, refId, REFERENCE_NAMESPACE);
562

    
563
		return true;
564
	}
565

    
566
	/**
567
	 * Copies the created and updated information from the nomReference to the cloned bibliographic reference
568
	 * @param referenceBase
569
	 * @param nomReference
570
	 */
571
	private void copyCreatedUpdated(Reference biblioReference, Reference nomReference) {
572
		biblioReference.setCreatedBy(nomReference.getCreatedBy());
573
		biblioReference.setCreated(nomReference.getCreated());
574
		biblioReference.setUpdatedBy(nomReference.getUpdatedBy());
575
		biblioReference.setUpdated(nomReference.getUpdated());
576

    
577
	}
578

    
579
	private Reference makeArticle (Map<String, Object> valueMap){
580

    
581
		IArticle article = ReferenceFactory.newArticle();
582
		Object inRefFk = valueMap.get("inRefFk".toLowerCase());
583
		Integer inRefCategoryFk = (Integer)valueMap.get("inRefCategoryFk".toLowerCase());
584
		Integer refId = (Integer)valueMap.get("refId".toLowerCase());
585

    
586
		if (inRefFk != null){
587
			if (inRefCategoryFk != REF_JOURNAL){
588
				logger.warn("Wrong inrefCategory for Article (refID = " + refId +"). Type must be 'Journal' but was not (RefCategoryFk=" + inRefCategoryFk + "))." +
589
					" InReference was added anyway! ");
590
			}
591
		}else{
592
			logger.warn ("Article has no inreference: " + refId);
593
		}
594
		makeStandardMapper(valueMap, (Reference)article); //url, pages, series, volume
595
		String url = (String)valueMap.get("url");
596
		if (url != null && url.contains("dx.doi.org")){
597
		    article.setDoi(DOI.fromString(url));
598
		    article.setUri(null);
599
		}
600
		return (Reference)article;
601
	}
602

    
603
	private Reference makePartOfOtherTitle (Map<String, Object> valueMap){
604

    
605
		Reference result;
606
		Object inRefFk = valueMap.get("inRefFk".toLowerCase());
607
		Integer inRefCategoryFk = (Integer)valueMap.get("inRefCategoryFk".toLowerCase());
608
		Integer refId = (Integer)valueMap.get("refId".toLowerCase());
609

    
610
		if (inRefCategoryFk == null){
611
			//null -> error
612
			logger.warn("Part-Of-Other-Title has no inRefCategoryFk! RefId = " + refId + ". ReferenceType set to Generic.");
613
			result = makeUnknown(valueMap);
614
		}else if (inRefFk == null){
615
			//TODO is this correct ??
616
			logger.warn("Part-Of-Other-Title has no in reference: " + refId);
617
			result = makeUnknown(valueMap);
618
		}else if (inRefCategoryFk == REF_BOOK){
619
			//BookSection
620
			IBookSection bookSection = ReferenceFactory.newBookSection();
621
			result = (Reference)bookSection;
622
		}else if (inRefCategoryFk == REF_ARTICLE){
623
			//Article
624
			logger.info("Reference (refId = " + refId + ") of type 'part_of_other_title' is part of 'article'." +
625
					" We use the section reference type for such in references now.") ;
626
			result = ReferenceFactory.newSection();
627
		}else if (inRefCategoryFk == REF_JOURNAL){
628
			//TODO
629
			logger.warn("Reference (refId = " + refId + ") of type 'part_of_other_title' has inReference of type 'journal'." +
630
					" This is not allowed! Generic reference created instead") ;
631
			result = ReferenceFactory.newGeneric();
632
			result.addMarker(Marker.NewInstance(MarkerType.TO_BE_CHECKED(), true));
633
		}else if (inRefCategoryFk == REF_PART_OF_OTHER_TITLE){
634
			logger.info("Reference (refId = " + refId + ") of type 'part_of_other_title' has inReference 'part of other title'." +
635
					" This is allowed, but may be true only for specific cases (e.g. parts of book chapters). You may want to check if this is correct") ;
636
			result = ReferenceFactory.newSection();
637
		}else{
638
			logger.warn("InReference type (catFk = " + inRefCategoryFk + ") of part-of-reference not recognized for refId " + refId + "." +
639
				" Create 'Generic' reference instead");
640
			result = ReferenceFactory.newGeneric();
641
		}
642
		makeStandardMapper(valueMap, result); //url, pages
643
		return result;
644
	}
645

    
646

    
647
	/**
648
	 * @param inRefFkInt
649
	 * @param biblioRefToSave
650
	 * @param nomRefToSave
651
	 * @param relatedBiblioReferences
652
	 * @param relatedNomReferences
653
	 * @return
654
	 */
655
	private boolean existsInMapOrToSave(Integer inRefFkInt, Map<Integer, Reference> refToSave, Map<String, Reference> relatedReferences) {
656
		boolean result = false;
657
		if (inRefFkInt == null){
658
			return false;
659
		}
660
		result |= refToSave.containsKey(inRefFkInt);
661
		result |= relatedReferences.containsKey(String.valueOf(inRefFkInt));
662
		return result;
663
	}
664

    
665
	private Reference makeWebSite(Map<String, Object> valueMap){
666
		if (logger.isDebugEnabled()){logger.debug("RefType 'Website'");}
667
		Reference webPage = ReferenceFactory.newWebPage();
668
		makeStandardMapper(valueMap, webPage); //placePublished, publisher
669
		return webPage;
670
	}
671

    
672
	private Reference makeUnknown(Map<String, Object> valueMap){
673
		if (logger.isDebugEnabled()){logger.debug("RefType 'Unknown'");}
674
		Reference generic = ReferenceFactory.newGeneric();
675
//		generic.setSeries(series);
676
		makeStandardMapper(valueMap, generic); //pages, placePublished, publisher, series, volume
677
		return generic;
678
	}
679

    
680
	private Reference makeInformal(Map<String, Object> valueMap){
681
		if (logger.isDebugEnabled()){logger.debug("RefType 'Informal'");}
682
		Reference generic = ReferenceFactory.newGeneric();
683
//		informal.setSeries(series);
684
		makeStandardMapper(valueMap, generic);//editor, pages, placePublished, publisher, series, volume
685
		String informal = (String)valueMap.get("InformalRefCategory".toLowerCase());
686
		if (isNotBlank(informal) ){
687
			generic.addExtension(informal, ExtensionType.INFORMAL_CATEGORY());
688
		}
689
		return generic;
690
	}
691

    
692
	private Reference makeDatabase(Map<String, Object> valueMap){
693
		if (logger.isDebugEnabled()){logger.debug("RefType 'Database'");}
694
		Reference database =  ReferenceFactory.newDatabase();
695
		makeStandardMapper(valueMap, database); //?
696
		return database;
697
	}
698

    
699
	private Reference makeJournal(Map<String, Object> valueMap){
700
		if (logger.isDebugEnabled()){logger.debug("RefType 'Journal'");}
701
		Reference journal = ReferenceFactory.newJournal();
702

    
703
		Set<String> omitAttributes = new HashSet<>();
704
		String series = "series";
705
//		omitAttributes.add(series);
706

    
707
		makeStandardMapper(valueMap, journal, omitAttributes); //issn,placePublished,publisher
708
//		if (valueMap.get(series) != null){
709
//			logger.warn("Series not yet implemented for journal!");
710
//		}
711
		return journal;
712
	}
713

    
714
	private Reference makeBook(
715
				Map<String, Object> valueMap){
716

    
717
		if (logger.isDebugEnabled()){logger.debug("RefType 'Book'");}
718
		Reference book = ReferenceFactory.newBook();
719
		Integer refId = (Integer)valueMap.get("refId".toLowerCase());
720

    
721
		//Set bookAttributes = new String[]{"edition", "isbn", "pages","publicationTown","publisher","volume"};
722

    
723
		Set<String> omitAttributes = new HashSet<>();
724
		String attrSeries = "series";
725
//		omitAttributes.add(attrSeries);
726

    
727
		makeStandardMapper(valueMap, book, omitAttributes);
728

    
729
		//Series (as String)
730
		IPrintSeries printSeries = null;
731
		if (valueMap.get(attrSeries) != null){
732
			String series = (String)valueMap.get("title".toLowerCase());
733
			if (series == null){
734
				String nomTitle = (String)valueMap.get("nomTitleAbbrev".toLowerCase());
735
				series = nomTitle;
736
			}
737
			printSeries = ReferenceFactory.newPrintSeries(series);
738
			logger.info("Implementation of printSeries is preliminary");
739
		}
740
		//Series (as Reference)
741
		if (book.getInSeries() != null && printSeries != null){
742
			logger.warn("Book has series string and inSeries reference. Can not take both. Series string neglected");
743
		}else{
744
			book.setInSeries(printSeries);
745
		}
746
		book.setEditor(null);
747
		return book;
748

    
749
	}
750

    
751
	/**
752
	 * Returns the requested object if it exists in one of both maps. Prefers the refToSaveMap in ambigious cases.
753
	 * @param inRefFkInt
754
	 * @param nomRefToSave
755
	 * @param relatedNomReferences
756
	 * @return
757
	 */
758
	private Reference getReferenceFromMaps(
759
			int inRefFkInt,
760
			Map<Integer, Reference> refToSaveMap,
761
			Map<String, Reference> relatedRefMap) {
762
		Reference result = null;
763
		result = refToSaveMap.get(inRefFkInt);
764
		if (result == null){
765
			result = relatedRefMap.get(String.valueOf(inRefFkInt));
766
		}
767
		return result;
768
	}
769

    
770
	private Reference makePrintSeries(Map<String, Object> valueMap){
771
		if (logger.isDebugEnabled()){logger.debug("RefType 'PrintSeries'");}
772
		Reference printSeries = ReferenceFactory.newPrintSeries();
773
		makeStandardMapper(valueMap, printSeries, null);
774
		return printSeries;
775
	}
776

    
777
	private Reference makeProceedings(Map<String, Object> valueMap){
778
		if (logger.isDebugEnabled()){logger.debug("RefType 'Proceedings'");}
779
		Reference proceedings = ReferenceFactory.newProceedings();
780
		makeStandardMapper(valueMap, proceedings, null);
781
		return proceedings;
782
	}
783

    
784
	private Reference makeThesis(Map<String, Object> valueMap){
785
		if (logger.isDebugEnabled()){logger.debug("RefType 'Thesis'");}
786
		Reference thesis = ReferenceFactory.newThesis();
787
		makeStandardMapper(valueMap, thesis, null);
788
		return thesis;
789
	}
790

    
791

    
792
	private Reference makeJournalVolume(Map<String, Object> valueMap){
793
		if (logger.isDebugEnabled()){logger.debug("RefType 'JournalVolume'");}
794
		//Proceedings proceedings = Proceedings.NewInstance();
795
		Reference journalVolume = ReferenceFactory.newGeneric();
796
		makeStandardMapper(valueMap, journalVolume, null);
797
		logger.warn("Journal volumes not yet implemented. Generic created instead but with errors");
798
		return journalVolume;
799
	}
800

    
801
	private boolean makeStandardMapper(Map<String, Object> valueMap, Reference ref){
802
		return makeStandardMapper(valueMap, ref, null);
803
	}
804

    
805

    
806
	private boolean makeStandardMapper(Map<String, Object> valueMap, CdmBase cdmBase, Set<String> omitAttributes){
807
		boolean result = true;
808
		for (CdmAttributeMapperBase mapper : classMappers){
809
			if (mapper instanceof CdmSingleAttributeMapperBase){
810
				result &= makeStandardSingleMapper(valueMap, cdmBase, (CdmSingleAttributeMapperBase)mapper, omitAttributes);
811
			}else if (mapper instanceof CdmOneToManyMapper){
812
				result &= makeMultipleValueAddMapper(valueMap, cdmBase, (CdmOneToManyMapper)mapper, omitAttributes);
813
			}else{
814
				logger.error("Unknown mapper type");
815
				result = false;
816
			}
817
		}
818
		return result;
819
	}
820

    
821
	private boolean makeStandardSingleMapper(Map<String, Object> valueMap, CdmBase cdmBase, CdmSingleAttributeMapperBase mapper, Set<String> omitAttributes){
822
		boolean result = true;
823
		if (omitAttributes == null){
824
			omitAttributes = new HashSet<>();
825
		}
826
		if (mapper instanceof DbImportExtensionMapper){
827
			result &= ((DbImportExtensionMapper)mapper).invoke(valueMap, cdmBase);
828
		}else if (mapper instanceof DbImportMarkerMapper){
829
			result &= ((DbImportMarkerMapper)mapper).invoke(valueMap, cdmBase);
830
		}else{
831
			String sourceAttribute = mapper.getSourceAttributeList().get(0).toLowerCase();
832
			Object value = valueMap.get(sourceAttribute);
833
			if (mapper instanceof CdmUriMapper && value != null){
834
				try {
835
					value = new URI (value.toString());
836
				} catch (URISyntaxException e) {
837
					logger.error("URI syntax exception: " + value.toString());
838
					value = null;
839
				}
840
			}
841
			if (value != null){
842
				String destinationAttribute = mapper.getDestinationAttribute();
843
				if (! omitAttributes.contains(destinationAttribute)){
844
					result &= ImportHelper.addValue(value, cdmBase, destinationAttribute, mapper.getTypeClass(), OVERWRITE, OBLIGATORY);
845
				}
846
			}
847
		}
848
		return result;
849
	}
850

    
851

    
852
	private boolean makeMultipleValueAddMapper(Map<String, Object> valueMap, CdmBase cdmBase, CdmOneToManyMapper<CdmBase, CdmBase, CdmSingleAttributeMapperBase> mapper, Set<String> omitAttributes){
853
		if (omitAttributes == null){
854
			omitAttributes = new HashSet<>();
855
		}
856
		boolean result = true;
857
		String destinationAttribute = mapper.getSingleAttributeName();
858
		List<Object> sourceValues = new ArrayList<>();
859
		List<Class> classes = new ArrayList<>();
860
		for (CdmSingleAttributeMapperBase singleMapper : mapper.getSingleMappers()){
861
			String sourceAttribute = singleMapper.getSourceAttribute();
862
			Object value = valueMap.get(sourceAttribute);
863
			sourceValues.add(value);
864
			Class<?> clazz = singleMapper.getTypeClass();
865
			classes.add(clazz);
866
		}
867

    
868
		result &= ImportHelper.addMultipleValues(sourceValues, cdmBase, destinationAttribute, classes, NO_OVERWRITE, OBLIGATORY);
869
		return result;
870
	}
871

    
872

    
873
	private static TeamOrPersonBase<?> getAuthorship(BerlinModelImportState state, String authorString, TeamOrPersonBase<?> nomAuthor){
874

    
875
	    TeamOrPersonBase<?> result;
876
		if (nomAuthor != null){
877
			result = nomAuthor;
878
		} else if (StringUtils.isNotBlank(authorString)){
879
			//TODO match with existing Persons/Teams
880
		    Team team = state.getRelatedObject(REF_AUTHOR_NAMESPACE, authorString, Team.class);
881
			if (team == null){
882
			    team = Team.NewInstance();
883
			    team.setNomenclaturalTitle(authorString);
884
			    team.setTitleCache(authorString, true);
885
			    state.addRelatedObject(REF_AUTHOR_NAMESPACE, authorString, team);
886
			    team.addImportSource(authorString, REF_AUTHOR_NAMESPACE, state.getTransactionalSourceReference(), null);
887
			}
888
			result = team;
889
		}else{
890
			result = null;
891
		}
892

    
893
		return result;
894
	}
895

    
896

    
897
	/**
898
	 * @param lowerCase
899
	 * @param config
900
	 * @return
901
	 */
902
	public Set<String> getObligatoryAttributes(boolean lowerCase, BerlinModelImportConfigurator config){
903
		Set<String> result = new HashSet<>();
904
		Class<ICdmImport>[] ioClassList = config.getIoClassList();
905
		logger.warn("getObligatoryAttributes has been commented because it still needs to be adapted to the new package structure");
906
		result.addAll(Arrays.asList(unclearMappers));
907
		result.addAll(Arrays.asList(createdAndNotesAttributes));
908
		result.addAll(Arrays.asList(operationalAttributes));
909
		CdmIoMapping mapping = new CdmIoMapping();
910
		for (CdmAttributeMapperBase mapper : classMappers){
911
			mapping.addMapper(mapper);
912
		}
913
		result.addAll(mapping.getSourceAttributes());
914
		if (lowerCase){
915
			Set<String> lowerCaseResult = new HashSet<>();
916
			for (String str : result){
917
				if (str != null){lowerCaseResult.add(str.toLowerCase());}
918
			}
919
			result = lowerCaseResult;
920
		}
921
		return result;
922
	}
923

    
924
	@Override
925
	protected boolean doCheck(BerlinModelImportState state){
926
		BerlinModelReferenceImportValidator validator = new BerlinModelReferenceImportValidator();
927
		return validator.validate(state, this);
928
	}
929

    
930
	@Override
931
	protected boolean isIgnore(BerlinModelImportState state){
932
		return (state.getConfig().getDoReferences() == IImportConfigurator.DO_REFERENCES.NONE);
933
	}
934

    
935

    
936

    
937

    
938
}
(13-13/21)