View Javadoc

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.common;
11  
12  import java.sql.ResultSet;
13  import java.sql.SQLException;
14  import java.util.UUID;
15  
16  import org.apache.log4j.Logger;
17  
18  import eu.etaxonomy.cdm.common.CdmUtils;
19  import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
20  import eu.etaxonomy.cdm.io.common.mapping.IInputTransformer;
21  import eu.etaxonomy.cdm.io.common.mapping.UndefinedTransformerMethodException;
22  import eu.etaxonomy.cdm.model.common.AnnotationType;
23  import eu.etaxonomy.cdm.model.common.CdmBase;
24  import eu.etaxonomy.cdm.model.common.DescriptionElementSource;
25  import eu.etaxonomy.cdm.model.common.ExtensionType;
26  import eu.etaxonomy.cdm.model.common.IOriginalSource;
27  import eu.etaxonomy.cdm.model.common.ISourceable;
28  import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
29  import eu.etaxonomy.cdm.model.common.IdentifiableSource;
30  import eu.etaxonomy.cdm.model.common.Language;
31  import eu.etaxonomy.cdm.model.common.MarkerType;
32  import eu.etaxonomy.cdm.model.common.TermVocabulary;
33  import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
34  import eu.etaxonomy.cdm.model.description.Feature;
35  import eu.etaxonomy.cdm.model.location.NamedArea;
36  import eu.etaxonomy.cdm.model.location.NamedAreaLevel;
37  import eu.etaxonomy.cdm.model.location.NamedAreaType;
38  import eu.etaxonomy.cdm.model.name.NonViralName;
39  import eu.etaxonomy.cdm.model.name.Rank;
40  import eu.etaxonomy.cdm.model.reference.ReferenceBase;
41  import eu.etaxonomy.cdm.model.taxon.Taxon;
42  import eu.etaxonomy.cdm.model.taxon.TaxonomicTree;
43  
44  /**
45   * @author a.mueller
46   * @created 01.07.2008
47   * @version 1.0
48   */
49  public abstract class CdmImportBase<CONFIG extends IImportConfigurator, STATE extends ImportStateBase> extends CdmIoBase<STATE> implements ICdmImport<CONFIG, STATE>{
50  	private static Logger logger = Logger.getLogger(CdmImportBase.class);
51  
52  	protected TaxonomicTree makeTree(STATE state, ReferenceBase reference){
53  		ReferenceBase ref = CdmBase.deproxy(reference, ReferenceBase.class);
54  		String treeName = "TaxonTree (Import)";
55  		if (ref != null && CdmUtils.isNotEmpty(ref.getTitleCache())){
56  			treeName = ref.getTitleCache();
57  		}
58  		TaxonomicTree tree = TaxonomicTree.NewInstance(treeName);
59  		tree.setReference(ref);
60  		
61  
62  		// use defined uuid for first tree
63  		CONFIG config = (CONFIG)state.getConfig();
64  		if (state.countTrees() < 1 ){
65  			tree.setUuid(config.getTaxonomicTreeUuid());
66  		}
67  		getTaxonTreeService().save(tree);
68  		state.putTree(ref, tree);
69  		return tree;
70  	}
71  	
72  	
73  	/**
74  	 * Alternative memory saving method variant of
75  	 * {@link #makeTree(STATE state, ReferenceBase ref)} which stores only the
76  	 * UUID instead of the full tree in the <code>ImportStateBase</code> by 
77  	 * using <code>state.putTreeUuid(ref, tree);</code>
78  	 * 
79  	 * @param state
80  	 * @param ref
81  	 * @return
82  	 */
83  	protected TaxonomicTree makeTreeMemSave(STATE state, ReferenceBase ref){
84  		String treeName = "TaxonTree (Import)";
85  		if (ref != null && CdmUtils.isNotEmpty(ref.getTitleCache())){
86  			treeName = ref.getTitleCache();
87  		}
88  		TaxonomicTree tree = TaxonomicTree.NewInstance(treeName);
89  		tree.setReference(ref);
90  		
91  
92  		// use defined uuid for first tree
93  		CONFIG config = (CONFIG)state.getConfig();
94  		if (state.countTrees() < 1 ){
95  			tree.setUuid(config.getTaxonomicTreeUuid());
96  		}
97  		getTaxonTreeService().save(tree);
98  		state.putTreeUuid(ref, tree);
99  		return tree;
100 	}
101 	
102 	
103 	protected ExtensionType getExtensionType(STATE state, UUID uuid, String label, String text, String labelAbbrev){
104 		ExtensionType extensionType = state.getExtensionType(uuid);
105 		if (extensionType == null){
106 			extensionType = (ExtensionType)getTermService().find(uuid);
107 			if (extensionType == null){
108 				extensionType = ExtensionType.NewInstance(text, label, labelAbbrev);
109 				extensionType.setUuid(uuid);
110 				ExtensionType.DOI().getVocabulary().addTerm(extensionType);
111 				getTermService().save(extensionType);
112 			}
113 			state.putExtensionType(extensionType);
114 		}
115 		return extensionType;
116 	}
117 	
118 	
119 	protected MarkerType getMarkerType(STATE state, String keyString) {
120 		IInputTransformer transformer = state.getTransformer();
121 		MarkerType markerType = null;
122 		try {
123 			markerType = transformer.getMarkerTypeByKey(keyString);
124 		} catch (UndefinedTransformerMethodException e) {
125 			logger.info("getMarkerTypeByKey not yet implemented for this import");
126 		}
127 		if (markerType == null ){
128 			UUID uuid;
129 			try {
130 				uuid = transformer.getMarkerTypeUuid(keyString);
131 				return getMarkerType(state, uuid, keyString, keyString, keyString);
132 			} catch (UndefinedTransformerMethodException e) {
133 				logger.warn("getMarkerTypeUuid not yet implemented for this import");
134 			}
135 		}
136 		return null;
137 	}
138 	
139 	protected MarkerType getMarkerType(STATE state, UUID uuid, String label, String text, String labelAbbrev){
140 		MarkerType markerType = state.getMarkerType(uuid);
141 		if (markerType == null){
142 			markerType = (MarkerType)getTermService().find(uuid);
143 			if (markerType == null){
144 				markerType = MarkerType.NewInstance(label, text, labelAbbrev);
145 				markerType.setUuid(uuid);
146 				MarkerType.COMPLETE().getVocabulary().addTerm(markerType);
147 				getTermService().save(markerType);
148 			}
149 			state.putMarkerType(markerType);
150 		}
151 		return markerType;
152 	}
153 	
154 	protected AnnotationType getAnnotationType(STATE state, UUID uuid, String label, String text, String labelAbbrev){
155 		AnnotationType annotationType = state.getAnnotationType(uuid);
156 		if (annotationType == null){
157 			annotationType = (AnnotationType)getTermService().find(uuid);
158 			if (annotationType == null){
159 				annotationType = AnnotationType.NewInstance(label, text, labelAbbrev);
160 				annotationType.setUuid(uuid);
161 				AnnotationType.EDITORIAL().getVocabulary().addTerm(annotationType);
162 				getTermService().save(annotationType);
163 			}
164 			state.putAnnotationType(annotationType);
165 		}
166 		return annotationType;
167 	}
168 	
169 	/**
170 	 * Returns a named area for a given uuid by first . If the named area does not
171 	 * @param state
172 	 * @param uuid
173 	 * @param label
174 	 * @param text
175 	 * @param labelAbbrev
176 	 * @param areaType
177 	 * @param level
178 	 * @return
179 	 */
180 	protected NamedArea getNamedArea(STATE state, UUID uuid, String label, String text, String labelAbbrev, NamedAreaType areaType, NamedAreaLevel level){
181 		NamedArea namedArea = state.getNamedArea(uuid);
182 		if (namedArea == null){
183 			namedArea = (NamedArea)getTermService().find(uuid);
184 			if (namedArea == null){
185 				namedArea = NamedArea.NewInstance(text, label, labelAbbrev);
186 				namedArea.setType(areaType);
187 				namedArea.setLevel(level);
188 				namedArea.setUuid(uuid);
189 				getTermService().save(namedArea);
190 			}
191 			state.putNamedArea(namedArea);
192 		}
193 		return namedArea;
194 	}
195 	
196 	/**
197 	 * Returns a feature for a given uuid by first ...
198 	 * @param state
199 	 * @param uuid
200 	 * @param label
201 	 * @param text
202 	 * @param labelAbbrev
203 	 * @return
204 	 */
205 	protected Feature getFeature(STATE state, UUID uuid, String label, String text, String labelAbbrev){
206 		if (uuid == null){
207 			return null;
208 		}
209 		Feature feature = state.getFeature(uuid);
210 		if (feature == null){
211 			feature = (Feature)getTermService().find(uuid);
212 			if (feature == null){
213 				feature = Feature.NewInstance(text, label, labelAbbrev);
214 				feature.setUuid(uuid);
215 				//set vocabulary ; FIXME use another user-defined vocabulary
216 				UUID uuidFeatureVoc = UUID.fromString("b187d555-f06f-4d65-9e53-da7c93f8eaa8"); 
217 				TermVocabulary<Feature> voc = getVocabularyService().find(uuidFeatureVoc);
218 				voc.addTerm(feature);
219 				getTermService().save(feature);
220 			}
221 			state.putFeature(feature);
222 		}
223 		return feature;
224 	}
225 
226 	/**
227 	 * Returns a language for a given uuid by first ...
228 	 * @param state
229 	 * @param uuid
230 	 * @param label
231 	 * @param text
232 	 * @param labelAbbrev
233 	 * @return
234 	 */
235 	protected Language getLanguage(STATE state, UUID uuid, String label, String text, String labelAbbrev){
236 		if (uuid == null){
237 			return null;
238 		}
239 		Language language = state.getLanguage(uuid);
240 		if (language == null){
241 			language = (Language)getTermService().find(uuid);
242 			if (language == null){
243 				language = Language.NewInstance(text, label, labelAbbrev);
244 				
245 				language.setUuid(uuid);
246 				//set vocabulary ; FIXME use another user-defined vocabulary
247 				UUID uuidLanguageVoc = UUID.fromString("45ac7043-7f5e-4f37-92f2-3874aaaef2de"); 
248 				TermVocabulary<Language> voc = getVocabularyService().find(uuidLanguageVoc);
249 				voc.addTerm(language);
250 				getTermService().save(language);
251 			}
252 			state.putLanguage(language);
253 		}
254 		return language;
255 	}
256 	
257 	/**
258 	 * Adds an orginal source to a sourceable objects (implemented for Identifiable entity and description element.
259 	 * If cdmBase is not sourceable nothing happens.
260 	 * TODO Move to DbImportBase once this exists.
261 	 * TODO also implemented in DbImportObjectCreationMapper (reduce redundance)
262 	 * @param rs
263 	 * @param cdmBase
264 	 * @param dbIdAttribute
265 	 * @param namespace
266 	 * @param citation
267 	 * @throws SQLException
268 	 */
269 	public void addOriginalSource(CdmBase cdmBase, Object idAttributeValue, String namespace, ReferenceBase citation) throws SQLException {
270 		if (cdmBase instanceof ISourceable ){
271 			IOriginalSource source;
272 			ISourceable sourceable = (ISourceable)cdmBase;
273 			Object id = idAttributeValue;
274 			String strId = String.valueOf(id);
275 			String microCitation = null;
276 			if (cdmBase instanceof IdentifiableEntity){
277 				source = IdentifiableSource.NewInstance(strId, namespace, citation, microCitation);
278 			}else if (cdmBase instanceof DescriptionElementBase){
279 				source = DescriptionElementSource.NewInstance(strId, namespace, citation, microCitation);
280 			}else{
281 				logger.warn("ISourceable not beeing identifiable entities or description element base are not yet supported. CdmBase is of type " + cdmBase.getClass().getName() + ". Original source not added.");
282 				return;
283 			}
284 			sourceable.addSource(source);
285 		}
286 	}
287 	
288 	/**
289 	 * @see #addOriginalSource(CdmBase, Object, String, ReferenceBase)
290 	 * @param rs
291 	 * @param cdmBase
292 	 * @param dbIdAttribute
293 	 * @param namespace
294 	 * @param citation
295 	 * @throws SQLException
296 	 */
297 	public void addOriginalSource(ResultSet rs, CdmBase cdmBase, String dbIdAttribute, String namespace, ReferenceBase citation) throws SQLException {
298 		Object id = rs.getObject(dbIdAttribute);
299 		addOriginalSource(cdmBase, id, namespace, citation);
300 	}
301 	
302 
303 	/**
304 	 * If the child taxon is missing genus or species epithet information and the rank is below <i>genus</i>
305 	 * or <i>species</i> respectively the according epithets are taken from the parent taxon.
306 	 * If the name is an autonym and has no combination author/basionym author the authors are taken from
307 	 * the parent.
308 	 * @param parentTaxon
309 	 * @param childTaxon
310 	 */
311 	protected void fillMissingEpithetsForTaxa(Taxon parentTaxon, Taxon childTaxon) {
312 		NonViralName parentName = HibernateProxyHelper.deproxy(parentTaxon.getName(), NonViralName.class);
313 		NonViralName childName = HibernateProxyHelper.deproxy(childTaxon.getName(), NonViralName.class);
314 		fillMissingEpithets(parentName, childName);
315 	}
316 	
317 	/**
318 	 * If the child name is missing genus or species epithet information and the rank is below <i>genus</i>
319 	 * or <i>species</i> respectively the according epithets are taken from the parent name.
320 	 * If the name is an autonym and has no combination author/basionym author the authors are taken from
321 	 * the parent.
322 	 * @param parentTaxon
323 	 * @param childTaxon
324 	 */
325 	protected void fillMissingEpithets(NonViralName parentName, NonViralName childName) {
326 		if (CdmUtils.isEmpty(childName.getGenusOrUninomial()) && childName.getRank().isLower(Rank.GENUS()) ){
327 			childName.setGenusOrUninomial(parentName.getGenusOrUninomial());
328 		}
329 		
330 		if (CdmUtils.isEmpty(childName.getSpecificEpithet()) && childName.getRank().isLower(Rank.SPECIES()) ){
331 			childName.setSpecificEpithet(parentName.getSpecificEpithet());
332 		}
333 		if (childName.isAutonym() && childName.getCombinationAuthorTeam() == null && childName.getBasionymAuthorTeam() == null ){
334 			childName.setCombinationAuthorTeam(parentName.getCombinationAuthorTeam());
335 			childName.setBasionymAuthorTeam(parentName.getBasionymAuthorTeam());
336 		}	
337 	}
338 	
339 }