package org.gbif.ipt.utils; import org.gbif.ipt.model.Resource; import org.gbif.ipt.service.InvalidConfigException; import org.gbif.ipt.service.InvalidConfigException.TYPE; import org.gbif.metadata.eml.Eml; import org.gbif.metadata.eml.EmlFactory; import org.gbif.metadata.eml.EmlWriter; import org.gbif.metadata.eml.KeywordSet; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.util.Iterator; import java.util.List; import java.util.Locale; import com.google.common.base.Strings; import freemarker.template.TemplateException; import org.apache.commons.lang3.StringUtils; import org.apache.log4j.Logger; import org.xml.sax.SAXException; /** * Utility class for common operation on EML documents/files. */ public class EmlUtils { protected static final Logger LOG = Logger.getLogger(EmlUtils.class); /* * Empty constructor. */ private EmlUtils() { } /** * Add or update KeywordSet identified by thesaurus name. If the KeywordSet is found and already contains a * a non empty and not null keywordString, its value is not overwritten. * * @param keywords list of KeywordSet to add/update to * @param keyword keyword string * @param thesaurus thesaurus name */ public static void addOrUpdateKeywordSet(List<KeywordSet> keywords, String keyword, String thesaurus) { if (!Strings.isNullOrEmpty(keyword) && !Strings.isNullOrEmpty(thesaurus)) { // capitalize incoming keyword, i.e., Occurrence, Specimen String capped = StringUtils.capitalize(keyword.toLowerCase()); boolean found = false; for (KeywordSet ks : keywords) { String keywordThesaurus = ks.getKeywordThesaurus(); if (!Strings.isNullOrEmpty(keywordThesaurus) && keywordThesaurus.equalsIgnoreCase(thesaurus)) { String keywordString = ks.getKeywordsString(); // update keywordString, only if empty if (Strings.isNullOrEmpty(keywordString)) { ks.setKeywordsString(capped); } found = true; break; } } // if no match, add new KeywordSet if (!found) { KeywordSet ks = new KeywordSet(); ks.setKeywordThesaurus(thesaurus); ks.setKeywordsString(capped); // add new KeywordSet keywords.add(ks); } } } /** * Remove all KeywordSet with specific thesaurus name. * * @param keywords list of KeywordSet to remove from * @param thesaurus thesaurus name */ public static void removeKeywordSet(List<KeywordSet> keywords, String thesaurus) { if (!Strings.isNullOrEmpty(thesaurus)) { for (Iterator<KeywordSet> iterator = keywords.iterator(); iterator.hasNext();) { String keywordThesaurus = iterator.next().getKeywordThesaurus(); if (!Strings.isNullOrEmpty(keywordThesaurus) && keywordThesaurus.equalsIgnoreCase(thesaurus)) { iterator.remove(); } } } } /** * Writes the EML file using a specific locale to interpret correctly: decimal separators, commas and currency * formats. */ public static void writeWithLocale(File emlFile, Resource resource, Locale locale) { Locale currentLocale = Locale.getDefault(); try { synchronized (currentLocale) { Locale.setDefault(locale); EmlWriter.writeEmlFile(emlFile, resource.getEml()); Locale.setDefault(currentLocale); } } catch (IOException e) { LOG.error(e); throw new InvalidConfigException(TYPE.CONFIG_WRITE, "IO exception when writing eml for " + resource); } catch (TemplateException e) { LOG.error("EML template exception", e); throw new InvalidConfigException(TYPE.EML, "EML template exception when writing eml for " + resource + ": " + e.getMessage()); } finally { Locale.setDefault(currentLocale); } } /** * Reads an EML file using a specific Locale to interpret correctly: decimal separators, commas and currency formats. * * @param emlFile EML file to read from * @param locale Locale to use when interpreting EML file * * @return EML file read from file, or new EML instance if the file to load from did not exist, or could not be parsed */ public static Eml loadWithLocale(File emlFile, Locale locale) { Eml eml = null; Locale currentLocale = Locale.getDefault(); try { InputStream in = new FileInputStream(emlFile); synchronized (currentLocale) { Locale.setDefault(locale); eml = EmlFactory.build(in); Locale.setDefault(currentLocale); } } catch (FileNotFoundException e) { eml = new Eml(); } catch (IOException e) { LOG.error(e); } catch (SAXException e) { LOG.error("Invalid EML document", e); eml = new Eml(); } catch (Exception e) { eml = new Eml(); } finally { Locale.setDefault(currentLocale); } return eml; } }