Project

General

Profile

Download (8.52 KB) Statistics
| Branch: | Tag: | 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.stream;
11

    
12
import java.util.ArrayList;
13
import java.util.HashMap;
14
import java.util.HashSet;
15
import java.util.List;
16
import java.util.Map;
17
import java.util.Set;
18
import java.util.UUID;
19

    
20
import org.apache.log4j.Logger;
21

    
22
import eu.etaxonomy.cdm.api.service.IIdentifiableEntityService;
23
import eu.etaxonomy.cdm.io.common.ImportStateBase;
24
import eu.etaxonomy.cdm.io.stream.mapping.IImportMapping;
25
import eu.etaxonomy.cdm.io.stream.mapping.InMemoryMapping;
26
import eu.etaxonomy.cdm.io.stream.mapping.MappingEntry;
27
import eu.etaxonomy.cdm.io.stream.mapping.IImportMapping.CdmKey;
28
import eu.etaxonomy.cdm.io.stream.terms.TermUri;
29
import eu.etaxonomy.cdm.model.common.CdmBase;
30
import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
31
import eu.etaxonomy.cdm.model.reference.Reference;
32
import eu.etaxonomy.cdm.model.term.DefinedTermBase;
33

    
34
/**
35
 * @author a.mueller
36
 * @since 23.11.2011
37
 */
