Project

General

Profile

Download (33.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.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
 * @since 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, "Ref. deposited at", "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 = nullSafeInt(rs, "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
							if(!thisRef.isProtectedTitleCache()){
328
							    thisRef.setTitleCache(null);
329
							    thisRef.getTitleCache();
330
							}
331
						}
332
						if(inRefFk.equals(0)){
333
						    logger.warn("InRefFk is 0 for refId "+ refId);
334
						}
335
					}
336

    
337
				} // end resultSet
338

    
339
				//save and store in map
340
				logger.info("Save references (" + refCounter.refCount + ")");
341
				getReferenceService().saveOrUpdate(refToSave.values());
342

    
343
//			}//end resultSetList
344

    
345
//			logger.info("end makeReferences ..." + getSuccessString(success));;
346
			return success;
347
		} catch (SQLException e) {
348
			logger.error("SQLException:" +  e);
349
			return false;
350
		}
351
	}
352

    
353

    
354
	@Override
355
	public Map<Object, Map<String, ? extends CdmBase>> getRelatedObjectsForPartition(ResultSet rs, BerlinModelImportState state) {
356
		String nameSpace;
357
		Class<?> cdmClass;
358
		Set<String> idSet;
359

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

    
362
		try{
363
			Set<String> teamIdSet = new HashSet<>();
364
			Set<String> referenceIdSet = new HashSet<>();
365
			Set<String> teamStringSet = new HashSet<>();
366

    
367
			while (rs.next()){
368
				handleForeignKey(rs, teamIdSet, "NomAuthorTeamFk");
369
				handleForeignKey(rs, referenceIdSet, "InRefFk");
370
				handleForeignKey(rs, teamStringSet, "refAuthorString");
371
				//TODO only needed in second path but state not available here to check if state is second path
372
				handleForeignKey(rs, referenceIdSet, "refId");
373
			}
374

    
375
			Set<String> teamStringSet2 = new HashSet<>();
376
			for (String teamString : teamStringSet){
377
			    teamStringSet2.add(teamString.replace("'", "´"));
378
			}
379

    
380
			//team map
381
			nameSpace = BerlinModelAuthorTeamImport.NAMESPACE;
382
			cdmClass = Team.class;
383
			idSet = teamIdSet;
384
			@SuppressWarnings("unchecked")
385
            Map<String, Team> teamMap = (Map<String, Team>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
386
			result.put(nameSpace, teamMap);
387

    
388
            //refAuthor map
389
            nameSpace = REF_AUTHOR_NAMESPACE;
390
            cdmClass = Team.class;
391
            idSet = teamStringSet2;
392
            @SuppressWarnings("unchecked")
393
            Map<String, Team> refAuthorMap = (Map<String, Team>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
394
            result.put(nameSpace, refAuthorMap);
395

    
396
			//reference map
397
			nameSpace = BerlinModelReferenceImport.REFERENCE_NAMESPACE;
398
			cdmClass = Reference.class;
399
			idSet = referenceIdSet;
400
			Map<String, Reference> referenceMap = (Map<String, Reference>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
401
			result.put(nameSpace, referenceMap);
402

    
403
		} catch (SQLException e) {
404
			throw new RuntimeException(e);
405
		}
406
		return result;
407
	}
408

    
409

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

    
429
	    boolean success = true;
430

    
431
		Integer refId = null;
432
		try {
433
			Map<String, Object> valueMap = getValueMap(rs);
434

    
435
			Integer categoryFk = (Integer)valueMap.get("refCategoryFk".toLowerCase());
436
			refId = (Integer)valueMap.get("refId".toLowerCase());
437
			Boolean thesisFlag = (Boolean)valueMap.get("thesisFlag".toLowerCase());
438

    
439

    
440
			Reference referenceBase;
441
			logger.debug("RefCategoryFk: " + categoryFk);
442

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

    
473
			//refYear
474
			String refYear = (String)valueMap.get("refYear".toLowerCase());
475
			referenceBase.setDatePublished(ImportHelper.getDatePublished(refYear));
476

    
477
			//created, updated, notes
478
			doCreatedUpdatedNotes(state, referenceBase, rs);
479

    
480
			//idInSource
481
			String idInSource = (String)valueMap.get("IdInSource".toLowerCase());
482
			if (isNotBlank(idInSource)){
483
				IdentifiableSource source = IdentifiableSource.NewDataImportInstance(idInSource);
484
				source.setIdNamespace("import to Berlin Model");
485
				referenceBase.addSource(source);
486
			}
487

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

    
491

    
492
		} catch (Exception e) {
493
			logger.warn("Reference with BM refId '" + CdmUtils.Nz(refId) +  "' threw Exception and could not be saved");
494
			e.printStackTrace();
495
			success = false;
496
		}
497
		return success;
498
	}
499

    
500

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

    
524
		@SuppressWarnings("unchecked")
525
        Map<String, Team> teamMap = partitioner.getObjectMap(BerlinModelAuthorTeamImport.NAMESPACE);
526

    
527
		String refCache = rs.getString("refCache");
528
		String nomRefCache = rs.getString("nomRefCache");
529
		String title = rs.getString("title");
530
		String nomTitleAbbrev = rs.getString("nomTitleAbbrev");
531
		boolean isPreliminary = rs.getBoolean("PreliminaryFlag");
532
		String refAuthorString = rs.getString("refAuthorString");
533
		Integer nomAuthorTeamFk = rs.getInt("NomAuthorTeamFk");
534
		String strNomAuthorTeamFk = String.valueOf(nomAuthorTeamFk);
535
		TeamOrPersonBase<?> nomAuthor = teamMap.get(strNomAuthorTeamFk);
536

    
537
		Reference sourceReference = state.getTransactionalSourceReference();
538

    
539
		//preliminary
540
		if (isPreliminary){
541
			ref.setAbbrevTitleCache(nomRefCache, true);
542
			ref.setTitleCache(refCache, true);
543
		}
544

    
545
		//title/abbrevTitle
546
		if (isNotBlank(nomTitleAbbrev)){
547
			ref.setAbbrevTitle(nomTitleAbbrev);
548
		}
549
		if (isNotBlank(title)){
550
			ref.setTitle(title);
551
		}
552

    
553
		//author
554
		TeamOrPersonBase<?> author = getAuthorship(state, refAuthorString , nomAuthor);
555
		ref.setAuthorship(author);
556

    
557
		//save
558
		if (! refToSave.containsKey(refId)){
559
			refToSave.put(refId, ref);
560
		}else{
561
			logger.warn("Duplicate refId in Berlin Model database. Second reference was not imported !!");
562
		}
563
		refCounter.refCount++;
564

    
565
		//refId
566
		ImportHelper.setOriginalSource(ref, sourceReference, refId, REFERENCE_NAMESPACE);
567

    
568
		return true;
569
	}
570

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

    
582
	}
