Project

General

Profile

Download (33.6 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.ICdmIO;
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 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
		public String toString(){return String.valueOf(refCount) ;};
152
	}
153

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

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

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

    
168
		String strSelectId = " SELECT Reference.RefId as refId ";
169
		String strSelectFull = 
170
			" SELECT Reference.* ,InReference.RefCategoryFk as InRefCategoryFk, RefSource.RefSource " ;
171
		String strFrom =  " FROM %s  " + 
172
		    	" LEFT OUTER JOIN Reference as InReference ON InReference.refId = Reference.inRefFk " +
173
				" LEFT OUTER JOIN RefSource ON Reference.RefSourceFk = RefSource.RefSourceId " +
174
		    	" WHERE (1=1) ";
175
		String strWherePartitioned = " AND (Reference.refId IN ("+ ID_LIST_TOKEN + ") ) "; 
176
		
177
		String referenceTable = CdmUtils.Nz(state.getConfig().getReferenceIdTable());
178
		referenceTable = referenceTable.isEmpty() ? " Reference"  : referenceTable + " as Reference ";
179
		String strIdFrom = String.format(strFrom, referenceTable );
180
		
181
		String strSelectIdBase = strSelectId + strIdFrom;
182
		
183
		String referenceFilter = CdmUtils.Nz(state.getConfig().getReferenceIdTable());
184
		if (! referenceFilter.isEmpty()){
185
			referenceFilter = " AND " + referenceFilter + " ";
186
		}
187
		referenceFilter = "";  //don't use it for now
188
		
189
		String strIdQueryFirstPath = strSelectId + strIdFrom ;
190
		String strIdQuerySecondPath = strSelectId + strIdFrom + " AND (Reference.InRefFk is NOT NULL) ";
191
		
192
//		if (config.getDoReferences() == CONCEPT_REFERENCES){
193
//			strIdQueryNoInRef += " AND ( Reference.refId IN ( SELECT ptRefFk FROM PTaxon) ) " + referenceFilter;
194
//		}
195

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

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

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

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

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

    
239
		Map<Integer, Reference> refToSave = new HashMap<Integer, Reference>();
240
		
241
		Map<String, Reference> relatedReferences = partitioner.getObjectMap(REFERENCE_NAMESPACE);
242
		
243
		BerlinModelImportConfigurator config = state.getConfig();
244
		
