Project

General

Profile

Download (34.5 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.log4j.Logger;
41
import org.springframework.stereotype.Component;
42

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

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

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

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

    
86

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

    
92

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

    
97

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

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

    
114
	private Set<Integer> commonNameRefSet = null;
115
	private void initializeCommonNameRefMap(BerlinModelImportState state) throws SQLException{
116
	    if (state.getConfig().isEuroMed()){
117
	        commonNameRefSet = new HashSet<>();
118
	        String queryStr = "SELECT DISTINCT RefFk "
119
	                + " FROM emCommonName ";
120
	        ResultSet rs = state.getConfig().getSource().getResultSet(queryStr);
121
	        while (rs.next()){
122
	            commonNameRefSet.add(rs.getInt("RefFk"));
123
	        }
124
	    }
125
	}
126

    
127
	protected static CdmAttributeMapperBase[] classMappers = new CdmAttributeMapperBase[]{
128
		new CdmStringMapper("edition", "edition"),
129
		new CdmStringMapper("volume", "volume"),
130
		new CdmStringMapper("publisher", "publisher"),
131
		new CdmStringMapper("publicationTown", "placePublished"),
132
		new CdmStringMapper("isbn", "isbn"),
133
		new CdmStringMapper("isbn", "isbn"),
134
		new CdmStringMapper("pageString", "pages"),
135
		new CdmStringMapper("series", "seriesPart"),
136
		new CdmStringMapper("issn", "issn"),
137
		new CdmUriMapper("url", "uri"),
138
		DbImportExtensionMapper.NewInstance("NomStandard", ExtensionType.NOMENCLATURAL_STANDARD()),
139
		DbImportExtensionMapper.NewInstance("DateString", DATE_STRING_UUID, "Date String", "Date String", "dates"),
140
		DbImportExtensionMapper.NewInstance("RefDepositedAt", REF_DEPOSITED_AT_UUID, "Ref. deposited at", "Reference is deposited at", "at"),
141
		DbImportExtensionMapper.NewInstance("RefSource", REF_SOURCE_UUID, "RefSource", "Reference Source", "source"),
142
		DbImportMarkerMapper.NewInstance("isPaper", IS_PAPER_UUID, "is paper", "is paper", "paper", false)
143
	};
144

    
145

    
146
	protected static String[] operationalAttributes = new String[]{
147
		"refId", "refCache", "nomRefCache", "preliminaryFlag", "inRefFk", "title", "nomTitleAbbrev",
148
		"refAuthorString", "nomAuthorTeamFk",
149
		"refCategoryFk", "thesisFlag", "informalRefCategory", "idInSource"
150
	};
151

    
152
	protected static String[] createdAndNotesAttributes = new String[]{
153
			"created_When", "updated_When", "created_Who", "updated_Who", "notes"
154
	};
155

    
156
	protected static String[] unclearMappers = new String[]{
157
			/*"isPaper",*/ "exportDate",
158
	};
159

    
160
	//TODO isPaper
161
	//
162

    
163

    
164

    
165
	//type to count the references nomReferences that have been created and saved
166
	private class RefCounter{
167
		RefCounter() {refCount = 0;}
168
		int refCount;
169

    
170
		@Override
171
        public String toString(){return String.valueOf(refCount) ;};
172
	}
173

    
174
	@Override
175
	protected String getRecordQuery(BerlinModelImportConfigurator config) {
176
		return null;  //not needed
177
	}
178

    
179
	@Override
180
	protected void doInvoke(BerlinModelImportState state){
181
		logger.info("start make " + getPluralString() + " ...");
182

    
183
		boolean success = true;
184
		initializeMappers(state);
185
		try {
186
            initializeCommonNameRefMap(state);
187
        } catch (SQLException e1) {
188
            e1.printStackTrace();
189
            logger.error("Error in initializeCommonNameRefMap in BerlinModelReferenceimport");
190
        }
191
		BerlinModelImportConfigurator config = state.getConfig();
192
		Source source = config.getSource();
193

    
194
		String strSelectId = " SELECT Reference.RefId as refId ";
195
		String strSelectFull =
196
			" SELECT Reference.* ,InReference.RefCategoryFk as InRefCategoryFk, RefSource.RefSource " ;
197
		String strFrom =  " FROM %s  " +
198
		    	" LEFT OUTER JOIN Reference as InReference ON InReference.refId = Reference.inRefFk " +
199
				" LEFT OUTER JOIN RefSource ON Reference.RefSourceFk = RefSource.RefSourceId " +
200
		    	" WHERE (1=1) ";
201
		String strWherePartitioned = " AND (Reference.refId IN ("+ ID_LIST_TOKEN + ") ) ";
202

    
203
		String referenceTable = CdmUtils.Nz(state.getConfig().getReferenceIdTable());
204
		referenceTable = referenceTable.isEmpty() ? " Reference"  : referenceTable + " as Reference ";
205
		String strIdFrom = String.format(strFrom, referenceTable );
206

    
207
		String referenceFilter = CdmUtils.Nz(state.getConfig().getReferenceIdTable());
208
		if (! referenceFilter.isEmpty()){
209
			referenceFilter = " AND " + referenceFilter + " ";
210
		}
211
		referenceFilter = "";  //don't use it for now
212

    
213
		String strIdQueryFirstPath = strSelectId + strIdFrom ;
214
		String strIdQuerySecondPath = strSelectId + strIdFrom + " AND (Reference.InRefFk is NOT NULL) ";
215

    
216
//		if (config.getDoReferences() == CONCEPT_REFERENCES){
217
//			strIdQueryNoInRef += " AND ( Reference.refId IN ( SELECT ptRefFk FROM PTaxon) ) " + referenceFilter;
218
//		}
219

    
220
		String strRecordQuery = strSelectFull + String.format(strFrom, " Reference ") + strWherePartitioned;
221

    
222
		int recordsPerTransaction = config.getRecordsPerTransaction();
223
		try{
224
			//firstPath
225
			ResultSetPartitioner<BerlinModelImportState> partitioner =
226
			        ResultSetPartitioner.NewInstance(source, strIdQueryFirstPath, strRecordQuery, recordsPerTransaction);
227
			while (partitioner.nextPartition()){
228
				partitioner.doPartition(this, state);
229
			}
230
			logger.info("end make references without in-references ... " + getSuccessString(success));
231
			state.setReferenceSecondPath(true);
232

    
233
//			if (config.getDoReferences() == ALL || config.getDoReferences() == NOMENCLATURAL){
234

    
235
			//secondPath
236
			partitioner = ResultSetPartitioner.NewInstance(source, strIdQuerySecondPath, strRecordQuery, recordsPerTransaction);
237
			while (partitioner.nextPartition()){
238
				partitioner.doPartition(this, state);
239
			}
240
			logger.info("end make references with no 1 in-reference ... " + getSuccessString(success));
241
			state.setReferenceSecondPath(false);
242

    
243
//			}
244

    
245
		} catch (SQLException e) {
246
			logger.error("SQLException:" +  e);
247
			state.setUnsuccessfull();
248
			return;
249
		}
250
		logger.info("end make " + getPluralString() + " ... " + getSuccessString(success));
251
		if (! success){
252
			state.setUnsuccessfull();
253
		}
254
		return;
255
	}
256

    
257
	@Override
258
	public boolean doPartition(@SuppressWarnings("rawtypes") ResultSetPartitioner partitioner, BerlinModelImportState state) {
259
        deduplicationHelper.restartSession();
260

    
261
	    if (state.isReferenceSecondPath()){
262
			return doPartitionSecondPath(partitioner, state);
263
		}
264
		boolean success = true;
265

    
266
		Map<Integer, Reference> refToSave = new HashMap<>();
267

    
268
		@SuppressWarnings("unchecked")
269
        Map<String, Reference> relatedReferences = partitioner.getObjectMap(REFERENCE_NAMESPACE);
270

    
271
		BerlinModelImportConfigurator config = state.getConfig();
272

    
273
		try {
274

    
275
			int i = 0;
276
			RefCounter refCounter  = new RefCounter();
277
			ResultSet rs = partitioner.getResultSet();
278

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

    
283
				success &= makeSingleReferenceRecord(rs, state, partitioner, refToSave, relatedReferences, refCounter);
284
			} // end resultSet
285

    
286
			//for the concept reference a fixed uuid may be needed -> change uuid
287
			Integer sourceSecId = (Integer)config.getSourceSecId();
288
			Reference sec = refToSave.get(sourceSecId);
289

    
290
			if (sec != null){
291
				sec.setUuid(config.getSecUuid());
292
				logger.info("SecUuid changed to: " + config.getSecUuid());
293
			}
294

    
295
			//save and store in map
296
			logger.info("Save references (" + refCounter.refCount + ")");
297
			getReferenceService().saveOrUpdate(refToSave.values());
298

    
299
//			logger.info("end makeReferences ..." + getSuccessString(success));;
300
			return success;
301
		} catch (SQLException e) {
302
			logger.error("SQLException:" +  e);
303
			return false;
304
		}
305
	}
