Project

General

Profile

Download (32.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.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 Logger logger = Logger.getLogger(BerlinModelReferenceImport.class);
80

    
81
	public static final String REFERENCE_NAMESPACE = "Reference";
82

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

    
88

    
89
	private final int modCount = 1000;
90
	private static final String pluralString = "references";
91
	private static final String dbTableName = "reference";
92

    
93

    
94
	public BerlinModelReferenceImport(){
95
		super(dbTableName, pluralString);
96
	}
97

    
98
	protected void initializeMappers(BerlinModelImportState state){
99
		for (CdmAttributeMapperBase mapper: classMappers){
100
			if (mapper instanceof DbSingleAttributeImportMapperBase){
101
				DbSingleAttributeImportMapperBase singleMapper = (DbSingleAttributeImportMapperBase)mapper;
102
				singleMapper.initialize(state, Reference.class);
103
			}
104
		}
105
		return;
106
	}
107

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

    
126

    
127
	protected static String[] operationalAttributes = new String[]{
128
		"refId", "refCache", "nomRefCache", "preliminaryFlag", "inRefFk", "title", "nomTitleAbbrev",
129
		"refAuthorString", "nomAuthorTeamFk",
130
		"refCategoryFk", "thesisFlag", "informalRefCategory", "idInSource"
131
	};
132

    
133
	protected static String[] createdAndNotesAttributes = new String[]{
134
			"created_When", "updated_When", "created_Who", "updated_Who", "notes"
135
	};
136

    
137
	protected static String[] unclearMappers = new String[]{
138
			/*"isPaper",*/ "exportDate",
139
	};
140

    
141
	//TODO isPaper
142
	//
143

    
144

    
145

    
146
	//type to count the references nomReferences that have been created and saved
147
	private class RefCounter{
148
		RefCounter() {refCount = 0;};
149
		int refCount;
150

    
151
		@Override
152
        public String toString(){return String.valueOf(refCount) ;};
153
	}
154

    
155
	@Override
156
	protected String getRecordQuery(BerlinModelImportConfigurator config) {
157
		return null;  //not needed
158
	}
159

    
160
	@Override
161
	protected void doInvoke(BerlinModelImportState state){
162
		logger.info("start make " + getPluralString() + " ...");
163

    
164
		boolean success = true;
165
		initializeMappers(state);
166
		BerlinModelImportConfigurator config = state.getConfig();
167
		Source source = config.getSource();
168

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

    
178
		String referenceTable = CdmUtils.Nz(state.getConfig().getReferenceIdTable());
179
		referenceTable = referenceTable.isEmpty() ? " Reference"  : referenceTable + " as Reference ";
180
		String strIdFrom = String.format(strFrom, referenceTable );
181

    
182
		String strSelectIdBase = strSelectId + strIdFrom;
183

    
184
		String referenceFilter = CdmUtils.Nz(state.getConfig().getReferenceIdTable());
185
		if (! referenceFilter.isEmpty()){
186
			referenceFilter = " AND " + referenceFilter + " ";
187
		}
188
		referenceFilter = "";  //don't use it for now
189

    
190
		String strIdQueryFirstPath = strSelectId + strIdFrom ;
191
		String strIdQuerySecondPath = strSelectId + strIdFrom + " AND (Reference.InRefFk is NOT NULL) ";
192

    
193
//		if (config.getDoReferences() == CONCEPT_REFERENCES){
194
//			strIdQueryNoInRef += " AND ( Reference.refId IN ( SELECT ptRefFk FROM PTaxon) ) " + referenceFilter;
195
//		}
196

    
197
		String strRecordQuery = strSelectFull + String.format(strFrom, " Reference ") + strWherePartitioned;
198

    
199
		int recordsPerTransaction = config.getRecordsPerTransaction();
200
		try{
201
			//firstPath
202
			ResultSetPartitioner partitioner = ResultSetPartitioner.NewInstance(source, strIdQueryFirstPath, strRecordQuery, recordsPerTransaction);
203
			while (partitioner.nextPartition()){
204
				partitioner.doPartition(this, state);
205
			}
206
			logger.info("end make references without in-references ... " + getSuccessString(success));
207
			state.setReferenceSecondPath(true);
208

    
209
//			if (config.getDoReferences() == ALL || config.getDoReferences() == NOMENCLATURAL){
210

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

    
219
//			}
220

    
221
		} catch (SQLException e) {
222
			logger.error("SQLException:" +  e);
223
			state.setUnsuccessfull();
224
			return;
225
		}
226
		logger.info("end make " + getPluralString() + " ... " + getSuccessString(success));
227
		if (! success){
228
			state.setUnsuccessfull();
229
		}
230
		return;
231
	}
232

    
233
	@Override
234
	public boolean doPartition(ResultSetPartitioner partitioner, BerlinModelImportState state) {
235
		if (state.isReferenceSecondPath()){
236
			return doPartitionSecondPath(partitioner, state);
237
		}
238
		boolean success = true;
239

    
240
		Map<Integer, Reference> refToSave = new HashMap<Integer, Reference>();
241

    
242
		Map<String, Reference> relatedReferences = partitioner.getObjectMap(REFERENCE_NAMESPACE);
243

    
244
		BerlinModelImportConfigurator config = state.getConfig();
245

    
246
		try {
247

    
248
				int i = 0;
249
				RefCounter refCounter  = new RefCounter();
250

    
251
				ResultSet rs = partitioner.getResultSet();
252

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

    
257
					success &= makeSingleReferenceRecord(rs, state, partitioner, refToSave, relatedReferences, refCounter);
258
				} // end resultSet
259

    
260
				//for the concept reference a fixed uuid may be needed -> change uuid
261
				Integer sourceSecId = (Integer)config.getSourceSecId();
262
				Reference sec = refToSave.get(sourceSecId);
263

    
264
				if (sec != null){
265
					sec.setUuid(config.getSecUuid());
266
					logger.info("SecUuid changed to: " + config.getSecUuid());
267
				}
268

    
269
				//save and store in map
270
				logger.info("Save references (" + refCounter.refCount + ")");
271
				getReferenceService().saveOrUpdate(refToSave.values());
272

    
273
//			}//end resultSetList
274

    
275
//			logger.info("end makeReferences ..." + getSuccessString(success));;
276
			return success;
277
		} catch (SQLException e) {
278
			logger.error("SQLException:" +  e);
279
			return false;
280
		}
281
	}