245
		try {
246

    
247
				int i = 0;
248
				RefCounter refCounter  = new RefCounter();
249
				
250
				ResultSet rs = partitioner.getResultSet();
251

    
252
				//for each resultset
253
				while (rs.next()){
254
					if ((i++ % modCount) == 0 && i!= 1 ){ logger.info("References handled: " + (i-1) + " in round -" );}
255
				
256
					success &= makeSingleReferenceRecord(rs, state, partitioner, refToSave, relatedReferences, refCounter);
257
				} // end resultSet
258
								
259
				//for the concept reference a fixed uuid may be needed -> change uuid
260
				Integer sourceSecId = (Integer)config.getSourceSecId();
261
				Reference<?> sec = refToSave.get(sourceSecId);
262

    
263
				if (sec != null){
264
					sec.setUuid(config.getSecUuid());
265
					logger.info("SecUuid changed to: " + config.getSecUuid());
266
				}
267
				
268
				//save and store in map
269
				logger.info("Save references (" + refCounter.refCount + ")");
270
				getReferenceService().saveOrUpdate(refToSave.values());
271

    
272
//			}//end resultSetList	
273

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

    
282

    
283

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

    
293
		Map<Integer, Reference> refToSave = new HashMap<Integer, Reference>();
294
		
295
		Map<String, Reference> relatedReferencesMap = partitioner.getObjectMap(REFERENCE_NAMESPACE);
296
		
297
		try {
298
				int i = 0;
299
				RefCounter refCounter  = new RefCounter();
300
			
301
				ResultSet rs = partitioner.getResultSet();
302
				//for each resultset
303
				while (rs.next()){
304
					if ((i++ % modCount) == 0 && i!= 1 ){ logger.info("References handled: " + (i-1) + " in round -" );}
305
				
306
					Integer refId = rs.getInt("refId");
307
					Integer inRefFk = rs.getInt("inRefFk");
308
					
309
					if (inRefFk != null){
310
						
311
						Reference<?> thisRef = relatedReferencesMap.get(String.valueOf(refId));
312
						
313
						Reference<?> inRef = relatedReferencesMap.get(String.valueOf(inRefFk));
314
						
315
						if (thisRef != null){
316
							if (inRef == null){
317
								logger.warn("No InRef found for nomRef: " + thisRef.getTitleCache() + "; RefId: " +  refId + "; inRefFK: " +  inRefFk);
318
							}
319
							thisRef.setInReference(inRef);
320
							refToSave.put(refId, thisRef);
321
							thisRef.setTitleCache(null);
322
							thisRef.getTitleCache();
323
						}
324
					}
325
					
326
				} // end resultSet
327

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

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

    
342

    
343
	@Override
344
	public Map<Object, Map<String, ? extends CdmBase>> getRelatedObjectsForPartition(ResultSet rs, BerlinModelImportState state) {
345
		String nameSpace;
346
		Class<?> cdmClass;
347
		Set<String> idSet;
348
		
349
		Map<Object, Map<String, ? extends CdmBase>> result = new HashMap<Object, Map<String, ? extends CdmBase>>();
350
		
351
		try{
352
			Set<String> teamIdSet = new HashSet<String>();
353
			Set<String> referenceIdSet = new HashSet<String>();
354
			
355
			while (rs.next()){
356
				handleForeignKey(rs, teamIdSet, "NomAuthorTeamFk");
357
				handleForeignKey(rs, referenceIdSet, "InRefFk");
358
				//TODO only needed in second path but state not available here to check if state is second path
359
				handleForeignKey(rs, referenceIdSet, "refId");
360
			}
361
			
362
			//team map
363
			nameSpace = BerlinModelAuthorTeamImport.NAMESPACE;
364
			cdmClass = Team.class;
365
			idSet = teamIdSet;
366
			Map<String, Team> teamMap = (Map<String, Team>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
367
			result.put(nameSpace, teamMap);
368

    
369
			//reference map
370
			nameSpace = BerlinModelReferenceImport.REFERENCE_NAMESPACE;
371
			cdmClass = Reference.class;
372
			idSet = referenceIdSet;
373
			Map<String, Reference> referenceMap = (Map<String, Reference>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
374
			result.put(nameSpace, referenceMap);
375
			
376
		} catch (SQLException e) {
377
			throw new RuntimeException(e);
378
		}
379
		return result;
380
	}
381
	
382
	
383
	/**
384
	 * Handles a single reference record
385
	 * @param rs
386
	 * @param state
387
	 * @param biblioRefToSave
388
	 * @param nomRefToSave
389
	 * @param relatedBiblioReferences
390
	 * @param relatedNomReferences
391
	 * @param refCounter
392
	 * @return
393
	 */
394
	private boolean makeSingleReferenceRecord(
395
				ResultSet rs, 
396
				BerlinModelImportState state,
397
				ResultSetPartitioner<BerlinModelImportState> partitioner,
398
				Map<Integer, Reference> refToSave, 
399
				Map<String, Reference> relatedReferences, 
400
				RefCounter refCounter){
401
		boolean success = true;
402

    
403
		Integer refId = null;
404
		try {
405
			Map<String, Object> valueMap = getValueMap(rs);
406
			
407
			Integer categoryFk = (Integer)valueMap.get("refCategoryFk".toLowerCase());
408
			refId = (Integer)valueMap.get("refId".toLowerCase());
409
			Boolean thesisFlag = (Boolean)valueMap.get("thesisFlag".toLowerCase());
410
			
411
			
412
			Reference<?> referenceBase;
413
			logger.debug("RefCategoryFk: " + categoryFk);
414
			
415
			if (thesisFlag){
416
				referenceBase = makeThesis(valueMap);
417
			}else if (categoryFk == REF_JOURNAL){
418
				referenceBase = makeJournal(valueMap);
419
			}else if(categoryFk == REF_BOOK){
420
				referenceBase = makeBook(valueMap, refToSave, relatedReferences);
421
			}else if(categoryFk == REF_DATABASE){
422
				referenceBase = makeDatabase(valueMap);
423
			}else if(categoryFk == REF_INFORMAL){
424
				referenceBase = makeInformal(valueMap);
425
			}else if(categoryFk == REF_WEBSITE){
426
				referenceBase = makeWebSite(valueMap);
427
			}else if(categoryFk == REF_UNKNOWN){
428
				referenceBase = makeUnknown(valueMap);
429
			}else if(categoryFk == REF_PRINT_SERIES){
430
				referenceBase = makePrintSeries(valueMap);
431
			}else if(categoryFk == REF_CONFERENCE_PROCEEDINGS){
432
				referenceBase = makeProceedings(valueMap);
433
			}else if(categoryFk == REF_ARTICLE){
434
				referenceBase = makeArticle(valueMap, refToSave, relatedReferences);
435
			}else if(categoryFk == REF_JOURNAL_VOLUME){
436
				referenceBase = makeJournalVolume(valueMap);
437
			}else if(categoryFk == REF_PART_OF_OTHER_TITLE){
438
				referenceBase = makePartOfOtherTitle(valueMap, refToSave, relatedReferences);
439
			}else{
440
				logger.warn("Unknown categoryFk (" + categoryFk + "). Create 'Generic instead'");
441
				referenceBase = ReferenceFactory.newGeneric();
442
				success = false;
443
			}
444
							
445
			//refYear
446
			String refYear = (String)valueMap.get("refYear".toLowerCase());
447
			referenceBase.setDatePublished(ImportHelper.getDatePublished(refYear)); 
448
			
449
			//created, updated, notes
450
			doCreatedUpdatedNotes(state, referenceBase, rs);						
451
			
452
			//idInSource
453
			String idInSource = (String)valueMap.get("IdInSource".toLowerCase());
454
			if (isNotBlank(idInSource)){
455
				IdentifiableSource source = IdentifiableSource.NewDataImportInstance(idInSource);
456
				source.setIdNamespace("import to Berlin Model");
457
				referenceBase.addSource(source);
458
			}
459
			
460
			//nom&BiblioReference  - must be last because a clone is created
461
			success &= makeNomAndBiblioReference(rs, state, partitioner, refId, referenceBase, refCounter, refToSave);
462

    
463

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

    
472
	
473
	/**
474
	 * Creates and saves a nom. reference and a biblio. reference after checking necessity
475
	 * @param rs
476
	 * @param refId
477
	 * @param ref
478
	 * @param refCounter
479
	 * @param biblioRefToSave
480
	 * @param nomRefToSave
481
	 * @param teamMap
482
	 * @param stores
483
	 * @return
484
	 * @throws SQLException
485
	 */
486
	private boolean makeNomAndBiblioReference(
487
				ResultSet rs, 
488
				BerlinModelImportState state,
489
				ResultSetPartitioner partitioner,
490
				int refId, 
491
				Reference<?> ref,  
492
				RefCounter refCounter, 
493
				Map<Integer, Reference> refToSave
494
				) throws SQLException{
495
		
496
		Map<String, Team> teamMap = partitioner.getObjectMap(BerlinModelAuthorTeamImport.NAMESPACE);
497
		
498
		String refCache = rs.getString("refCache");
499
		String nomRefCache = rs.getString("nomRefCache");
500
		String title = rs.getString("title");
501
		String nomTitleAbbrev = rs.getString("nomTitleAbbrev");
502
		boolean isPreliminary = rs.getBoolean("PreliminaryFlag");
503
		String refAuthorString = rs.getString("refAuthorString");
504
		Integer nomAuthorTeamFk = rs.getInt("NomAuthorTeamFk");
505
		String strNomAuthorTeamFk = String.valueOf(nomAuthorTeamFk);
506
		TeamOrPersonBase<?> nomAuthor = teamMap.get(strNomAuthorTeamFk);
507

    
508
		Reference<?> sourceReference = state.getTransactionalSourceReference();
509
		
510
		//preliminary
511
		if (isPreliminary){
512
			ref.setAbbrevTitleCache(nomRefCache, true);
513
			ref.setTitleCache(refCache, true);
514
		}
515

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

    
524
		//author
525
		TeamOrPersonBase<?> author = getAuthorTeam(refAuthorString , nomAuthor);
526
		ref.setAuthorTeam(author);
527
		
528
		//save
529
		if (! refToSave.containsKey(refId)){
530
			refToSave.put(refId, ref);
531
		}else{
532
			logger.warn("Duplicate refId in Berlin Model database. Second reference was not imported !!");
533
		}
534
		refCounter.refCount++;
535
		
536
		//refId
537
		ImportHelper.setOriginalSource(ref, sourceReference, refId, REFERENCE_NAMESPACE);
538
		
539
		return true;
540
	}
541
	
542
	/**
543
	 * Copies the created and updated information from the nomReference to the cloned bibliographic reference
544
	 * @param referenceBase
545
	 * @param nomReference
546
	 */
547
	private void copyCreatedUpdated(Reference<?> biblioReference, Reference nomReference) {
548
		biblioReference.setCreatedBy(nomReference.getCreatedBy());
549
		biblioReference.setCreated(nomReference.getCreated());
550
		biblioReference.setUpdatedBy(nomReference.getUpdatedBy());
551
		biblioReference.setUpdated(nomReference.getUpdated());
552
		
553
	}
554

    
555
	private Reference<?> makeArticle (Map<String, Object> valueMap, Map<Integer, Reference> refToSave, Map<String, Reference> relatedReferences){
556
		
557
		IArticle article = ReferenceFactory.newArticle();
558
		Object inRefFk = valueMap.get("inRefFk".toLowerCase());
559
		Integer inRefCategoryFk = (Integer)valueMap.get("inRefCategoryFk".toLowerCase());
560
		Integer refId = (Integer)valueMap.get("refId".toLowerCase());
561
		
562
		if (inRefFk != null){
563
			if (inRefCategoryFk != REF_JOURNAL){
564
				logger.warn("Wrong inrefCategory for Article (refID = " + refId +"). Type must be 'Journal' but was not (RefCategoryFk=" + inRefCategoryFk + "))." +
565
					" InReference was added anyway! ");
566
			}
567
		}else{
568
			logger.warn ("Article has no inreference: " + refId);
569
		}
570
		makeStandardMapper(valueMap, (Reference)article); //url, pages, series, volume
571
		return (Reference<?>)article;
572
	}
573
	
574
	private Reference<?> makePartOfOtherTitle (Map<String, Object> valueMap, 
575
			Map<Integer, Reference> refToSave, Map<String, Reference> relatedReferences){
576
		
577
		Reference<?> result;
578
		Object inRefFk = valueMap.get("inRefFk".toLowerCase());
579
		Integer inRefCategoryFk = (Integer)valueMap.get("inRefCategoryFk".toLowerCase());
580
		Integer refId = (Integer)valueMap.get("refId".toLowerCase());
581
		
582
		if (inRefCategoryFk == null){
583
			//null -> error
584
			logger.warn("Part-Of-Other-Title has no inRefCategoryFk! RefId = " + refId + ". ReferenceType set to Generic.");
585
			result = makeUnknown(valueMap);
586
		}else if (inRefFk == null){
587
			//TODO is this correct ??
588
			logger.warn("Part-Of-Other-Title has no in reference: " + refId);
589
			result = makeUnknown(valueMap);
590
		}else if (inRefCategoryFk == REF_BOOK){
591
			//BookSection
592
			IBookSection bookSection = ReferenceFactory.newBookSection();
593
			result = (Reference<?>)bookSection;
594
		}else if (inRefCategoryFk == REF_ARTICLE){
595
			//Article
596
			logger.info("Reference (refId = " + refId + ") of type 'part_of_other_title' is part of 'article'." +
597
					" We use the section reference type for such in references now.") ;
598
			result = ReferenceFactory.newSection();
599
		}else if (inRefCategoryFk == REF_JOURNAL){
600
			//TODO 
601
			logger.warn("Reference (refId = " + refId + ") of type 'part_of_other_title' has inReference of type 'journal'." +
602
					" This is not allowed! Generic reference created instead") ;
603
			result = ReferenceFactory.newGeneric();
604
			result.addMarker(Marker.NewInstance(MarkerType.TO_BE_CHECKED(), true));
605
		}else if (inRefCategoryFk == REF_PART_OF_OTHER_TITLE){
606
			logger.info("Reference (refId = " + refId + ") of type 'part_of_other_title' has inReference 'part of other title'." +
607
					" 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") ;
608
			result = ReferenceFactory.newSection();
609
		}else{
610
			logger.warn("InReference type (catFk = " + inRefCategoryFk + ") of part-of-reference not recognized for refId " + refId + "." +
611
				" Create 'Generic' reference instead");
612
			result = ReferenceFactory.newGeneric();
613
		}
614
		makeStandardMapper(valueMap, result); //url, pages
615
		return result;
616
	}
617
	
618

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

    
637
	private Reference<?> makeWebSite(Map<String, Object> valueMap){
638
		if (logger.isDebugEnabled()){logger.debug("RefType 'Website'");}
639
		Reference<?> webPage = ReferenceFactory.newWebPage();
640
		makeStandardMapper(valueMap, webPage); //placePublished, publisher
641
		return webPage;
642
	}
643
	
644
	private Reference<?> makeUnknown(Map<String, Object> valueMap){
645
		if (logger.isDebugEnabled()){logger.debug("RefType 'Unknown'");}
646
		Reference<?> generic = ReferenceFactory.newGeneric();
647
//		generic.setSeries(series);
648
		makeStandardMapper(valueMap, generic); //pages, placePublished, publisher, series, volume
649
		return generic;
650
	}
651

    
652
	private Reference<?> makeInformal(Map<String, Object> valueMap){
653
		if (logger.isDebugEnabled()){logger.debug("RefType 'Informal'");}
654
		Reference<?> generic = ReferenceFactory.newGeneric();
655
//		informal.setSeries(series);
656
		makeStandardMapper(valueMap, generic);//editor, pages, placePublished, publisher, series, volume
657
		String informal = (String)valueMap.get("InformalRefCategory".toLowerCase());
658
		if (isNotBlank(informal) ){
659
			generic.addExtension(informal, ExtensionType.INFORMAL_CATEGORY());
660
		}
661
		return generic;
662
	}
663
	
664
	private Reference<?> makeDatabase(Map<String, Object> valueMap){
665
		if (logger.isDebugEnabled()){logger.debug("RefType 'Database'");}
666
		Reference<?> database =  ReferenceFactory.newDatabase();
667
		makeStandardMapper(valueMap, database); //?
668
		return database;
669
	}
670
	
671
	private Reference<?> makeJournal(Map<String, Object> valueMap){
672
		if (logger.isDebugEnabled()){logger.debug("RefType 'Journal'");}
673
		Reference<?> journal = ReferenceFactory.newJournal();
674
		
675
		Set<String> omitAttributes = new HashSet<String>();
676
		String series = "series";
677
//		omitAttributes.add(series);
678
		
679
		makeStandardMapper(valueMap, journal, omitAttributes); //issn,placePublished,publisher
680
//		if (valueMap.get(series) != null){
681
//			logger.warn("Series not yet implemented for journal!");
682
//		}
683
		return journal;
684
	}
685
	
686
	private Reference<?> makeBook(
687
				Map<String, Object> valueMap, 
688
				Map<Integer, Reference> refToSave, 
689
				Map<String, Reference> relatedReferences){
690
		if (logger.isDebugEnabled()){logger.debug("RefType 'Book'");}
691
		Reference<?> book = ReferenceFactory.newBook();
692
		Integer refId = (Integer)valueMap.get("refId".toLowerCase());
693
		
694
		//Set bookAttributes = new String[]{"edition", "isbn", "pages","publicationTown","publisher","volume"};
695
		
696
		Set<String> omitAttributes = new HashSet<String>();
697
		String attrSeries = "series";
698
//		omitAttributes.add(attrSeries);
699
		
700
		makeStandardMapper(valueMap, book, omitAttributes);
701
		
702
		//Series (as String)
703
		IPrintSeries printSeries = null;
704
		if (valueMap.get(attrSeries) != null){
705
			String series = (String)valueMap.get("title".toLowerCase());
706
			if (series == null){
707
				String nomTitle = (String)valueMap.get("nomTitleAbbrev".toLowerCase());
708
				series = nomTitle;
709
			}
710
			printSeries = ReferenceFactory.newPrintSeries(series);
711
			logger.info("Implementation of printSeries is preliminary");
712
		}
713
		//Series (as Reference)
714
		if (book.getInSeries() != null && printSeries != null){
715
			logger.warn("Book has series string and inSeries reference. Can not take both. Series string neglected");
716
		}else{
717
			book.setInSeries(printSeries);
718
		}
719
		book.setEditor(null);
720
		return book;
721
		
722
	}
723
	
724
	/**
725
	 * Returns the requested object if it exists in one of both maps. Prefers the refToSaveMap in ambigious cases.
726
	 * @param inRefFkInt
727
	 * @param nomRefToSave
728
	 * @param relatedNomReferences
729
	 * @return
730
	 */
731
	private Reference<?> getReferenceFromMaps(
732
			int inRefFkInt,
733
			Map<Integer, Reference> refToSaveMap,
734
			Map<String, Reference> relatedRefMap) {
735
		Reference<?> result = null;
736
		result = refToSaveMap.get(inRefFkInt);
737
		if (result == null){
738
			result = relatedRefMap.get(String.valueOf(inRefFkInt));
739
		}
740
		return result;
741
	}
742

    
743
	private Reference<?> makePrintSeries(Map<String, Object> valueMap){
744
		if (logger.isDebugEnabled()){logger.debug("RefType 'PrintSeries'");}
745
		Reference<?> printSeries = ReferenceFactory.newPrintSeries();
746
		makeStandardMapper(valueMap, printSeries, null);
747
		return printSeries;
748
	}
749
	
750
	private Reference<?> makeProceedings(Map<String, Object> valueMap){
751
		if (logger.isDebugEnabled()){logger.debug("RefType 'Proceedings'");}
752
		Reference<?> proceedings = ReferenceFactory.newProceedings();
753
		makeStandardMapper(valueMap, proceedings, null);	
754
		return proceedings;
755
	}
756

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

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

    
778
	
779
	private boolean makeStandardMapper(Map<String, Object> valueMap, CdmBase cdmBase, Set<String> omitAttributes){
780
		boolean result = true;	
781
		for (CdmAttributeMapperBase mapper : classMappers){
782
			if (mapper instanceof CdmSingleAttributeMapperBase){
783
				result &= makeStandardSingleMapper(valueMap, cdmBase, (CdmSingleAttributeMapperBase)mapper, omitAttributes);
784
			}else if (mapper instanceof CdmOneToManyMapper){
785
				result &= makeMultipleValueAddMapper(valueMap, cdmBase, (CdmOneToManyMapper)mapper, omitAttributes);
786
			}else{
787
				logger.error("Unknown mapper type");
788
				result = false;
789
			}
790
		}
791
		return result;
792
	}
793
	
794
	private boolean makeStandardSingleMapper(Map<String, Object> valueMap, CdmBase cdmBase, CdmSingleAttributeMapperBase mapper, Set<String> omitAttributes){
795
		boolean result = true;
796
		if (omitAttributes == null){
797
			omitAttributes = new HashSet<String>();
798
		}
799
		if (mapper instanceof DbImportExtensionMapper){
800
			result &= ((DbImportExtensionMapper)mapper).invoke(valueMap, cdmBase);
801
		}else if (mapper instanceof DbImportMarkerMapper){
802
			result &= ((DbImportMarkerMapper)mapper).invoke(valueMap, cdmBase);
803
		}else{
804
			String sourceAttribute = mapper.getSourceAttributeList().get(0).toLowerCase();
805
			Object value = valueMap.get(sourceAttribute);
806
			if (mapper instanceof CdmUriMapper && value != null){
807
				try {
808
					value = new URI (value.toString());
809
				} catch (URISyntaxException e) {
810
					logger.error("URI syntax exception: " + value.toString());
811
					value = null;
812
				}
813
			}
814
			if (value != null){
815
				String destinationAttribute = mapper.getDestinationAttribute();
816
				if (! omitAttributes.contains(destinationAttribute)){
817
					result &= ImportHelper.addValue(value, cdmBase, destinationAttribute, mapper.getTypeClass(), OVERWRITE, OBLIGATORY);
818
				}
819
			}
820
		}
821
		return result;
822
	}
823

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

    
845
	
846
	private static TeamOrPersonBase<?> getAuthorTeam(String authorString, TeamOrPersonBase<?> nomAuthor){
847
		TeamOrPersonBase<?> result;
848
		if (nomAuthor != null){
849
			result = nomAuthor;
850
		} else if (StringUtils.isNotBlank(authorString)){
851
			//FIXME check for existing team / persons
852
			TeamOrPersonBase<?> team = Team.NewInstance();
853
			team.setNomenclaturalTitle(authorString);
854
			team.setTitleCache(authorString, true);
855
			team.setNomenclaturalTitle(authorString);
856
			result = team;
857
		}else{
858
			result = null;
859
		}
860
		
861
		return result;
862
	}
863
	
864
	
865
	/**
866
	 * @param lowerCase
867
	 * @param config
868
	 * @return
869
	 */
870
	public Set<String> getObligatoryAttributes(boolean lowerCase, BerlinModelImportConfigurator config){
871
		Set<String> result = new HashSet<String>();
872
		Class<ICdmIO>[] ioClassList = config.getIoClassList();
873
		logger.warn("getObligatoryAttributes has been commented because it still needs to be adapted to the new package structure");
874
		result.addAll(Arrays.asList(unclearMappers));
875
		result.addAll(Arrays.asList(createdAndNotesAttributes));
876
		result.addAll(Arrays.asList(operationalAttributes));
877
		CdmIoMapping mapping = new CdmIoMapping();
878
		for (CdmAttributeMapperBase mapper : classMappers){
879
			mapping.addMapper(mapper);
880
		}
881
		result.addAll(mapping.getSourceAttributes());
882
		if (lowerCase){
883
			Set<String> lowerCaseResult = new HashSet<String>();
884
			for (String str : result){
885
				if (str != null){lowerCaseResult.add(str.toLowerCase());}
886
			}
887
			result = lowerCaseResult;
888
		}
889
		return result;
890
	}
891

    
892
	@Override
893
	protected boolean doCheck(BerlinModelImportState state){
894
		BerlinModelReferenceImportValidator validator = new BerlinModelReferenceImportValidator();
895
		return validator.validate(state, this);
896
	}
897
	
898
	@Override
899
	protected boolean isIgnore(BerlinModelImportState state){
900
		return (state.getConfig().getDoReferences() == IImportConfigurator.DO_REFERENCES.NONE);
901
	}
902

    
903
	
904

    
905

    
906
}
(13-13/21)