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.berlinModel.in;
11  
12  import static eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer.NAME_FACT_ALSO_PUBLISHED_IN;
13  import static eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer.NAME_FACT_PROTOLOGUE;
14  
15  import java.io.File;
16  import java.io.IOException;
17  import java.net.MalformedURLException;
18  import java.net.URL;
19  import java.sql.ResultSet;
20  import java.sql.SQLException;
21  import java.util.HashMap;
22  import java.util.HashSet;
23  import java.util.Map;
24  import java.util.Set;
25  
26  import org.apache.log4j.Logger;
27  import org.springframework.stereotype.Component;
28  
29  import eu.etaxonomy.cdm.common.CdmUtils;
30  import eu.etaxonomy.cdm.common.mediaMetaData.ImageMetaData;
31  import eu.etaxonomy.cdm.io.berlinModel.in.validation.BerlinModelNameFactsImportValidator;
32  import eu.etaxonomy.cdm.io.common.IOValidator;
33  import eu.etaxonomy.cdm.io.common.ResultSetPartitioner;
34  import eu.etaxonomy.cdm.model.agent.Person;
35  import eu.etaxonomy.cdm.model.common.CdmBase;
36  import eu.etaxonomy.cdm.model.common.Language;
37  import eu.etaxonomy.cdm.model.description.Feature;
38  import eu.etaxonomy.cdm.model.description.TaxonNameDescription;
39  import eu.etaxonomy.cdm.model.description.TextData;
40  import eu.etaxonomy.cdm.model.media.ImageFile;
41  import eu.etaxonomy.cdm.model.media.Media;
42  import eu.etaxonomy.cdm.model.media.MediaRepresentation;
43  import eu.etaxonomy.cdm.model.media.MediaRepresentationPart;
44  import eu.etaxonomy.cdm.model.name.TaxonNameBase;
45  import eu.etaxonomy.cdm.model.reference.ReferenceBase;
46  
47  
48  /**
49   * @author a.mueller
50   * @created 20.03.2008
51   * @version 1.0
52   */
53  @Component
54  public class BerlinModelNameFactsImport  extends BerlinModelImportBase  {
55  	private static final Logger logger = Logger.getLogger(BerlinModelNameFactsImport.class);
56  
57  	public static final String NAMESPACE = "NameFact";
58  
59  	/**
60  	 * write info message after modCount iterations
61  	 */
62  	private int modCount = 50;
63  	private static final String pluralString = "name facts";
64  	private static final String dbTableName = "NameFact";
65  
66  	
67  	public BerlinModelNameFactsImport(){
68  		super();
69  	}
70  
71  	/* (non-Javadoc)
72  	 * @see eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportBase#getRecordQuery(eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportConfigurator)
73  	 */
74  	@Override
75  	protected String getRecordQuery(BerlinModelImportConfigurator config) {
76  		String strQuery = 
77  			" SELECT NameFact.*, Name.NameID as nameId, NameFactCategory.NameFactCategory " + 
78  			" FROM NameFact INNER JOIN " +
79                	" Name ON NameFact.PTNameFk = Name.NameId  INNER JOIN "+
80                	" NameFactCategory ON NameFactCategory.NameFactCategoryID = NameFact.NameFactCategoryFK " + 
81              " WHERE (NameFactId IN ("+ ID_LIST_TOKEN+") )";
82  		return strQuery;
83  	}
84  
85  	/* (non-Javadoc)
86  	 * @see eu.etaxonomy.cdm.io.berlinModel.in.IPartitionedIO#doPartition(eu.etaxonomy.cdm.io.berlinModel.in.ResultSetPartitioner, eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportState)
87  	 */
88  	public boolean doPartition(ResultSetPartitioner partitioner, BerlinModelImportState state) {
89  		boolean success = true ;
90  		BerlinModelImportConfigurator config = state.getConfig();
91  		Set<TaxonNameBase> nameToSave = new HashSet<TaxonNameBase>();
92  		Map<String, TaxonNameBase> nameMap = (Map<String, TaxonNameBase>) partitioner.getObjectMap(BerlinModelTaxonNameImport.NAMESPACE);
93  		Map<String, ReferenceBase> biblioRefMap = partitioner.getObjectMap(BerlinModelReferenceImport.BIBLIO_REFERENCE_NAMESPACE);
94  		Map<String, ReferenceBase> nomRefMap = partitioner.getObjectMap(BerlinModelReferenceImport.NOM_REFERENCE_NAMESPACE);
95  
96  		ResultSet rs = partitioner.getResultSet();
97  		
98  		ReferenceBase<?> sourceRef = state.getConfig().getSourceReference();
99  		try {
100 			int i = 0;
101 			//for each reference
102 			while (rs.next() && (config.getMaximumNumberOfNameFacts() == 0 || i < config.getMaximumNumberOfNameFacts())){
103 				
104 				if ((i++ % modCount) == 0  && i!= 1 ){ logger.info("NameFacts handled: " + (i-1));}
105 				
106 				int nameFactId = rs.getInt("nameFactId");
107 				int nameId = rs.getInt("nameId");
108 				Object nameFactRefFkObj = rs.getObject("nameFactRefFk");
109 				String nameFactRefDetail = rs.getString("nameFactRefDetail");
110 				
111 				String category = CdmUtils.Nz(rs.getString("NameFactCategory"));
112 				String nameFact = CdmUtils.Nz(rs.getString("nameFact"));
113 				
114 				TaxonNameBase taxonNameBase = nameMap.get(String.valueOf(nameId));
115 				String nameFactRefFk = String.valueOf(nameFactRefFkObj);
116 				ReferenceBase citation = getReferenceOnlyFromMaps(biblioRefMap, 
117 						nomRefMap, nameFactRefFk);
118 				
119 				if (taxonNameBase != null){
120 					//PROTOLOGUE
121 					if (category.equalsIgnoreCase(NAME_FACT_PROTOLOGUE)){
122 						//ReferenceBase ref = (ReferenceBase)taxonNameBase.getNomenclaturalReference();
123 						//ref = Book.NewInstance();
124 						try{
125 							Media media = getMedia(nameFact, config.getMediaUrl(), config.getMediaPath());
126 							if (media.getRepresentations().size() > 0){
127 								TaxonNameDescription description = TaxonNameDescription.NewInstance();
128 								TextData protolog = TextData.NewInstance(Feature.PROTOLOGUE());
129 								protolog.addMedia(media);
130 								protolog.addSource(String.valueOf(nameFactId), NAMESPACE, null, null, null, null);
131 								description.addElement(protolog);
132 								taxonNameBase.addDescription(description);
133 								if (citation != null){
134 									description.addDescriptionSource(citation);
135 									protolog.addSource(null, null, citation, nameFactRefDetail, null, null);
136 								}
137 							}//end NAME_FACT_PROTOLOGUE
138 						}catch(NullPointerException e){
139 							logger.warn("MediaUrl and/or MediaPath not set. Could not get protologue.");
140 							success = false;
141 						}						
142 					}else if (category.equalsIgnoreCase(NAME_FACT_ALSO_PUBLISHED_IN)){
143 						if (! nameFact.equals("")){
144 							TaxonNameDescription description = TaxonNameDescription.NewInstance();
145 							TextData additionalPublication = TextData.NewInstance(Feature.ADDITIONAL_PUBLICATION());
146 							//TODO language
147 							Language language = Language.DEFAULT();
148 							additionalPublication.putText(nameFact, language);
149 							additionalPublication.addSource(String.valueOf(nameFactId), NAMESPACE, citation, 
150 									nameFactRefDetail, null, null);
151 							description.addElement(additionalPublication);
152 							taxonNameBase.addDescription(description);
153 						}
154 					}else {
155 						//TODO
156 						logger.warn("NameFactCategory '" + category + "' not yet implemented");
157 						success = false;
158 					}
159 					
160 					//TODO
161 //					DoubtfulFlag    bit        Checked
162 //					PublishFlag      bit        Checked
163 //					Created_When  datetime           Checked
164 //					Updated_When datetime           Checked
165 //					Created_Who    nvarchar(255)    Checked
166 //					Updated_Who  nvarchar(255)    Checked
167 //					Notes      nvarchar(1000)           Checked
168 					
169 					nameToSave.add(taxonNameBase);
170 				}else{
171 					//TODO
172 					logger.warn("TaxonName for NameFact " + nameFactId + " does not exist in store");
173 					success = false;
174 				}
175 				//put
176 			}
177 			if (config.getMaximumNumberOfNameFacts() != 0 && i >= config.getMaximumNumberOfNameFacts() - 1){ 
178 				logger.warn("ONLY " + config.getMaximumNumberOfNameFacts() + " NAMEFACTS imported !!!" )
179 			;};
180 			logger.info("Names to save: " + nameToSave.size());
181 			getNameService().save(nameToSave);	
182 			return success;
183 		} catch (SQLException e) {
184 			logger.error("SQLException:" +  e);
185 			return false;
186 		}
187 
188 	}
189 
190 	/* (non-Javadoc)
191 	 * @see eu.etaxonomy.cdm.io.berlinModel.in.IPartitionedIO#getRelatedObjectsForPartition(java.sql.ResultSet)
192 	 */
193 	public Map<Object, Map<String, ? extends CdmBase>> getRelatedObjectsForPartition(ResultSet rs) {
194 		String nameSpace;
195 		Class cdmClass;
196 		Set<String> idSet;
197 		Map<Object, Map<String, ? extends CdmBase>> result = new HashMap<Object, Map<String, ? extends CdmBase>>();
198 		
199 		try{
200 			Set<String> nameIdSet = new HashSet<String>();
201 			Set<String> referenceIdSet = new HashSet<String>();
202 			while (rs.next()){
203 				handleForeignKey(rs, nameIdSet, "PTnameFk");
204 				handleForeignKey(rs, referenceIdSet, "nameFactRefFk");
205 	}
206 	
207 			//name map
208 			nameSpace = BerlinModelTaxonNameImport.NAMESPACE;
209 			cdmClass = TaxonNameBase.class;
210 			idSet = nameIdSet;
211 			Map<String, Person> objectMap = (Map<String, Person>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
212 			result.put(nameSpace, objectMap);
213 
214 			//nom reference map
215 			nameSpace = BerlinModelReferenceImport.NOM_REFERENCE_NAMESPACE;
216 			cdmClass = ReferenceBase.class;
217 			idSet = referenceIdSet;
218 			Map<String, ReferenceBase> nomReferenceMap = (Map<String, ReferenceBase>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
219 			result.put(nameSpace, nomReferenceMap);
220 
221 			//biblio reference map
222 			nameSpace = BerlinModelReferenceImport.BIBLIO_REFERENCE_NAMESPACE;
223 			cdmClass = ReferenceBase.class;
224 			idSet = referenceIdSet;
225 			Map<String, ReferenceBase> biblioReferenceMap = (Map<String, ReferenceBase>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
226 			result.put(nameSpace, biblioReferenceMap);
227 
228 
229 		} catch (SQLException e) {
230 			throw new RuntimeException(e);
231 		}
232 		return result;
233 	}
234 
235 	
236 	//FIXME gibt es da keine allgemeine Methode in common?
237 	public Media getMedia(String nameFact, URL mediaUrl, File mediaPath){
238 		if (mediaUrl == null){
239 			logger.warn("Media Url should not be null");
240 			return null;
241 		}
242 		String mimeTypeTif = "image/tiff";
243 		String mimeTypeJpg = "image/jpeg";
244 		String mimeTypePng = "image/png";
245 		String mimeTypePdf = "application/pdf"; 
246 		String suffixTif = "tif";
247 		String suffixJpg = "jpg";
248 		String suffixPng = "png";
249 		String suffixPdf = "pdf"; 
250 		
251 		String sep = File.separator;
252 		Integer size = null;
253 		
254 		logger.debug("Getting media for NameFact: " + nameFact);
255 		
256 		Media media = Media.NewInstance();
257 		
258 		String mediaUrlString = mediaUrl.toString();
259 
260 		//tiff
261 		String urlStringTif = mediaUrlString + "tif/" + nameFact + "." + suffixTif;
262 		File file = new File(mediaPath, "tif" + sep + nameFact + "." + suffixTif);
263 		MediaRepresentation representationTif = MediaRepresentation.NewInstance(mimeTypeTif, suffixTif);
264 		if (file.exists()){
265 			representationTif.addRepresentationPart(makeImage(urlStringTif, size, file));
266 		}
267 		if(representationTif.getParts().size() > 0){
268 			media.addRepresentation(representationTif);
269 		}
270 		// end tif
271 		// jpg
272 		boolean fileExists = true;
273 		int jpgCount = 0;
274 		MediaRepresentation representationJpg = MediaRepresentation.NewInstance(mimeTypeJpg, suffixJpg);
275 		while(fileExists){
276 			String urlStringJpeg = mediaUrlString + "cmd_jpg/" + nameFact + "_page_000" + jpgCount + "." + suffixJpg;		
277 			file = new File(mediaPath, "cmd_jpg" + sep + nameFact + "_page_000" + jpgCount + "." + suffixJpg);
278 			jpgCount++;
279 			if (file.exists()){ 
280 				representationJpg.addRepresentationPart(makeImage(urlStringJpeg, size, file));
281 			}else{
282 				fileExists = false;
283 			}
284 		}
285 		if(representationJpg.getParts().size() > 0){
286 			media.addRepresentation(representationJpg);
287 		}
288 		// end jpg
289 		//png
290 		String urlStringPng = mediaUrlString + "png/" + nameFact + "." + suffixPng;
291 		file = new File(mediaPath, "png" + sep + nameFact + "." + suffixPng);
292 		MediaRepresentation representationPng = MediaRepresentation.NewInstance(mimeTypePng, suffixPng);
293 		if (file.exists()){ 
294 			representationPng.addRepresentationPart(makeImage(urlStringPng, size, file));
295 		}else{
296 			fileExists = true;
297 			int pngCount = 0;
298 			while (fileExists){
299 				pngCount++;
300 				urlStringPng = mediaUrlString + "png/" + nameFact + "00" + pngCount + "." + suffixPng;
301 				file = new File(mediaPath, "png" + sep + nameFact + "00" + pngCount + "." + suffixPng);
302 				
303 				if (file.exists()){ 
304 					representationPng.addRepresentationPart(makeImage(urlStringPng, size, file));
305 				}else{
306 					fileExists = false;
307 				}
308 			}
309 		} 
310 		if(representationPng.getParts().size() > 0){
311 			media.addRepresentation(representationPng);
312 		}
313 		//end png
314         //pdf 
315         String urlStringPdf = mediaUrlString + "pdf/" + nameFact + "." + suffixPdf; 
316         file = new File(mediaPath, "pdf" + sep + nameFact + "." + suffixPdf); 
317         MediaRepresentation representationPdf = MediaRepresentation.NewInstance(mimeTypePdf, suffixPdf); 
318         if (file.exists()){  
319                 representationPdf.addRepresentationPart(MediaRepresentationPart.NewInstance(urlStringPdf, size)); 
320         }else{ 
321                 fileExists = true; 
322                 int pdfCount = 0; 
323                 while (fileExists){ 
324                         pdfCount++; 
325                         urlStringPdf = mediaUrlString + "pdf/" + nameFact + "00" + pdfCount + "." + suffixPdf; 
326                         file = new File(mediaPath, "pdf/" + sep + nameFact + "00" + pdfCount + "." + suffixPdf); 
327                          
328                         if (file.exists()){  
329                                 representationPdf.addRepresentationPart(MediaRepresentationPart.NewInstance(urlStringPdf, size)); 
330                         }else{ 
331                                 fileExists = false; 
332                         } 
333                 } 
334         }  
335         if(representationPdf.getParts().size() > 0){
336         	media.addRepresentation(representationPdf);
337         }
338         //end pdf 
339 		
340 		if(logger.isDebugEnabled()){
341 			for (MediaRepresentation rep : media.getRepresentations()){
342 				for (MediaRepresentationPart part : rep.getParts()){
343 					logger.debug("in representation: " + part.getUri());
344 				}
345 			}
346 		}
347 		
348 		return media;
349 	}
350 
351 	
352 	private ImageFile makeImage(String imageUri, Integer size, File file){
353 		ImageMetaData imageMetaData = ImageMetaData.newInstance();
354 		try {
355 			imageMetaData.readMetaData(file.toURI(), 0);
356 		} catch (IOException e) {
357 			logger.error("IOError reading image metadata." , e);
358 		}
359 		ImageFile image = ImageFile.NewInstance(imageUri, size, imageMetaData);
360 		return image;
361 	}
362 
363 	
364 	/* (non-Javadoc)
365 	 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#doCheck(eu.etaxonomy.cdm.io.common.IoStateBase)
366 	 */
367 	@Override
368 	protected boolean doCheck(BerlinModelImportState state){
369 		IOValidator<BerlinModelImportState> validator = new BerlinModelNameFactsImportValidator();
370 		return validator.validate(state);
371 	}
372 
373 	
374 	/* (non-Javadoc)
375 	 * @see eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportBase#getTableName()
376 	 */
377 	@Override
378 	protected String getTableName() {
379 		return dbTableName;
380 	}
381 	
382 	/* (non-Javadoc)
383 	 * @see eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportBase#getPluralString()
384 	 */
385 	@Override
386 	public String getPluralString() {
387 		return pluralString;
388 	}
389 
390 	
391 	/* (non-Javadoc)
392 	 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#isIgnore(eu.etaxonomy.cdm.io.common.IImportConfigurator)
393 	 */
394 	protected boolean isIgnore(BerlinModelImportState state){
395 		return ! state.getConfig().isDoNameFacts();
396 	}
397 	
398 
399 	
400 	//for testing only
401 	public static void main(String[] args) {
402 		
403 		BerlinModelNameFactsImport nf = new BerlinModelNameFactsImport();
404 		
405 		URL url;
406 		try {
407 			url = new URL("http://wp5.e-taxonomy.eu/dataportal/cichorieae/media/protolog/");
408 			File path = new File("/Volumes/protolog/protolog/");
409 			if(path.exists()){
410 				String fact = "Acanthocephalus_amplexifolius";
411 				// make getMedia public for this to work
412 				Media media = nf.getMedia(fact, url, path);
413 				logger.info(media);
414 				for (MediaRepresentation rep : media.getRepresentations()){
415 					logger.info(rep.getMimeType());
416 					for (MediaRepresentationPart part : rep.getParts()){
417 						logger.info(part.getUri());
418 					}
419 				}
420 			}
421 		} catch (MalformedURLException e) {
422 			e.printStackTrace();
423 		}		
424 	}
425 }