282

    
283

    
284

    
285
	/**
286
	 * Adds the inReference to the according references.
287
	 * @param partitioner
288
	 * @param state
289
	 * @return
290
	 */
291
	private boolean doPartitionSecondPath(ResultSetPartitioner partitioner, BerlinModelImportState state) {
292
		boolean success = true;
293

    
294
		Map<Integer, Reference> refToSave = new HashMap<Integer, Reference>();
295

    
296
		Map<String, Reference> relatedReferencesMap = partitioner.getObjectMap(REFERENCE_NAMESPACE);
297

    
298
		try {
299
				int i = 0;
300
				RefCounter refCounter  = new RefCounter();
301

    
302
				ResultSet rs = partitioner.getResultSet();
303
				//for each resultset
304
				while (rs.next()){
305
					if ((i++ % modCount) == 0 && i!= 1 ){ logger.info("References handled: " + (i-1) + " in round -" );}
306

    
307
					Integer refId = rs.getInt("refId");
308
					Integer inRefFk = rs.getInt("inRefFk");
309

    
310
					if (inRefFk != null){
311

    
312
						Reference thisRef = relatedReferencesMap.get(String.valueOf(refId));
313

    
314
						Reference inRef = relatedReferencesMap.get(String.valueOf(inRefFk));
315

    
316
						if (thisRef != null){
317
							if (inRef == null){
318
								logger.warn("No InRef found for nomRef: " + thisRef.getTitleCache() + "; RefId: " +  refId + "; inRefFK: " +  inRefFk);
319
							}
320
							thisRef.setInReference(inRef);
321
							refToSave.put(refId, thisRef);
322
							thisRef.setTitleCache(null);
323
							thisRef.getTitleCache();
324
						}
325
					}
326

    
327
				} // end resultSet
328

    
329
				//save and store in map
330
				logger.info("Save references (" + refCounter.refCount + ")");
331
				getReferenceService().saveOrUpdate(refToSave.values());
332

    
333
//			}//end resultSetList
334

    
335
//			logger.info("end makeReferences ..." + getSuccessString(success));;
336
			return success;
337
		} catch (SQLException e) {
338
			logger.error("SQLException:" +  e);
339
			return false;
340
		}
341
	}
