3 * Copyright (C) 2007 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
7 * The contents of this file are subject to the Mozilla Public License Version 1.1
8 * See LICENSE.TXT at the top of this package for the full license terms.
11 package eu
.etaxonomy
.cdm
.io
.stream
;
13 import java
.util
.ArrayList
;
14 import java
.util
.HashMap
;
15 import java
.util
.HashSet
;
16 import java
.util
.List
;
19 import java
.util
.UUID
;
21 import org
.apache
.log4j
.Logger
;
23 import eu
.etaxonomy
.cdm
.api
.service
.IIdentifiableEntityService
;
24 import eu
.etaxonomy
.cdm
.io
.common
.ImportStateBase
;
25 import eu
.etaxonomy
.cdm
.io
.dwca
.TermUri
;
26 import eu
.etaxonomy
.cdm
.io
.dwca
.in
.IImportMapping
;
27 import eu
.etaxonomy
.cdm
.io
.dwca
.in
.IImportMapping
.CdmKey
;
28 import eu
.etaxonomy
.cdm
.io
.dwca
.in
.InMemoryMapping
;
29 import eu
.etaxonomy
.cdm
.io
.dwca
.in
.MappedCdmBase
;
30 import eu
.etaxonomy
.cdm
.io
.dwca
.in
.MappingEntry
;
31 import eu
.etaxonomy
.cdm
.model
.common
.CdmBase
;
32 import eu
.etaxonomy
.cdm
.model
.common
.IdentifiableEntity
;
33 import eu
.etaxonomy
.cdm
.model
.reference
.Reference
;
39 public abstract class StreamImportStateBase
<CONFIG
extends StreamImportConfiguratorBase
, IO
extends StreamImportBase
> extends ImportStateBase
<CONFIG
, IO
>{
40 private static final Logger logger
= Logger
.getLogger(StreamImportStateBase
.class);
42 private UUID uuid
= UUID
.randomUUID();
45 private Map
<String
, Map
<String
, IdentifiableEntity
>> partitionStore
;
47 private final IImportMapping mapping
;
49 public StreamImportStateBase(CONFIG config
) {
51 if (config
.getStateUuid()!= null){
52 uuid
= config
.getStateUuid();
54 String message
= "State uuid: " + uuid
.toString();
56 System
.out
.println(message
);
58 mapping
= getConfig().getMappingType().getMappingInstance(uuid
.toString(), getConfig().getDatabaseMappingFile());
62 * True, if taxa have been fully created.
65 public boolean isTaxaCreated() {
71 * @param taxaCreated the taxaCreated to set
73 public void setTaxaCreated(boolean taxaCreated
) {
74 this.taxaCreated
= taxaCreated
;
78 this.mapping
.finish();
81 //********************* MAPPING ACCESS *********************************
82 //TODO this may move to an external class soon
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");
88 mapping
.putMapping(mappedCdmBase
.getNamespace(), mappedCdmBase
.getSourceId(), CdmBase
.deproxy(mappedCdmBase
.getCdmBase(), IdentifiableEntity
.class));
92 public void putMapping(String namespace
, Integer sourceKey
, IdentifiableEntity
<?
> destinationObject
){
93 mapping
.putMapping(namespace
, sourceKey
, destinationObject
);
96 public void putMapping(String namespace
, String sourceKey
, IdentifiableEntity
<?
> destinationObject
){
97 mapping
.putMapping(namespace
, sourceKey
, destinationObject
);
101 public List
<IdentifiableEntity
> get(String namespace
, String sourceKey
){
102 return get(namespace
, sourceKey
, null);
105 public <CLASS
extends IdentifiableEntity
> List
<CLASS
> get(String namespace
, String sourceKey
,Class
<CLASS
> destinationClass
){
106 List
<CLASS
> result
= new ArrayList
<CLASS
>();
107 if (this.partitionStore
!= null){
108 Map
<String
, IdentifiableEntity
> namespaceMap
= this.partitionStore
.get(namespace
);
109 if (namespaceMap
!= null){
110 IdentifiableEntity
<?
> cdmBase
= namespaceMap
.get(sourceKey
);
111 if (cdmBase
== null){
112 logger
.info("CdmBase does not exist in mapping: " + sourceKey
);
113 }else if (cdmBase
.isInstanceOf(destinationClass
)){
114 CLASS typedCdmBase
= CdmBase
.deproxy(cdmBase
, destinationClass
);
115 result
.add(typedCdmBase
);
120 Set
<CdmKey
> keySet
= mapping
.get(namespace
, sourceKey
);
121 for (CdmKey
<CLASS
> key
: keySet
){
122 if (destinationClass
== null || destinationClass
.isAssignableFrom(key
.getClazz())){
123 IIdentifiableEntityService
<CLASS
> service
= getCurrentIO().getServiceByClass(key
.getClazz());
124 CLASS entity
= CdmBase
.deproxy(service
.find(key
.getId()), key
.getClazz());
133 public boolean exists(String namespace
, String sourceKey
,Class
<?
> destinationClass
){
134 return mapping
.exists(namespace
, sourceKey
, destinationClass
);
138 public void loadRelatedObjects (InMemoryMapping mapping
){
139 Map
<String
, Map
<String
, IdentifiableEntity
>> result
= new HashMap
<String
, Map
<String
,IdentifiableEntity
>>();
141 List
<MappingEntry
<String
, String
, Class
, Integer
>> mappingEntryList
= mapping
.getEntryList();
143 //order ids by destination classes
144 Map
<Class
, Set
<Integer
>> destinationNamespaceMap
= new HashMap
<Class
, Set
<Integer
>>();
145 for (MappingEntry
<String
, String
, Class
, Integer
> entry
: mappingEntryList
){
146 Set
<Integer
> idSet
= destinationNamespaceMap
.get(entry
.getDestinationNamespace());
148 idSet
= new HashSet
<Integer
>();
149 destinationNamespaceMap
.put(entry
.getDestinationNamespace(), idSet
);
151 idSet
.add(entry
.getDestinationId());
154 //retrieve cdm objects per class
155 Map
<Class
, Map
<Integer
, IdentifiableEntity
>> classMap
= new HashMap
<Class
, Map
<Integer
,IdentifiableEntity
>>();
156 for (Class
<?
> cdmClass
: destinationNamespaceMap
.keySet()){
157 IIdentifiableEntityService
<?
> classService
= getCurrentIO().getServiceByClass(cdmClass
);
158 Set
<Integer
> idSet
= destinationNamespaceMap
.get(cdmClass
);
159 List
<?
extends IdentifiableEntity
> relatedObjects
= classService
.findById(idSet
);
162 Map
<Integer
, IdentifiableEntity
> idMap
= new HashMap
<Integer
, IdentifiableEntity
>();
163 for (IdentifiableEntity
<?
> identEnt
: relatedObjects
){
164 idMap
.put(identEnt
.getId(), identEnt
);
168 classMap
.put(cdmClass
, idMap
);
171 //fill related object map
172 for (MappingEntry
<String
, String
, Class
, Integer
> entry
: mappingEntryList
){
173 IdentifiableEntity cdmBase
= getCdmObject(classMap
, entry
);
175 Map
<String
, IdentifiableEntity
> namespaceMap
= getOrMakeNamespaceMap(result
, entry
.getNamespace());
176 if (cdmBase
!= null){
177 namespaceMap
.put(entry
.getSourceKey(), cdmBase
);
179 logger
.info("CdmBase not found for mapping entry.");
184 this.partitionStore
= result
;
188 public void addRelatedObject(String sourceNamespace
, String sourceKey
, IdentifiableEntity
<?
> cdmEntity
){
189 Map
<String
, IdentifiableEntity
> namespaceMap
= getOrMakeNamespaceMap(this.partitionStore
, sourceNamespace
);
190 if (cdmEntity
!= null){
191 namespaceMap
.put(sourceKey
, cdmEntity
);
193 logger
.info("CdmBase is null and will not be added to related objects.");
198 // public Map<String, Map<String, IdentifiableEntity>> getPartitionStore() {
199 // return partitionStore;
202 public void unloadPartitionStore(Map
<String
, Map
<String
, IdentifiableEntity
>> partitionStore
) {
203 this.partitionStore
= new HashMap
<String
, Map
<String
,IdentifiableEntity
>>();
206 public IImportMapping
getMapping() {
211 private Map
<String
, IdentifiableEntity
> getOrMakeNamespaceMap(Map
<String
, Map
<String
, IdentifiableEntity
>> relatedObjectMap2
, String namespace
) {
212 Map
<String
, IdentifiableEntity
> namespaceMap
= relatedObjectMap2
.get(namespace
);
213 if (namespaceMap
== null){
214 namespaceMap
= new HashMap
<String
, IdentifiableEntity
>();
215 relatedObjectMap2
.put(namespace
, namespaceMap
);
221 private IdentifiableEntity
getCdmObject(Map
<Class
, Map
<Integer
, IdentifiableEntity
>> classMap
,
222 MappingEntry
<String
, String
, Class
, Integer
> entry
) {
223 Class
<?
> cdmClass
= entry
.getDestinationNamespace();
224 Integer cdmKey
= entry
.getDestinationId();
225 Map
<Integer
, IdentifiableEntity
> idMap
= classMap
.get(cdmClass
);
227 return idMap
.get(cdmKey
);
234 * Returns the source reference object that is attached to the current transaction.
237 public Reference
<?
> getTransactionalSourceReference() {
238 TermUri namespaceSourceReference
= TermUri
.CDM_SOURCE_REFERENCE
;
239 UUID sourceReferenceUuid
= getConfig().getSourceRefUuid();
240 List
<Reference
> references
= this.get(namespaceSourceReference
.toString(), sourceReferenceUuid
.toString(), Reference
.class);
241 if (references
.isEmpty()){
242 //TODO better fire warning, but not yet available for state
243 throw new RuntimeException("Source reference can not be found. This should not happen.");
244 }else if (references
.size() > 1){
245 //TODO better fire warning, but not yet available for state
246 throw new RuntimeException("More than 1 source reference found. This is not yet handled.");
248 return references
.get(0);