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.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
 * @created 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
				DbSingleAttributeImportMapperBase singleMapper = (DbSingleAttributeImportMapperBase)mapper;
106
				singleMapper.initialize(state, Reference.class);
107
			}
108
		}
109
		return;
110
	}
111

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

    
130

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

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

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

    
145
	//TODO isPaper
146
	//
147

    
148

    
149

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

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

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

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

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

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

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

    
186
		String strSelectIdBase = strSelectId + strIdFrom;
187

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

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

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

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

    
203
		int recordsPerTransaction = config.getRecordsPerTransaction();
204
		try{
205
			//firstPath
206
			ResultSetPartitioner partitioner = 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<Integer, Reference>();
245

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

    
249
		BerlinModelImportConfigurator config = state.getConfig();
250

    
251
		try {
252

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

    
256
				ResultSet rs = partitioner.getResultSet();
257

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

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

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

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

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

    
278
//			}//end resultSetList
279

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

    
288

    
289

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

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

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

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

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

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

    
315
					if (inRefFk != null){
316

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

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

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

    
332
				} // end resultSet
333

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

    
338
//			}//end resultSetList
339

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

    
348

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

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

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

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

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

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

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

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

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

    
404

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

    
424
	    boolean success = true;
425

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

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

    
434

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

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

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

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

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

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

    
486

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

    
495

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

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

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

    
532
		Reference sourceReference = state.getTransactionalSourceReference();
533

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

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

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

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

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

    
563
		return true;
564
	}
565

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

    
577
	}
578

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

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

    
586
		if (inRefFk != null){
587
			if (inRefCategoryFk != REF_JOURNAL){
588
				logger.warn("Wrong inrefCategory for Article (refID = " + refId +"). Type must be 'Journal' but was not (RefCategoryFk=" + inRefCategoryFk + "))." +
589
					" InReference was added anyway! ");
590
			}
591
		}else{
592
			logger.warn ("Article has no inreference: " + refId);
593
		}
594
		makeStandardMapper(valueMap, (Reference)article); //url, pages, series, volume
595
		return (Reference)article;
596
	}
597

    
598
	private Reference makePartOfOtherTitle (Map<String, Object> valueMap,
599
			Map<Integer, Reference> refToSave, Map<String, Reference> relatedReferences){
600

    
601
		Reference result;
602
		Object inRefFk = valueMap.get("inRefFk".toLowerCase());
603
		Integer inRefCategoryFk = (Integer)valueMap.get("inRefCategoryFk".toLowerCase());
604
		Integer refId = (Integer)valueMap.get("refId".toLowerCase());
605

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

    
642

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

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

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

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

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

    
695
	private Reference makeJournal(Map<String, Object> valueMap){
696
		if (logger.isDebugEnabled()){logger.debug("RefType 'Journal'");}
697
		Reference journal = ReferenceFactory.newJournal();
698

    
699
		Set<String> omitAttributes = new HashSet<String>();
700
		String series = "series";
701
//		omitAttributes.add(series);
702

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

    
710
	private Reference makeBook(
711
				Map<String, Object> valueMap,
712
				Map<Integer, Reference> refToSave,
713
				Map<String, Reference> relatedReferences){
714
		if (logger.isDebugEnabled()){logger.debug("RefType 'Book'");}
715
		Reference book = ReferenceFactory.newBook();
716
		Integer refId = (Integer)valueMap.get("refId".toLowerCase());
717

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

    
720
		Set<String> omitAttributes = new HashSet<>();
721
		String attrSeries = "series";
722
//		omitAttributes.add(attrSeries);
723

    
724
		makeStandardMapper(valueMap, book, omitAttributes);
725

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

    
746
	}
747

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

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

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

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

    
788

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

    
798
	private boolean makeStandardMapper(Map<String, Object> valueMap, Reference ref){
799
		return makeStandardMapper(valueMap, ref, null);
800
	}
801

    
802

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

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

    
848

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

    
865
		result &= ImportHelper.addMultipleValues(sourceValues, cdmBase, destinationAttribute, classes, NO_OVERWRITE, OBLIGATORY);
866
		return result;
867
	}
868

    
869

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

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

    
890
		return result;
891
	}
892

    
893

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

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

    
927
	@Override
928
	protected boolean isIgnore(BerlinModelImportState state){
929
		return (state.getConfig().getDoReferences() == IImportConfigurator.DO_REFERENCES.NONE);
930
	}
931

    
932

    
933

    
934

    
935
}
(13-13/21)