342

    
343

    
344
	@Override
345
	public Map<Object, Map<String, ? extends CdmBase>> getRelatedObjectsForPartition(ResultSet rs, BerlinModelImportState state) {
346
		String nameSpace;
347
		Class<?> cdmClass;
348
		Set<String> idSet;
349

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

    
352
		try{
353
			Set<String> teamIdSet = new HashSet<String>();
354
			Set<String> referenceIdSet = new HashSet<String>();
355

    
356
			while (rs.next()){
357
				handleForeignKey(rs, teamIdSet, "NomAuthorTeamFk");
358
				handleForeignKey(rs, referenceIdSet, "InRefFk");
359
				//TODO only needed in second path but state not available here to check if state is second path
360
				handleForeignKey(rs, referenceIdSet, "refId");
361
			}
362

    
363
			//team map
364
			nameSpace = BerlinModelAuthorTeamImport.NAMESPACE;
365
			cdmClass = Team.class;
366
			idSet = teamIdSet;
367
			Map<String, Team> teamMap = (Map<String, Team>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
368
			result.put(nameSpace, teamMap);
369

    
370
			//reference map
371
			nameSpace = BerlinModelReferenceImport.REFERENCE_NAMESPACE;
372
			cdmClass = Reference.class;
373
			idSet = referenceIdSet;
374
			Map<String, Reference> referenceMap = (Map<String, Reference>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
375
			result.put(nameSpace, referenceMap);
376

    
377
		} catch (SQLException e) {
378
			throw new RuntimeException(e);
379
		}
380
		return result;
381
	}
382

    
383

    
384
	/**
385
	 * Handles a single reference record
386
	 * @param rs
387
	 * @param state
388
	 * @param biblioRefToSave
389
	 * @param nomRefToSave
390
	 * @param relatedBiblioReferences
391
	 * @param relatedNomReferences
392
	 * @param refCounter
393
	 * @return
394
	 */
395
	private boolean makeSingleReferenceRecord(
396
				ResultSet rs,
397
				BerlinModelImportState state,
398
				ResultSetPartitioner<BerlinModelImportState> partitioner,
399
				Map<Integer, Reference> refToSave,
400
				Map<String, Reference> relatedReferences,
401
				RefCounter refCounter){
402
		boolean success = true;
403

    
404
		Integer refId = null;
405
		try {
406
			Map<String, Object> valueMap = getValueMap(rs);
407

    
408
			Integer categoryFk = (Integer)valueMap.get("refCategoryFk".toLowerCase());
409
			refId = (Integer)valueMap.get("refId".toLowerCase());
410
			Boolean thesisFlag = (Boolean)valueMap.get("thesisFlag".toLowerCase());
411

    
412

    
413
			Reference referenceBase;
414
			logger.debug("RefCategoryFk: " + categoryFk);
415

    
416
			if (thesisFlag){
417
				referenceBase = makeThesis(valueMap);
418
			}else if (categoryFk == REF_JOURNAL){
419
				referenceBase = makeJournal(valueMap);
420
			}else if(categoryFk == REF_BOOK){
421
				referenceBase = makeBook(valueMap, refToSave, relatedReferences);
422
			}else if(categoryFk == REF_DATABASE){
423
				referenceBase = makeDatabase(valueMap);
424
			}else if(categoryFk == REF_INFORMAL){
425
				referenceBase = makeInformal(valueMap);
426
			}else if(categoryFk == REF_WEBSITE){
427
				referenceBase = makeWebSite(valueMap);
428
			}else if(categoryFk == REF_UNKNOWN){
429
				referenceBase = makeUnknown(valueMap);
430
			}else if(categoryFk == REF_PRINT_SERIES){
431
				referenceBase = makePrintSeries(valueMap);
432
			}else if(categoryFk == REF_CONFERENCE_PROCEEDINGS){
433
				referenceBase = makeProceedings(valueMap);
434
			}else if(categoryFk == REF_ARTICLE){
435
				referenceBase = makeArticle(valueMap, refToSave, relatedReferences);
436
			}else if(categoryFk == REF_JOURNAL_VOLUME){
437
				referenceBase = makeJournalVolume(valueMap);
438
			}else if(categoryFk == REF_PART_OF_OTHER_TITLE){
439
				referenceBase = makePartOfOtherTitle(valueMap, refToSave, relatedReferences);
440
			}else{
441
				logger.warn("Unknown categoryFk (" + categoryFk + "). Create 'Generic instead'");
442
				referenceBase = ReferenceFactory.newGeneric();
443
				success = false;
444
			}
445

    
446
			//refYear
447
			String refYear = (String)valueMap.get("refYear".toLowerCase());
448
			referenceBase.setDatePublished(ImportHelper.getDatePublished(refYear));
449

    
450
			//created, updated, notes
451
			doCreatedUpdatedNotes(state, referenceBase, rs);
452

    
453
			//idInSource
454
			String idInSource = (String)valueMap.get("IdInSource".toLowerCase());
455
			if (isNotBlank(idInSource)){
456
				IdentifiableSource source = IdentifiableSource.NewDataImportInstance(idInSource);
457
				source.setIdNamespace("import to Berlin Model");
458
				referenceBase.addSource(source);
459
			}
460

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

    
464

    
465
		} catch (Exception e) {
466
			logger.warn("Reference with BM refId '" + CdmUtils.Nz(refId) +  "' threw Exception and could not be saved");
467
			e.printStackTrace();
468
			success = false;
469
		}
470
		return success;
471
	}
472

    
473

    
474
	/**
475
	 * Creates and saves a nom. reference and a biblio. reference after checking necessity
476
	 * @param rs
477
	 * @param refId
478
	 * @param ref
479
	 * @param refCounter
480
	 * @param biblioRefToSave
481
	 * @param nomRefToSave
482
	 * @param teamMap
483
	 * @param stores
484
	 * @return
485
	 * @throws SQLException
486
	 */
487
	private boolean makeNomAndBiblioReference(
488
				ResultSet rs,
489
				BerlinModelImportState state,
490
				ResultSetPartitioner partitioner,
491
				int refId,
492
				Reference ref,
493
				RefCounter refCounter,
494
				Map<Integer, Reference> refToSave
495
				) throws SQLException{
496

    
497
		Map<String, Team> teamMap = partitioner.getObjectMap(BerlinModelAuthorTeamImport.NAMESPACE);
498

    
499
		String refCache = rs.getString("refCache");
500
		String nomRefCache = rs.getString("nomRefCache");
501
		String title = rs.getString("title");
502
		String nomTitleAbbrev = rs.getString("nomTitleAbbrev");
503
		boolean isPreliminary = rs.getBoolean("PreliminaryFlag");
504
		String refAuthorString = rs.getString("refAuthorString");
505
		Integer nomAuthorTeamFk = rs.getInt("NomAuthorTeamFk");
506
		String strNomAuthorTeamFk = String.valueOf(nomAuthorTeamFk);
507
		TeamOrPersonBase<?> nomAuthor = teamMap.get(strNomAuthorTeamFk);
508

    
509
		Reference sourceReference = state.getTransactionalSourceReference();
510

    
511
		//preliminary
512
		if (isPreliminary){
513
			ref.setAbbrevTitleCache(nomRefCache, true);
514
			ref.setTitleCache(refCache, true);
515
		}
516

    
517
		//title/abbrevTitle
518
		if (isNotBlank(nomTitleAbbrev)){
519
			ref.setAbbrevTitle(nomTitleAbbrev);
520
		}
521
		if (isNotBlank(title)){
522
			ref.setTitle(title);
523
		}
524

    
525
		//author
526
		TeamOrPersonBase<?> author = getAuthorship(refAuthorString , nomAuthor);
527
		ref.setAuthorship(author);
528

    
529
		//save
530
		if (! refToSave.containsKey(refId)){
531
			refToSave.put(refId, ref);
532
		}else{
533
			logger.warn("Duplicate refId in Berlin Model database. Second reference was not imported !!");
534
		}
535
		refCounter.refCount++;
536

    
537
		//refId
538
		ImportHelper.setOriginalSource(ref, sourceReference, refId, REFERENCE_NAMESPACE);
539

    
540
		return true;
541
	}
542

    
543
	/**
544
	 * Copies the created and updated information from the nomReference to the cloned bibliographic reference
545
	 * @param referenceBase
546
	 * @param nomReference
547
	 */
548
	private void copyCreatedUpdated(Reference biblioReference, Reference nomReference) {
549
		biblioReference.setCreatedBy(nomReference.getCreatedBy());
550
		biblioReference.setCreated(nomReference.getCreated());
551
		biblioReference.setUpdatedBy(nomReference.getUpdatedBy());
552
		biblioReference.setUpdated(nomReference.getUpdated());
553

    
554
	}
555

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

    
558
		IArticle article = ReferenceFactory.newArticle();
559
		Object inRefFk = valueMap.get("inRefFk".toLowerCase());
560
		Integer inRefCategoryFk = (Integer)valueMap.get("inRefCategoryFk".toLowerCase());
561
		Integer refId = (Integer)valueMap.get("refId".toLowerCase());
562

    
563
		if (inRefFk != null){
564
			if (inRefCategoryFk != REF_JOURNAL){
565
				logger.warn("Wrong inrefCategory for Article (refID = " + refId +"). Type must be 'Journal' but was not (RefCategoryFk=" + inRefCategoryFk + "))." +
566
					" InReference was added anyway! ");
567
			}
568
		}else{
569
			logger.warn ("Article has no inreference: " + refId);
570
		}
571
		makeStandardMapper(valueMap, (Reference)article); //url, pages, series, volume
572
		return (Reference)article;
573
	}
574

    
575
	private Reference makePartOfOtherTitle (Map<String, Object> valueMap,
576
			Map<Integer, Reference> refToSave, Map<String, Reference> relatedReferences){
577

    
578
		Reference result;
579
		Object inRefFk = valueMap.get("inRefFk".toLowerCase());
580
		Integer inRefCategoryFk = (Integer)valueMap.get("inRefCategoryFk".toLowerCase());
581
		Integer refId = (Integer)valueMap.get("refId".toLowerCase());
582

    
583
		if (inRefCategoryFk == null){
584
			//null -> error
585
			logger.warn("Part-Of-Other-Title has no inRefCategoryFk! RefId = " + refId + ". ReferenceType set to Generic.");
586
			result = makeUnknown(valueMap);
587
		}else if (inRefFk == null){
588
			//TODO is this correct ??
589
			logger.warn("Part-Of-Other-Title has no in reference: " + refId);
590
			result = makeUnknown(valueMap);
591
		}else if (inRefCategoryFk == REF_BOOK){
592
			//BookSection
593
			IBookSection bookSection = ReferenceFactory.newBookSection();
594
			result = (Reference)bookSection;
595
		}else if (inRefCategoryFk == REF_ARTICLE){
596
			//Article
597
			logger.info("Reference (refId = " + refId + ") of type 'part_of_other_title' is part of 'article'." +
598
					" We use the section reference type for such in references now.") ;
599
			result = ReferenceFactory.newSection();
600
		}else if (inRefCategoryFk == REF_JOURNAL){
601
			//TODO
602
			logger.warn("Reference (refId = " + refId + ") of type 'part_of_other_title' has inReference of type 'journal'." +
603
					" This is not allowed! Generic reference created instead") ;
604
			result = ReferenceFactory.newGeneric();
605
			result.addMarker(Marker.NewInstance(MarkerType.TO_BE_CHECKED(), true));
606
		}else if (inRefCategoryFk == REF_PART_OF_OTHER_TITLE){
607
			logger.info("Reference (refId = " + refId + ") of type 'part_of_other_title' has inReference 'part of other title'." +
608
					" 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") ;
609
			result = ReferenceFactory.newSection();
610
		}else{
611
			logger.warn("InReference type (catFk = " + inRefCategoryFk + ") of part-of-reference not recognized for refId " + refId + "." +
612
				" Create 'Generic' reference instead");
613
			result = ReferenceFactory.newGeneric();
614
		}
615
		makeStandardMapper(valueMap, result); //url, pages
616
		return result;
617
	}
618

    
619

    
620
	/**
621
	 * @param inRefFkInt
622
	 * @param biblioRefToSave
623
	 * @param nomRefToSave
624
	 * @param relatedBiblioReferences
625
	 * @param relatedNomReferences
626
	 * @return
627
	 */
628
	private boolean existsInMapOrToSave(Integer inRefFkInt, Map<Integer, Reference> refToSave, Map<String, Reference> relatedReferences) {
629
		boolean result = false;
630
		if (inRefFkInt == null){
631
			return false;
632
		}
633
		result |= refToSave.containsKey(inRefFkInt);
634
		result |= relatedReferences.containsKey(String.valueOf(inRefFkInt));
635
		return result;
636
	}
637

    
638
	private Reference makeWebSite(Map<String, Object> valueMap){
639
		if (logger.isDebugEnabled()){logger.debug("RefType 'Website'");}
640
		Reference webPage = ReferenceFactory.newWebPage();
641
		makeStandardMapper(valueMap, webPage); //placePublished, publisher
642
		return webPage;
643
	}
644

    
645
	private Reference makeUnknown(Map<String, Object> valueMap){
646
		if (logger.isDebugEnabled()){logger.debug("RefType 'Unknown'");}
647
		Reference generic = ReferenceFactory.newGeneric();
648
//		generic.setSeries(series);
649
		makeStandardMapper(valueMap, generic); //pages, placePublished, publisher, series, volume
650
		return generic;
651
	}
652

    
653
	private Reference makeInformal(Map<String, Object> valueMap){
654
		if (logger.isDebugEnabled()){logger.debug("RefType 'Informal'");}
655
		Reference generic = ReferenceFactory.newGeneric();
656
//		informal.setSeries(series);
657
		makeStandardMapper(valueMap, generic);//editor, pages, placePublished, publisher, series, volume
658
		String informal = (String)valueMap.get("InformalRefCategory".toLowerCase());
659
		if (isNotBlank(informal) ){
660
			generic.addExtension(informal, ExtensionType.INFORMAL_CATEGORY());
661
		}
662
		return generic;
663
	}
664

    
665
	private Reference makeDatabase(Map<String, Object> valueMap){
666
		if (logger.isDebugEnabled()){logger.debug("RefType 'Database'");}
667
		Reference database =  ReferenceFactory.newDatabase();
668
		makeStandardMapper(valueMap, database); //?
669
		return database;
670
	}
671

    
672
	private Reference makeJournal(Map<String, Object> valueMap){
673
		if (logger.isDebugEnabled()){logger.debug("RefType 'Journal'");}
674
		Reference journal = ReferenceFactory.newJournal();
675

    
676
		Set<String> omitAttributes = new HashSet<String>();
677
		String series = "series";
678
//		omitAttributes.add(series);
679

    
680
		makeStandardMapper(valueMap, journal, omitAttributes); //issn,placePublished,publisher
681
//		if (valueMap.get(series) != null){
682
//			logger.warn("Series not yet implemented for journal!");
683
//		}
684
		return journal;
685
	}
686

    
687
	private Reference makeBook(
688
				Map<String, Object> valueMap,
689
				Map<Integer, Reference> refToSave,
690
				Map<String, Reference> relatedReferences){
691
		if (logger.isDebugEnabled()){logger.debug("RefType 'Book'");}
692
		Reference book = ReferenceFactory.newBook();
693
		Integer refId = (Integer)valueMap.get("refId".toLowerCase());
694

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

    
697
		Set<String> omitAttributes = new HashSet<String>();
698
		String attrSeries = "series";
699
//		omitAttributes.add(attrSeries);
700

    
701
		makeStandardMapper(valueMap, book, omitAttributes);
702

    
703
		//Series (as String)
704
		IPrintSeries printSeries = null;
705
		if (valueMap.get(attrSeries) != null){
706
			String series = (String)valueMap.get("title".toLowerCase());
707
			if (series == null){
708
				String nomTitle = (String)valueMap.get("nomTitleAbbrev".toLowerCase());
709
				series = nomTitle;
710
			}
711
			printSeries = ReferenceFactory.newPrintSeries(series);
712
			logger.info("Implementation of printSeries is preliminary");
713
		}
714
		//Series (as Reference)
715
		if (book.getInSeries() != null && printSeries != null){
716
			logger.warn("Book has series string and inSeries reference. Can not take both. Series string neglected");
717
		}else{
718
			book.setInSeries(printSeries);
719
		}
720
		book.setEditor(null);
721
		return book;
722

    
723
	}
724

    
725
	/**
726
	 * Returns the requested object if it exists in one of both maps. Prefers the refToSaveMap in ambigious cases.
727
	 * @param inRefFkInt
728
	 * @param nomRefToSave
729
	 * @param relatedNomReferences
730
	 * @return
731
	 */
732
	private Reference getReferenceFromMaps(
733
			int inRefFkInt,
734
			Map<Integer, Reference> refToSaveMap,
735
			Map<String, Reference> relatedRefMap) {
736
		Reference result = null;
737
		result = refToSaveMap.get(inRefFkInt);
738
		if (result == null){
739
			result = relatedRefMap.get(String.valueOf(inRefFkInt));
740
		}
741
		return result;
742
	}
743

    
744
	private Reference makePrintSeries(Map<String, Object> valueMap){
745
		if (logger.isDebugEnabled()){logger.debug("RefType 'PrintSeries'");}
746
		Reference printSeries = ReferenceFactory.newPrintSeries();
747
		makeStandardMapper(valueMap, printSeries, null);
748
		return printSeries;
749
	}
750

    
751
	private Reference makeProceedings(Map<String, Object> valueMap){
752
		if (logger.isDebugEnabled()){logger.debug("RefType 'Proceedings'");}
753
		Reference proceedings = ReferenceFactory.newProceedings();
754
		makeStandardMapper(valueMap, proceedings, null);
755
		return proceedings;
756
	}
757

    
758
	private Reference makeThesis(Map<String, Object> valueMap){
759
		if (logger.isDebugEnabled()){logger.debug("RefType 'Thesis'");}
760
		Reference thesis = ReferenceFactory.newThesis();
761
		makeStandardMapper(valueMap, thesis, null);
762
		return thesis;
763
	}
764

    
765

    
766
	private Reference makeJournalVolume(Map<String, Object> valueMap){
767
		if (logger.isDebugEnabled()){logger.debug("RefType 'JournalVolume'");}
768
		//Proceedings proceedings = Proceedings.NewInstance();
769
		Reference journalVolume = ReferenceFactory.newGeneric();
770
		makeStandardMapper(valueMap, journalVolume, null);
771
		logger.warn("Journal volumes not yet implemented. Generic created instead but with errors");
772
		return journalVolume;
773
	}
774

    
775
	private boolean makeStandardMapper(Map<String, Object> valueMap, Reference ref){
776
		return makeStandardMapper(valueMap, ref, null);
777
	}
778

    
779

    
780
	private boolean makeStandardMapper(Map<String, Object> valueMap, CdmBase cdmBase, Set<String> omitAttributes){
781
		boolean result = true;
782
		for (CdmAttributeMapperBase mapper : classMappers){
783
			if (mapper instanceof CdmSingleAttributeMapperBase){
784
				result &= makeStandardSingleMapper(valueMap, cdmBase, (CdmSingleAttributeMapperBase)mapper, omitAttributes);
785
			}else if (mapper instanceof CdmOneToManyMapper){
786
				result &= makeMultipleValueAddMapper(valueMap, cdmBase, (CdmOneToManyMapper)mapper, omitAttributes);
787
			}else{
788
				logger.error("Unknown mapper type");
789
				result = false;
790
			}
791
		}
792
		return result;
793
	}
794

    
795
	private boolean makeStandardSingleMapper(Map<String, Object> valueMap, CdmBase cdmBase, CdmSingleAttributeMapperBase mapper, Set<String> omitAttributes){
796
		boolean result = true;
797
		if (omitAttributes == null){
798
			omitAttributes = new HashSet<String>();
799
		}
800
		if (mapper instanceof DbImportExtensionMapper){
801
			result &= ((DbImportExtensionMapper)mapper).invoke(valueMap, cdmBase);
802
		}else if (mapper instanceof DbImportMarkerMapper){
803
			result &= ((DbImportMarkerMapper)mapper).invoke(valueMap, cdmBase);
804
		}else{
805
			String sourceAttribute = mapper.getSourceAttributeList().get(0).toLowerCase();
806
			Object value = valueMap.get(sourceAttribute);
807
			if (mapper instanceof CdmUriMapper && value != null){
808
				try {
809
					value = new URI (value.toString());
810
				} catch (URISyntaxException e) {
811
					logger.error("URI syntax exception: " + value.toString());
812
					value = null;
813
				}
814
			}
815
			if (value != null){
816
				String destinationAttribute = mapper.getDestinationAttribute();
817
				if (! omitAttributes.contains(destinationAttribute)){
818
					result &= ImportHelper.addValue(value, cdmBase, destinationAttribute, mapper.getTypeClass(), OVERWRITE, OBLIGATORY);
819
				}
820
			}
821
		}
822
		return result;
823
	}
824

    
825

    
826
	private boolean makeMultipleValueAddMapper(Map<String, Object> valueMap, CdmBase cdmBase, CdmOneToManyMapper<CdmBase, CdmBase, CdmSingleAttributeMapperBase> mapper, Set<String> omitAttributes){
827
		if (omitAttributes == null){
828
			omitAttributes = new HashSet<String>();
829
		}
830
		boolean result = true;
831
		String destinationAttribute = mapper.getSingleAttributeName();
832
		List<Object> sourceValues = new ArrayList<Object>();
833
		List<Class> classes = new ArrayList<Class>();
834
		for (CdmSingleAttributeMapperBase singleMapper : mapper.getSingleMappers()){
835
			String sourceAttribute = singleMapper.getSourceAttribute();
836
			Object value = valueMap.get(sourceAttribute);
837
			sourceValues.add(value);
838
			Class<?> clazz = singleMapper.getTypeClass();
839
			classes.add(clazz);
840
		}
841

    
842
		result &= ImportHelper.addMultipleValues(sourceValues, cdmBase, destinationAttribute, classes, NO_OVERWRITE, OBLIGATORY);
843
		return result;
844
	}
845

    
846

    
847
	private static TeamOrPersonBase<?> getAuthorship(String authorString, TeamOrPersonBase<?> nomAuthor){
848
		TeamOrPersonBase<?> result;
849
		if (nomAuthor != null){
850
			result = nomAuthor;
851
		} else if (StringUtils.isNotBlank(authorString)){
852
			//FIXME check for existing team / persons
853
			TeamOrPersonBase<?> team = Team.NewInstance();
854
			team.setNomenclaturalTitle(authorString);
855
			team.setTitleCache(authorString, true);
856
			team.setNomenclaturalTitle(authorString);
857
			result = team;
858
		}else{
859
			result = null;
860
		}
861

    
862
		return result;
863
	}
864

    
865

    
866
	/**
867
	 * @param lowerCase
868
	 * @param config
869
	 * @return
870
	 */
871
	public Set<String> getObligatoryAttributes(boolean lowerCase, BerlinModelImportConfigurator config){
872
		Set<String> result = new HashSet<String>();
873
		Class<ICdmImport>[] ioClassList = config.getIoClassList();
874
		logger.warn("getObligatoryAttributes has been commented because it still needs to be adapted to the new package structure");
875
		result.addAll(Arrays.asList(unclearMappers));
876
		result.addAll(Arrays.asList(createdAndNotesAttributes));
877
		result.addAll(Arrays.asList(operationalAttributes));
878
		CdmIoMapping mapping = new CdmIoMapping();
879
		for (CdmAttributeMapperBase mapper : classMappers){
880
			mapping.addMapper(mapper);
881
		}
882
		result.addAll(mapping.getSourceAttributes());
883
		if (lowerCase){
884
			Set<String> lowerCaseResult = new HashSet<String>();
885
			for (String str : result){
886
				if (str != null){lowerCaseResult.add(str.toLowerCase());}
887
			}
888
			result = lowerCaseResult;
889
		}
890
		return result;
891
	}
892

    
893
	@Override
894
	protected boolean doCheck(BerlinModelImportState state){
895
		BerlinModelReferenceImportValidator validator = new BerlinModelReferenceImportValidator();
896
		return validator.validate(state, this);
897
	}
898

    
899
	@Override
900
	protected boolean isIgnore(BerlinModelImportState state){
901
		return (state.getConfig().getDoReferences() == IImportConfigurator.DO_REFERENCES.NONE);
902
	}
903

    
904

    
905

    
906

    
907
}
(13-13/21)