Project

General

Profile

Download (34.4 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<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(ResultSetPartitioner partitioner, BerlinModelImportState state) {
259
		if (state.isReferenceSecondPath()){
260
			return doPartitionSecondPath(partitioner, state);
261
		}
262
		boolean success = true;
263

    
264
		Map<Integer, Reference> refToSave = new HashMap<>();
265

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

    
269
		BerlinModelImportConfigurator config = state.getConfig();
270

    
271
		try {
272

    
273
				int i = 0;
274
				RefCounter refCounter  = new RefCounter();
275

    
276
				ResultSet rs = partitioner.getResultSet();
277

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

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

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

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

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

    
298
//			}//end resultSetList
299

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

    
308

    
309

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

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

    
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
				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

    
593
		return true;
594
	}
595

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

    
607
	}
608

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

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

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

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

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

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

    
676

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

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

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

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

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

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

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

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

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

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

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

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

    
757
		makeStandardMapper(valueMap, book, omitAttributes);
758

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

    
779
	}
780

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

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

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

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

    
821

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

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

    
835

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

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

    
881

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

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

    
902

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

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

    
923
		return result;
924
	}
925

    
926

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

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

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

    
965

    
966

    
967

    
968
}
(14-14/22)