306

    
307

    
308

    
309
	/**
310
	 * Adds the inReference to the according references.
311
	 * @param partitioner
312
	 * @param state
313
	 * @return
314
	 */
315
	private boolean doPartitionSecondPath(@SuppressWarnings("rawtypes") ResultSetPartitioner partitioner, BerlinModelImportState state) {
316
		boolean success = true;
317

    
318
		Map<Integer, Reference> refToSave = new HashMap<>();
319

    
320
		@SuppressWarnings("unchecked")
321
        Map<String, Reference> relatedReferencesMap = partitioner.getObjectMap(REFERENCE_NAMESPACE);
322

    
323
		try {
324
				int i = 0;
325
				RefCounter refCounter  = new RefCounter();
326

    
327
				ResultSet rs = partitioner.getResultSet();
328
				//for each resultset
329
				while (rs.next()){
330
					if ((i++ % modCount) == 0 && i!= 1 ){ logger.info("References handled: " + (i-1) + " in round -" );}
331

    
332
					Integer refId = rs.getInt("refId");
333
					Integer inRefFk = nullSafeInt(rs, "inRefFk");
334

    
335
					if (inRefFk != null){
336

    
337
						Reference thisRef = relatedReferencesMap.get(String.valueOf(refId));
338

    
339
						Reference inRef = relatedReferencesMap.get(String.valueOf(inRefFk));
340

    
341
						if (thisRef != null){
342
							if (inRef == null){
343
								logger.warn("No InRef found for nomRef: " + thisRef.getTitleCache() + "; RefId: " +  refId + "; inRefFK: " +  inRefFk);
344
							}
345
							thisRef.setInReference(inRef);
346
							refToSave.put(refId, thisRef);
347
							if(!thisRef.isProtectedTitleCache()){
348
							    thisRef.setTitleCache(null);
349
							    thisRef.getTitleCache();
350
							}
351
						}
352
						if(inRefFk.equals(0)){
353
						    logger.warn("InRefFk is 0 for refId "+ refId);
354
						}
355
					}
356

    
357
				} // end resultSet
358

    
359
				//save and store in map
360
				logger.info("Save references (" + refCounter.refCount + ")");
361
				getReferenceService().saveOrUpdate(refToSave.values());
362

    
363
//			}//end resultSetList
364

    
365
//			logger.info("end makeReferences ..." + getSuccessString(success));;
366
			return success;
367
		} catch (SQLException e) {
368
			logger.error("SQLException:" +  e);
369
			return false;
370
		}
371
	}
