package org.molgenis.data.importer.emx; import com.google.common.collect.ImmutableMap; import org.molgenis.data.DataService; import org.molgenis.data.DatabaseAction; import org.molgenis.data.RepositoryCollection; import org.molgenis.data.importer.*; import org.molgenis.data.meta.MetaDataService; import org.molgenis.data.meta.model.EntityType; import org.molgenis.data.support.GenericImporterExtensions; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.core.Ordered; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; import java.io.File; import java.util.LinkedHashMap; import java.util.List; import java.util.Set; import static com.google.common.collect.Lists.newArrayList; import static com.google.common.collect.Maps.newLinkedHashMap; import static java.util.Objects.requireNonNull; import static java.util.stream.StreamSupport.stream; @Component public class EmxImportService implements ImportService { private static final Logger LOG = LoggerFactory.getLogger(EmxImportService.class); private final MetaDataParser parser; private final ImportWriter writer; private final DataService dataService; @Autowired public EmxImportService(MetaDataParser parser, ImportWriter writer, DataService dataService) { this.parser = requireNonNull(parser); this.writer = requireNonNull(writer); this.dataService = requireNonNull(dataService); } @Override public boolean canImport(File file, RepositoryCollection source) { String fileNameExtension = StringUtils.getFilenameExtension(file.getName()); if (GenericImporterExtensions.getEMX().contains(fileNameExtension.toLowerCase())) { for (String entityName : source.getEntityNames()) { if (entityName.equalsIgnoreCase(EmxMetaDataParser.EMX_ATTRIBUTES)) return true; if (entityName.equalsIgnoreCase(EmxMetaDataParser.EMX_LANGUAGES)) return true; if (entityName.equalsIgnoreCase(EmxMetaDataParser.EMX_I18NSTRINGS)) return true; if (dataService.getMeta().getEntityType(entityName) != null) return true; } } return false; } @Override public EntityImportReport doImport(final RepositoryCollection source, DatabaseAction databaseAction, String defaultPackage) { ParsedMetaData parsedMetaData = parser.parse(source, defaultPackage); // TODO altered entities (merge, see getEntityType) return doImport(new EmxImportJob(databaseAction, source, parsedMetaData, defaultPackage)); } /** * Does the import in a transaction. Manually rolls back schema changes if something goes wrong. Refreshes the * metadata. * * @return {@link EntityImportReport} describing what happened */ public EntityImportReport doImport(EmxImportJob job) { try { return writer.doImport(job); } catch (Exception e) { LOG.error("Error handling EmxImportJob", e); throw e; } } @Override public EntitiesValidationReport validateImport(File file, RepositoryCollection source) { return parser.validate(source); } @Override public int getOrder() { return Ordered.HIGHEST_PRECEDENCE; } @Override public List<DatabaseAction> getSupportedDatabaseActions() { return newArrayList(DatabaseAction.values()); } @Override public boolean getMustChangeEntityName() { return false; } @Override public Set<String> getSupportedFileExtensions() { return GenericImporterExtensions.getEMX(); } @Override public LinkedHashMap<String, Boolean> determineImportableEntities(MetaDataService metaDataService, RepositoryCollection repositoryCollection, String selectedPackage) { List<String> skipEntities = newArrayList(EmxMetaDataParser.EMX_ATTRIBUTES, EmxMetaDataParser.EMX_PACKAGES, EmxMetaDataParser.EMX_ENTITIES, EmxMetaDataParser.EMX_TAGS); ImmutableMap<String, EntityType> EntityTypeMap = parser.parse(repositoryCollection, selectedPackage) .getEntityMap(); LinkedHashMap<String, Boolean> importableEntitiesMap = newLinkedHashMap(); stream(EntityTypeMap.keySet().spliterator(), false).forEach(entityName -> { boolean importable = skipEntities.contains(entityName) || metaDataService .isEntityTypeCompatible(EntityTypeMap.get(entityName)); importableEntitiesMap.put(entityName, importable); }); return importableEntitiesMap; } }