583

    
584
	private Reference makeArticle (Map<String, Object> valueMap){
585

    
586
		IArticle article = ReferenceFactory.newArticle();
587
		Object inRefFk = valueMap.get("inRefFk".toLowerCase());
588
		Integer inRefCategoryFk = (Integer)valueMap.get("inRefCategoryFk".toLowerCase());
589
		Integer refId = (Integer)valueMap.get("refId".toLowerCase());
590

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

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

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

    
651

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

    
670
	private Reference makeWebSite(Map<String, Object> valueMap){
671
		if (logger.isDebugEnabled()){logger.debug("RefType 'Website'");}
672
		Reference webPage = ReferenceFactory.newWebPage();
673
		makeStandardMapper(valueMap, webPage); //placePublished, publisher
674
		return webPage;
675
	}
676

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

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

    
697
	private Reference makeDatabase(Map<String, Object> valueMap){
698
		if (logger.isDebugEnabled()){logger.debug("RefType 'Database'");}
699
		Reference database =  ReferenceFactory.newDatabase();
700
		makeStandardMapper(valueMap, database); //?
701
		return database;
702
	}
703

    
704
	private Reference makeJournal(Map<String, Object> valueMap){
705
		if (logger.isDebugEnabled()){logger.debug("RefType 'Journal'");}
706
		Reference journal = ReferenceFactory.newJournal();
707

    
708
		Set<String> omitAttributes = new HashSet<>();
709
		String series = "series";
710
//		omitAttributes.add(series);
711

    
712
		makeStandardMapper(valueMap, journal, omitAttributes); //issn,placePublished,publisher
713
//		if (valueMap.get(series) != null){
714
//			logger.warn("Series not yet implemented for journal!");
715
//		}
716
		return journal;
717
	}
718

    
719
	private Reference makeBook(
720
				Map<String, Object> valueMap){
721

    
722
		if (logger.isDebugEnabled()){logger.debug("RefType 'Book'");}
723
		Reference book = ReferenceFactory.newBook();
724
		Integer refId = (Integer)valueMap.get("refId".toLowerCase());
725

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

    
728
		Set<String> omitAttributes = new HashSet<>();
729
		String attrSeries = "series";
730
//		omitAttributes.add(attrSeries);
731

    
732
		makeStandardMapper(valueMap, book, omitAttributes);
733

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

    
754
	}
755

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

    
775
	private Reference makePrintSeries(Map<String, Object> valueMap){
776
		if (logger.isDebugEnabled()){logger.debug("RefType 'PrintSeries'");}
777
		Reference printSeries = ReferenceFactory.newPrintSeries();
778
		makeStandardMapper(valueMap, printSeries, null);
779
		return printSeries;
780
	}
781

    
782
	private Reference makeProceedings(Map<String, Object> valueMap){
783
		if (logger.isDebugEnabled()){logger.debug("RefType 'Proceedings'");}
784
		Reference proceedings = ReferenceFactory.newProceedings();
785
		makeStandardMapper(valueMap, proceedings, null);
786
		return proceedings;
787
	}
788

    
789
	private Reference makeThesis(Map<String, Object> valueMap){
790
		if (logger.isDebugEnabled()){logger.debug("RefType 'Thesis'");}
791
		Reference thesis = ReferenceFactory.newThesis();
792
		makeStandardMapper(valueMap, thesis, null);
793
		return thesis;
794
	}
795

    
796

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

    
806
	private boolean makeStandardMapper(Map<String, Object> valueMap, Reference ref){
807
		return makeStandardMapper(valueMap, ref, null);
808
	}
809

    
810

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

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

    
856

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

    
873
		result &= ImportHelper.addMultipleValues(sourceValues, cdmBase, destinationAttribute, classes, NO_OVERWRITE, OBLIGATORY);
874
		return result;
875
	}
876

    
877

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

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

    
898
		return result;
899
	}
900

    
901

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

    
929
	@Override
930
	protected boolean doCheck(BerlinModelImportState state){
931
		BerlinModelReferenceImportValidator validator = new BerlinModelReferenceImportValidator();
932
		return validator.validate(state, this);
933
	}
934

    
935
	@Override
936
	protected boolean isIgnore(BerlinModelImportState state){
937
		return (state.getConfig().getDoReferences() == IImportConfigurator.DO_REFERENCES.NONE);
938
	}
939

    
940

    
941

    
942

    
943
}
(13-13/21)