38
public abstract class StreamImportStateBase<CONFIG extends StreamImportConfiguratorBase, IO extends StreamImportBase>
39
            extends ImportStateBase<CONFIG, IO>{
40
	private static final Logger logger = Logger.getLogger(StreamImportStateBase.class);
41

    
42
	private UUID uuid = UUID.randomUUID();
43

    
44
	boolean taxaCreated;
45
	private Map<String, Map<String, IdentifiableEntity>> partitionStore;
46

    
47
	private final IImportMapping mapping;
48

    
49
	public StreamImportStateBase(CONFIG config) {
50
		super(config);
51
		if (config.getStateUuid()!= null){
52
		    uuid = config.getStateUuid();
53
		}else{
54
		    String message = "State uuid: " + uuid.toString();
55
		    logger.warn(message);
56
		    System.out.println(message);
57
		}
58
		mapping = getConfig().getMappingType().getMappingInstance(uuid.toString(), getConfig().getDatabaseMappingFile());
59
	}
60

    
61
	/**
62
	 * True, if taxa have been fully created.
63
	 * @return
64
	 */
65
	public boolean isTaxaCreated() {
66
		return taxaCreated;
67

    
68
	}
69

    
70
	/**
71
	 * @param taxaCreated the taxaCreated to set
72
	 */
73
	public void setTaxaCreated(boolean taxaCreated) {
74
		this.taxaCreated = taxaCreated;
75
	}
76

    
77
	public void finish(){
78
		this.mapping.finish();
79
	}
80

    
81
//********************* MAPPING ACCESS *********************************
82
	//TODO this may move to an external class soon
83

    
84
	public void putMapping(MappedCdmBase mappedCdmBase) throws IllegalArgumentException{
85
		if (! mappedCdmBase.getCdmBase().isInstanceOf(IdentifiableEntity.class)){
86
			throw new IllegalArgumentException("Mapped cdmBase does not map an identifiable entity");
87
		}
88
		putMapping(mappedCdmBase.getNamespace(), mappedCdmBase.getSourceId(), CdmBase.deproxy(mappedCdmBase.getCdmBase(), IdentifiableEntity.class));
89
	}
90

    
91

    
92
	public void putMapping(String namespace, Integer sourceKey, IdentifiableEntity<?> destinationObject){
93
	    putMapping(namespace, String.valueOf(sourceKey), destinationObject);
94
	}
95

    
96
	public void putMapping(String namespace, String sourceKey, IdentifiableEntity<?> destinationObject){
97
		if (destinationObject.isInstanceOf(DefinedTermBase.class)){
98
		    addRelatedObject(namespace, sourceKey, destinationObject);
99
		}
100
	    mapping.putMapping(namespace, sourceKey, destinationObject);
101
	}
102

    
103

    
104
	public List<IdentifiableEntity> get(String namespace, String sourceKey){
105
		return get(namespace, sourceKey, null);
106
	}
107

    
108
	public <CLASS extends IdentifiableEntity> List<CLASS> get(String namespace, String sourceKey, Class<CLASS> destinationClass){
109
		List<CLASS> result = new ArrayList<>();
110
		if (this.partitionStore != null){
111
			Map<String, IdentifiableEntity> namespaceMap = this.partitionStore.get(namespace);
112
			if (namespaceMap != null){
113
				IdentifiableEntity<?> cdmBase = namespaceMap.get(sourceKey);
114
				if (cdmBase == null){
115
					logger.info("CdmBase does not exist in mapping: " + sourceKey);
116
				}else if (cdmBase.isInstanceOf(destinationClass)){
117
					CLASS typedCdmBase = CdmBase.deproxy(cdmBase, destinationClass);
118
					result.add(typedCdmBase);
119
				}
120

    
121
			}
122
		}else{
123
			Set<CdmKey> keySet = mapping.get(namespace, sourceKey);
124
			for (CdmKey<CLASS> key: keySet){
125
				if (destinationClass == null || destinationClass.isAssignableFrom(key.getClazz())){
126
					IIdentifiableEntityService<CLASS> service = getCurrentIO().getServiceByClass(key.getClazz());
127
					CLASS entity = CdmBase.deproxy(service.find(key.getId()), key.getClazz());
128
					result.add(entity);
129
				}
130
			}
131
			return result;
132
		}
133
		return result;
134
	}
135

    
136
	public boolean exists(String namespace, String sourceKey,Class<?> destinationClass){
137
		return mapping.exists(namespace, sourceKey, destinationClass);
138
	}
139

    
140

    
141
	public  void loadRelatedObjects (InMemoryMapping mapping){
142
		Map<String, Map<String, IdentifiableEntity>> result = new HashMap<>();
143

    
144
		List<MappingEntry<String, String, Class, Integer>> mappingEntryList = mapping.getEntryList();
145

    
146
		//order ids by destination classes
147
		Map<Class, Set<Integer>> destinationNamespaceMap = new HashMap<>();
148
		for (MappingEntry<String, String, Class, Integer> entry : mappingEntryList){
149
			Set<Integer> idSet = destinationNamespaceMap.get(entry.getDestinationNamespace());
150
			if (idSet == null){
151
				idSet = new HashSet<>();
152
				destinationNamespaceMap.put(entry.getDestinationNamespace(), idSet);
153
			}
154
			idSet.add(entry.getDestinationId());
155
		}
156

    
157
		//retrieve cdm objects per class
158
		Map<Class, Map<Integer, IdentifiableEntity>> classMap = new HashMap<>();
159
		for (Class<?> cdmClass : destinationNamespaceMap.keySet()){
160
			IIdentifiableEntityService<?> classService = getCurrentIO().getServiceByClass(cdmClass);
161
			Set<Integer> idSet = destinationNamespaceMap.get(cdmClass);
162
			List<? extends IdentifiableEntity> relatedObjects = classService.findById(idSet);
163

    
164
			//put into id map
165
			Map<Integer, IdentifiableEntity> idMap = new HashMap<>();
166
			for (IdentifiableEntity<?> identEnt : relatedObjects){
167
				idMap.put(identEnt.getId(), identEnt);
168
			}
169

    
170
			//add to class map
171
			classMap.put(cdmClass, idMap);
172
		}
173

    
174
		//fill related object map
175
		for (MappingEntry<String, String, Class, Integer> entry : mappingEntryList){
176
			IdentifiableEntity<?> cdmBase = getCdmObject(classMap, entry);
177

    
178
			Map<String, IdentifiableEntity> namespaceMap = getOrMakeNamespaceMap(result, entry.getNamespace());
179
			if (cdmBase != null){
180
				namespaceMap.put(entry.getSourceKey(), cdmBase);
181
			}else{
182
				logger.info("CdmBase not found for mapping entry.");
183
			}
184
		}
185

    
186
		//store
187
		this.partitionStore = result;
188

    
189
	}
190

    
191
	public void addRelatedObject(String sourceNamespace, String sourceKey, IdentifiableEntity<?> cdmEntity){
192
		Map<String, IdentifiableEntity> namespaceMap = getOrMakeNamespaceMap(this.partitionStore, sourceNamespace);
193
		if (cdmEntity != null){
194
			namespaceMap.put(sourceKey, cdmEntity);
195
		}else{
196
			logger.info("CdmBase is null and will not be added to related objects.");
197
		}
198
	}
199

    
200
	public void unloadPartitionStore(Map<String, Map<String, IdentifiableEntity>> partitionStore) {
201
		this.partitionStore = new HashMap<>();
202
	}
203

    
204
	public IImportMapping getMapping() {
205
		return this.mapping;
206
	}
207

    
208

    
209
	private Map<String, IdentifiableEntity> getOrMakeNamespaceMap(Map<String, Map<String, IdentifiableEntity>> relatedObjectMap, String namespace) {
210
		Map<String, IdentifiableEntity> namespaceMap = relatedObjectMap.get(namespace);
211
		if (namespaceMap == null){
212
			namespaceMap = new HashMap<>();
213
			relatedObjectMap.put(namespace, namespaceMap);
214
		}
215
		return namespaceMap;
216
	}
217

    
218

    
219
	private IdentifiableEntity getCdmObject(Map<Class, Map<Integer, IdentifiableEntity>> classMap,
220
			MappingEntry<String, String, Class, Integer> entry) {
221
		Class<?> cdmClass = entry.getDestinationNamespace();
222
		Integer cdmKey = entry.getDestinationId();
223
		Map<Integer, IdentifiableEntity> idMap = classMap.get(cdmClass);
224
		if (idMap != null){
225
			return idMap.get(cdmKey);
226
		}else{
227
			return null;
228
		}
229
	}
230

    
231
	/**
232
	 * Returns the source reference object that is attached to the current transaction.
233
	 * @return
234
	 */
235
	public Reference getTransactionalSourceReference() {
236
		TermUri namespaceSourceReference = TermUri.CDM_SOURCE_REFERENCE;
237
		UUID sourceReferenceUuid = getConfig().getSourceRefUuid();
238
		List<Reference> references = this.get(namespaceSourceReference.toString(), sourceReferenceUuid.toString(), Reference.class);
239
		if (references.isEmpty()){
240
			//TODO better fire warning, but not yet available for state
241
			throw new RuntimeException("Source reference can not be found. This should not happen.");
242
		}else if (references.size() > 1){
243
			//TODO better fire warning, but not yet available for state
244
			throw new RuntimeException("More than 1 source reference found. This is not yet handled.");
245
		}else{
246
			return references.get(0);
247
		}
248

    
249
	}
250

    
251

    
252

    
253
}
(19-19/21)