372

    
373

    
374
	@Override
375
	public Map<Object, Map<String, ? extends CdmBase>> getRelatedObjectsForPartition(ResultSet rs, BerlinModelImportState state) {
376
		String nameSpace;
377
		Class<?> cdmClass;
378
		Set<String> idSet;
379

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

    
382
		try{
383
			Set<String> teamIdSet = new HashSet<>();
384
			Set<String> referenceIdSet = new HashSet<>();
385
			Set<String> teamStringSet = new HashSet<>();
386

    
387
			while (rs.next()){
388
				handleForeignKey(rs, teamIdSet, "NomAuthorTeamFk");
389
				handleForeignKey(rs, referenceIdSet, "InRefFk");
390
				handleForeignKey(rs, teamStringSet, "refAuthorString");
391
				//TODO only needed in second path but state not available here to check if state is second path
392
				handleForeignKey(rs, referenceIdSet, "refId");
393
			}
394

    
395
			Set<String> teamStringSet2 = new HashSet<>();
396
			for (String teamString : teamStringSet){
397
			    teamStringSet2.add(teamString.replace("'", "´"));
398
			}
399

    
400
			//team map
401
			nameSpace = BerlinModelAuthorTeamImport.NAMESPACE;
402
			cdmClass = Team.class;
403
			idSet = teamIdSet;
404
			@SuppressWarnings("unchecked")
405
            Map<String, Team> teamMap = (Map<String, Team>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
406
			result.put(nameSpace, teamMap);
407

    
408
            //refAuthor map
409
            nameSpace = REF_AUTHOR_NAMESPACE;
410
            cdmClass = Team.class;
411
            idSet = teamStringSet2;
412
            @SuppressWarnings("unchecked")
413
            Map<String, Team> refAuthorMap = (Map<String, Team>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
414
            result.put(nameSpace, refAuthorMap);
415

    
416
			//reference map
417
			nameSpace = BerlinModelReferenceImport.REFERENCE_NAMESPACE;
418
			cdmClass = Reference.class;
419
			idSet = referenceIdSet;
420
			Map<String, Reference> referenceMap = (Map<String, Reference>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
421
			result.put(nameSpace, referenceMap);
422

    
423
		} catch (SQLException e) {
424
			throw new RuntimeException(e);
425
		}
426
		return result;
427
	}
428

    
429

    
430
	/**
431
	 * Handles a single reference record
432
	 * @param rs
433
	 * @param state
434
	 * @param biblioRefToSave
435
	 * @param nomRefToSave
436
	 * @param relatedBiblioReferences
437
	 * @param relatedNomReferences
438
	 * @param refCounter
439
	 * @return
440
	 */
441
	private boolean makeSingleReferenceRecord(
442
				ResultSet rs,
443
				BerlinModelImportState state,
444
				ResultSetPartitioner<BerlinModelImportState> partitioner,
445
				Map<Integer, Reference> refToSave,
446
				Map<String, Reference> relatedReferences,
447
				RefCounter refCounter){
448

    
449
	    boolean success = true;
450

    
451
		Integer refId = null;
452
		try {
453
			Map<String, Object> valueMap = getValueMap(rs);
454

    
455
			Integer categoryFk = (Integer)valueMap.get("refCategoryFk".toLowerCase());
456
			refId = (Integer)valueMap.get("refId".toLowerCase());
457
			Boolean thesisFlag = (Boolean)valueMap.get("thesisFlag".toLowerCase());
458

    
459

    
460
			Reference reference;
461
			logger.debug("RefCategoryFk: " + categoryFk);
462

    
463
			if (thesisFlag){
464
				reference = makeThesis(valueMap);
465
			}else if (categoryFk == REF_JOURNAL){
466
				reference = makeJournal(valueMap);
467
			}else if(categoryFk == REF_BOOK){
468
				reference = makeBook(valueMap);
469
			}else if(categoryFk == REF_DATABASE){
470
				reference = makeDatabase(valueMap);
471
			}else if(categoryFk == REF_INFORMAL){
472
				reference = makeInformal(valueMap);
473
			}else if(categoryFk == REF_WEBSITE){
474
				reference = makeWebSite(valueMap);
475
			}else if(categoryFk == REF_UNKNOWN){
476
				reference = makeUnknown(valueMap);
477
			}else if(categoryFk == REF_PRINT_SERIES){
478
				reference = makePrintSeries(valueMap);
479
			}else if(categoryFk == REF_CONFERENCE_PROCEEDINGS){
480
				reference = makeProceedings(valueMap);
481
			}else if(categoryFk == REF_ARTICLE){
482
				reference = makeArticle(valueMap);
483
			}else if(categoryFk == REF_JOURNAL_VOLUME){
484
				reference = makeJournalVolume(valueMap);
485
			}else if(categoryFk == REF_PART_OF_OTHER_TITLE){
486
				reference = makePartOfOtherTitle(valueMap);
487
			}else{
488
				logger.warn("Unknown categoryFk (" + categoryFk + "). Create 'Generic instead'");
489
				reference = ReferenceFactory.newGeneric();
490
				success = false;
491
			}
492

    
493
			//refYear
494
			String refYear = (String)valueMap.get("refYear".toLowerCase());
495
			reference.setDatePublished(ImportHelper.getDatePublished(refYear));
496

    
497
			//created, updated, notes
498
			doCreatedUpdatedNotes(state, reference, rs);
499

    
500
			//idInSource
501
			String idInSource = (String)valueMap.get("IdInSource".toLowerCase());
502
			if (isNotBlank(idInSource)){
503
				IdentifiableSource source = IdentifiableSource.NewDataImportInstance(idInSource);
504
				source.setIdNamespace("import to Berlin Model");
505
				reference.addSource(source);
506
			}
507

    
508
			//nom&BiblioReference  - must be last because a clone is created
509
			success &= makeNomAndBiblioReference(rs, state, partitioner, refId, reference, refCounter, refToSave);
510

    
511

    
512
		} catch (Exception e) {
513
			logger.warn("Reference with BM refId '" + CdmUtils.Nz(refId) +  "' threw Exception and could not be saved");
514
			e.printStackTrace();
515
			success = false;
516
		}
517
		return success;
518
	}
519

    
520

    
521
	/**
522
	 * Creates and saves a nom. reference and a biblio. reference after checking necessity
523
	 * @param rs
524
	 * @param refId
525
	 * @param ref
526
	 * @param refCounter
527
	 * @param biblioRefToSave
528
	 * @param nomRefToSave
529
	 * @param teamMap
530
	 * @param stores
531
	 * @return
532
	 * @throws SQLException
533
	 */
534
	private boolean makeNomAndBiblioReference(
535
				ResultSet rs,
536
				BerlinModelImportState state,
537
				@SuppressWarnings("rawtypes") ResultSetPartitioner partitioner,
538
				int refId,
539
				Reference ref,
540
				RefCounter refCounter,
541
				Map<Integer, Reference> refToSave
542
				) throws SQLException{
543

    
544
		@SuppressWarnings("unchecked")
545
        Map<String, Team> teamMap = partitioner.getObjectMap(BerlinModelAuthorTeamImport.NAMESPACE);
546

    
547
		String refCache = rs.getString("refCache");
548
		String nomRefCache = rs.getString("nomRefCache");
549
		String title = rs.getString("title");
550
		String nomTitleAbbrev = rs.getString("nomTitleAbbrev");
551
		boolean isPreliminary = rs.getBoolean("PreliminaryFlag");
552
		String refAuthorString = rs.getString("refAuthorString");
553
		Integer nomAuthorTeamFk = rs.getInt("NomAuthorTeamFk");
554
		String strNomAuthorTeamFk = String.valueOf(nomAuthorTeamFk);
555
		TeamOrPersonBase<?> nomAuthor = teamMap.get(strNomAuthorTeamFk);
556

    
557
		Reference sourceReference = state.getTransactionalSourceReference();
558

    
559
		//preliminary
560
		if (isPreliminary){
561
			ref.setAbbrevTitleCache(nomRefCache, true);
562
			ref.setTitleCache(refCache, true);
563
		}
564

    
565
		//title/abbrevTitle
566
		if (isNotBlank(nomTitleAbbrev)){
567
			ref.setAbbrevTitle(nomTitleAbbrev);
568
		}
569
		if (isNotBlank(title)){
570
			ref.setTitle(title);
571
		}
572

    
573
		//author
574
		TeamOrPersonBase<?> author = getAuthorship(state, refAuthorString, nomAuthor);
575
		ref.setAuthorship(author);
576

    
577
		//save
578
		if (! refToSave.containsKey(refId)){
579
			refToSave.put(refId, ref);
580
		}else{
581
			logger.warn("Duplicate refId in Berlin Model database. Second reference was not imported !!");
582
		}
583
		refCounter.refCount++;
584

    
585
		//refId
586
		ImportHelper.setOriginalSource(ref, sourceReference, refId, REFERENCE_NAMESPACE);
587

    
588
		if (commonNameRefSet != null && commonNameRefSet.contains(refId)){
589
            ref.addMarker(Marker.NewInstance(MarkerType.COMMON_NAME_REFERENCE(), true));
590
        }
591

    
592
		return true;
593
	}
594

    
595
	/**
596
	 * Copies the created and updated information from the nomReference to the cloned bibliographic reference
597
	 * @param referenceBase
598
	 * @param nomReference
599
	 */
600
	private void copyCreatedUpdated(Reference biblioReference, Reference nomReference) {
601
		biblioReference.setCreatedBy(nomReference.getCreatedBy());
602
		biblioReference.setCreated(nomReference.getCreated());
603
		biblioReference.setUpdatedBy(nomReference.getUpdatedBy());
604
		biblioReference.setUpdated(nomReference.getUpdated());
605

    
606
	}
607

    
608
	private Reference makeArticle (Map<String, Object> valueMap){
609

    
610
		IArticle article = ReferenceFactory.newArticle();
611
		Object inRefFk = valueMap.get("inRefFk".toLowerCase());
612
		Integer inRefCategoryFk = (Integer)valueMap.get("inRefCategoryFk".toLowerCase());
613
		Integer refId = (Integer)valueMap.get("refId".toLowerCase());
614

    
615
		if (inRefFk != null){
616
			if (inRefCategoryFk != REF_JOURNAL){
617
				logger.warn("Wrong inrefCategory for Article (refID = " + refId +"). Type must be 'Journal' but was not (RefCategoryFk=" + inRefCategoryFk + "))." +
618
					" InReference was added anyway! ");
619
			}
620
		}else{
621
			logger.warn ("Article has no inreference: " + refId);
622
		}
623
		makeStandardMapper(valueMap, (Reference)article); //url, pages, series, volume
624
		String url = (String)valueMap.get("url");
625
		if (url != null && url.contains("dx.doi.org")){
626
		    article.setDoi(DOI.fromString(url));
627
		    article.setUri(null);
628
		}
629
		return (Reference)article;
630
	}
631

    
632
	private Reference makePartOfOtherTitle (Map<String, Object> valueMap){
633

    
634
		Reference result;
635
		Object inRefFk = valueMap.get("inRefFk".toLowerCase());
636
		Integer inRefCategoryFk = (Integer)valueMap.get("inRefCategoryFk".toLowerCase());
637
		Integer refId = (Integer)valueMap.get("refId".toLowerCase());
638

    
639
		if (inRefCategoryFk == null){
640
			//null -> error
641
			logger.warn("Part-Of-Other-Title has no inRefCategoryFk! RefId = " + refId + ". ReferenceType set to Generic.");
642
			result = makeUnknown(valueMap);
643
		}else if (inRefFk == null){
644
			//TODO is this correct ??
645
			logger.warn("Part-Of-Other-Title has no in reference: " + refId);
646
			result = makeUnknown(valueMap);
647
		}else if (inRefCategoryFk == REF_BOOK){
648
			//BookSection
649
			IBookSection bookSection = ReferenceFactory.newBookSection();
650
			result = (Reference)bookSection;
651
		}else if (inRefCategoryFk == REF_ARTICLE){
652
			//Article
653
			logger.info("Reference (refId = " + refId + ") of type 'part_of_other_title' is part of 'article'." +
654
					" We use the section reference type for such in references now.") ;
655
			result = ReferenceFactory.newSection();
656
		}else if (inRefCategoryFk == REF_JOURNAL){
657
			//TODO
658
			logger.warn("Reference (refId = " + refId + ") of type 'part_of_other_title' has inReference of type 'journal'." +
659
					" This is not allowed! Generic reference created instead") ;
660
			result = ReferenceFactory.newGeneric();
661
			result.addMarker(Marker.NewInstance(MarkerType.TO_BE_CHECKED(), true));
662
		}else if (inRefCategoryFk == REF_PART_OF_OTHER_TITLE){
663
			logger.info("Reference (refId = " + refId + ") of type 'part_of_other_title' has inReference 'part of other title'." +
664
					" 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") ;
665
			result = ReferenceFactory.newSection();
666
		}else{
667
			logger.warn("InReference type (catFk = " + inRefCategoryFk + ") of part-of-reference not recognized for refId " + refId + "." +
668
				" Create 'Generic' reference instead");
669
			result = ReferenceFactory.newGeneric();
670
		}
671
		makeStandardMapper(valueMap, result); //url, pages
672
		return result;
673
	}
674

    
675

    
676
	/**
677
	 * @param inRefFkInt
678
	 * @param biblioRefToSave
679
	 * @param nomRefToSave
680
	 * @param relatedBiblioReferences
681
	 * @param relatedNomReferences
682
	 * @return
683
	 */
684
	private boolean existsInMapOrToSave(Integer inRefFkInt, Map<Integer, Reference> refToSave, Map<String, Reference> relatedReferences) {
685
		boolean result = false;
686
		if (inRefFkInt == null){
687
			return false;
688
		}
689
		result |= refToSave.containsKey(inRefFkInt);
690
		result |= relatedReferences.containsKey(String.valueOf(inRefFkInt));
691
		return result;
692
	}
693

    
694
	private Reference makeWebSite(Map<String, Object> valueMap){
695
		if (logger.isDebugEnabled()){logger.debug("RefType 'Website'");}
696
		Reference webPage = ReferenceFactory.newWebPage();
697
		makeStandardMapper(valueMap, webPage); //placePublished, publisher
698
		return webPage;
699
	}
700

    
701
	private Reference makeUnknown(Map<String, Object> valueMap){
702
		if (logger.isDebugEnabled()){logger.debug("RefType 'Unknown'");}
703
		Reference generic = ReferenceFactory.newGeneric();
704
//		generic.setSeries(series);
705
		makeStandardMapper(valueMap, generic); //pages, placePublished, publisher, series, volume
706
		return generic;
707
	}
708

    
709
	private Reference makeInformal(Map<String, Object> valueMap){
710
		if (logger.isDebugEnabled()){logger.debug("RefType 'Informal'");}
711
		Reference generic = ReferenceFactory.newGeneric();
712
//		informal.setSeries(series);
713
		makeStandardMapper(valueMap, generic);//editor, pages, placePublished, publisher, series, volume
714
		String informal = (String)valueMap.get("InformalRefCategory".toLowerCase());
715
		if (isNotBlank(informal) ){
716
			generic.addExtension(informal, ExtensionType.INFORMAL_CATEGORY());
717
		}
718
		return generic;
719
	}
720

    
721
	private Reference makeDatabase(Map<String, Object> valueMap){
722
		if (logger.isDebugEnabled()){logger.debug("RefType 'Database'");}
723
		Reference database =  ReferenceFactory.newDatabase();
724
		makeStandardMapper(valueMap, database); //?
725
		return database;
726
	}
727

    
728
	private Reference makeJournal(Map<String, Object> valueMap){
729
		if (logger.isDebugEnabled()){logger.debug("RefType 'Journal'");}
730
		Reference journal = ReferenceFactory.newJournal();
731

    
732
		Set<String> omitAttributes = new HashSet<>();
733
		String series = "series";
734
//		omitAttributes.add(series);
735

    
736
		makeStandardMapper(valueMap, journal, omitAttributes); //issn,placePublished,publisher
737
//		if (valueMap.get(series) != null){
738
//			logger.warn("Series not yet implemented for journal!");
739
//		}
740
		return journal;
741
	}
742

    
743
	private Reference makeBook(
744
				Map<String, Object> valueMap){
745

    
746
		if (logger.isDebugEnabled()){logger.debug("RefType 'Book'");}
747
		Reference book = ReferenceFactory.newBook();
748
		Integer refId = (Integer)valueMap.get("refId".toLowerCase());
749

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

    
752
		Set<String> omitAttributes = new HashSet<>();
753
		String attrSeries = "series";
754
//		omitAttributes.add(attrSeries);
755

    
756
		makeStandardMapper(valueMap, book, omitAttributes);
757

    
758
		//Series (as String)
759
		IPrintSeries printSeries = null;
760
		if (valueMap.get(attrSeries) != null){
761
			String series = (String)valueMap.get("title".toLowerCase());
762
			if (series == null){
763
				String nomTitle = (String)valueMap.get("nomTitleAbbrev".toLowerCase());
764
				series = nomTitle;
765
			}
766
			printSeries = ReferenceFactory.newPrintSeries(series);
767
			logger.info("Implementation of printSeries is preliminary");
768
		}
769
		//Series (as Reference)
770
		if (book.getInSeries() != null && printSeries != null){
771
			logger.warn("Book has series string and inSeries reference. Can not take both. Series string neglected");
772
		}else{
773
			book.setInSeries(printSeries);
774
		}
775
		book.setEditor(null);
776
		return book;
777

    
778
	}
779

    
780
	/**
781
	 * Returns the requested object if it exists in one of both maps. Prefers the refToSaveMap in ambigious cases.
782
	 * @param inRefFkInt
783
	 * @param nomRefToSave
784
	 * @param relatedNomReferences
785
	 * @return
786
	 */
787
	private Reference getReferenceFromMaps(
788
			int inRefFkInt,
789
			Map<Integer, Reference> refToSaveMap,
790
			Map<String, Reference> relatedRefMap) {
791
		Reference result = null;
792
		result = refToSaveMap.get(inRefFkInt);
793
		if (result == null){
794
			result = relatedRefMap.get(String.valueOf(inRefFkInt));
795
		}
796
		return result;
797
	}
798

    
799
	private Reference makePrintSeries(Map<String, Object> valueMap){
800
		if (logger.isDebugEnabled()){logger.debug("RefType 'PrintSeries'");}
801
		Reference printSeries = ReferenceFactory.newPrintSeries();
802
		makeStandardMapper(valueMap, printSeries, null);
803
		return printSeries;
804
	}
805

    
806
	private Reference makeProceedings(Map<String, Object> valueMap){
807
		if (logger.isDebugEnabled()){logger.debug("RefType 'Proceedings'");}
808
		Reference proceedings = ReferenceFactory.newProceedings();
809
		makeStandardMapper(valueMap, proceedings, null);
810
		return proceedings;
811
	}
812

    
813
	private Reference makeThesis(Map<String, Object> valueMap){
814
		if (logger.isDebugEnabled()){logger.debug("RefType 'Thesis'");}
815
		Reference thesis = ReferenceFactory.newThesis();
816
		makeStandardMapper(valueMap, thesis, null);
817
		return thesis;
818
	}
819

    
820

    
821
	private Reference makeJournalVolume(Map<String, Object> valueMap){
822
		if (logger.isDebugEnabled()){logger.debug("RefType 'JournalVolume'");}
823
		//Proceedings proceedings = Proceedings.NewInstance();
824
		Reference journalVolume = ReferenceFactory.newGeneric();
825
		makeStandardMapper(valueMap, journalVolume, null);
826
		logger.warn("Journal volumes not yet implemented. Generic created instead but with errors");
827
		return journalVolume;
828
	}
829

    
830
	private boolean makeStandardMapper(Map<String, Object> valueMap, Reference ref){
831
		return makeStandardMapper(valueMap, ref, null);
832
	}
833

    
834

    
835
	private boolean makeStandardMapper(Map<String, Object> valueMap, CdmBase cdmBase, Set<String> omitAttributes){
836
		boolean result = true;
837
		for (CdmAttributeMapperBase mapper : classMappers){
838
			if (mapper instanceof CdmSingleAttributeMapperBase){
839
				result &= makeStandardSingleMapper(valueMap, cdmBase, (CdmSingleAttributeMapperBase)mapper, omitAttributes);
840
			}else if (mapper instanceof CdmOneToManyMapper){
841
				result &= makeMultipleValueAddMapper(valueMap, cdmBase, (CdmOneToManyMapper)mapper, omitAttributes);
842
			}else{
843
				logger.error("Unknown mapper type");
844
				result = false;
845
			}
846
		}
847
		return result;
848
	}
849

    
850
	private boolean makeStandardSingleMapper(Map<String, Object> valueMap, CdmBase cdmBase, CdmSingleAttributeMapperBase mapper, Set<String> omitAttributes){
851
		boolean result = true;
852
		if (omitAttributes == null){
853
			omitAttributes = new HashSet<>();
854
		}
855
		if (mapper instanceof DbImportExtensionMapper){
856
			result &= ((DbImportExtensionMapper)mapper).invoke(valueMap, cdmBase);
857
		}else if (mapper instanceof DbImportMarkerMapper){
858
			result &= ((DbImportMarkerMapper)mapper).invoke(valueMap, cdmBase);
859
		}else{
860
			String sourceAttribute = mapper.getSourceAttributeList().get(0).toLowerCase();
861
			Object value = valueMap.get(sourceAttribute);
862
			if (mapper instanceof CdmUriMapper && value != null){
863
				try {
864
					value = new URI (value.toString());
865
				} catch (URISyntaxException e) {
866
					logger.error("URI syntax exception: " + value.toString());
867
					value = null;
868
				}
869
			}
870
			if (value != null){
871
				String destinationAttribute = mapper.getDestinationAttribute();
872
				if (! omitAttributes.contains(destinationAttribute)){
873
					result &= ImportHelper.addValue(value, cdmBase, destinationAttribute, mapper.getTypeClass(), OVERWRITE, OBLIGATORY);
874
				}
875
			}
876
		}
877
		return result;
878
	}
879

    
880

    
881
	private boolean makeMultipleValueAddMapper(Map<String, Object> valueMap, CdmBase cdmBase, CdmOneToManyMapper<CdmBase, CdmBase, CdmSingleAttributeMapperBase> mapper, Set<String> omitAttributes){
882
		if (omitAttributes == null){
883
			omitAttributes = new HashSet<>();
884
		}
885
		boolean result = true;
886
		String destinationAttribute = mapper.getSingleAttributeName();
887
		List<Object> sourceValues = new ArrayList<>();
888
		List<Class> classes = new ArrayList<>();
889
		for (CdmSingleAttributeMapperBase singleMapper : mapper.getSingleMappers()){
890
			String sourceAttribute = singleMapper.getSourceAttribute();
891
			Object value = valueMap.get(sourceAttribute);
892
			sourceValues.add(value);
893
			Class<?> clazz = singleMapper.getTypeClass();
894
			classes.add(clazz);
895
		}
896

    
897
		result &= ImportHelper.addMultipleValues(sourceValues, cdmBase, destinationAttribute, classes, NO_OVERWRITE, OBLIGATORY);
898
		return result;
899
	}
900

    
901

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

    
904
	    TeamOrPersonBase<?> result;
905
		if (nomAuthor != null){
906
			result = nomAuthor;
907
		} else if (StringUtils.isNotBlank(authorString)){
908
			//TODO match with existing Persons/Teams
909
		    Team team = state.getRelatedObject(REF_AUTHOR_NAMESPACE, authorString, Team.class);
910
			if (team == null){
911
			    team = Team.NewInstance();
912
			    team.setNomenclaturalTitle(authorString);
913
			    team.setTitleCache(authorString, true);
914
			    state.addRelatedObject(REF_AUTHOR_NAMESPACE, authorString, team);
915
			    team.addImportSource(authorString, REF_AUTHOR_NAMESPACE, state.getTransactionalSourceReference(), null);
916
			}
917
			result = team;
918
		}else{
919
			result = null;
920
		}
921

    
922
		return result;
923
	}
924

    
925

    
926
	/**
927
	 * @param lowerCase
928
	 * @param config
929
	 * @return
930
	 */
931
	public Set<String> getObligatoryAttributes(boolean lowerCase, BerlinModelImportConfigurator config){
932
		Set<String> result = new HashSet<>();
933
		Class<ICdmImport>[] ioClassList = config.getIoClassList();
934
		logger.warn("getObligatoryAttributes has been commented because it still needs to be adapted to the new package structure");
935
		result.addAll(Arrays.asList(unclearMappers));
936
		result.addAll(Arrays.asList(createdAndNotesAttributes));
937
		result.addAll(Arrays.asList(operationalAttributes));
938
		CdmIoMapping mapping = new CdmIoMapping();
939
		for (CdmAttributeMapperBase mapper : classMappers){
940
			mapping.addMapper(mapper);
941
		}
942
		result.addAll(mapping.getSourceAttributes());
943
		if (lowerCase){
944
			Set<String> lowerCaseResult = new HashSet<>();
945
			for (String str : result){
946
				if (str != null){lowerCaseResult.add(str.toLowerCase());}
947
			}
948
			result = lowerCaseResult;
949
		}
950
		return result;
951
	}
952

    
953
	@Override
954
	protected boolean doCheck(BerlinModelImportState state){
955
		BerlinModelReferenceImportValidator validator = new BerlinModelReferenceImportValidator();
956
		return validator.validate(state, this);
957
	}
958

    
959
	@Override
960
	protected boolean isIgnore(BerlinModelImportState state){
961
		return (state.getConfig().getDoReferences() == IImportConfigurator.DO_REFERENCES.NONE);
962
	}
963

    
964
}
(14-14/22)