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<BerlinModelImportState> partitioner =
207
			        ResultSetPartitioner.NewInstance(source, strIdQueryFirstPath, strRecordQuery, recordsPerTransaction);
208
			while (partitioner.nextPartition()){
209
				partitioner.doPartition(this, state);
210
			}
211
			logger.info("end make references without in-references ... " + getSuccessString(success));
212
			state.setReferenceSecondPath(true);
213

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

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

    
224
//			}
225

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

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

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

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

    
250
		BerlinModelImportConfigurator config = state.getConfig();
251

    
252
		try {
253

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

    
257
				ResultSet rs = partitioner.getResultSet();
258

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

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

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

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

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

    
279
//			}//end resultSetList
280

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

    
289

    
290

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

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

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

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

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

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

    
316
					if (inRefFk != null){
317

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

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

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

    
333
				} // end resultSet
334

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

    
339
//			}//end resultSetList
340

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

    
349

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

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

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

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

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

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

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

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

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

    
405

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

    
425
	    boolean success = true;
426

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

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

    
435

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

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

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

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

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

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

    
487

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

    
496

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

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

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

    
533
		Reference sourceReference = state.getTransactionalSourceReference();
534

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

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

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

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

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

    
564
		return true;
565
	}
566

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

    
578
	}
579

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

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

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

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

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

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

    
643

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

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

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

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

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

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

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

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

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

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

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

    
725
		makeStandardMapper(valueMap, book, omitAttributes);
726

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

    
747
	}
748

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

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

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

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

    
789

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

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

    
803

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

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

    
849

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

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

    
870

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

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

    
891
		return result;
892
	}
893

    
894

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

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

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

    
933

    
934

    
935

    
936
}
(13-13/21)